Skip to content

Commit

Permalink
feat(ast-dump): add flag for main check, type check to be enabled if …
Browse files Browse the repository at this point in the history
…needed
  • Loading branch information
JaDogg committed Mar 2, 2024
1 parent 4638ba3 commit 95a5855
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 39 deletions.
30 changes: 23 additions & 7 deletions compiler/src/ast_json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,22 +43,38 @@
#ifndef PROGRAM_NAME
#define PROGRAM_NAME "ast"
#endif
#include "utilities/argparser.h"
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";
auto args = argparser::ARGS(PROGRAM_NAME, "Compile Yaksha AST to Json", "");
auto help = argparser::OP_BOOL('h', "--help", "Print this help message");
auto check_main = argparser::OP_BOOL('c', "--check-main", "Enable main() check");
auto check_types = argparser::OP_BOOL('t', "--check-types", "Enable type checking");
args.optional_ = {&help, &check_main, &check_types};
auto code = argparser::PO("mainfile.yaka", "Yaksha code file.");
auto lib = argparser::PO_OPT("[LIBS_PARENT_PATH]", "Path to the parent directory of the libraries");
args.positional_ = {&code, &lib};
argparser::parse_args(argc, argv, args);
if (help.is_set_) {
argparser::print_help(args);
return EXIT_SUCCESS;
}
if (!args.errors_.empty()) {
argparser::print_errors(args);
argparser::print_help(args);
return EXIT_FAILURE;
}
comp_result result;
try {
multifile_compiler mc{};
mc.main_required_ = false;
mc.main_required_ = check_main.is_set_;
mc.check_types_ = check_types.is_set_;
mc.usage_analysis_ = false; // disable usage analysis as JSON will dump all
codegen_json cg{};
if (argc == 2) {// Just code.yaka is passed
result = mc.compile(argv[1], &cg);
if (!lib.is_set_) {// Just code.yaka is passed
result = mc.compile(code.value_, &cg);
} else {// code.yaka + LIBS_PARENT_PATH
result = mc.compile(argv[1], argv[2], &cg);
result = mc.compile(code.value_, lib.value_, &cg);
}
if (result.failed_) { return EXIT_FAILURE; }
} catch (parsing_error &e) { errors::print_errors({e}); }
Expand Down
68 changes: 36 additions & 32 deletions compiler/src/compiler/multifile_compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,41 +191,45 @@ comp_result multifile_compiler::compile_all(codegen *code_generator) {
return {true, ""};
}
LOG_COMP("has a main() or no main required");
// Ensure all data types have the proper module
for (auto f : cf_->files_) { f->data_->parser_->rescan_datatypes(); }
// Type check all files
for (auto f : cf_->files_) {
f->data_->type_checker_ =
new type_checker(f->filepath_.string(), cf_, f->data_->dsv_,
&(cf_->pool_), &token_pool_);
// TODO create a function in the type checker to do this
for (auto impo : f->data_->parser_->import_stmts_) {
auto obj = ykobject(&(cf_->pool_));
obj.object_type_ = object_type::MODULE;
obj.string_val_ = impo->data_->filepath_.string();
obj.module_file_ = impo->data_->filepath_.string();
obj.module_name_ = impo->name_->token_;
f->data_->type_checker_->scope_.define_global(impo->name_->token_, obj);
if (check_types_) {
// Ensure all data types have the proper module
for (auto f : cf_->files_) { f->data_->parser_->rescan_datatypes(); }
// Type check all files
for (auto f : cf_->files_) {
f->data_->type_checker_ =
new type_checker(f->filepath_.string(), cf_, f->data_->dsv_,
&(cf_->pool_), &token_pool_);
// TODO create a function in the type checker to do this
for (auto impo : f->data_->parser_->import_stmts_) {
auto obj = ykobject(&(cf_->pool_));
obj.object_type_ = object_type::MODULE;
obj.string_val_ = impo->data_->filepath_.string();
obj.module_file_ = impo->data_->filepath_.string();
obj.module_name_ = impo->name_->token_;
f->data_->type_checker_->scope_.define_global(impo->name_->token_, obj);
}
f->data_->type_checker_->check(f->data_->parser_->stmts_);
if (!f->data_->type_checker_->errors_.empty()) {
errors::print_errors(f->data_->type_checker_->errors_);
LOG_COMP("type checker found errors: " << f->filepath_.string());
has_errors = true;
}
}
f->data_->type_checker_->check(f->data_->parser_->stmts_);
if (!f->data_->type_checker_->errors_.empty()) {
errors::print_errors(f->data_->type_checker_->errors_);
LOG_COMP("type checker found errors: " << f->filepath_.string());
has_errors = true;
if (has_errors) {
LOG_COMP("found type checking errors");
return {true, ""};
}
}
if (has_errors) {
LOG_COMP("found type checking errors");
return {true, ""};
}
// Statement usage analysis
// So we know which 'functions / classes / consts' are actually used
usage_analyser ua{main_file_info};
ua.analyse();
if (!ua.errors_.empty()) {
errors::print_errors(ua.errors_);
LOG_COMP("usage analyser found errors");
return {true, ""};
if (usage_analysis_) {
// Statement usage analysis
// So we know which 'functions / classes / consts' are actually used
usage_analyser ua{main_file_info};
ua.analyse();
if (!ua.errors_.empty()) {
errors::print_errors(ua.errors_);
LOG_COMP("usage analyser found errors");
return {true, ""};
}
}
return code_generator->emit(cf_, &token_pool_);
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/src/compiler/multifile_compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ namespace yaksha {
const std::string &libs_path, codegen *code_generator);
[[nodiscard]] codefiles &get_codefiles() const;
bool main_required_ = true;
bool check_types_ = true;
bool usage_analysis_ = true;

private:
gc_pool<token> token_pool_{};
Expand Down

0 comments on commit 95a5855

Please sign in to comment.