✨ add new module import syntax rule
This commit is contained in:
parent
c35ad2e6fa
commit
88e4b86ccb
|
@ -4,6 +4,20 @@
|
||||||
|
|
||||||
namespace nasal {
|
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) {
|
bool ast_dumper::visit_null_expr(null_expr* node) {
|
||||||
dump_indent();
|
dump_indent();
|
||||||
std::cout << "null" << format_location(node->get_location());
|
std::cout << "null" << format_location(node->get_location());
|
||||||
|
|
|
@ -41,6 +41,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
bool visit_use_stmt(use_stmt*) override;
|
||||||
bool visit_null_expr(null_expr*) override;
|
bool visit_null_expr(null_expr*) override;
|
||||||
bool visit_nil_expr(nil_expr*) override;
|
bool visit_nil_expr(nil_expr*) override;
|
||||||
bool visit_number_literal(number_literal*) override;
|
bool visit_number_literal(number_literal*) override;
|
||||||
|
|
|
@ -7,6 +7,13 @@ bool ast_visitor::visit_expr(expr* node) {
|
||||||
return true;
|
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) {
|
bool ast_visitor::visit_call(call* node) {
|
||||||
node->accept(this);
|
node->accept(this);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -7,6 +7,7 @@ namespace nasal {
|
||||||
class ast_visitor {
|
class ast_visitor {
|
||||||
public:
|
public:
|
||||||
virtual bool visit_expr(expr*);
|
virtual bool visit_expr(expr*);
|
||||||
|
virtual bool visit_use_stmt(use_stmt*);
|
||||||
virtual bool visit_call(call*);
|
virtual bool visit_call(call*);
|
||||||
virtual bool visit_null_expr(null_expr*);
|
virtual bool visit_null_expr(null_expr*);
|
||||||
virtual bool visit_nil_expr(nil_expr*);
|
virtual bool visit_nil_expr(nil_expr*);
|
||||||
|
|
|
@ -7,6 +7,16 @@ void expr::accept(ast_visitor* visitor) {
|
||||||
visitor->visit_expr(this);
|
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) {
|
void call::accept(ast_visitor* visitor) {
|
||||||
visitor->visit_call(this);
|
visitor->visit_call(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ namespace nasal {
|
||||||
|
|
||||||
enum class expr_type:u32 {
|
enum class expr_type:u32 {
|
||||||
ast_null = 0, // null node
|
ast_null = 0, // null node
|
||||||
|
ast_use, // use statement
|
||||||
ast_block, // code block
|
ast_block, // code block
|
||||||
ast_nil, // nil keyword
|
ast_nil, // nil keyword
|
||||||
ast_num, // number, basic value type
|
ast_num, // number, basic value type
|
||||||
|
@ -46,6 +47,7 @@ enum class expr_type:u32 {
|
||||||
};
|
};
|
||||||
|
|
||||||
class ast_visitor;
|
class ast_visitor;
|
||||||
|
class identifier;
|
||||||
class hash_pair;
|
class hash_pair;
|
||||||
class parameter;
|
class parameter;
|
||||||
class slice_vector;
|
class slice_vector;
|
||||||
|
@ -77,6 +79,19 @@ public:
|
||||||
virtual void accept(ast_visitor*);
|
virtual void accept(ast_visitor*);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class use_stmt: public expr {
|
||||||
|
private:
|
||||||
|
std::vector<identifier*> 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 {
|
class call: public expr {
|
||||||
public:
|
public:
|
||||||
call(const span& location, expr_type node_type):
|
call(const span& location, expr_type node_type):
|
||||||
|
|
|
@ -1166,6 +1166,7 @@ void codegen::repl_mode_info_output_gen(expr* node) {
|
||||||
void codegen::block_gen(code_block* node) {
|
void codegen::block_gen(code_block* node) {
|
||||||
for(auto tmp : node->get_expressions()) {
|
for(auto tmp : node->get_expressions()) {
|
||||||
switch(tmp->get_type()) {
|
switch(tmp->get_type()) {
|
||||||
|
case expr_type::ast_use: break;
|
||||||
case expr_type::ast_null: break;
|
case expr_type::ast_null: break;
|
||||||
case expr_type::ast_id:
|
case expr_type::ast_id:
|
||||||
if (need_repl_output && local.empty()) {
|
if (need_repl_output && local.empty()) {
|
||||||
|
|
|
@ -28,6 +28,7 @@ enum class tok:u32 {
|
||||||
id, // identifier
|
id, // identifier
|
||||||
tktrue, // keyword true
|
tktrue, // keyword true
|
||||||
tkfalse, // keyword false
|
tkfalse, // keyword false
|
||||||
|
use, // keyword use
|
||||||
rfor, // loop keyword for
|
rfor, // loop keyword for
|
||||||
forindex, // loop keyword forindex
|
forindex, // loop keyword forindex
|
||||||
foreach, // loop keyword foreach
|
foreach, // loop keyword foreach
|
||||||
|
@ -103,6 +104,7 @@ private:
|
||||||
std::vector<token> toks;
|
std::vector<token> toks;
|
||||||
|
|
||||||
const std::unordered_map<std::string, tok> typetbl {
|
const std::unordered_map<std::string, tok> typetbl {
|
||||||
|
{"use" ,tok::use },
|
||||||
{"true" ,tok::tktrue },
|
{"true" ,tok::tktrue },
|
||||||
{"false" ,tok::tkfalse },
|
{"false" ,tok::tkfalse },
|
||||||
{"for" ,tok::rfor },
|
{"for" ,tok::rfor },
|
||||||
|
|
|
@ -197,6 +197,18 @@ void parse::update_location(expr* node) {
|
||||||
node->update_location(toks[ptr-1].loc);
|
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() {
|
null_expr* parse::null() {
|
||||||
return new null_expr(toks[ptr].loc);
|
return new null_expr(toks[ptr].loc);
|
||||||
}
|
}
|
||||||
|
@ -355,6 +367,7 @@ expr* parse::expression() {
|
||||||
die(thisspan, "must use return in functions");
|
die(thisspan, "must use return in functions");
|
||||||
}
|
}
|
||||||
switch(type) {
|
switch(type) {
|
||||||
|
case tok::use: return use_stmt_gen();
|
||||||
case tok::tknil:
|
case tok::tknil:
|
||||||
case tok::num:
|
case tok::num:
|
||||||
case tok::str:
|
case tok::str:
|
||||||
|
|
|
@ -24,6 +24,7 @@ private:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const std::unordered_map<tok, std::string> tokname {
|
const std::unordered_map<tok, std::string> tokname {
|
||||||
|
{tok::use ,"use" },
|
||||||
{tok::rfor ,"for" },
|
{tok::rfor ,"for" },
|
||||||
{tok::forindex,"forindex"},
|
{tok::forindex,"forindex"},
|
||||||
{tok::foreach ,"foreach" },
|
{tok::foreach ,"foreach" },
|
||||||
|
@ -92,6 +93,7 @@ private:
|
||||||
void update_location(expr*);
|
void update_location(expr*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
use_stmt* use_stmt_gen();
|
||||||
null_expr* null();
|
null_expr* null();
|
||||||
nil_expr* nil();
|
nil_expr* nil();
|
||||||
number_literal* num();
|
number_literal* num();
|
||||||
|
|
Loading…
Reference in New Issue