✨ update
This commit is contained in:
parent
c5d6a6694b
commit
ac49c0d676
|
@ -49,7 +49,9 @@ enum class expr_type:u32 {
|
||||||
ast_cond, // mark a sub-tree of conditional expression
|
ast_cond, // mark a sub-tree of conditional expression
|
||||||
ast_if, // if keyword
|
ast_if, // if keyword
|
||||||
ast_multi_id, // multi identifiers sub-tree
|
ast_multi_id, // multi identifiers sub-tree
|
||||||
|
ast_tuple,
|
||||||
ast_def, // definition
|
ast_def, // definition
|
||||||
|
ast_multi_assign,
|
||||||
ast_continue, // continue keyword, only used in loop
|
ast_continue, // continue keyword, only used in loop
|
||||||
ast_break, // break keyword, only used in loop
|
ast_break, // break keyword, only used in loop
|
||||||
ast_ret // return keyword, only used in function block
|
ast_ret // return keyword, only used in function block
|
||||||
|
@ -316,6 +318,21 @@ public:
|
||||||
virtual void accept(ast_visitor*) override;
|
virtual void accept(ast_visitor*) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class call_expr:public expr {
|
||||||
|
private:
|
||||||
|
expr* first;
|
||||||
|
std::vector<expr*> calls;
|
||||||
|
|
||||||
|
public:
|
||||||
|
call_expr(const span& location):
|
||||||
|
expr(location, expr_type::ast_call),
|
||||||
|
first(nullptr) {}
|
||||||
|
~call_expr();
|
||||||
|
void set_first(expr* node) {first = node;}
|
||||||
|
void add_call(expr* node) {calls.push_back(node);}
|
||||||
|
virtual void accept(ast_visitor*) override;
|
||||||
|
};
|
||||||
|
|
||||||
class call_hash:public expr {
|
class call_hash:public expr {
|
||||||
private:
|
private:
|
||||||
std::string field;
|
std::string field;
|
||||||
|
@ -369,17 +386,17 @@ public:
|
||||||
virtual void accept(ast_visitor*) override;
|
virtual void accept(ast_visitor*) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class definition:public expr {
|
class definition_expr:public expr {
|
||||||
private:
|
private:
|
||||||
identifier* variable;
|
identifier* variable;
|
||||||
multi_define* variables;
|
multi_define* variables;
|
||||||
expr* value;
|
expr* value;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
definition(const span& location):
|
definition_expr(const span& location):
|
||||||
expr(location, expr_type::ast_def),
|
expr(location, expr_type::ast_def),
|
||||||
variable(nullptr), variables(nullptr), value(nullptr) {}
|
variable(nullptr), variables(nullptr), value(nullptr) {}
|
||||||
~definition();
|
~definition_expr();
|
||||||
virtual void accept(ast_visitor*) override;
|
virtual void accept(ast_visitor*) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -391,6 +408,33 @@ public:
|
||||||
multi_define(const span& location):
|
multi_define(const span& location):
|
||||||
expr(location, expr_type::ast_multi_id) {}
|
expr(location, expr_type::ast_multi_id) {}
|
||||||
~multi_define();
|
~multi_define();
|
||||||
|
void add_var(expr* node) {variables.push_back(node);}
|
||||||
|
virtual void accept(ast_visitor*) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class tuple_expr:public expr {
|
||||||
|
private:
|
||||||
|
std::vector<expr*> elements;
|
||||||
|
|
||||||
|
public:
|
||||||
|
tuple_expr(const span& location):
|
||||||
|
expr(location, expr_type::ast_tuple) {}
|
||||||
|
~tuple_expr();
|
||||||
|
void add_element(expr* node) {elements.push_back(node);}
|
||||||
|
virtual void accept(ast_visitor*) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class multi_assign:public expr {
|
||||||
|
private:
|
||||||
|
tuple_expr* left;
|
||||||
|
expr* right;
|
||||||
|
|
||||||
|
public:
|
||||||
|
multi_assign(const span& location):
|
||||||
|
expr(location, expr_type::ast_multi_assign) {}
|
||||||
|
~multi_assign();
|
||||||
|
void set_left(tuple_expr* node) {left = node;}
|
||||||
|
void set_right(expr* node) {right = node;}
|
||||||
virtual void accept(ast_visitor*) override;
|
virtual void accept(ast_visitor*) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -438,17 +482,17 @@ public:
|
||||||
class iter_expr:public expr {
|
class iter_expr:public expr {
|
||||||
private:
|
private:
|
||||||
identifier* name;
|
identifier* name;
|
||||||
expr* value;
|
expr* call;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
iter_expr(const span& location):
|
iter_expr(const span& location):
|
||||||
expr(location, expr_type::ast_iter),
|
expr(location, expr_type::ast_iter),
|
||||||
name(nullptr), value(nullptr) {}
|
name(nullptr), call(nullptr) {}
|
||||||
~iter_expr();
|
~iter_expr();
|
||||||
void set_name(identifier* node) {name = node;}
|
void set_name(identifier* node) {name = node;}
|
||||||
void set_value(expr* node) {value = node;}
|
void set_call(expr* node) {call = node;}
|
||||||
identifier* get_name() {return name;}
|
identifier* get_name() {return name;}
|
||||||
expr* get_value() {return value;}
|
expr* get_call() {return call;}
|
||||||
virtual void accept(ast_visitor*) override;
|
virtual void accept(ast_visitor*) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -117,21 +117,26 @@ bool parse::check_tuple() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parse::check_func_end(const ast& node) {
|
bool parse::check_func_end(expr* node) {
|
||||||
u32 type=node.type();
|
auto type=node->get_type();
|
||||||
if (type==ast_func) {
|
if (type==expr_type::ast_func) {
|
||||||
return true;
|
return true;
|
||||||
} else if (type==ast_num || type==ast_id || type==ast_str || type==ast_nil || type==ast_vec || type==ast_hash) {
|
} else if (type==expr_type::ast_num ||
|
||||||
|
type==expr_type::ast_id ||
|
||||||
|
type==expr_type::ast_str ||
|
||||||
|
type==expr_type::ast_nil ||
|
||||||
|
type==expr_type::ast_vec ||
|
||||||
|
type==expr_type::ast_hash) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (node.child().empty() || (
|
if (node.child().empty() || (
|
||||||
type!=ast_def &&
|
type!=expr_type::ast_def &&
|
||||||
type!=ast_equal &&
|
type!=expr_type::ast_equal &&
|
||||||
type!=ast_addeq &&
|
type!=expr_type::ast_addeq &&
|
||||||
type!=ast_subeq &&
|
type!=expr_type::ast_subeq &&
|
||||||
type!=ast_multeq &&
|
type!=expr_type::ast_multeq &&
|
||||||
type!=ast_diveq &&
|
type!=expr_type::ast_diveq &&
|
||||||
type!=ast_lnkeq)) {
|
type!=expr_type::ast_lnkeq)) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return check_func_end(node.child().back());
|
return check_func_end(node.child().back());
|
||||||
|
@ -326,7 +331,7 @@ void parse::params(function* func_node) {
|
||||||
expr* parse::lcurve_expr() {
|
expr* parse::lcurve_expr() {
|
||||||
if (toks[ptr+1].type==tok::var)
|
if (toks[ptr+1].type==tok::var)
|
||||||
return definition();
|
return definition();
|
||||||
return check_tuple()?multi_assgin():calc();
|
return check_tuple()?multi_assignment():calc();
|
||||||
}
|
}
|
||||||
|
|
||||||
expr* parse::expression() {
|
expr* parse::expression() {
|
||||||
|
@ -712,7 +717,7 @@ slice_vector* parse::subvec() {
|
||||||
}
|
}
|
||||||
|
|
||||||
expr* parse::definition() {
|
expr* parse::definition() {
|
||||||
ast node(toks[ptr].loc, ast_def);
|
auto node = new definition_expr(toks[ptr].loc);
|
||||||
if (lookahead(tok::var)) {
|
if (lookahead(tok::var)) {
|
||||||
match(tok::var);
|
match(tok::var);
|
||||||
switch(toks[ptr].type) {
|
switch(toks[ptr].type) {
|
||||||
|
@ -733,33 +738,33 @@ expr* parse::definition() {
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
expr* parse::incurve_def() {
|
multi_define* parse::incurve_def() {
|
||||||
const auto& loc=toks[ptr].loc;
|
const auto& loc=toks[ptr].loc;
|
||||||
match(tok::lcurve);
|
match(tok::lcurve);
|
||||||
match(tok::var);
|
match(tok::var);
|
||||||
ast node=multi_id();
|
auto node = multi_id();
|
||||||
update_location(node);
|
update_location(node);
|
||||||
match(tok::rcurve);
|
match(tok::rcurve);
|
||||||
node.set_begin(loc.begin_line, loc.begin_column);
|
node->set_begin(loc.begin_line, loc.begin_column);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
expr* parse::outcurve_def() {
|
multi_define* parse::outcurve_def() {
|
||||||
const auto& loc=toks[ptr].loc;
|
const auto& loc=toks[ptr].loc;
|
||||||
match(tok::lcurve);
|
match(tok::lcurve);
|
||||||
ast node=multi_id();
|
auto node = multi_id();
|
||||||
update_location(node);
|
update_location(node);
|
||||||
match(tok::rcurve);
|
match(tok::rcurve);
|
||||||
node.set_begin(loc.begin_line, loc.begin_column);
|
node->set_begin(loc.begin_line, loc.begin_column);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
expr* parse::multi_id() {
|
expr* parse::multi_id() {
|
||||||
ast node(toks[ptr].loc, ast_multi_id);
|
auto node = new multi_define(toks[ptr].loc);
|
||||||
while(!lookahead(tok::eof)) {
|
while(!lookahead(tok::eof)) {
|
||||||
// only identifier is allowed here
|
// only identifier is allowed here
|
||||||
// but we check it at codegen stage
|
// but we check it at codegen stage
|
||||||
node.add(calc());
|
node->add_var(calc());
|
||||||
if (lookahead(tok::comma)) {
|
if (lookahead(tok::comma)) {
|
||||||
match(tok::comma);
|
match(tok::comma);
|
||||||
} else if (lookahead(tok::id)) { // first set of identifier
|
} else if (lookahead(tok::id)) { // first set of identifier
|
||||||
|
@ -772,7 +777,7 @@ expr* parse::multi_id() {
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
expr* parse::multi_scalar() {
|
tuple_expr* parse::multi_scalar() {
|
||||||
// if check_call_memory is true,we will check if value called here can reach a memory space
|
// if check_call_memory is true,we will check if value called here can reach a memory space
|
||||||
const tok panic[]={
|
const tok panic[]={
|
||||||
tok::id,tok::str,tok::num,tok::tktrue,
|
tok::id,tok::str,tok::num,tok::tktrue,
|
||||||
|
@ -780,10 +785,10 @@ expr* parse::multi_scalar() {
|
||||||
tok::func,tok::var,tok::lcurve,tok::floater,
|
tok::func,tok::var,tok::lcurve,tok::floater,
|
||||||
tok::lbrace,tok::lbracket,tok::null
|
tok::lbrace,tok::lbracket,tok::null
|
||||||
};
|
};
|
||||||
ast node(toks[ptr].loc, ast_tuple);
|
auto node = new tuple_expr(toks[ptr].loc);
|
||||||
match(tok::lcurve);
|
match(tok::lcurve);
|
||||||
while(!lookahead(tok::rcurve)) {
|
while(!lookahead(tok::rcurve)) {
|
||||||
node.add(calc());
|
node->add_element(calc());
|
||||||
if (lookahead(tok::comma)) {
|
if (lookahead(tok::comma)) {
|
||||||
match(tok::comma);
|
match(tok::comma);
|
||||||
} else if (lookahead(tok::eof)) {
|
} else if (lookahead(tok::eof)) {
|
||||||
|
@ -797,18 +802,18 @@ expr* parse::multi_scalar() {
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
expr* parse::multi_assgin() {
|
multi_assign* parse::multi_assignment() {
|
||||||
ast node(toks[ptr].loc, ast_multi_assign);
|
auto node = new multi_assign(toks[ptr].loc);
|
||||||
node.add(multi_scalar());
|
node->set_left(multi_scalar());
|
||||||
match(tok::eq);
|
match(tok::eq);
|
||||||
if (lookahead(tok::eof)) {
|
if (lookahead(tok::eof)) {
|
||||||
die(thisspan, "expected value list");
|
die(thisspan, "expected value list");
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
if (lookahead(tok::lcurve)) {
|
if (lookahead(tok::lcurve)) {
|
||||||
node.add(check_tuple()?multi_scalar():calc());
|
node->set_right(check_tuple()?multi_scalar():calc());
|
||||||
} else {
|
} else {
|
||||||
node.add(calc());
|
node->set_right(calc());
|
||||||
}
|
}
|
||||||
update_location(node);
|
update_location(node);
|
||||||
return node;
|
return node;
|
||||||
|
@ -917,14 +922,14 @@ iter_expr* parse::iter_gen() {
|
||||||
auto node = new iter_expr(toks[ptr].loc);
|
auto node = new iter_expr(toks[ptr].loc);
|
||||||
if (lookahead(tok::var)) {
|
if (lookahead(tok::var)) {
|
||||||
match(tok::var);
|
match(tok::var);
|
||||||
node.set_type(ast_iter);
|
|
||||||
node->set_name(id());
|
node->set_name(id());
|
||||||
} else {
|
} else {
|
||||||
node.set_type(ast_call);
|
auto tmp = new call_expr(toks[ptr].loc);
|
||||||
node.add(id());
|
tmp->set_first(id());
|
||||||
while(is_call(toks[ptr].type)) {
|
while(is_call(toks[ptr].type)) {
|
||||||
node.add(call_scalar());
|
tmp->add_call(call_scalar());
|
||||||
}
|
}
|
||||||
|
node->set_call(tmp);
|
||||||
}
|
}
|
||||||
update_location(node);
|
update_location(node);
|
||||||
return node;
|
return node;
|
||||||
|
|
|
@ -84,7 +84,7 @@ private:
|
||||||
bool is_call(tok);
|
bool is_call(tok);
|
||||||
bool check_comma(const tok*);
|
bool check_comma(const tok*);
|
||||||
bool check_tuple();
|
bool check_tuple();
|
||||||
bool check_func_end(const ast&);
|
bool check_func_end(expr*);
|
||||||
bool check_special_call();
|
bool check_special_call();
|
||||||
bool need_semi_check(expr*);
|
bool need_semi_check(expr*);
|
||||||
void update_location(expr*);
|
void update_location(expr*);
|
||||||
|
@ -121,11 +121,11 @@ private:
|
||||||
call_function* callf();
|
call_function* callf();
|
||||||
slice_vector* subvec();
|
slice_vector* subvec();
|
||||||
expr* definition();
|
expr* definition();
|
||||||
expr* incurve_def();
|
multi_define* incurve_def();
|
||||||
expr* outcurve_def();
|
multi_define* outcurve_def();
|
||||||
expr* multi_id();
|
multi_define* multi_id();
|
||||||
expr* multi_scalar();
|
tuple_expr* multi_scalar();
|
||||||
expr* multi_assgin();
|
multi_assign* multi_assignment();
|
||||||
expr* loop();
|
expr* loop();
|
||||||
while_expr* while_loop();
|
while_expr* while_loop();
|
||||||
for_expr* for_loop();
|
for_expr* for_loop();
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "nasal_dbg.h"
|
#include "nasal_dbg.h"
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
const u32 VM_AST =0x01;
|
const u32 VM_AST =0x01;
|
||||||
const u32 VM_CODE =0x02;
|
const u32 VM_CODE =0x02;
|
||||||
|
@ -55,6 +56,7 @@ std::ostream& logo(std::ostream& out) {
|
||||||
<<" \\_\\ \\/ \\__,_|___/\\__,_|_|\n"
|
<<" \\_\\ \\/ \\__,_|___/\\__,_|_|\n"
|
||||||
<<"ver : "<<__nasver<<" ("<<__DATE__<<" "<<__TIME__<<")\n"
|
<<"ver : "<<__nasver<<" ("<<__DATE__<<" "<<__TIME__<<")\n"
|
||||||
<<"std : c++ "<<__cplusplus<<"\n"
|
<<"std : c++ "<<__cplusplus<<"\n"
|
||||||
|
<<"core : "<<std::thread::hardware_concurrency()<<" cores\n"
|
||||||
<<"repo : https://github.com/ValKmjolnir/Nasal-Interpreter\n"
|
<<"repo : https://github.com/ValKmjolnir/Nasal-Interpreter\n"
|
||||||
<<"repo : https://gitee.com/valkmjolnir/Nasal-Interpreter\n"
|
<<"repo : https://gitee.com/valkmjolnir/Nasal-Interpreter\n"
|
||||||
<<"wiki : https://wiki.flightgear.org/Nasal_scripting_language\n"
|
<<"wiki : https://wiki.flightgear.org/Nasal_scripting_language\n"
|
||||||
|
|
|
@ -151,7 +151,7 @@ private:
|
||||||
ast outcurve_def();
|
ast outcurve_def();
|
||||||
ast multi_id();
|
ast multi_id();
|
||||||
ast multi_scalar();
|
ast multi_scalar();
|
||||||
ast multi_assgin();
|
ast multi_assign();
|
||||||
ast loop();
|
ast loop();
|
||||||
ast while_loop();
|
ast while_loop();
|
||||||
ast for_loop();
|
ast for_loop();
|
||||||
|
@ -459,7 +459,7 @@ ast parse::params() {
|
||||||
ast parse::lcurve_expr() {
|
ast parse::lcurve_expr() {
|
||||||
if (toks[ptr+1].type==tok::var)
|
if (toks[ptr+1].type==tok::var)
|
||||||
return definition();
|
return definition();
|
||||||
return check_tuple()?multi_assgin():calc();
|
return check_tuple()?multi_assign():calc();
|
||||||
}
|
}
|
||||||
|
|
||||||
ast parse::expr() {
|
ast parse::expr() {
|
||||||
|
@ -917,7 +917,7 @@ ast parse::multi_scalar() {
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
ast parse::multi_assgin() {
|
ast parse::multi_assign() {
|
||||||
ast node(toks[ptr].loc, ast_multi_assign);
|
ast node(toks[ptr].loc, ast_multi_assign);
|
||||||
node.add(multi_scalar());
|
node.add(multi_scalar());
|
||||||
match(tok::eq);
|
match(tok::eq);
|
||||||
|
|
Loading…
Reference in New Issue