From 88e4b86ccb3c3da535651e4f124d1f4a83a10be3 Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Tue, 31 Oct 2023 00:36:49 +0800 Subject: [PATCH] :sparkles: add new module import syntax rule --- src/ast_dumper.cpp | 14 ++++++++++++++ src/ast_dumper.h | 1 + src/ast_visitor.cpp | 7 +++++++ src/ast_visitor.h | 1 + src/nasal_ast.cpp | 10 ++++++++++ src/nasal_ast.h | 15 +++++++++++++++ src/nasal_codegen.cpp | 1 + src/nasal_lexer.h | 2 ++ src/nasal_parse.cpp | 13 +++++++++++++ src/nasal_parse.h | 2 ++ 10 files changed, 66 insertions(+) diff --git a/src/ast_dumper.cpp b/src/ast_dumper.cpp index 525d42a9..900fdd8e 100644 --- a/src/ast_dumper.cpp +++ b/src/ast_dumper.cpp @@ -4,6 +4,20 @@ namespace nasal { +bool ast_dumper::visit_use_stmt(use_stmt* node) { + dump_indent(); + std::cout << "use" << format_location(node->get_location()); + push_indent(); + for(auto i : node->get_path()) { + if (i==node->get_path().back()) { + set_last(); + } + i->accept(this); + } + pop_indent(); + return true; +} + bool ast_dumper::visit_null_expr(null_expr* node) { dump_indent(); std::cout << "null" << format_location(node->get_location()); diff --git a/src/ast_dumper.h b/src/ast_dumper.h index 13856986..b5014d5d 100644 --- a/src/ast_dumper.h +++ b/src/ast_dumper.h @@ -41,6 +41,7 @@ class ast_dumper:public ast_visitor { } public: + bool visit_use_stmt(use_stmt*) override; bool visit_null_expr(null_expr*) override; bool visit_nil_expr(nil_expr*) override; bool visit_number_literal(number_literal*) override; diff --git a/src/ast_visitor.cpp b/src/ast_visitor.cpp index 677c0433..f438b4b1 100644 --- a/src/ast_visitor.cpp +++ b/src/ast_visitor.cpp @@ -7,6 +7,13 @@ bool ast_visitor::visit_expr(expr* node) { return true; } +bool ast_visitor::visit_use_stmt(use_stmt* node) { + for(auto i : node->get_path()) { + i->accept(this); + } + return true; +} + bool ast_visitor::visit_call(call* node) { node->accept(this); return true; diff --git a/src/ast_visitor.h b/src/ast_visitor.h index 62f4dff3..4235541d 100644 --- a/src/ast_visitor.h +++ b/src/ast_visitor.h @@ -7,6 +7,7 @@ namespace nasal { class ast_visitor { public: virtual bool visit_expr(expr*); + virtual bool visit_use_stmt(use_stmt*); virtual bool visit_call(call*); virtual bool visit_null_expr(null_expr*); virtual bool visit_nil_expr(nil_expr*); diff --git a/src/nasal_ast.cpp b/src/nasal_ast.cpp index a1c88597..b1c27e14 100644 --- a/src/nasal_ast.cpp +++ b/src/nasal_ast.cpp @@ -7,6 +7,16 @@ void expr::accept(ast_visitor* visitor) { visitor->visit_expr(this); } +use_stmt::~use_stmt() { + for(auto i : path) { + delete i; + } +} + +void use_stmt::accept(ast_visitor* visitor) { + visitor->visit_use_stmt(this); +} + void call::accept(ast_visitor* visitor) { visitor->visit_call(this); } diff --git a/src/nasal_ast.h b/src/nasal_ast.h index 4d8c6c17..eb75e168 100644 --- a/src/nasal_ast.h +++ b/src/nasal_ast.h @@ -10,6 +10,7 @@ namespace nasal { enum class expr_type:u32 { ast_null = 0, // null node + ast_use, // use statement ast_block, // code block ast_nil, // nil keyword ast_num, // number, basic value type @@ -46,6 +47,7 @@ enum class expr_type:u32 { }; class ast_visitor; +class identifier; class hash_pair; class parameter; class slice_vector; @@ -77,6 +79,19 @@ class expr { virtual void accept(ast_visitor*); }; +class use_stmt: public expr { +private: + std::vector path; + +public: + use_stmt(const span& location): + expr(location, expr_type::ast_use) {} + ~use_stmt() override; + void accept(ast_visitor*) override; + void add_path(identifier* node) {path.push_back(node);} + const auto& get_path() const {return path;} +}; + class call: public expr { public: call(const span& location, expr_type node_type): diff --git a/src/nasal_codegen.cpp b/src/nasal_codegen.cpp index 04443e66..37d4906a 100644 --- a/src/nasal_codegen.cpp +++ b/src/nasal_codegen.cpp @@ -1166,6 +1166,7 @@ void codegen::repl_mode_info_output_gen(expr* node) { void codegen::block_gen(code_block* node) { for(auto tmp : node->get_expressions()) { switch(tmp->get_type()) { + case expr_type::ast_use: break; case expr_type::ast_null: break; case expr_type::ast_id: if (need_repl_output && local.empty()) { diff --git a/src/nasal_lexer.h b/src/nasal_lexer.h index 2862a571..99c200d5 100644 --- a/src/nasal_lexer.h +++ b/src/nasal_lexer.h @@ -28,6 +28,7 @@ enum class tok:u32 { id, // identifier tktrue, // keyword true tkfalse, // keyword false + use, // keyword use rfor, // loop keyword for forindex, // loop keyword forindex foreach, // loop keyword foreach @@ -103,6 +104,7 @@ class lexer { std::vector toks; const std::unordered_map typetbl { + {"use" ,tok::use }, {"true" ,tok::tktrue }, {"false" ,tok::tkfalse }, {"for" ,tok::rfor }, diff --git a/src/nasal_parse.cpp b/src/nasal_parse.cpp index 71111afb..60d4dbc7 100644 --- a/src/nasal_parse.cpp +++ b/src/nasal_parse.cpp @@ -197,6 +197,18 @@ void parse::update_location(expr* node) { node->update_location(toks[ptr-1].loc); } +use_stmt* parse::use_stmt_gen() { + auto node = new use_stmt(toks[ptr].loc); + match(tok::use); + node->add_path(id()); + while(lookahead(tok::dot)) { + match(tok::dot); + node->add_path(id()); + } + update_location(node); + return node; +} + null_expr* parse::null() { return new null_expr(toks[ptr].loc); } @@ -355,6 +367,7 @@ expr* parse::expression() { die(thisspan, "must use return in functions"); } switch(type) { + case tok::use: return use_stmt_gen(); case tok::tknil: case tok::num: case tok::str: diff --git a/src/nasal_parse.h b/src/nasal_parse.h index 1bcf5080..472b3427 100644 --- a/src/nasal_parse.h +++ b/src/nasal_parse.h @@ -24,6 +24,7 @@ class parse { private: const std::unordered_map tokname { + {tok::use ,"use" }, {tok::rfor ,"for" }, {tok::forindex,"forindex"}, {tok::foreach ,"foreach" }, @@ -92,6 +93,7 @@ class parse { void update_location(expr*); private: + use_stmt* use_stmt_gen(); null_expr* null(); nil_expr* nil(); number_literal* num();