Skip to content

Commit

Permalink
feat: initial skeleton version of ast export feature
Browse files Browse the repository at this point in the history
  • Loading branch information
JaDogg committed Jan 13, 2024
1 parent 97651e2 commit 5e17e1c
Show file tree
Hide file tree
Showing 9 changed files with 221 additions and 4 deletions.
3 changes: 2 additions & 1 deletion compiler/scripts/update_makefile.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@
import os.path
from typing import List, Tuple

IGNORE = ["main.cpp", "test_main.cpp", "fuzz_main.cpp", "viz_main.cpp", "utf8proc_data.c", "print_str.c", "dump.cpp",
IGNORE = ["main.cpp", "test_main.cpp", "fuzz_main.cpp", "viz_main.cpp",
"ast_json.cpp", "utf8proc_data.c", "print_str.c", "dump.cpp",
"comp_main.cpp", "reloader.cpp", "reloader_alt.cpp", "yk__wasm4_libc.c",
"yk__fake_whereami.c", "yk.cpp", "carpntr_wrapper.cpp", "lisp_main.cpp",
"html_gen.cpp", "_include_io.c", "_include_mman_win.c", "_include_bstr.c"]
Expand Down
2 changes: 2 additions & 0 deletions compiler/src/ast/codefiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ file_info *codefiles::initialize_parsing_or_null(const std::string &code,
path_to_fi_[str_path] = fi;
prefixes_.insert({"yy__"});
files_.emplace_back(fi);
this->main_file_info_ = fi;
for (auto imp : fi->data_->parser_->import_stmts_) {
auto import_data = scan_or_null(imp);
if (import_data == nullptr) { return nullptr; }
Expand Down Expand Up @@ -117,6 +118,7 @@ file_info *codefiles::initialize_parsing_or_null(const std::string &filename) {
path_to_fi_[str_path] = fi;
prefixes_.insert({"yy__"});
files_.emplace_back(fi);
this->main_file_info_ = fi;
for (auto imp : fi->data_->parser_->import_stmts_) {
auto import_data = scan_or_null(imp);
if (import_data == nullptr) { return nullptr; }
Expand Down
1 change: 1 addition & 0 deletions compiler/src/ast/codefiles.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ namespace yaksha {
const std::string &filename);
file_info *scan_or_null(import_stmt *st);
std::vector<file_info *> files_;
file_info *main_file_info_{nullptr};
ykdt_pool pool_;
yaksha_macros yaksha_macros_{};
entry_struct_func_compiler *esc_;
Expand Down
66 changes: 66 additions & 0 deletions compiler/src/ast_json.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// ==============================================================================================
// ╦ ┬┌─┐┌─┐┌┐┌┌─┐┌─┐ Yaksha Programming Language
// ║ ││ ├┤ │││└─┐├┤ is Licensed with GPLv3 + exta terms. Please see below.
// ╩═╝┴└─┘└─┘┘└┘└─┘└─┘
// Note: libs - MIT license, runtime/3rd - various
// ==============================================================================================
// GPLv3:
//
// Yaksha - Programming Language.
// Copyright (C) 2020 - 2023 Bhathiya Perera
//
// This program is free software: you can redistribute it and/or modify it under the terms
// of the GNU General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with this program.
// If not, see https://www.gnu.org/licenses/.
//
// ==============================================================================================
// Additional Terms:
//
// Please note that any commercial use of the programming language's compiler source code
// (everything except compiler/runtime, compiler/libs and compiler/3rd) require a written agreement
// with author of the language (Bhathiya Perera).
//
// If you are using it for an open source project, please give credits.
// Your own project must use GPLv3 license with these additional terms.
//
// You may use programs written in Yaksha/YakshaLisp for any legal purpose
// (commercial, open-source, closed-source, etc) as long as it agrees
// to the licenses of linked runtime libraries (see compiler/runtime/README.md).
//
// ==============================================================================================
#include "compiler/codegen_json.h"
#include "compiler/multifile_compiler.h"
#include "utilities/error_printer.h"
#include <iostream>
#ifndef PROGRAM_NAME
#define PROGRAM_NAME "ast"
#endif
using namespace yaksha;
int main(int argc, char *argv[]) {
if (argc != 2 && argc != 3) {
std::cerr << "Usage: " << PROGRAM_NAME
<< " script.yaka [LIBS_PARENT_PATH]\n";
return EXIT_FAILURE;
}
comp_result result;
try {
multifile_compiler mc{};
codegen_json cg{};
if (argc == 2) {// Just code.yaka is passed
result = mc.compile(argv[1], &cg);
} else { // code.yaka + LIBS_PARENT_PATH
result = mc.compile(argv[1], argv[2], &cg);
}
if (result.failed_) { return EXIT_FAILURE; }
} catch (parsing_error &e) { errors::print_errors({e}); }
std::cout << result.code_;
return EXIT_SUCCESS;
}
4 changes: 2 additions & 2 deletions compiler/src/comp_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ int main(int argc, char *argv[]) {
try {
multifile_compiler mc{};
codegen_c cg{};
if (argc == 2) {// Just script is passed
if (argc == 2) {// Just code.yaka is passed
result = mc.compile(argv[1], &cg);
} else {// Script + LIBS_PARENT_PATH
} else { // code.yaka + LIBS_PARENT_PATH
result = mc.compile(argv[1], argv[2], &cg);
}
if (result.failed_) { return EXIT_FAILURE; }
Expand Down
90 changes: 89 additions & 1 deletion compiler/src/compiler/codegen_json.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,96 @@
// codegen_json.cpp
#include "codegen_json.h"
#include "ast/codefiles.h"
#include "ast/parser.h"
#include "compiler/comp_result.h"
using namespace yaksha;
codegen_json::codegen_json() = default;
codegen_json::~codegen_json() = default;
comp_result codegen_json::emit(codefiles *cf, gc_pool<token> *token_pool) { return comp_result(); }
comp_result codegen_json::emit(codefiles *cf, gc_pool<token> *token_pool) {
to_json_compiler to_json{};
return {false, to_json.compile(cf->main_file_info_)};
}
std::string to_json_compiler::compile(file_info *fi) {
// Compile the main file to a JSON
json_ << "{\n";
json_ << "\"file\": \"" << fi->filepath_.string() << "\",\n";
json_ << "\"ast\": [\n";
auto statements = fi->data_->parser_->stmts_;
for (auto stmt : statements) {
stmt->accept(this);
}
json_ << "]\n";
json_ << "}\n";
return json_.str();
}
void to_json_compiler::visit_assign_expr(assign_expr *obj) {}
void to_json_compiler::visit_assign_arr_expr(assign_arr_expr *obj) {}
void to_json_compiler::visit_assign_member_expr(assign_member_expr *obj) {}
void to_json_compiler::visit_binary_expr(binary_expr *obj) {}
void to_json_compiler::visit_curly_call_expr(curly_call_expr *obj) {}
void to_json_compiler::visit_fncall_expr(fncall_expr *obj) {}
void to_json_compiler::visit_get_expr(get_expr *obj) {}
void to_json_compiler::visit_grouping_expr(grouping_expr *obj) {}
void to_json_compiler::visit_literal_expr(literal_expr *obj) {}
void to_json_compiler::visit_logical_expr(logical_expr *obj) {}
void to_json_compiler::visit_macro_call_expr(macro_call_expr *obj) {}
void to_json_compiler::visit_set_expr(set_expr *obj) {}
void to_json_compiler::visit_square_bracket_access_expr(
square_bracket_access_expr *obj) {}
void to_json_compiler::visit_square_bracket_set_expr(
square_bracket_set_expr *obj) {}
void to_json_compiler::visit_unary_expr(unary_expr *obj) {}
void to_json_compiler::visit_variable_expr(variable_expr *obj) {}
void to_json_compiler::visit_block_stmt(block_stmt *obj) {
// Code blocks?
}
void to_json_compiler::visit_break_stmt(break_stmt *obj) {}
void to_json_compiler::visit_ccode_stmt(ccode_stmt *obj) {}
void to_json_compiler::visit_cfor_stmt(cfor_stmt *obj) {}
void to_json_compiler::visit_class_stmt(class_stmt *obj) {
// Both classes and structs are treated the same way
}
void to_json_compiler::visit_compins_stmt(compins_stmt *obj) {
// This is a special to_c_compiler instruction, no need to be implemented here
}
void to_json_compiler::visit_const_stmt(const_stmt *obj) {}
void to_json_compiler::visit_continue_stmt(continue_stmt *obj) {}
void to_json_compiler::visit_def_stmt(def_stmt *obj) {
auto name = obj->name_->token_;
json_ << "{\n";
json_ << "\"type\": \"def\",\n";
json_ << "\"name\": \"" << name << "\",\n";
json_ << "\"params\": [\n";
for (auto& param: obj->params_) {
json_ << "{\n";
json_ << "\"name\": \"" << param.name_->token_ << "\",\n";
json_ << "\"type\": \"" << param.data_type_->as_string() << "\"\n";
json_ << "},\n";
}
json_ << "],\n";
json_ << "\"return_type\": \"" << obj->return_type_->as_string() << "\",\n";
json_ << "\"body\": [\n";
obj->function_body_->accept(this); // visit block_stmt
json_ << "]\n";
json_ << "},\n";
}
void to_json_compiler::visit_defer_stmt(defer_stmt *obj) {}
void to_json_compiler::visit_del_stmt(del_stmt *obj) {}
void to_json_compiler::visit_enum_stmt(enum_stmt *obj) {}
void to_json_compiler::visit_expression_stmt(expression_stmt *obj) {}
void to_json_compiler::visit_foreach_stmt(foreach_stmt *obj) {}
void to_json_compiler::visit_forendless_stmt(forendless_stmt *obj) {}
void to_json_compiler::visit_if_stmt(if_stmt *obj) {}
void to_json_compiler::visit_import_stmt(import_stmt *obj) {}
void to_json_compiler::visit_let_stmt(let_stmt *obj) {}
void to_json_compiler::visit_nativeconst_stmt(nativeconst_stmt *obj) {}
void to_json_compiler::visit_pass_stmt(pass_stmt *obj) {}
void to_json_compiler::visit_return_stmt(return_stmt *obj) {}
void to_json_compiler::visit_runtimefeature_stmt(runtimefeature_stmt *obj) {
}
void to_json_compiler::visit_union_stmt(union_stmt *obj) {
// Placeholder statement - this is not parsed
}
void to_json_compiler::visit_while_stmt(while_stmt *obj) {
// Placeholder statement - this is not parsed
}
50 changes: 50 additions & 0 deletions compiler/src/compiler/codegen_json.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// codegen_json.h
#ifndef CODEGEN_JSON_H
#define CODEGEN_JSON_H
#include "ast/ast.h"
#include "codegen.h"
namespace yaksha {
struct codegen_json: codegen {
Expand All @@ -10,5 +11,54 @@ namespace yaksha {

private:
};

struct to_json_compiler : expr_visitor, stmt_visitor {
std::string compile(file_info *fi);
// -------------- expr_visitor --------------
void visit_assign_expr(assign_expr *obj) override;
void visit_assign_arr_expr(assign_arr_expr *obj) override;
void visit_assign_member_expr(assign_member_expr *obj) override;
void visit_binary_expr(binary_expr *obj) override;
void visit_curly_call_expr(curly_call_expr *obj) override;
void visit_fncall_expr(fncall_expr *obj) override;
void visit_get_expr(get_expr *obj) override;
void visit_grouping_expr(grouping_expr *obj) override;
void visit_literal_expr(literal_expr *obj) override;
void visit_logical_expr(logical_expr *obj) override;
void visit_macro_call_expr(macro_call_expr *obj) override;
void visit_set_expr(set_expr *obj) override;
void visit_square_bracket_access_expr(
square_bracket_access_expr *obj) override;
void visit_square_bracket_set_expr(square_bracket_set_expr *obj) override;
void visit_unary_expr(unary_expr *obj) override;
void visit_variable_expr(variable_expr *obj) override;
// -------------- stmt_visitor --------------
void visit_block_stmt(block_stmt *obj) override;
void visit_break_stmt(break_stmt *obj) override;
void visit_ccode_stmt(ccode_stmt *obj) override;
void visit_cfor_stmt(cfor_stmt *obj) override;
void visit_class_stmt(class_stmt *obj) override;
void visit_compins_stmt(compins_stmt *obj) override;
void visit_const_stmt(const_stmt *obj) override;
void visit_continue_stmt(continue_stmt *obj) override;
void visit_def_stmt(def_stmt *obj) override;
void visit_defer_stmt(defer_stmt *obj) override;
void visit_del_stmt(del_stmt *obj) override;
void visit_enum_stmt(enum_stmt *obj) override;
void visit_expression_stmt(expression_stmt *obj) override;
void visit_foreach_stmt(foreach_stmt *obj) override;
void visit_forendless_stmt(forendless_stmt *obj) override;
void visit_if_stmt(if_stmt *obj) override;
void visit_import_stmt(import_stmt *obj) override;
void visit_let_stmt(let_stmt *obj) override;
void visit_nativeconst_stmt(nativeconst_stmt *obj) override;
void visit_pass_stmt(pass_stmt *obj) override;
void visit_return_stmt(return_stmt *obj) override;
void visit_runtimefeature_stmt(runtimefeature_stmt *obj) override;
void visit_union_stmt(union_stmt *obj) override;
void visit_while_stmt(while_stmt *obj) override;
private:
std::stringstream json_{};
};
}
#endif
1 change: 1 addition & 0 deletions compiler/src/utilities/cpp_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ constexpr auto operator+(T e) noexcept
#else
#define LOG_COMP(msg)
#endif
// Enable below to perform dead code elimination
#ifndef YAKSHA_DEADCODE_ELIMINATION
#define YAKSHA_DEADCODE_ELIMINATION
#endif
Expand Down
8 changes: 8 additions & 0 deletions compiler/src/yk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@
#include "comp_main.cpp"
#undef main
#undef PROGRAM_NAME
#define PROGRAM_NAME "yaksha ast"
#define main ast_main
#include "ast_json.cpp"
#undef main
#undef PROGRAM_NAME
// dump_main(int: argc, char** argv)
#define PROGRAM_NAME "yaksha dump"
#define main dump_main
Expand Down Expand Up @@ -134,6 +139,8 @@ void display_help() {
std::cout << colours::green(
" # Compile a given file (must have main() function), library "
"path is required if libs are used\n");
std::cout << "yaksha ast file_path.yaka [libs_path]\n";
std::cout << colours::green(" # Compile Yaksha to a JSON representation of the AST\n");
std::cout << "yaksha reload dll_path/dll.so\n";
std::cout << colours::green(" # Run given hot-reload .dll/.dylib/.so file\n");
std::cout << "yaksha viz file_path.yaka\n";
Expand Down Expand Up @@ -162,6 +169,7 @@ int main(int argc, char *argv[]) {
return EXIT_SUCCESS;
}
if (first_arg == "compile") { return compiler_main(argc - 1, &argv[1]); }
if (first_arg == "ast") { return ast_main(argc - 1, &argv[1]); }
if (first_arg == "reload") { return reloader_main(argc - 1, &argv[1]); }
if (first_arg == "viz") { return viz_main(argc - 1, &argv[1]); }
if (first_arg == "dump") { return dump_main(argc - 1, &argv[1]); }
Expand Down

0 comments on commit 5e17e1c

Please sign in to comment.