✨ add parse process for `??` & `?.`
This commit is contained in:
parent
32c0b93e05
commit
43c229fc72
|
@ -185,6 +185,7 @@ bool ast_dumper::visit_binary_operator(binary_operator* node) {
|
|||
case binary_operator::binary_type::leq: std::cout << "<="; break;
|
||||
case binary_operator::binary_type::condition_and: std::cout << "and"; break;
|
||||
case binary_operator::binary_type::condition_or: std::cout << "or"; break;
|
||||
case binary_operator::binary_type::nullchain: std::cout << "??"; break;
|
||||
}
|
||||
std::cout << "\"" << format_location(node);
|
||||
push_indent();
|
||||
|
@ -241,6 +242,13 @@ bool ast_dumper::visit_call_hash(call_hash* node) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ast_dumper::visit_null_access(null_access* node) {
|
||||
dump_indent();
|
||||
std::cout << "null_access " << node->get_field();
|
||||
std::cout << format_location(node);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ast_dumper::visit_call_vector(call_vector* node) {
|
||||
dump_indent();
|
||||
std::cout << "call_vector";
|
||||
|
|
|
@ -70,6 +70,7 @@ public:
|
|||
bool visit_unary_operator(unary_operator*) override;
|
||||
bool visit_call_expr(call_expr*) override;
|
||||
bool visit_call_hash(call_hash*) override;
|
||||
bool visit_null_access(null_access*) override;
|
||||
bool visit_call_vector(call_vector*) override;
|
||||
bool visit_call_function(call_function*) override;
|
||||
bool visit_slice_vector(slice_vector*) override;
|
||||
|
|
|
@ -116,6 +116,10 @@ bool ast_visitor::visit_call_hash(call_hash* node) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ast_visitor::visit_null_access(null_access* node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ast_visitor::visit_call_vector(call_vector* node) {
|
||||
for(auto i : node->get_slices()) {
|
||||
i->accept(this);
|
||||
|
|
|
@ -26,6 +26,7 @@ public:
|
|||
virtual bool visit_unary_operator(unary_operator*);
|
||||
virtual bool visit_call_expr(call_expr*);
|
||||
virtual bool visit_call_hash(call_hash*);
|
||||
virtual bool visit_null_access(null_access*);
|
||||
virtual bool visit_call_vector(call_vector*);
|
||||
virtual bool visit_call_function(call_function*);
|
||||
virtual bool visit_slice_vector(slice_vector*);
|
||||
|
|
|
@ -173,6 +173,10 @@ void call_hash::accept(ast_visitor* visitor) {
|
|||
visitor->visit_call_hash(this);
|
||||
}
|
||||
|
||||
void null_access::accept(ast_visitor* visitor) {
|
||||
visitor->visit_null_access(this);
|
||||
}
|
||||
|
||||
call_vector::~call_vector() {
|
||||
for(auto i : calls) {
|
||||
delete i;
|
||||
|
|
|
@ -23,6 +23,7 @@ enum class expr_type {
|
|||
ast_pair, // pair of key and value in hashmap
|
||||
ast_call, // mark a sub-tree of calling an identifier
|
||||
ast_callh, // id.name
|
||||
ast_nullaccess, // id?.name
|
||||
ast_callv, // id[index]
|
||||
ast_callf, // id()
|
||||
ast_subvec, // id[index:index]
|
||||
|
@ -302,7 +303,8 @@ public:
|
|||
bitwise_xor,
|
||||
bitwise_and,
|
||||
condition_and,
|
||||
condition_or
|
||||
condition_or,
|
||||
nullchain
|
||||
};
|
||||
|
||||
private:
|
||||
|
@ -389,6 +391,19 @@ public:
|
|||
void accept(ast_visitor*) override;
|
||||
};
|
||||
|
||||
class null_access: public call {
|
||||
private:
|
||||
std::string field;
|
||||
|
||||
public:
|
||||
null_access(const span& location, const std::string& name):
|
||||
call(location, expr_type::ast_nullaccess),
|
||||
field(name) {}
|
||||
~null_access() override = default;
|
||||
const std::string& get_field() const {return field;}
|
||||
void accept(ast_visitor*) override;
|
||||
};
|
||||
|
||||
class call_vector: public call {
|
||||
private:
|
||||
std::vector<slice_vector*> calls;
|
||||
|
|
|
@ -98,7 +98,8 @@ bool parse::lookahead(tok type) {
|
|||
}
|
||||
|
||||
bool parse::is_call(tok type) {
|
||||
return type==tok::tk_lcurve || type==tok::tk_lbracket || type==tok::tk_dot;
|
||||
return type==tok::tk_lcurve || type==tok::tk_lbracket ||
|
||||
type==tok::tk_dot || type==tok::tk_quesdot;
|
||||
}
|
||||
|
||||
bool parse::check_comma(const tok* panic_set) {
|
||||
|
@ -568,7 +569,7 @@ expr* parse::and_expr() {
|
|||
}
|
||||
|
||||
expr* parse::cmp_expr() {
|
||||
auto node = additive_expr();
|
||||
auto node = null_chain_expr();
|
||||
while(tok::tk_cmpeq<=toks[ptr].type && toks[ptr].type<=tok::tk_geq) {
|
||||
auto tmp = new binary_operator(toks[ptr].loc);
|
||||
switch(toks[ptr].type) {
|
||||
|
@ -582,6 +583,21 @@ expr* parse::cmp_expr() {
|
|||
}
|
||||
tmp->set_left(node);
|
||||
match(toks[ptr].type);
|
||||
tmp->set_right(null_chain_expr());
|
||||
update_location(tmp);
|
||||
node = tmp;
|
||||
}
|
||||
update_location(node);
|
||||
return node;
|
||||
}
|
||||
|
||||
expr* parse::null_chain_expr() {
|
||||
auto node = additive_expr();
|
||||
while(lookahead(tok::tk_quesques)) {
|
||||
auto tmp = new binary_operator(toks[ptr].loc);
|
||||
tmp->set_operator_type(binary_operator::binary_type::nullchain);
|
||||
tmp->set_left(node);
|
||||
match(tok::tk_quesques);
|
||||
tmp->set_right(additive_expr());
|
||||
update_location(tmp);
|
||||
node = tmp;
|
||||
|
@ -722,6 +738,7 @@ call* parse::call_scalar() {
|
|||
case tok::tk_lcurve: return callf(); break;
|
||||
case tok::tk_lbracket: return callv(); break;
|
||||
case tok::tk_dot: return callh(); break;
|
||||
case tok::tk_quesdot: return null_access_call(); break;
|
||||
default: break;
|
||||
}
|
||||
// unreachable
|
||||
|
@ -737,6 +754,15 @@ call_hash* parse::callh() {
|
|||
return node;
|
||||
}
|
||||
|
||||
null_access* parse::null_access_call() {
|
||||
const auto& begin_loc = toks[ptr].loc;
|
||||
match(tok::tk_quesdot);
|
||||
auto node = new null_access(begin_loc, toks[ptr].str);
|
||||
update_location(node);
|
||||
match(tok::tk_id, "expected hashmap key"); // get key
|
||||
return node;
|
||||
}
|
||||
|
||||
call_vector* parse::callv() {
|
||||
// panic set for this token is not ','
|
||||
// this is the FIRST set of subvec
|
||||
|
|
|
@ -119,12 +119,14 @@ private:
|
|||
expr* or_expr();
|
||||
expr* and_expr();
|
||||
expr* cmp_expr();
|
||||
expr* null_chain_expr();
|
||||
expr* additive_expr();
|
||||
expr* multive_expr();
|
||||
unary_operator* unary();
|
||||
expr* scalar();
|
||||
call* call_scalar();
|
||||
call_hash* callh();
|
||||
null_access* null_access_call();
|
||||
call_vector* callv();
|
||||
call_function* callf();
|
||||
slice_vector* subvec();
|
||||
|
|
Loading…
Reference in New Issue