diff --git a/gen/gsc/parser.ypp b/gen/gsc/parser.ypp index 1d237172..58dedebb 100644 --- a/gen/gsc/parser.ypp +++ b/gen/gsc/parser.ypp @@ -153,19 +153,19 @@ namespace xsk::gsc %type program %type include -%type declaration +%type declaration %type decl_usingtree %type decl_constant %type decl_function -%type stmt -%type stmt_or_dev +%type stmt +%type stmt_or_dev %type stmt_list %type stmt_or_dev_list %type stmt_dev %type stmt_comp %type stmt_expr -%type stmt_call -%type stmt_assign +%type stmt_call +%type stmt_assign %type stmt_endon %type stmt_notify %type stmt_wait @@ -191,21 +191,21 @@ namespace xsk::gsc %type stmt_assert %type stmt_assertex %type stmt_assertmsg -%type expr -%type expr_or_empty -%type expr_assign -%type expr_increment -%type expr_decrement -%type expr_ternary -%type expr_binary -%type expr_primitive +%type expr +%type expr_or_empty +%type expr_increment +%type expr_decrement +%type expr_assign +%type expr_ternary +%type expr_binary +%type expr_primitive %type expr_complement %type expr_negate %type expr_not %type expr_call %type expr_method -%type expr_function -%type expr_pointer +%type expr_function +%type expr_pointer %type expr_add_array %type expr_parameters %type expr_arguments @@ -213,14 +213,14 @@ namespace xsk::gsc %type expr_isdefined %type expr_istrue %type expr_reference -%type expr_tuple +%type expr_tuple %type expr_tuple_arguments -%type expr_tuple_types +%type expr_tuple_types %type expr_array %type expr_field %type expr_size %type expr_paren -%type expr_object +%type expr_object %type expr_thisthread %type expr_empty_array %type expr_undefined @@ -273,7 +273,7 @@ namespace xsk::gsc root : program { ast = std::move($1); } - | { ast = make_program(@$); } + | { ast = program::make(@$); } ; program @@ -286,13 +286,13 @@ program | program declaration { $$ = std::move($1); $$->declarations.push_back(std::move($2)); } | SEMICOLON - { $$ = make_program(@$); } + { $$ = program::make(@$); } | inline - { $$ = make_program(@$); } + { $$ = program::make(@$); } | include - { $$ = make_program(@$); $$->includes.push_back(std::move($1)); } + { $$ = program::make(@$); $$->includes.push_back(std::move($1)); } | declaration - { $$ = make_program(@$); $$->declarations.push_back(std::move($1)); } + { $$ = program::make(@$); $$->declarations.push_back(std::move($1)); } ; inline @@ -301,276 +301,277 @@ inline include : INCLUDE expr_path SEMICOLON - { $$ = make_include(@$, std::move($2)); } + { $$ = include::make(@$, std::move($2)); } ; declaration - : DEVBEGIN { $$.as_dev_begin = make_decl_dev_begin(@$); } - | DEVEND { $$.as_dev_end = make_decl_dev_end(@$); } - | decl_usingtree { $$.as_usingtree = std::move($1); } - | decl_constant { $$.as_constant = std::move($1); } - | decl_function { $$.as_function = std::move($1); } + : DEVBEGIN { $$ = decl_dev_begin::make(@$); } + | DEVEND { $$ = decl_dev_end::make(@$); } + | decl_usingtree { $$ = std::move($1); } + | decl_constant { $$ = std::move($1); } + | decl_function { $$ = std::move($1); } ; decl_usingtree : USINGTREE LPAREN expr_string RPAREN SEMICOLON - { ppr.ban_header(@$); $$ = make_decl_usingtree(@$, std::move($3)); } + { ppr.ban_header(@$); $$ = decl_usingtree::make(@$, std::move($3)); } ; decl_constant : expr_identifier ASSIGN expr SEMICOLON { - ppr.ban_header(@$); $$ = make_decl_constant(@$, std::move($1), std::move($3)); + ppr.ban_header(@$); $$ = decl_constant::make(@$, std::move($1), std::move($3)); printf("%s" , fmt::format("{}: constants deprecated, use #define instead\n", @$.print()).data()); } ; decl_function : expr_identifier LPAREN expr_parameters RPAREN stmt_comp - { ppr.ban_header(@$); $$ = make_decl_function(@$, std::move($1), std::move($3), std::move($5)); } + { ppr.ban_header(@$); $$ = decl_function::make(@$, std::move($1), std::move($3), std::move($5)); } ; stmt - : stmt_comp { $$.as_comp = std::move($1); } - | stmt_call { $$.as_call = std::move($1); } - | stmt_assign { $$.as_assign = std::move($1); } - | stmt_endon { $$.as_endon = std::move($1); } - | stmt_notify { $$.as_notify = std::move($1); } - | stmt_wait { $$.as_wait = std::move($1); } - | stmt_waittill { $$.as_waittill = std::move($1); } - | stmt_waittillmatch { $$.as_waittillmatch = std::move($1); } - | stmt_waittillframeend { $$.as_waittillframeend = std::move($1); } - | stmt_waitframe { $$.as_waitframe = std::move($1); } - | stmt_if { $$.as_if = std::move($1); } - | stmt_ifelse { $$.as_ifelse = std::move($1); } - | stmt_while { $$.as_while = std::move($1); } - | stmt_dowhile { $$.as_dowhile = std::move($1); } - | stmt_for { $$.as_for = std::move($1); } - | stmt_foreach { $$.as_foreach = std::move($1); } - | stmt_switch { $$.as_switch = std::move($1); } - | stmt_case { $$.as_case = std::move($1); } - | stmt_default { $$.as_default = std::move($1); } - | stmt_break { $$.as_break = std::move($1); } - | stmt_continue { $$.as_continue = std::move($1); } - | stmt_return { $$.as_return = std::move($1); } - | stmt_breakpoint { $$.as_breakpoint = std::move($1); } - | stmt_prof_begin { $$.as_prof_begin = std::move($1); } - | stmt_prof_end { $$.as_prof_end = std::move($1); } - | stmt_assert { $$.as_assert = std::move($1); } - | stmt_assertex { $$.as_assertex = std::move($1); } - | stmt_assertmsg { $$.as_assertmsg = std::move($1); } + : stmt_comp { $$ = std::move($1); } + | stmt_call { $$ = std::move($1); } + | stmt_assign { $$ = std::move($1); } + | stmt_endon { $$ = std::move($1); } + | stmt_notify { $$ = std::move($1); } + | stmt_wait { $$ = std::move($1); } + | stmt_waittill { $$ = std::move($1); } + | stmt_waittillmatch { $$ = std::move($1); } + | stmt_waittillframeend { $$ = std::move($1); } + | stmt_waitframe { $$ = std::move($1); } + | stmt_if { $$ = std::move($1); } + | stmt_ifelse { $$ = std::move($1); } + | stmt_while { $$ = std::move($1); } + | stmt_dowhile { $$ = std::move($1); } + | stmt_for { $$ = std::move($1); } + | stmt_foreach { $$ = std::move($1); } + | stmt_switch { $$ = std::move($1); } + | stmt_case { $$ = std::move($1); } + | stmt_default { $$ = std::move($1); } + | stmt_break { $$ = std::move($1); } + | stmt_continue { $$ = std::move($1); } + | stmt_return { $$ = std::move($1); } + | stmt_breakpoint { $$ = std::move($1); } + | stmt_prof_begin { $$ = std::move($1); } + | stmt_prof_end { $$ = std::move($1); } + | stmt_assert { $$ = std::move($1); } + | stmt_assertex { $$ = std::move($1); } + | stmt_assertmsg { $$ = std::move($1); } ; stmt_or_dev : stmt { $$ = std::move($1); } - | stmt_dev { $$.as_dev = std::move($1); } + | stmt_dev { $$ = std::move($1); } ; stmt_list : stmt_list stmt { $$ = std::move($1); $$->list.push_back(std::move($2)); } | stmt - { $$ = make_stmt_list(@$); $$->list.push_back(std::move($1)); } + { $$ = stmt_list::make(@$); $$->list.push_back(std::move($1)); } | stmt_list SEMICOLON { $$ = std::move($1); } | SEMICOLON - { $$ = make_stmt_list(@$); } + { $$ = stmt_list::make(@$); } ; stmt_or_dev_list : stmt_or_dev_list stmt_or_dev { $$ = std::move($1); $$->list.push_back(std::move($2)); } | stmt_or_dev - { $$ = make_stmt_list(@$); $$->list.push_back(std::move($1)); } + { $$ = stmt_list::make(@$); $$->list.push_back(std::move($1)); } | stmt_or_dev_list SEMICOLON { $$ = std::move($1); } | SEMICOLON - { $$ = make_stmt_list(@$); } + { $$ = stmt_list::make(@$); } ; stmt_dev - : DEVBEGIN stmt_list DEVEND { $$ = make_stmt_dev(@$, std::move($2)); } - | DEVBEGIN DEVEND { $$ = make_stmt_dev(@$, make_stmt_list(@$)); } + : DEVBEGIN stmt_list DEVEND { $$ = stmt_dev::make(@$, std::move($2)); } + | DEVBEGIN DEVEND { $$ = stmt_dev::make(@$, stmt_list::make(@$)); } ; stmt_comp - : LBRACE stmt_or_dev_list RBRACE { $$ = make_stmt_comp(@$, std::move($2)); } - | LBRACE RBRACE { $$ = make_stmt_comp(@$, make_stmt_list(@$)); } + : LBRACE stmt_or_dev_list RBRACE { $$ = stmt_comp::make(@$, std::move($2)); } + | LBRACE RBRACE { $$ = stmt_comp::make(@$, stmt_list::make(@$)); } ; stmt_expr : expr_assign - { $$ = make_stmt_expr(@$, std::move($1)); } + { $$ = stmt_expr::make(@$, std::move($1)); } | expr_increment - { $$ = make_stmt_expr(@$, std::move($1)); } + { $$ = stmt_expr::make(@$, std::move($1)); } | expr_decrement - { $$ = make_stmt_expr(@$, std::move($1)); } + { $$ = stmt_expr::make(@$, std::move($1)); } | - { $$ = make_stmt_expr(@$, make_node(@$)); } + { $$ = stmt_expr::make(@$, expr_empty::make(@$)); } ; stmt_call : expr_call SEMICOLON - { $$ = make_stmt_call(@$, expr{ std::move($1) }); } + { $$ = stmt_expr::make(@$, std::move($1)); } | expr_method SEMICOLON - { $$ = make_stmt_call(@$, expr{ std::move($1) }); } + { $$ = stmt_expr::make(@$, std::move($1)); } ; stmt_assign : expr_assign SEMICOLON - { $$ = make_stmt_assign(@$, std::move($1)); } + { $$ = stmt_expr::make(@$, std::move($1)); } | expr_increment SEMICOLON - { $$ = make_stmt_assign(@$, std::move($1)); } + { $$ = stmt_expr::make(@$, std::move($1)); } | expr_decrement SEMICOLON - { $$ = make_stmt_assign(@$, std::move($1)); } + { $$ = stmt_expr::make(@$, std::move($1)); } ; stmt_endon : expr_object ENDON LPAREN expr RPAREN SEMICOLON - { $$ = make_stmt_endon(@$, std::move($1), std::move($4)); } + { $$ = stmt_endon::make(@$, std::move($1), std::move($4)); } ; stmt_notify : expr_object NOTIFY LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON - { $$ = make_stmt_notify(@$, std::move($1), std::move($4), std::move($6)); } + { $$ = stmt_notify::make(@$, std::move($1), std::move($4), std::move($6)); } | expr_object NOTIFY LPAREN expr RPAREN SEMICOLON - { $$ = make_stmt_notify(@$, std::move($1), std::move($4), make_expr_arguments(@$)); } + { $$ = stmt_notify::make(@$, std::move($1), std::move($4), expr_arguments::make(@$)); } ; stmt_wait : WAIT expr SEMICOLON - { $$ = make_stmt_wait(@$, std::move($2)); } + { $$ = stmt_wait::make(@$, std::move($2)); } ; stmt_waittill : expr_object WAITTILL LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON - { $$ = make_stmt_waittill(@$, std::move($1), std::move($4), std::move($6)); } + { $$ = stmt_waittill::make(@$, std::move($1), std::move($4), std::move($6)); } | expr_object WAITTILL LPAREN expr RPAREN SEMICOLON - { $$ = make_stmt_waittill(@$, std::move($1), std::move($4), make_expr_arguments(@$)); } + { $$ = stmt_waittill::make(@$, std::move($1), std::move($4), expr_arguments::make(@$)); } ; stmt_waittillmatch : expr_object WAITTILLMATCH LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON - { $$ = make_stmt_waittillmatch(@$, std::move($1), std::move($4), std::move($6)); } + { $$ = stmt_waittillmatch::make(@$, std::move($1), std::move($4), std::move($6)); } | expr_object WAITTILLMATCH LPAREN expr RPAREN SEMICOLON - { $$ = make_stmt_waittillmatch(@$, std::move($1), std::move($4), make_expr_arguments(@$)); } + { $$ = stmt_waittillmatch::make(@$, std::move($1), std::move($4), expr_arguments::make(@$)); } ; stmt_waittillframeend : WAITTILLFRAMEEND SEMICOLON - { $$ = make_stmt_waittillframeend(@$); } + { $$ = stmt_waittillframeend::make(@$); } ; stmt_waitframe : WAITFRAME SEMICOLON - { $$ = make_stmt_waitframe(@$); } + { $$ = stmt_waitframe::make(@$); } | WAITFRAME LPAREN RPAREN SEMICOLON - { $$ = make_stmt_waitframe(@$); } + { $$ = stmt_waitframe::make(@$); } ; stmt_if : IF LPAREN expr RPAREN stmt %prec THEN - { $$ = make_stmt_if(@$, std::move($3), std::move($5)); } + { $$ = stmt_if::make(@$, std::move($3), std::move($5)); } ; stmt_ifelse : IF LPAREN expr RPAREN stmt ELSE stmt - { $$ = make_stmt_ifelse(@$, std::move($3), std::move($5), std::move($7)); } + { $$ = stmt_ifelse::make(@$, std::move($3), std::move($5), std::move($7)); } ; stmt_while : WHILE LPAREN expr RPAREN stmt - { $$ = make_stmt_while(@$, std::move($3), std::move($5)); } + { $$ = stmt_while::make(@$, std::move($3), std::move($5)); } ; stmt_dowhile : DO stmt WHILE LPAREN expr RPAREN SEMICOLON - { $$ = make_stmt_dowhile(@$, std::move($5), std::move($2)); } + { $$ = stmt_dowhile::make(@$, std::move($5), std::move($2)); } ; stmt_for : FOR LPAREN stmt_expr SEMICOLON expr_or_empty SEMICOLON stmt_expr RPAREN stmt - { $$ = make_stmt_for(@$, stmt{ std::move($3) }, std::move($5), stmt{ std::move($7) }, std::move($9)); } + { $$ = stmt_for::make(@$, std::move($3), std::move($5), std::move($7), std::move($9)); } ; stmt_foreach : FOREACH LPAREN expr_identifier IN expr RPAREN stmt { - auto array = expr{ make_expr_identifier(@$, fmt::format("_temp_{}", ++index)) }; - auto key = expr{ make_expr_identifier(@$, fmt::format("_temp_{}", ++index)) }; - $$ = make_stmt_foreach(@$, std::move($5), expr{ std::move($3) }, expr{ make_node(@$) }, std::move(array), std::move(key), std::move($7), false); } + auto array = expr_identifier::make(@$, fmt::format("_temp_{}", ++index)); + auto key = expr_identifier::make(@$, fmt::format("_temp_{}", ++index)); + $$ = stmt_foreach::make(@$, std::move($5), std::move($3), expr_empty::make(@$), std::move(array), std::move(key), std::move($7), false); + } | FOREACH LPAREN expr_identifier COMMA expr_identifier IN expr RPAREN stmt { - auto array = expr{ make_expr_identifier(@$, fmt::format("_temp_{}", ++index)) }; - auto key = (ctx_->props() & props::foreach) ? expr{ make_expr_identifier(@$, fmt::format("_temp_{}", ++index)) } : expr{ std::move($3) }; - $$ = make_stmt_foreach(@$, std::move($7), expr{ std::move($5) }, (ctx_->props() & props::foreach) ? expr{ std::move($3) } : expr{ make_node(@$) }, std::move(array), std::move(key), std::move($9), true); + auto array = expr_identifier::make(@$, fmt::format("_temp_{}", ++index)); + expr::ptr key = (ctx_->props() & props::foreach) ? expr_identifier::make(@$, fmt::format("_temp_{}", ++index)) : std::move($3); + $$ = stmt_foreach::make(@$, std::move($7), std::move($5), (ctx_->props() & props::foreach) ? std::move($3) : (expr::ptr)expr_empty::make(@$), std::move(array), std::move(key), std::move($9), true); } ; stmt_switch : SWITCH LPAREN expr RPAREN stmt_comp - { $$ = make_stmt_switch(@$, std::move($3), std::move($5)); + { $$ = stmt_switch::make(@$, std::move($3), std::move($5)); parse_switch(*$$); } ; stmt_case : CASE expr_integer COLON - { $$ = make_stmt_case(@$, expr{ std::move($2) }, make_stmt_list(@$)); } + { $$ = stmt_case::make(@$, std::move($2), stmt_list::make(@$)); } | CASE expr_string COLON - { $$ = make_stmt_case(@$, expr{ std::move($2) }, make_stmt_list(@$)); } + { $$ = stmt_case::make(@$, std::move($2), stmt_list::make(@$)); } ; stmt_default : DEFAULT COLON - { $$ = make_stmt_default(@$, make_stmt_list(@$)); } + { $$ = stmt_default::make(@$, stmt_list::make(@$)); } ; stmt_break : BREAK SEMICOLON - { $$ = make_stmt_break(@$); } + { $$ = stmt_break::make(@$); } ; stmt_continue : CONTINUE SEMICOLON - { $$ = make_stmt_continue(@$); } + { $$ = stmt_continue::make(@$); } ; stmt_return : RETURN expr SEMICOLON - { $$ = make_stmt_return(@$, std::move($2)); } + { $$ = stmt_return::make(@$, std::move($2)); } | RETURN SEMICOLON - { $$ = make_stmt_return(@$, make_node(@$)); } + { $$ = stmt_return::make(@$, expr_empty::make(@$)); } ; stmt_breakpoint : BREAKPOINT SEMICOLON - { $$ = make_stmt_breakpoint(@$); } + { $$ = stmt_breakpoint::make(@$); } ; stmt_prof_begin : PROFBEGIN LPAREN expr_arguments RPAREN SEMICOLON - { $$ = make_stmt_prof_begin(@$, std::move($3)); } + { $$ = stmt_prof_begin::make(@$, std::move($3)); } ; stmt_prof_end : PROFEND LPAREN expr_arguments RPAREN SEMICOLON - { $$ = make_stmt_prof_end(@$, std::move($3)); } + { $$ = stmt_prof_end::make(@$, std::move($3)); } ; stmt_assert : ASSERT LPAREN expr_arguments RPAREN SEMICOLON - { $$ = make_stmt_assert(@$, std::move($3)); } + { $$ = stmt_assert::make(@$, std::move($3)); } ; stmt_assertex : ASSERTEX LPAREN expr_arguments RPAREN SEMICOLON - { $$ = make_stmt_assertex(@$, std::move($3)); } + { $$ = stmt_assertex::make(@$, std::move($3)); } ; stmt_assertmsg : ASSERTMSG LPAREN expr_arguments RPAREN SEMICOLON - { $$ = make_stmt_assertmsg(@$, std::move($3)); } + { $$ = stmt_assertmsg::make(@$, std::move($3)); } ; expr @@ -581,232 +582,233 @@ expr expr_or_empty : expr { $$ = std::move($1); } - | { $$.as_node = make_node(@$); } - ; - -expr_assign - : expr_tuple ASSIGN expr - { $$.as_node = make_expr_assign_equal(@$, std::move($1), std::move($3)); } - | expr_object ASSIGN expr - { $$.as_node = make_expr_assign_equal(@$, std::move($1), std::move($3)); } - | expr_object ASSIGN_BW_OR expr - { $$.as_node = make_expr_assign_bitwise_or(@$, std::move($1), std::move($3)); } - | expr_object ASSIGN_BW_AND expr - { $$.as_node = make_expr_assign_bitwise_and(@$, std::move($1), std::move($3)); } - | expr_object ASSIGN_BW_EXOR expr - { $$.as_node = make_expr_assign_bitwise_exor(@$, std::move($1), std::move($3)); } - | expr_object ASSIGN_LSHIFT expr - { $$.as_node = make_expr_assign_shift_left(@$, std::move($1),std::move( $3)); } - | expr_object ASSIGN_RSHIFT expr - { $$.as_node = make_expr_assign_shift_right(@$, std::move($1), std::move($3)); } - | expr_object ASSIGN_ADD expr - { $$.as_node = make_expr_assign_add(@$, std::move($1), std::move($3)); } - | expr_object ASSIGN_SUB expr - { $$.as_node = make_expr_assign_sub(@$, std::move($1), std::move($3)); } - | expr_object ASSIGN_MUL expr - { $$.as_node = make_expr_assign_mul(@$, std::move($1), std::move($3)); } - | expr_object ASSIGN_DIV expr - { $$.as_node = make_expr_assign_div(@$, std::move($1), std::move($3)); } - | expr_object ASSIGN_MOD expr - { $$.as_node = make_expr_assign_mod(@$, std::move($1), std::move($3)); } + | { $$ = expr_empty::make(@$); } ; expr_increment : INCREMENT expr_object %prec PREINC - { $$.as_node = make_expr_increment(@$, std::move($2), true); } + { $$ = expr_increment::make(@$, std::move($2), true); } | expr_object INCREMENT %prec POSTINC - { $$.as_node = make_expr_increment(@$, std::move($1), false); } + { $$ = expr_increment::make(@$, std::move($1), false); } ; expr_decrement : DECREMENT expr_object %prec PREDEC - { $$.as_node = make_expr_decrement(@$, std::move($2), true); } + { $$ = expr_decrement::make(@$, std::move($2), true); } | expr_object DECREMENT %prec POSTDEC - { $$.as_node = make_expr_decrement(@$, std::move($1), false); } + { $$ = expr_decrement::make(@$, std::move($1), false); } + ; + +expr_assign + : expr_tuple ASSIGN expr + { $$ = expr_assign::make(@$, std::move($1), std::move($3), expr_assign::op::eq); } + | expr_object ASSIGN expr + { $$ = expr_assign::make(@$, std::move($1), std::move($3), expr_assign::op::eq); } + | expr_object ASSIGN_BW_OR expr + { $$ = expr_assign::make(@$, std::move($1), std::move($3), expr_assign::op::bwor); } + | expr_object ASSIGN_BW_AND expr + { $$ = expr_assign::make(@$, std::move($1), std::move($3), expr_assign::op::bwand); } + | expr_object ASSIGN_BW_EXOR expr + { $$ = expr_assign::make(@$, std::move($1), std::move($3), expr_assign::op::bwexor); } + | expr_object ASSIGN_LSHIFT expr + { $$ = expr_assign::make(@$, std::move($1), std::move($3), expr_assign::op::shl); } + | expr_object ASSIGN_RSHIFT expr + { $$ = expr_assign::make(@$, std::move($1), std::move($3), expr_assign::op::shr); } + | expr_object ASSIGN_ADD expr + { $$ = expr_assign::make(@$, std::move($1), std::move($3), expr_assign::op::add); } + | expr_object ASSIGN_SUB expr + { $$ = expr_assign::make(@$, std::move($1), std::move($3), expr_assign::op::sub); } + | expr_object ASSIGN_MUL expr + { $$ = expr_assign::make(@$, std::move($1), std::move($3), expr_assign::op::mul); } + | expr_object ASSIGN_DIV expr + { $$ = expr_assign::make(@$, std::move($1), std::move($3), expr_assign::op::div); } + | expr_object ASSIGN_MOD expr + { $$ = expr_assign::make(@$, std::move($1), std::move($3), expr_assign::op::mod); } ; expr_ternary : expr QMARK expr COLON expr %prec TERN - { $$.as_node = make_expr_ternary(@$, std::move($1), std::move($3), std::move($5)); } + { $$ = expr_ternary::make(@$, std::move($1), std::move($3), std::move($5)); } ; expr_binary : expr OR expr - { $$.as_node = make_expr_or(@$, std::move($1), std::move($3)); } + { $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::bool_or); } | expr AND expr - { $$.as_node = make_expr_and(@$, std::move($1), std::move($3)); } + { $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::bool_and); } | expr EQUALITY expr - { $$.as_node = make_expr_equality(@$, std::move($1), std::move($3)); } + { $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::eq); } | expr INEQUALITY expr - { $$.as_node = make_expr_inequality(@$, std::move($1), std::move($3)); } + { $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::ne); } | expr LESS_EQUAL expr - { $$.as_node = make_expr_less_equal(@$, std::move($1), std::move($3)); } + { $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::le); } | expr GREATER_EQUAL expr - { $$.as_node = make_expr_greater_equal(@$, std::move($1), std::move($3)); } + { $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::ge); } | expr LESS expr - { $$.as_node = make_expr_less(@$, std::move($1), std::move($3)); } + { $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::lt); } | expr GREATER expr - { $$.as_node = make_expr_greater(@$, std::move($1), std::move($3)); } + { $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::gt); } | expr BITWISE_OR expr - { $$.as_node = make_expr_bitwise_or(@$, std::move($1), std::move($3)); } + { $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::bwor); } | expr BITWISE_AND expr - { $$.as_node = make_expr_bitwise_and(@$, std::move($1), std::move($3)); } + { $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::bwand); } | expr BITWISE_EXOR expr - { $$.as_node = make_expr_bitwise_exor(@$, std::move($1), std::move($3)); } + { $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::bwexor); } | expr LSHIFT expr - { $$.as_node = make_expr_shift_left(@$, std::move($1), std::move($3)); } + { $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::shl); } | expr RSHIFT expr - { $$.as_node = make_expr_shift_right(@$, std::move($1), std::move($3)); } + { $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::shr); } | expr ADD expr - { $$.as_node = make_expr_add(@$, std::move($1), std::move($3)); } + { $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::add); } | expr SUB expr - { $$.as_node = make_expr_sub(@$, std::move($1), std::move($3)); } + { $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::sub); } | expr MUL expr - { $$.as_node = make_expr_mul(@$, std::move($1), std::move($3)); } + { $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::mul); } | expr DIV expr - { $$.as_node = make_expr_div(@$, std::move($1), std::move($3)); } + { $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::div); } | expr MOD expr - { $$.as_node = make_expr_mod(@$, std::move($1), std::move($3)); } + { $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::mod); } ; expr_primitive - : expr_complement { $$.as_node = std::move($1); } - | expr_negate { $$.as_node = std::move($1); } - | expr_not { $$.as_node = std::move($1); } - | expr_call { $$.as_node = std::move($1); } - | expr_method { $$.as_node = std::move($1); } - | expr_add_array { $$.as_node = std::move($1); } - | expr_isdefined { $$.as_node = std::move($1); } - | expr_istrue { $$.as_node = std::move($1); } - | expr_reference { $$.as_node = std::move($1); } - | expr_array { $$.as_node = std::move($1); } - | expr_field { $$.as_node = std::move($1); } - | expr_size { $$.as_node = std::move($1); } - | expr_paren { $$.as_node = std::move($1); } - | expr_thisthread { $$.as_node = std::move($1); } - | expr_empty_array { $$.as_node = std::move($1); } - | expr_undefined { $$.as_node = std::move($1); } - | expr_game { $$.as_node = std::move($1); } - | expr_self { $$.as_node = std::move($1); } - | expr_anim { $$.as_node = std::move($1); } - | expr_level { $$.as_node = std::move($1); } - | expr_animation { $$.as_node = std::move($1); } - | expr_animtree { $$.as_node = std::move($1); } - | expr_identifier { $$.as_node = std::move($1); } - | expr_istring { $$.as_node = std::move($1); } - | expr_string { $$.as_node = std::move($1); } - | expr_vector { $$.as_node = std::move($1); } - | expr_float { $$.as_node = std::move($1); } - | expr_integer { $$.as_node = std::move($1); } - | expr_false { $$.as_node = std::move($1); } - | expr_true { $$.as_node = std::move($1); } + : expr_complement { $$ = std::move($1); } + | expr_negate { $$ = std::move($1); } + | expr_not { $$ = std::move($1); } + | expr_call { $$ = std::move($1); } + | expr_method { $$ = std::move($1); } + | expr_add_array { $$ = std::move($1); } + | expr_isdefined { $$ = std::move($1); } + | expr_istrue { $$ = std::move($1); } + | expr_reference { $$ = std::move($1); } + | expr_array { $$ = std::move($1); } + | expr_field { $$ = std::move($1); } + | expr_size { $$ = std::move($1); } + | expr_paren { $$ = std::move($1); } + | expr_thisthread { $$ = std::move($1); } + | expr_empty_array { $$ = std::move($1); } + | expr_undefined { $$ = std::move($1); } + | expr_game { $$ = std::move($1); } + | expr_self { $$ = std::move($1); } + | expr_anim { $$ = std::move($1); } + | expr_level { $$ = std::move($1); } + | expr_animation { $$ = std::move($1); } + | expr_animtree { $$ = std::move($1); } + | expr_identifier { $$ = std::move($1); } + | expr_istring { $$ = std::move($1); } + | expr_string { $$ = std::move($1); } + | expr_vector { $$ = std::move($1); } + | expr_float { $$ = std::move($1); } + | expr_integer { $$ = std::move($1); } + | expr_false { $$ = std::move($1); } + | expr_true { $$ = std::move($1); } ; expr_complement : COMPLEMENT expr - { $$ = make_expr_complement(@$, std::move($2)); } + { $$ = expr_complement::make(@$, std::move($2)); } ; expr_negate : SUB expr_identifier %prec NEG - { $$ = make_expr_negate(@$, expr{ std::move($2) }); } + { $$ = expr_negate::make(@$, std::move($2)); } | SUB expr_paren %prec NEG - { $$ = make_expr_negate(@$, expr{ std::move($2) }); } + { $$ = expr_negate::make(@$, std::move($2)); } | SUB expr_array %prec NEG - { $$ = make_expr_negate(@$, expr{ std::move($2) }); } + { $$ = expr_negate::make(@$, std::move($2)); } | SUB expr_field %prec NEG - { $$ = make_expr_negate(@$, expr{ std::move($2) }); } + { $$ = expr_negate::make(@$, std::move($2)); } ; expr_not : NOT expr - { $$ = make_expr_not(@$, std::move($2)); } + { $$ = expr_not::make(@$, std::move($2)); } ; expr_call - : expr_function { $$ = make_expr_call(@$, std::move($1)); } - | expr_pointer { $$ = make_expr_call(@$, std::move($1)); } + : expr_function { $$ = expr_call::make(@$, std::move($1)); } + | expr_pointer { $$ = expr_call::make(@$, std::move($1)); } ; expr_method - : expr_object expr_function { $$ = make_expr_method(@$, std::move($1), std::move($2)); } - | expr_object expr_pointer { $$ = make_expr_method(@$, std::move($1), std::move($2)); } + : expr_object expr_function { $$ = expr_method::make(@$, std::move($1), std::move($2)); } + | expr_object expr_pointer { $$ = expr_method::make(@$, std::move($1), std::move($2)); } ; expr_function : expr_identifier LPAREN expr_arguments RPAREN - { $$.as_function = make_expr_function(@$, make_expr_path(@$), std::move($1), std::move($3), call::mode::normal); } + { $$ = expr_function::make(@$, expr_path::make(@$), std::move($1), std::move($3), call::mode::normal); } | expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN - { $$.as_function = make_expr_function(@$, std::move($1), std::move($3), std::move($5), call::mode::normal); } + { $$ = expr_function::make(@$, std::move($1), std::move($3), std::move($5), call::mode::normal); } | THREAD expr_identifier LPAREN expr_arguments RPAREN - { $$.as_function = make_expr_function(@$, make_expr_path(@$), std::move($2), std::move($4), call::mode::thread); } + { $$ = expr_function::make(@$, expr_path::make(@$), std::move($2), std::move($4), call::mode::thread); } | THREAD expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN - { $$.as_function = make_expr_function(@$, std::move($2), std::move($4), std::move($6), call::mode::thread); } + { $$ = expr_function::make(@$, std::move($2), std::move($4), std::move($6), call::mode::thread); } | CHILDTHREAD expr_identifier LPAREN expr_arguments RPAREN - { $$.as_function = make_expr_function(@$, make_expr_path(@$), std::move($2), std::move($4), call::mode::childthread); } + { $$ = expr_function::make(@$, expr_path::make(@$), std::move($2), std::move($4), call::mode::childthread); } | CHILDTHREAD expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN - { $$.as_function = make_expr_function(@$, std::move($2), std::move($4), std::move($6), call::mode::childthread); } + { $$ = expr_function::make(@$, std::move($2), std::move($4), std::move($6), call::mode::childthread); } ; expr_pointer : LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN - { $$.as_pointer = make_expr_pointer(@$, std::move($3), std::move($7), call::mode::normal); } + { $$ = expr_pointer::make(@$, std::move($3), std::move($7), call::mode::normal); } | THREAD LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN - { $$.as_pointer = make_expr_pointer(@$, std::move($4), std::move($8), call::mode::thread); } + { $$ = expr_pointer::make(@$, std::move($4), std::move($8), call::mode::thread); } | CHILDTHREAD LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN - { $$.as_pointer = make_expr_pointer(@$, std::move($4), std::move($8), call::mode::childthread); } + { $$ = expr_pointer::make(@$, std::move($4), std::move($8), call::mode::childthread); } | CALL LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN - { $$.as_pointer = make_expr_pointer(@$, std::move($4), std::move($8), call::mode::builtin); } + { $$ = expr_pointer::make(@$, std::move($4), std::move($8), call::mode::builtin); } ; expr_add_array : LBRACKET expr_arguments_no_empty RBRACKET - { $$ = make_expr_add_array(@$, std::move($2)); } + { $$ = expr_add_array::make(@$, std::move($2)); } ; expr_parameters : expr_parameters COMMA expr_identifier { $$ = std::move($1); $$->list.push_back(std::move($3)); } | expr_identifier - { $$ = make_expr_parameters(@$); $$->list.push_back(std::move($1)); } + { $$ = expr_parameters::make(@$); $$->list.push_back(std::move($1)); } | - { $$ = make_expr_parameters(@$); } + { $$ = expr_parameters::make(@$); } ; expr_arguments : expr_arguments_no_empty { $$ = std::move($1); } | - { $$ = make_expr_arguments(@$); } + { $$ = expr_arguments::make(@$); } ; expr_arguments_no_empty : expr_arguments COMMA expr { $$ = std::move($1); $$->list.push_back(std::move($3)); } | expr %prec ADD_ARRAY - { $$ = make_expr_arguments(@$); $$->list.push_back(std::move($1)); } + { $$ = expr_arguments::make(@$); $$->list.push_back(std::move($1)); } ; expr_isdefined : ISDEFINED LPAREN expr RPAREN - { $$ = make_expr_isdefined(@$, std::move($3)); } + { $$ = expr_isdefined::make(@$, std::move($3)); } ; expr_istrue : ISTRUE LPAREN expr RPAREN - { $$ = make_expr_istrue(@$, std::move($3)); } + { $$ = expr_istrue::make(@$, std::move($3)); } ; expr_reference : DOUBLECOLON expr_identifier - { $$ = make_expr_reference(@$, make_expr_path(@$), std::move($2)); } + { $$ = expr_reference::make(@$, expr_path::make(@$), std::move($2)); } | expr_path DOUBLECOLON expr_identifier - { $$ = make_expr_reference(@$, std::move($1), std::move($3)); } + { $$ = expr_reference::make(@$, std::move($1), std::move($3)); } ; expr_tuple : LBRACKET expr_tuple_arguments RBRACKET - { $$.as_node = std::move($2); - $$.as_tuple->temp = expr{ std::make_unique($$.loc(), fmt::format("_temp_{}", ++index)) }; + { + $$ = std::move($2); + $$->as().temp = expr_identifier::make($$->loc(), fmt::format("_temp_{}", ++index)); } ; @@ -814,150 +816,150 @@ expr_tuple_arguments : expr_tuple_arguments COMMA expr_tuple_types { $$ = std::move($1); $$->list.push_back(std::move($3)); } | expr_tuple_types - { $$ = make_expr_tuple(@$); $$->list.push_back(std::move($1)); } + { $$ = expr_tuple::make(@$); $$->list.push_back(std::move($1)); } ; expr_tuple_types - : expr_array { $$.as_node = std::move($1); } - | expr_field { $$.as_node = std::move($1); } - | expr_identifier { $$.as_node = std::move($1); } + : expr_array { $$ = std::move($1); } + | expr_field { $$ = std::move($1); } + | expr_identifier { $$ = std::move($1); } ; expr_array : expr_object LBRACKET expr RBRACKET - { $$ = make_expr_array(@$, std::move($1), std::move($3)); } + { $$ = expr_array::make(@$, std::move($1), std::move($3)); } ; expr_field : expr_object DOT expr_identifier_nosize - { $$ = make_expr_field(@$, std::move($1), std::move($3)); } + { $$ = expr_field::make(@$, std::move($1), std::move($3)); } ; expr_size : expr_object DOT SIZE %prec SIZEOF - { $$ = make_expr_size(@$, std::move($1)); } + { $$ = expr_size::make(@$, std::move($1)); } ; expr_paren : LPAREN expr RPAREN - { $$ = make_expr_paren(@$, std::move($2)); } + { $$ = expr_paren::make(@$, std::move($2)); } ; expr_object - : expr_call { $$.as_node = std::move($1); } - | expr_method { $$.as_node = std::move($1); } - | expr_array { $$.as_node = std::move($1); } - | expr_field { $$.as_node = std::move($1); } - | expr_game { $$.as_node = std::move($1); } - | expr_self { $$.as_node = std::move($1); } - | expr_anim { $$.as_node = std::move($1); } - | expr_level { $$.as_node = std::move($1); } - | expr_identifier { $$.as_node = std::move($1); } + : expr_call { $$ = std::move($1); } + | expr_method { $$ = std::move($1); } + | expr_array { $$ = std::move($1); } + | expr_field { $$ = std::move($1); } + | expr_game { $$ = std::move($1); } + | expr_self { $$ = std::move($1); } + | expr_anim { $$ = std::move($1); } + | expr_level { $$ = std::move($1); } + | expr_identifier { $$ = std::move($1); } ; expr_thisthread : THISTHREAD - { $$ = make_expr_thisthread(@$); }; + { $$ = expr_thisthread::make(@$); }; ; expr_empty_array : LBRACKET RBRACKET - { $$ = make_expr_empty_array(@$); }; + { $$ = expr_empty_array::make(@$); }; ; expr_undefined : UNDEFINED - { $$ = make_expr_undefined(@$); }; + { $$ = expr_undefined::make(@$); }; ; expr_game : GAME - { $$ = make_expr_game(@$); }; + { $$ = expr_game::make(@$); }; ; expr_self : SELF - { $$ = make_expr_self(@$); }; + { $$ = expr_self::make(@$); }; ; expr_anim : ANIM - { $$ = make_expr_anim(@$); }; + { $$ = expr_anim::make(@$); }; ; expr_level : LEVEL - { $$ = make_expr_level(@$); }; + { $$ = expr_level::make(@$); }; ; expr_animation : MOD IDENTIFIER %prec ANIMREF - { $$ = make_expr_animation(@$, $2); }; + { $$ = expr_animation::make(@$, $2); }; ; expr_animtree : ANIMTREE - { $$ = make_expr_animtree(@$); }; + { $$ = expr_animtree::make(@$); }; ; expr_identifier_nosize : IDENTIFIER - { $$ = make_expr_identifier(@$, $1); }; + { $$ = expr_identifier::make(@$, $1); }; ; expr_identifier : IDENTIFIER - { $$ = make_expr_identifier(@$, $1); }; + { $$ = expr_identifier::make(@$, $1); }; | SIZE - { $$ = make_expr_identifier(@$, "size"); }; + { $$ = expr_identifier::make(@$, "size"); }; ; expr_path : PATH DIV IDENTIFIER - { $$ = make_expr_path(@$, $1 + "/" + $3); }; + { $$ = expr_path::make(@$, $1 + "/" + $3); }; | IDENTIFIER - { $$ = make_expr_path(@$, $1); }; + { $$ = expr_path::make(@$, $1); }; | PATH - { $$ = make_expr_path(@$, $1); }; + { $$ = expr_path::make(@$, $1); }; ; expr_istring : ISTRING - { $$ = make_expr_istring(@$, $1); }; + { $$ = expr_istring::make(@$, $1); }; ; expr_string : STRING - { $$ = make_expr_string(@$, $1); }; + { $$ = expr_string::make(@$, $1); }; ; expr_vector : LPAREN expr COMMA expr COMMA expr RPAREN - { $$ = make_expr_vector(@$, std::move($2), std::move($4), std::move($6)); }; + { $$ = expr_vector::make(@$, std::move($2), std::move($4), std::move($6)); }; ; expr_float : SUB FLOAT %prec NEG - { $$ = make_expr_float(@$, "-" + $2); }; + { $$ = expr_float::make(@$, "-" + $2); }; | FLOAT - { $$ = make_expr_float(@$, $1); }; + { $$ = expr_float::make(@$, $1); }; ; expr_integer : SUB INTEGER %prec NEG - { $$ = make_expr_integer(@$, "-" + $2); }; + { $$ = expr_integer::make(@$, "-" + $2); }; | INTEGER - { $$ = make_expr_integer(@$, $1); }; + { $$ = expr_integer::make(@$, $1); }; ; expr_false : FALSE - { $$ = make_expr_false(@$); }; + { $$ = expr_false::make(@$); }; ; expr_true : TRUE - { $$ = make_expr_true(@$); }; + { $$ = expr_true::make(@$); }; ; %% @@ -972,8 +974,8 @@ void parser::error(location const& loc, std::string const& msg) auto parse_switch(stmt_switch& stm) -> void { - auto body = make_stmt_list(stm.body->block->loc()); - auto current_case = stmt{ nullptr }; + auto body = stmt_list::make(stm.body->block->loc()); + auto curr = stmt::ptr{ nullptr }; auto num = stm.body->block->list.size(); @@ -981,41 +983,41 @@ auto parse_switch(stmt_switch& stm) -> void { auto& entry = stm.body->block->list[0]; - if (entry == node::stmt_case || entry == node::stmt_default) + if (entry->is() || entry->is()) { - if (current_case.as_node != nullptr) + if (curr != nullptr) { - body->list.push_back(std::move(current_case)); + body->list.push_back(std::move(curr)); } - current_case = std::move(stm.body->block->list[0]); + curr = std::move(stm.body->block->list[0]); stm.body->block->list.erase(stm.body->block->list.begin()); } else { - if (current_case.as_node != nullptr) + if (curr != nullptr) { - if (current_case == node::stmt_case) + if (curr->is()) { - current_case.as_case->body->list.push_back(std::move(entry)); + curr->as().body->list.push_back(std::move(entry)); stm.body->block->list.erase(stm.body->block->list.begin()); } else { - current_case.as_default->body->list.push_back(std::move(entry)); + curr->as().body->list.push_back(std::move(entry)); stm.body->block->list.erase(stm.body->block->list.begin()); } } else { - throw comp_error(entry.loc(), "missing case statement"); + throw comp_error(entry->loc(), "missing case statement"); } } } - if (current_case.as_node != nullptr) + if (curr != nullptr) { - body->list.push_back(std::move(current_case)); + body->list.push_back(std::move(curr)); } stm.body->block = std::move(body); diff --git a/include/xsk/gsc/common/ast.hpp b/include/xsk/gsc/common/ast.hpp index 5d1e00fa..713f3c8a 100644 --- a/include/xsk/gsc/common/ast.hpp +++ b/include/xsk/gsc/common/ast.hpp @@ -14,7 +14,10 @@ struct node enum type { - null, + node_null, + node_voidcodepos, + node_prescriptcall, + expr_empty, expr_true, expr_false, expr_integer, @@ -51,44 +54,18 @@ struct node expr_complement, expr_negate, expr_not, - expr_add, - expr_sub, - expr_mul, - expr_div, - expr_mod, - expr_shift_left, - expr_shift_right, - expr_bitwise_or, - expr_bitwise_and, - expr_bitwise_exor, - expr_equality, - expr_inequality, - expr_less_equal, - expr_greater_equal, - expr_less, - expr_greater, - expr_or, - expr_and, + expr_binary, expr_ternary, + expr_assign, expr_increment, expr_decrement, - expr_assign_equal, - expr_assign_add, - expr_assign_sub, - expr_assign_mul, - expr_assign_div, - expr_assign_mod, - expr_assign_shift_left, - expr_assign_shift_right, - expr_assign_bitwise_or, - expr_assign_bitwise_and, - expr_assign_bitwise_exor, + expr_var_create, + expr_var_access, + stmt_empty, stmt_list, stmt_comp, stmt_dev, stmt_expr, - stmt_call, - stmt_assign, stmt_endon, stmt_notify, stmt_wait, @@ -114,6 +91,17 @@ struct node stmt_assert, stmt_assertex, stmt_assertmsg, + stmt_create, + stmt_remove, + stmt_clear, + stmt_jmp, + stmt_jmp_back, + stmt_jmp_cond, + stmt_jmp_true, + stmt_jmp_false, + stmt_jmp_switch, + stmt_jmp_endswitch, + decl_empty, decl_function, decl_constant, decl_usingtree, @@ -121,30 +109,9 @@ struct node decl_dev_end, include, program, - asm_jmp, - asm_jmp_back, - asm_jmp_cond, - asm_jmp_true, - asm_jmp_false, - asm_switch, - asm_endswitch, - asm_prescriptcall, - asm_voidcodepos, - asm_create, - asm_access, - asm_remove, - asm_clear, }; -public: - node() : kind_(type::null) {} - node(location const& loc) : kind_(type::null), loc_(loc) {} - node(type t) : kind_(t) {} - node(type t, location const& loc) : kind_(t), loc_(loc) {} - virtual ~node() = default; - friend bool operator==(node const& n, type t); - friend bool operator==(node const& lhs, node const& rhs); auto kind() const -> type { return kind_; } auto loc() const -> location const& { return loc_; } @@ -154,344 +121,158 @@ public: auto is_special_stmt_dev() -> bool; auto is_special_stmt_noif() -> bool; auto is_special_stmt_dev_noif() -> bool; - auto is_binary() -> bool; - auto precedence() -> u8; + auto is_assign() -> bool; + + virtual auto precedence() -> u8; + + template + static auto as(node::ptr) -> std::unique_ptr; + +protected: + node(type t) : kind_(t) {} + node(type t, location const& loc) : kind_(t), loc_(loc) {} private: type kind_; location loc_; }; -struct expr_true; -struct expr_false; -struct expr_integer; -struct expr_float; -struct expr_vector; -struct expr_string; -struct expr_istring; -struct expr_path; -struct expr_identifier; -struct expr_animtree; -struct expr_animation; -struct expr_level; -struct expr_anim; -struct expr_self; -struct expr_game; -struct expr_undefined; -struct expr_empty_array; -struct expr_thisthread; -struct expr_paren; -struct expr_size; -struct expr_field; -struct expr_array; -struct expr_tuple; -struct expr_reference; -struct expr_istrue; -struct expr_isdefined; -struct expr_arguments; -struct expr_parameters; -struct expr_add_array; -struct expr_pointer; -struct expr_function; -struct expr_method; -struct expr_call; -struct expr_complement; -struct expr_negate; -struct expr_not; -struct expr_binary; -struct expr_add; -struct expr_sub; -struct expr_mul; -struct expr_div; -struct expr_mod; -struct expr_shift_left; -struct expr_shift_right; -struct expr_bitwise_or; -struct expr_bitwise_and; -struct expr_bitwise_exor; -struct expr_equality; -struct expr_inequality; -struct expr_less_equal; -struct expr_greater_equal; -struct expr_less; -struct expr_greater; -struct expr_or; -struct expr_and; -struct expr_ternary; -struct expr_increment; -struct expr_decrement; -struct expr_assign; -struct expr_assign_equal; -struct expr_assign_add; -struct expr_assign_sub; -struct expr_assign_mul; -struct expr_assign_div; -struct expr_assign_mod; -struct expr_assign_shift_left; -struct expr_assign_shift_right; -struct expr_assign_bitwise_or; -struct expr_assign_bitwise_and; -struct expr_assign_bitwise_exor; -struct stmt_list; -struct stmt_comp; -struct stmt_dev; -struct stmt_expr; -struct stmt_call; -struct stmt_assign; -struct stmt_endon; -struct stmt_notify; -struct stmt_wait; -struct stmt_waittill; -struct stmt_waittillmatch; -struct stmt_waittillframeend; -struct stmt_waitframe; -struct stmt_if; -struct stmt_ifelse; -struct stmt_while; -struct stmt_dowhile; -struct stmt_for; -struct stmt_foreach; -struct stmt_switch; -struct stmt_case; -struct stmt_default; -struct stmt_break; -struct stmt_continue; -struct stmt_return; -struct stmt_breakpoint; -struct stmt_prof_begin; -struct stmt_prof_end; -struct stmt_assert; -struct stmt_assertex; -struct stmt_assertmsg; -struct decl_function; -struct decl_constant; -struct decl_usingtree; -struct decl_dev_begin; -struct decl_dev_end; -struct include; -struct program; -struct asm_jmp; -struct asm_jmp_back; -struct asm_jmp_cond; -struct asm_jmp_false; -struct asm_jmp_true; -struct asm_switch; -struct asm_endswitch; -struct asm_prescriptcall; -struct asm_voidcodepos; -struct asm_create; -struct asm_access; -struct asm_remove; -struct asm_clear; - -union call +struct expr : node { + using ptr = std::unique_ptr; + + virtual ~expr() = default; + + friend auto operator==(expr const& lhs, expr const& rhs) -> bool; + + template + auto is() const -> bool; + + template + auto as() const -> T const&; + + template + auto as() -> T&; + +protected: + expr(type t); + expr(type t, location const& loc); +}; + +struct call : expr +{ + using ptr = std::unique_ptr; + enum class type { local, far, builtin }; enum class mode { normal, thread, childthread, builtin }; - std::unique_ptr as_node; - std::unique_ptr as_pointer; - std::unique_ptr as_function; + virtual ~call() = default; - call(); - call(std::unique_ptr value); - call(call&& value); - call(call const&) = delete; - call& operator=(call const&) = delete; - ~call(); - friend auto operator==(call const& lhs, node::type rhs) -> bool; - auto loc() const -> location; - auto kind() const -> node::type; - auto label() const -> std::string; + template + auto is() const -> bool; + + template + auto as() const -> T const&; + + template + auto as() -> T&; + +protected: + call(node::type t); + call(node::type t, location const& loc); }; -union expr +struct stmt : node { - std::unique_ptr as_node; - std::unique_ptr as_true; - std::unique_ptr as_false; - std::unique_ptr as_integer; - std::unique_ptr as_float; - std::unique_ptr as_vector; - std::unique_ptr as_string; - std::unique_ptr as_istring; - std::unique_ptr as_path; - std::unique_ptr as_identifier; - std::unique_ptr as_animtree; - std::unique_ptr as_animation; - std::unique_ptr as_level; - std::unique_ptr as_anim; - std::unique_ptr as_self; - std::unique_ptr as_game; - std::unique_ptr as_undefined; - std::unique_ptr as_empty_array; - std::unique_ptr as_thisthread; - std::unique_ptr as_paren; - std::unique_ptr as_size; - std::unique_ptr as_field; - std::unique_ptr as_array; - std::unique_ptr as_tuple; - std::unique_ptr as_reference; - std::unique_ptr as_istrue; - std::unique_ptr as_isdefined; - std::unique_ptr as_arguments; - std::unique_ptr as_parameters; - std::unique_ptr as_add_array; - std::unique_ptr as_pointer; - std::unique_ptr as_function; - std::unique_ptr as_method; - std::unique_ptr as_call; - std::unique_ptr as_complement; - std::unique_ptr as_negate; - std::unique_ptr as_not; - std::unique_ptr as_binary; - std::unique_ptr as_add; - std::unique_ptr as_sub; - std::unique_ptr as_mul; - std::unique_ptr as_div; - std::unique_ptr as_mod; - std::unique_ptr as_shift_left; - std::unique_ptr as_shift_right; - std::unique_ptr as_bitwise_or; - std::unique_ptr as_bitwise_and; - std::unique_ptr as_bitwise_exor; - std::unique_ptr as_equality; - std::unique_ptr as_inequality; - std::unique_ptr as_less_equal; - std::unique_ptr as_greater_equal; - std::unique_ptr as_less; - std::unique_ptr as_greater; - std::unique_ptr as_or; - std::unique_ptr as_and; - std::unique_ptr as_ternary; - std::unique_ptr as_increment; - std::unique_ptr as_decrement; - std::unique_ptr as_assign; - std::unique_ptr as_assign_equal; - std::unique_ptr as_assign_add; - std::unique_ptr as_assign_sub; - std::unique_ptr as_assign_mul; - std::unique_ptr as_assign_div; - std::unique_ptr as_assign_mod; - std::unique_ptr as_assign_shift_left; - std::unique_ptr as_assign_shift_right; - std::unique_ptr as_assign_bw_or; - std::unique_ptr as_assign_bw_and; - std::unique_ptr as_assign_bw_exor; - std::unique_ptr as_asm_create; - std::unique_ptr as_asm_access; + using ptr = std::unique_ptr; - expr(); - expr(std::unique_ptr value); - expr(expr&& value); - expr& operator=(expr&& value); - expr(expr const&) = delete; - expr& operator=(expr const&) = delete; - ~expr(); - friend auto operator!=(expr const& lhs, node::type rhs) -> bool; - friend auto operator==(expr const& lhs, node::type rhs) -> bool; - friend auto operator==(expr const& lhs, expr const& rhs) -> bool; - auto loc() const -> location; - auto kind() const -> node::type; - auto label() const -> std::string; + virtual ~stmt() = default; + + template + auto is() const -> bool; + + template + auto as() const -> T const&; + + template + auto as() -> T&; + +protected: + stmt(type t); + stmt(type t, location const& loc); }; -union stmt +struct decl : node { - std::unique_ptr as_node; - std::unique_ptr as_list; - std::unique_ptr as_comp; - std::unique_ptr as_dev; - std::unique_ptr as_expr; - std::unique_ptr as_call; - std::unique_ptr as_assign; - std::unique_ptr as_endon; - std::unique_ptr as_notify; - std::unique_ptr as_wait; - std::unique_ptr as_waittill; - std::unique_ptr as_waittillmatch; - std::unique_ptr as_waittillframeend; - std::unique_ptr as_waitframe; - std::unique_ptr as_if; - std::unique_ptr as_ifelse; - std::unique_ptr as_while; - std::unique_ptr as_dowhile; - std::unique_ptr as_for; - std::unique_ptr as_foreach; - std::unique_ptr as_switch; - std::unique_ptr as_case; - std::unique_ptr as_default; - std::unique_ptr as_break; - std::unique_ptr as_continue; - std::unique_ptr as_return; - std::unique_ptr as_breakpoint; - std::unique_ptr as_prof_begin; - std::unique_ptr as_prof_end; - std::unique_ptr as_assert; - std::unique_ptr as_assertex; - std::unique_ptr as_assertmsg; - std::unique_ptr as_cond; - std::unique_ptr as_jump; - std::unique_ptr as_jump_back; - std::unique_ptr as_asm_switch; - std::unique_ptr as_asm_endswitch; - std::unique_ptr as_asm_create; - std::unique_ptr as_asm_access; - std::unique_ptr as_asm_remove; - std::unique_ptr as_asm_clear; + using ptr = std::unique_ptr; - stmt(); - stmt(std::unique_ptr value); - stmt(stmt&& value); - stmt& operator=(stmt&& value); - stmt(stmt const&) = delete; - stmt& operator=(stmt const&) = delete; - ~stmt(); - friend auto operator==(stmt const& lhs, node::type rhs) -> bool; - auto loc() const -> location; - auto kind() const -> node::type; - auto label() const -> std::string; + virtual ~decl() = default; + + template + auto is() const -> bool; + + template + auto as() const -> T const&; + + template + auto as() -> T&; + +protected: + decl(type t); + decl(type t, location const& loc); }; -union decl +#define XSK_GSC_AST_MAKE(node_type) \ +template \ +inline static auto make(Args&&... args) -> std::unique_ptr \ +{ \ + return std::unique_ptr(new node_type(std::forward(args)...)); \ +} + +struct node_prescriptcall : public node { - std::unique_ptr as_node; - std::unique_ptr as_dev_begin; - std::unique_ptr as_dev_end; - std::unique_ptr as_usingtree; - std::unique_ptr as_constant; - std::unique_ptr as_function; + using ptr = std::unique_ptr; - decl(); - decl(std::unique_ptr value); - decl(decl&& value); - decl& operator=(decl&& value); - decl(decl const&) = delete; - decl& operator=(decl const&) = delete; - ~decl(); - friend auto operator==(decl const& lhs, node::type rhs) -> bool; - auto loc() const -> location; - auto kind() const -> node::type; - auto label() const -> std::string; + node_prescriptcall(location const& loc); + XSK_GSC_AST_MAKE(node_prescriptcall) }; -struct expr_true : public node +struct node_voidcodepos : public node +{ + using ptr = std::unique_ptr; + + node_voidcodepos(location const& loc); + XSK_GSC_AST_MAKE(node_voidcodepos) +}; + +struct expr_empty : public expr +{ + using ptr = std::unique_ptr; + + expr_empty(location const& loc); + friend auto operator==(expr_empty const& lhs, expr_empty const& rhs) -> bool; + XSK_GSC_AST_MAKE(expr_empty) +}; + +struct expr_true : public expr { using ptr = std::unique_ptr; expr_true(location const& loc); friend auto operator==(expr_true const& lhs, expr_true const& rhs) -> bool; + XSK_GSC_AST_MAKE(expr_true) }; -struct expr_false : public node +struct expr_false : public expr { using ptr = std::unique_ptr; expr_false(location const& loc); friend auto operator==(expr_false const& lhs, expr_false const& rhs) -> bool; + XSK_GSC_AST_MAKE(expr_false) }; -struct expr_integer : public node +struct expr_integer : public expr { using ptr = std::unique_ptr; @@ -499,9 +280,10 @@ struct expr_integer : public node expr_integer(location const& loc, std::string const& value); friend auto operator==(expr_integer const& lhs, expr_integer const& rhs) -> bool; + XSK_GSC_AST_MAKE(expr_integer) }; -struct expr_float : public node +struct expr_float : public expr { using ptr = std::unique_ptr; @@ -509,21 +291,23 @@ struct expr_float : public node expr_float(location const& loc, std::string const& value); friend auto operator==(expr_float const& lhs, expr_float const& rhs) -> bool; + XSK_GSC_AST_MAKE(expr_float) }; -struct expr_vector : public node +struct expr_vector : public expr { using ptr = std::unique_ptr; - expr x; - expr y; - expr z; + expr::ptr x; + expr::ptr y; + expr::ptr z; - expr_vector(location const& loc, expr x, expr y, expr z); + expr_vector(location const& loc, expr::ptr x, expr::ptr y, expr::ptr z); friend auto operator==(expr_vector const& lhs, expr_vector const& rhs) -> bool; + XSK_GSC_AST_MAKE(expr_vector) }; -struct expr_string : public node +struct expr_string : public expr { using ptr = std::unique_ptr; @@ -531,9 +315,10 @@ struct expr_string : public node expr_string(location const& loc, std::string const& value); friend auto operator==(expr_string const& lhs, expr_string const& rhs) -> bool; + XSK_GSC_AST_MAKE(expr_string) }; -struct expr_istring : public node +struct expr_istring : public expr { using ptr = std::unique_ptr; @@ -541,9 +326,10 @@ struct expr_istring : public node expr_istring(location const& loc, std::string const& value); friend auto operator==(expr_istring const& lhs, expr_istring const& rhs) -> bool; + XSK_GSC_AST_MAKE(expr_istring) }; -struct expr_path : public node +struct expr_path : public expr { using ptr = std::unique_ptr; @@ -552,9 +338,10 @@ struct expr_path : public node expr_path(location const& loc); expr_path(location const& loc, std::string const& value); friend auto operator==(expr_path const& lhs, expr_path const& rhs) -> bool; + XSK_GSC_AST_MAKE(expr_path) }; -struct expr_identifier : public node +struct expr_identifier : public expr { using ptr = std::unique_ptr; @@ -562,17 +349,19 @@ struct expr_identifier : public node expr_identifier(location const& loc, std::string const& value); friend auto operator==(expr_identifier const& lhs, expr_identifier const& rhs) -> bool; + XSK_GSC_AST_MAKE(expr_identifier) }; -struct expr_animtree : public node +struct expr_animtree : public expr { using ptr = std::unique_ptr; expr_animtree(location const& loc); friend auto operator==(expr_animtree const& lhs, expr_animtree const& rhs) -> bool; + XSK_GSC_AST_MAKE(expr_animtree) }; -struct expr_animation : public node +struct expr_animation : public expr { using ptr = std::unique_ptr; @@ -580,117 +369,130 @@ struct expr_animation : public node expr_animation(location const& loc, std::string const& value); friend auto operator==(expr_animation const& lhs, expr_animation const& rhs) -> bool; + XSK_GSC_AST_MAKE(expr_animation) }; -struct expr_level : public node +struct expr_level : public expr { using ptr = std::unique_ptr; expr_level(location const& loc); friend auto operator==(expr_level const& lhs, expr_level const& rhs) -> bool; + XSK_GSC_AST_MAKE(expr_level) }; -struct expr_anim : public node +struct expr_anim : public expr { using ptr = std::unique_ptr; expr_anim(location const& loc); friend auto operator==(expr_anim const& lhs, expr_anim const& rhs) -> bool; + XSK_GSC_AST_MAKE(expr_anim) }; -struct expr_self : public node +struct expr_self : public expr { using ptr = std::unique_ptr; expr_self(location const& loc); friend auto operator==(expr_self const& lhs, expr_self const& rhs) -> bool; + XSK_GSC_AST_MAKE(expr_self) }; -struct expr_game : public node +struct expr_game : public expr { using ptr = std::unique_ptr; expr_game(location const& loc); friend auto operator==(expr_game const& lhs, expr_game const& rhs) -> bool; + XSK_GSC_AST_MAKE(expr_game) }; -struct expr_undefined : public node +struct expr_undefined : public expr { using ptr = std::unique_ptr; expr_undefined(location const& loc); friend auto operator==(expr_undefined const& lhs, expr_undefined const& rhs) -> bool; + XSK_GSC_AST_MAKE(expr_undefined) }; -struct expr_empty_array : public node +struct expr_empty_array : public expr { using ptr = std::unique_ptr; expr_empty_array(location const& loc); friend auto operator==(expr_empty_array const& lhs, expr_empty_array const& rhs) -> bool; + XSK_GSC_AST_MAKE(expr_empty_array) }; -struct expr_thisthread : public node +struct expr_thisthread : public expr { using ptr = std::unique_ptr; expr_thisthread(location const& loc); friend auto operator==(expr_thisthread const& lhs, expr_thisthread const& rhs) -> bool; + XSK_GSC_AST_MAKE(expr_thisthread) }; -struct expr_paren : public node +struct expr_paren : public expr { using ptr = std::unique_ptr; - expr value; + expr::ptr value; - expr_paren(location const& loc, expr value); + expr_paren(location const& loc, expr::ptr value); friend auto operator==(expr_paren const& lhs, expr_paren const& rhs) -> bool; + XSK_GSC_AST_MAKE(expr_paren) }; -struct expr_size : public node +struct expr_size : public expr { using ptr = std::unique_ptr; - expr obj; + expr::ptr obj; - expr_size(location const& loc, expr obj); + expr_size(location const& loc, expr::ptr obj); friend auto operator==(expr_size const& lhs, expr_size const& rhs) -> bool; + XSK_GSC_AST_MAKE(expr_size) }; -struct expr_field : public node +struct expr_field : public expr { using ptr = std::unique_ptr; - expr obj; + expr::ptr obj; expr_identifier::ptr field; - expr_field(location const& loc, expr obj, expr_identifier::ptr field); + expr_field(location const& loc, expr::ptr obj, expr_identifier::ptr field); friend auto operator==(expr_field const& lhs, expr_field const& rhs) -> bool; + XSK_GSC_AST_MAKE(expr_field) }; -struct expr_array : public node +struct expr_array : public expr { using ptr = std::unique_ptr; - expr obj; - expr key; + expr::ptr obj; + expr::ptr key; - expr_array(location const& loc, expr obj, expr key); + expr_array(location const& loc, expr::ptr obj, expr::ptr key); friend auto operator==(expr_array const& lhs, expr_array const& rhs) -> bool; + XSK_GSC_AST_MAKE(expr_array) }; -struct expr_tuple : public node +struct expr_tuple : public expr { using ptr = std::unique_ptr; - std::vector list; - expr temp; + std::vector list; + expr::ptr temp; expr_tuple(location const& loc); + XSK_GSC_AST_MAKE(expr_tuple) }; -struct expr_reference : public node +struct expr_reference : public expr { using ptr = std::unique_ptr; @@ -698,65 +500,72 @@ struct expr_reference : public node expr_identifier::ptr name; expr_reference(location const& loc, expr_path::ptr path, expr_identifier::ptr name); + XSK_GSC_AST_MAKE(expr_reference) }; -struct expr_istrue : public node +struct expr_istrue : public expr { using ptr = std::unique_ptr; - expr value; + expr::ptr value; - expr_istrue(location const& loc, expr value); + expr_istrue(location const& loc, expr::ptr value); + XSK_GSC_AST_MAKE(expr_istrue) }; -struct expr_isdefined : public node +struct expr_isdefined : public expr { using ptr = std::unique_ptr; - expr value; + expr::ptr value; - expr_isdefined(location const& loc, expr value); + expr_isdefined(location const& loc, expr::ptr value); + XSK_GSC_AST_MAKE(expr_isdefined) }; -struct expr_arguments : public node +struct expr_arguments : public expr { using ptr = std::unique_ptr; - std::vector list; + std::vector list; expr_arguments(location const& loc); + XSK_GSC_AST_MAKE(expr_arguments) }; -struct expr_parameters : public node +struct expr_parameters : public expr { using ptr = std::unique_ptr; std::vector list; expr_parameters(location const& loc); + XSK_GSC_AST_MAKE(expr_parameters) }; -struct expr_add_array : public node +struct expr_add_array : public expr { using ptr = std::unique_ptr; expr_arguments::ptr args; expr_add_array(location const& loc, expr_arguments::ptr args); + XSK_GSC_AST_MAKE(expr_add_array) }; -struct expr_pointer : public node +struct expr_pointer : public call { using ptr = std::unique_ptr; - expr func; + expr::ptr func; expr_arguments::ptr args; call::mode mode; - expr_pointer(location const& loc, expr func, expr_arguments::ptr args, call::mode mode); + expr_pointer(location const& loc, expr::ptr func, expr_arguments::ptr args, call::mode mode); + XSK_GSC_AST_MAKE(expr_pointer) }; -struct expr_function : public node +struct expr_function : public call { using ptr = std::unique_ptr; @@ -766,518 +575,363 @@ struct expr_function : public node call::mode mode; expr_function(location const& loc, expr_path::ptr path, expr_identifier::ptr name, expr_arguments::ptr args, call::mode mode); + XSK_GSC_AST_MAKE(expr_function) }; -struct expr_method : public node +struct expr_method : public expr { using ptr = std::unique_ptr; - expr obj; - call value; + expr::ptr obj; + call::ptr value; - expr_method(location const& loc, expr obj, call value); + expr_method(location const& loc, expr::ptr obj, call::ptr value); + XSK_GSC_AST_MAKE(expr_method) }; -struct expr_call : public node +struct expr_call : public expr { using ptr = std::unique_ptr; - call value; + call::ptr value; - expr_call(location const& loc, call value); + expr_call(location const& loc, call::ptr value); + XSK_GSC_AST_MAKE(expr_call) }; -struct expr_complement : public node +struct expr_complement : public expr { using ptr = std::unique_ptr; - expr rvalue; + expr::ptr rvalue; - expr_complement(location const& loc, expr rvalue); + expr_complement(location const& loc, expr::ptr rvalue); + XSK_GSC_AST_MAKE(expr_complement) }; -struct expr_negate : public node +struct expr_negate : public expr { using ptr = std::unique_ptr; - expr rvalue; + expr::ptr rvalue; - expr_negate(location const& loc, expr rvalue); + expr_negate(location const& loc, expr::ptr rvalue); + XSK_GSC_AST_MAKE(expr_negate) }; -struct expr_not : public node +struct expr_not : public expr { using ptr = std::unique_ptr; - expr rvalue; + expr::ptr rvalue; - expr_not(location const& loc, expr rvalue); + expr_not(location const& loc, expr::ptr rvalue); + XSK_GSC_AST_MAKE(expr_not) }; -struct expr_binary : public node +struct expr_binary : public expr { using ptr = std::unique_ptr; - expr lvalue; - expr rvalue; + enum class op { eq, ne, le, ge, lt, gt, add, sub, mul, div, mod, shl, shr, bwor, bwand, bwexor, bool_or, bool_and }; - expr_binary(type t, location const& loc, expr lvalue, expr rvalue); + expr::ptr lvalue; + expr::ptr rvalue; + op oper; + + expr_binary(location const& loc, expr::ptr lvalue, expr::ptr rvalue, op oper); + XSK_GSC_AST_MAKE(expr_binary) + auto precedence() -> u8; }; -struct expr_add : public expr_binary -{ - using ptr = std::unique_ptr; - - expr_add(location const& loc, expr lvalue, expr rvalue); -}; - -struct expr_sub : public expr_binary -{ - using ptr = std::unique_ptr; - - expr_sub(location const& loc, expr lvalue, expr rvalue); -}; - -struct expr_mul : public expr_binary -{ - using ptr = std::unique_ptr; - - expr_mul(location const& loc, expr lvalue, expr rvalue); -}; - -struct expr_div : public expr_binary -{ - using ptr = std::unique_ptr; - - expr_div(location const& loc, expr lvalue, expr rvalue); -}; - -struct expr_mod : public expr_binary -{ - using ptr = std::unique_ptr; - - expr_mod(location const& loc, expr lvalue, expr rvalue); -}; - -struct expr_shift_left : public expr_binary -{ - using ptr = std::unique_ptr; - - expr_shift_left(location const& loc, expr lvalue, expr rvalue); -}; - -struct expr_shift_right : public expr_binary -{ - using ptr = std::unique_ptr; - - expr_shift_right(location const& loc, expr lvalue, expr rvalue); -}; - -struct expr_bitwise_or : public expr_binary -{ - using ptr = std::unique_ptr; - - expr_bitwise_or(location const& loc, expr lvalue, expr rvalue); -}; - -struct expr_bitwise_and : public expr_binary -{ - using ptr = std::unique_ptr; - - expr_bitwise_and(location const& loc, expr lvalue, expr rvalue); -}; - -struct expr_bitwise_exor : public expr_binary -{ - using ptr = std::unique_ptr; - - expr_bitwise_exor(location const& loc, expr lvalue, expr rvalue); -}; - -struct expr_equality : public expr_binary -{ - using ptr = std::unique_ptr; - - expr_equality(location const& loc, expr lvalue, expr rvalue); -}; - -struct expr_inequality : public expr_binary -{ - using ptr = std::unique_ptr; - - expr_inequality(location const& loc, expr lvalue, expr rvalue); -}; - -struct expr_less_equal : public expr_binary -{ - using ptr = std::unique_ptr; - - expr_less_equal(location const& loc, expr lvalue, expr rvalue); -}; - -struct expr_greater_equal : public expr_binary -{ - using ptr = std::unique_ptr; - - expr_greater_equal(location const& loc, expr lvalue, expr rvalue); -}; - -struct expr_less : public expr_binary -{ - using ptr = std::unique_ptr; - - expr_less(location const& loc, expr lvalue, expr rvalue); -}; - -struct expr_greater : public expr_binary -{ - using ptr = std::unique_ptr; - - expr_greater(location const& loc, expr lvalue, expr rvalue); -}; - -struct expr_or : public expr_binary -{ - using ptr = std::unique_ptr; - - expr_or(location const& loc, expr lvalue, expr rvalue); -}; - -struct expr_and : public expr_binary -{ - using ptr = std::unique_ptr; - - expr_and(location const& loc, expr lvalue, expr rvalue); -}; - -struct expr_ternary : public node +struct expr_ternary : public expr { using ptr = std::unique_ptr; - expr test; - expr true_expr; - expr false_expr; + expr::ptr test; + expr::ptr true_expr; + expr::ptr false_expr; - expr_ternary(location const& loc, expr test, expr true_expr, expr false_expr); + expr_ternary(location const& loc, expr::ptr test, expr::ptr true_expr, expr::ptr false_expr); + XSK_GSC_AST_MAKE(expr_ternary) }; -struct expr_increment : node -{ - using ptr = std::unique_ptr; - - expr lvalue; - bool prefix; - - expr_increment(location const& loc, expr lvalue, bool prefix); -}; - -struct expr_decrement : node -{ - using ptr = std::unique_ptr; - - expr lvalue; - bool prefix; - - expr_decrement(location const& loc, expr lvalue, bool prefix); -}; - -struct expr_assign : public node +struct expr_assign : public expr { using ptr = std::unique_ptr; - expr lvalue; - expr rvalue; + enum class op { eq, add, sub, mul, div, mod, shl, shr, bwor, bwand, bwexor }; - expr_assign(type t, location const& loc, expr lvalue, expr rvalue); + expr::ptr lvalue; + expr::ptr rvalue; + op oper; + + expr_assign(location const& loc, expr::ptr lvalue, expr::ptr rvalue, op oper); + XSK_GSC_AST_MAKE(expr_assign) }; -struct expr_assign_equal : public expr_assign +struct expr_increment : expr { - using ptr = std::unique_ptr; + using ptr = std::unique_ptr; - expr_assign_equal(location const& loc, expr lvalue, expr rvalue); + expr::ptr lvalue; + bool prefix; + + expr_increment(location const& loc, expr::ptr lvalue, bool prefix); + XSK_GSC_AST_MAKE(expr_increment) }; -struct expr_assign_add : public expr_assign +struct expr_decrement : expr { - using ptr = std::unique_ptr; + using ptr = std::unique_ptr; - expr_assign_add(location const& loc, expr lvalue, expr rvalue); + expr::ptr lvalue; + bool prefix; + + expr_decrement(location const& loc, expr::ptr lvalue, bool prefix); + XSK_GSC_AST_MAKE(expr_decrement) }; -struct expr_assign_sub : public expr_assign +struct expr_var_create : public expr { - using ptr = std::unique_ptr; + using ptr = std::unique_ptr; - expr_assign_sub(location const& loc, expr lvalue, expr rvalue); + std::string index; + std::vector vars; + + expr_var_create(location const& loc, std::string const& index); + XSK_GSC_AST_MAKE(expr_var_create) }; -struct expr_assign_mul : public expr_assign +struct expr_var_access : public expr { - using ptr = std::unique_ptr; + using ptr = std::unique_ptr; - expr_assign_mul(location const& loc, expr lvalue, expr rvalue); + std::string index; + + expr_var_access(location const& loc, std::string const& index); + XSK_GSC_AST_MAKE(expr_var_access) }; -struct expr_assign_div : public expr_assign +struct stmt_empty : public stmt { - using ptr = std::unique_ptr; + using ptr = std::unique_ptr; - expr_assign_div(location const& loc, expr lvalue, expr rvalue); + stmt_empty(location const& loc); + XSK_GSC_AST_MAKE(stmt_empty) }; -struct expr_assign_mod : public expr_assign -{ - using ptr = std::unique_ptr; - - expr_assign_mod(location const& loc, expr lvalue, expr rvalue); -}; - -struct expr_assign_shift_left : public expr_assign -{ - using ptr = std::unique_ptr; - - expr_assign_shift_left(location const& loc, expr lvalue, expr rvalue); -}; - -struct expr_assign_shift_right : public expr_assign -{ - using ptr = std::unique_ptr; - - expr_assign_shift_right(location const& loc, expr lvalue, expr rvalue); -}; - -struct expr_assign_bitwise_or : public expr_assign -{ - using ptr = std::unique_ptr; - - expr_assign_bitwise_or(location const& loc, expr lvalue, expr rvalue); -}; - -struct expr_assign_bitwise_and : public expr_assign -{ - using ptr = std::unique_ptr; - - expr_assign_bitwise_and(location const& loc, expr lvalue, expr rvalue); -}; - -struct expr_assign_bitwise_exor : public expr_assign -{ - using ptr = std::unique_ptr; - - expr_assign_bitwise_exor(location const& loc, expr lvalue, expr rvalue); -}; - -struct stmt_list : public node +struct stmt_list : public stmt { using ptr = std::unique_ptr; - std::vector list; + std::vector list; stmt_list(location const& loc); + XSK_GSC_AST_MAKE(stmt_list) }; -struct stmt_comp : public node +struct stmt_comp : public stmt { using ptr = std::unique_ptr; stmt_list::ptr block; stmt_comp(location const& loc, stmt_list::ptr block); + XSK_GSC_AST_MAKE(stmt_comp) }; -struct stmt_dev : public node +struct stmt_dev : public stmt { using ptr = std::unique_ptr; stmt_list::ptr block; stmt_dev(location const& loc, stmt_list::ptr block); + XSK_GSC_AST_MAKE(stmt_dev) }; -struct stmt_expr : public node +struct stmt_expr : public stmt { using ptr = std::unique_ptr; - expr value; + expr::ptr value; - stmt_expr(location const& loc, expr value); + stmt_expr(location const& loc, expr::ptr value); + XSK_GSC_AST_MAKE(stmt_expr) }; -struct stmt_call : public node -{ - using ptr = std::unique_ptr; - - expr value; - - stmt_call(location const& loc, expr value); -}; - -struct stmt_assign : public node -{ - using ptr = std::unique_ptr; - - expr value; - - stmt_assign(location const& loc, expr value); -}; - -struct stmt_endon : public node +struct stmt_endon : public stmt { using ptr = std::unique_ptr; - expr obj; - expr event; + expr::ptr obj; + expr::ptr event; - stmt_endon(location const& loc, expr obj, expr event); + stmt_endon(location const& loc, expr::ptr obj, expr::ptr event); + XSK_GSC_AST_MAKE(stmt_endon) }; -struct stmt_notify : public node +struct stmt_notify : public stmt { using ptr = std::unique_ptr; - expr obj; - expr event; + expr::ptr obj; + expr::ptr event; expr_arguments::ptr args; - stmt_notify(location const& loc, expr obj, expr event, expr_arguments::ptr args); + stmt_notify(location const& loc, expr::ptr obj, expr::ptr event, expr_arguments::ptr args); + XSK_GSC_AST_MAKE(stmt_notify) }; -struct stmt_wait : public node +struct stmt_wait : public stmt { using ptr = std::unique_ptr; - expr time; + expr::ptr time; - stmt_wait(location const& loc, expr time); + stmt_wait(location const& loc, expr::ptr time); + XSK_GSC_AST_MAKE(stmt_wait) }; -struct stmt_waittill : public node +struct stmt_waittill : public stmt { using ptr = std::unique_ptr; - expr obj; - expr event; + expr::ptr obj; + expr::ptr event; expr_arguments::ptr args; - stmt_waittill(location const& loc, expr obj, expr event, expr_arguments::ptr args); + stmt_waittill(location const& loc, expr::ptr obj, expr::ptr event, expr_arguments::ptr args); + XSK_GSC_AST_MAKE(stmt_waittill) }; -struct stmt_waittillmatch : public node +struct stmt_waittillmatch : public stmt { using ptr = std::unique_ptr; - expr obj; - expr event; + expr::ptr obj; + expr::ptr event; expr_arguments::ptr args; - stmt_waittillmatch(location const& loc, expr obj, expr expr, expr_arguments::ptr args); + stmt_waittillmatch(location const& loc, expr::ptr obj, expr::ptr expr, expr_arguments::ptr args); + XSK_GSC_AST_MAKE(stmt_waittillmatch) }; -struct stmt_waittillframeend : public node +struct stmt_waittillframeend : public stmt { using ptr = std::unique_ptr; stmt_waittillframeend(location const& loc); + XSK_GSC_AST_MAKE(stmt_waittillframeend) }; -struct stmt_waitframe : public node +struct stmt_waitframe : public stmt { using ptr = std::unique_ptr; stmt_waitframe(location const& loc); + XSK_GSC_AST_MAKE(stmt_waitframe) }; -struct stmt_if : public node +struct stmt_if : public stmt { using ptr = std::unique_ptr; - expr test; - stmt body; + expr::ptr test; + stmt::ptr body; - stmt_if(location const& loc, expr test, stmt body); + stmt_if(location const& loc, expr::ptr test, stmt::ptr body); + XSK_GSC_AST_MAKE(stmt_if) }; -struct stmt_ifelse : public node +struct stmt_ifelse : public stmt { using ptr = std::unique_ptr; - expr test; - stmt stmt_if; - stmt stmt_else; + expr::ptr test; + stmt::ptr stmt_if; + stmt::ptr stmt_else; - stmt_ifelse(location const& loc, expr test, stmt stmt_if, stmt stmt_else); + stmt_ifelse(location const& loc, expr::ptr test, stmt::ptr stmt_if, stmt::ptr stmt_else); + XSK_GSC_AST_MAKE(stmt_ifelse) }; -struct stmt_while : public node +struct stmt_while : public stmt { using ptr = std::unique_ptr; - expr test; - stmt body; + expr::ptr test; + stmt::ptr body; - stmt_while(location const& loc, expr test, stmt body); + stmt_while(location const& loc, expr::ptr test, stmt::ptr body); + XSK_GSC_AST_MAKE(stmt_while) }; -struct stmt_dowhile : public node +struct stmt_dowhile : public stmt { using ptr = std::unique_ptr; - expr test; - stmt body; + expr::ptr test; + stmt::ptr body; - stmt_dowhile(location const& loc, expr test, stmt body); + stmt_dowhile(location const& loc, expr::ptr test, stmt::ptr body); + XSK_GSC_AST_MAKE(stmt_dowhile) }; -struct stmt_for : public node +struct stmt_for : public stmt { using ptr = std::unique_ptr; - stmt init; - expr test; - stmt iter; - stmt body; + stmt::ptr init; + expr::ptr test; + stmt::ptr iter; + stmt::ptr body; - stmt_for(location const& loc, stmt init, expr test, stmt iter, stmt body); + stmt_for(location const& loc, stmt::ptr init, expr::ptr test, stmt::ptr iter, stmt::ptr body); + XSK_GSC_AST_MAKE(stmt_for) }; -struct stmt_foreach : public node +struct stmt_foreach : public stmt { using ptr = std::unique_ptr; - expr container; - expr value; - expr index; - expr array; - expr key; - stmt body; + expr::ptr container; + expr::ptr value; + expr::ptr index; + expr::ptr array; + expr::ptr key; + stmt::ptr body; bool use_key; - stmt_foreach(location const& loc, expr container, expr value, expr index, expr array, expr key, stmt body, bool use_key); + stmt_foreach(location const& loc, expr::ptr container, expr::ptr value, expr::ptr index, expr::ptr array, expr::ptr key, stmt::ptr body, bool use_key); + XSK_GSC_AST_MAKE(stmt_foreach) }; -struct stmt_switch : public node +struct stmt_switch : public stmt { using ptr = std::unique_ptr; - expr test; + expr::ptr test; stmt_comp::ptr body; - stmt_switch(location const& loc, expr test, stmt_comp::ptr body); + stmt_switch(location const& loc, expr::ptr test, stmt_comp::ptr body); + XSK_GSC_AST_MAKE(stmt_switch) }; -struct stmt_case : public node +struct stmt_case : public stmt { using ptr = std::unique_ptr; - expr value; + expr::ptr value; stmt_list::ptr body; - stmt_case(location const& loc, expr value); - stmt_case(location const& loc, expr value, stmt_list::ptr body); + stmt_case(location const& loc, expr::ptr value); + stmt_case(location const& loc, expr::ptr value, stmt_list::ptr body); + XSK_GSC_AST_MAKE(stmt_case) }; -struct stmt_default : public node +struct stmt_default : public stmt { using ptr = std::unique_ptr; @@ -1285,84 +939,207 @@ struct stmt_default : public node stmt_default(location const& loc); stmt_default(location const& loc, stmt_list::ptr body); + XSK_GSC_AST_MAKE(stmt_default) }; -struct stmt_break : public node +struct stmt_break : public stmt { using ptr = std::unique_ptr; stmt_break(location const& loc); + XSK_GSC_AST_MAKE(stmt_break) }; -struct stmt_continue : public node +struct stmt_continue : public stmt { using ptr = std::unique_ptr; stmt_continue(location const& loc); + XSK_GSC_AST_MAKE(stmt_continue) }; -struct stmt_return : public node +struct stmt_return : public stmt { using ptr = std::unique_ptr; - expr value; + expr::ptr value; - stmt_return(location const& loc, expr value); + stmt_return(location const& loc, expr::ptr value); + XSK_GSC_AST_MAKE(stmt_return) }; -struct stmt_breakpoint : public node +struct stmt_breakpoint : public stmt { using ptr = std::unique_ptr; stmt_breakpoint(location const& loc); + XSK_GSC_AST_MAKE(stmt_breakpoint) }; -struct stmt_prof_begin : public node +struct stmt_prof_begin : public stmt { using ptr = std::unique_ptr; expr_arguments::ptr args; stmt_prof_begin(location const& loc, expr_arguments::ptr args); + XSK_GSC_AST_MAKE(stmt_prof_begin) }; -struct stmt_prof_end : public node +struct stmt_prof_end : public stmt { using ptr = std::unique_ptr; expr_arguments::ptr args; stmt_prof_end(location const& loc, expr_arguments::ptr args); + XSK_GSC_AST_MAKE(stmt_prof_end) }; -struct stmt_assert : public node +struct stmt_assert : public stmt { using ptr = std::unique_ptr; expr_arguments::ptr args; stmt_assert(location const& loc, expr_arguments::ptr args); + XSK_GSC_AST_MAKE(stmt_assert) }; -struct stmt_assertex : public node +struct stmt_assertex : public stmt { using ptr = std::unique_ptr; expr_arguments::ptr args; stmt_assertex(location const& loc, expr_arguments::ptr args); + XSK_GSC_AST_MAKE(stmt_assertex) }; -struct stmt_assertmsg : public node +struct stmt_assertmsg : public stmt { using ptr = std::unique_ptr; expr_arguments::ptr args; stmt_assertmsg(location const& loc, expr_arguments::ptr args); + XSK_GSC_AST_MAKE(stmt_assertmsg) }; -struct decl_function : public node +struct stmt_create : public stmt +{ + using ptr = std::unique_ptr; + + std::string index; + std::vector vars; + + stmt_create(location const& loc, std::string const& index); + XSK_GSC_AST_MAKE(stmt_create) +}; + +struct stmt_remove : public stmt +{ + using ptr = std::unique_ptr; + + std::string index; + + stmt_remove(location const& loc, std::string const& index); + XSK_GSC_AST_MAKE(stmt_remove) +}; + +struct stmt_clear : public stmt +{ + using ptr = std::unique_ptr; + + std::string index; + + stmt_clear(location const& loc, std::string const& index); + XSK_GSC_AST_MAKE(stmt_clear) +}; + +struct stmt_jmp : public stmt +{ + using ptr = std::unique_ptr; + + std::string value; + + stmt_jmp(location const& loc, std::string const& value); + XSK_GSC_AST_MAKE(stmt_jmp) +}; + +struct stmt_jmp_back : public stmt +{ + using ptr = std::unique_ptr; + + std::string value; + + stmt_jmp_back(location const& loc, std::string const& value); + XSK_GSC_AST_MAKE(stmt_jmp_back) +}; + +struct stmt_jmp_cond : public stmt +{ + using ptr = std::unique_ptr; + + expr::ptr test; + std::string value; + + stmt_jmp_cond(location const& loc, expr::ptr test, std::string const& value); + XSK_GSC_AST_MAKE(stmt_jmp_cond) +}; + +struct stmt_jmp_true : public stmt +{ + using ptr = std::unique_ptr; + + expr::ptr test; + std::string value; + + stmt_jmp_true(location const& loc, expr::ptr test, std::string const& value); + XSK_GSC_AST_MAKE(stmt_jmp_true) +}; + +struct stmt_jmp_false : public stmt +{ + using ptr = std::unique_ptr; + + expr::ptr test; + std::string value; + + stmt_jmp_false(location const& loc, expr::ptr test, std::string const& value); + XSK_GSC_AST_MAKE(stmt_jmp_false) +}; + +struct stmt_jmp_switch : public stmt +{ + using ptr = std::unique_ptr; + + expr::ptr test; + std::string value; + + stmt_jmp_switch(location const& loc, expr::ptr test, std::string const& value); + XSK_GSC_AST_MAKE(stmt_jmp_switch) +}; + +struct stmt_jmp_endswitch : public stmt +{ + using ptr = std::unique_ptr; + + std::vector data; + + stmt_jmp_endswitch(location const& loc, std::vector data); + XSK_GSC_AST_MAKE(stmt_jmp_endswitch) +}; + +struct decl_empty : public decl +{ + using ptr = std::unique_ptr; + + decl_empty(location const& loc); + XSK_GSC_AST_MAKE(decl_empty) +}; + +struct decl_function : public decl { using ptr = std::unique_ptr; @@ -1371,39 +1148,44 @@ struct decl_function : public node stmt_comp::ptr body; decl_function(location const& loc, expr_identifier::ptr name, expr_parameters::ptr params, stmt_comp::ptr body); + XSK_GSC_AST_MAKE(decl_function) }; -struct decl_constant : public node +struct decl_constant : public decl { using ptr = std::unique_ptr; expr_identifier::ptr name; - expr value; + expr::ptr value; - decl_constant(location const& loc, expr_identifier::ptr name, expr value); + decl_constant(location const& loc, expr_identifier::ptr name, expr::ptr value); + XSK_GSC_AST_MAKE(decl_constant) }; -struct decl_usingtree : public node +struct decl_usingtree : public decl { using ptr = std::unique_ptr; expr_string::ptr name; decl_usingtree(location const& loc, expr_string::ptr name); + XSK_GSC_AST_MAKE(decl_usingtree) }; -struct decl_dev_begin : public node +struct decl_dev_begin : public decl { using ptr = std::unique_ptr; decl_dev_begin(location const& loc); + XSK_GSC_AST_MAKE(decl_dev_begin) }; -struct decl_dev_end : public node +struct decl_dev_end : public decl { using ptr = std::unique_ptr; decl_dev_end(location const& loc); + XSK_GSC_AST_MAKE(decl_dev_end) }; struct include : public node @@ -1413,6 +1195,7 @@ struct include : public node expr_path::ptr path; include(location const& loc, expr_path::ptr path); + XSK_GSC_AST_MAKE(include) }; struct program : public node @@ -1420,258 +1203,13 @@ struct program : public node using ptr = std::unique_ptr; std::vector includes; - std::vector declarations; + std::vector declarations; program(); program(location const& loc); + XSK_GSC_AST_MAKE(program) }; -struct asm_jmp : public node -{ - using ptr = std::unique_ptr; +#undef XSK_GSC_AST_MAKE - std::string value; - - asm_jmp(location const& loc, std::string const& value); -}; - -struct asm_jmp_back : public node -{ - using ptr = std::unique_ptr; - - std::string value; - - asm_jmp_back(location const& loc, std::string const& value); -}; - -struct asm_jmp_cond : public node -{ - using ptr = std::unique_ptr; - - expr test; - std::string value; - - asm_jmp_cond(location const& loc, expr test, std::string const& value); -}; - -struct asm_jmp_true : public node -{ - using ptr = std::unique_ptr; - - expr test; - std::string value; - - asm_jmp_true(location const& loc, expr test, std::string const& value); -}; - -struct asm_jmp_false : public node -{ - using ptr = std::unique_ptr; - - expr test; - std::string value; - - asm_jmp_false(location const& loc, expr test, std::string const& value); -}; - -struct asm_switch : public node -{ - using ptr = std::unique_ptr; - - expr test; - std::string value; - - asm_switch(location const& loc, expr test, std::string const& value); -}; - -struct asm_endswitch : public node -{ - using ptr = std::unique_ptr; - - std::vector data; - - asm_endswitch(location const& loc, std::vector data); -}; - -struct asm_prescriptcall : public node -{ - using ptr = std::unique_ptr; - - asm_prescriptcall(location const& loc); -}; - -struct asm_voidcodepos : public node -{ - using ptr = std::unique_ptr; - - asm_voidcodepos(location const& loc); -}; - -struct asm_create : public node -{ - using ptr = std::unique_ptr; - - std::string index; - std::vector vars; - - asm_create(location const& loc, std::string const& index); -}; - -struct asm_access : public node -{ - using ptr = std::unique_ptr; - - std::string index; - - asm_access(location const& loc, std::string const& index); -}; - -struct asm_remove : public node -{ - using ptr = std::unique_ptr; - - std::string index; - - asm_remove(location const& loc, std::string const& index); -}; - -struct asm_clear : public node -{ - using ptr = std::unique_ptr; - - std::string index; - - asm_clear(location const& loc, std::string const& index); -}; - -#define XSK_GSC_MAKE_GENERIC(node_type) \ -template \ -inline auto make_ ## node_type(Args&&... args) -> std::unique_ptr \ -{ \ - return std::unique_ptr(new node_type(std::forward(args)...)); \ -} - -XSK_GSC_MAKE_GENERIC(node) -XSK_GSC_MAKE_GENERIC(expr_true) -XSK_GSC_MAKE_GENERIC(expr_false) -XSK_GSC_MAKE_GENERIC(expr_integer) -XSK_GSC_MAKE_GENERIC(expr_float) -XSK_GSC_MAKE_GENERIC(expr_vector) -XSK_GSC_MAKE_GENERIC(expr_string) -XSK_GSC_MAKE_GENERIC(expr_istring) -XSK_GSC_MAKE_GENERIC(expr_path) -XSK_GSC_MAKE_GENERIC(expr_identifier) -XSK_GSC_MAKE_GENERIC(expr_animtree) -XSK_GSC_MAKE_GENERIC(expr_animation) -XSK_GSC_MAKE_GENERIC(expr_level) -XSK_GSC_MAKE_GENERIC(expr_anim) -XSK_GSC_MAKE_GENERIC(expr_self) -XSK_GSC_MAKE_GENERIC(expr_game) -XSK_GSC_MAKE_GENERIC(expr_undefined) -XSK_GSC_MAKE_GENERIC(expr_empty_array) -XSK_GSC_MAKE_GENERIC(expr_thisthread) -XSK_GSC_MAKE_GENERIC(expr_paren) -XSK_GSC_MAKE_GENERIC(expr_size) -XSK_GSC_MAKE_GENERIC(expr_field) -XSK_GSC_MAKE_GENERIC(expr_array) -XSK_GSC_MAKE_GENERIC(expr_tuple) -XSK_GSC_MAKE_GENERIC(expr_reference) -XSK_GSC_MAKE_GENERIC(expr_istrue) -XSK_GSC_MAKE_GENERIC(expr_isdefined) -XSK_GSC_MAKE_GENERIC(expr_arguments) -XSK_GSC_MAKE_GENERIC(expr_parameters) -XSK_GSC_MAKE_GENERIC(expr_add_array) -XSK_GSC_MAKE_GENERIC(expr_pointer) -XSK_GSC_MAKE_GENERIC(expr_function) -XSK_GSC_MAKE_GENERIC(expr_method) -XSK_GSC_MAKE_GENERIC(expr_call) -XSK_GSC_MAKE_GENERIC(expr_complement) -XSK_GSC_MAKE_GENERIC(expr_negate) -XSK_GSC_MAKE_GENERIC(expr_not) -XSK_GSC_MAKE_GENERIC(expr_add) -XSK_GSC_MAKE_GENERIC(expr_sub) -XSK_GSC_MAKE_GENERIC(expr_mul) -XSK_GSC_MAKE_GENERIC(expr_div) -XSK_GSC_MAKE_GENERIC(expr_mod) -XSK_GSC_MAKE_GENERIC(expr_shift_left) -XSK_GSC_MAKE_GENERIC(expr_shift_right) -XSK_GSC_MAKE_GENERIC(expr_bitwise_or) -XSK_GSC_MAKE_GENERIC(expr_bitwise_and) -XSK_GSC_MAKE_GENERIC(expr_bitwise_exor) -XSK_GSC_MAKE_GENERIC(expr_equality) -XSK_GSC_MAKE_GENERIC(expr_inequality) -XSK_GSC_MAKE_GENERIC(expr_less_equal) -XSK_GSC_MAKE_GENERIC(expr_greater_equal) -XSK_GSC_MAKE_GENERIC(expr_less) -XSK_GSC_MAKE_GENERIC(expr_greater) -XSK_GSC_MAKE_GENERIC(expr_or) -XSK_GSC_MAKE_GENERIC(expr_and) -XSK_GSC_MAKE_GENERIC(expr_ternary) -XSK_GSC_MAKE_GENERIC(expr_increment) -XSK_GSC_MAKE_GENERIC(expr_decrement) -XSK_GSC_MAKE_GENERIC(expr_assign_equal) -XSK_GSC_MAKE_GENERIC(expr_assign_add) -XSK_GSC_MAKE_GENERIC(expr_assign_sub) -XSK_GSC_MAKE_GENERIC(expr_assign_mul) -XSK_GSC_MAKE_GENERIC(expr_assign_div) -XSK_GSC_MAKE_GENERIC(expr_assign_mod) -XSK_GSC_MAKE_GENERIC(expr_assign_shift_left) -XSK_GSC_MAKE_GENERIC(expr_assign_shift_right) -XSK_GSC_MAKE_GENERIC(expr_assign_bitwise_or) -XSK_GSC_MAKE_GENERIC(expr_assign_bitwise_and) -XSK_GSC_MAKE_GENERIC(expr_assign_bitwise_exor) -XSK_GSC_MAKE_GENERIC(stmt_list) -XSK_GSC_MAKE_GENERIC(stmt_comp) -XSK_GSC_MAKE_GENERIC(stmt_dev) -XSK_GSC_MAKE_GENERIC(stmt_expr) -XSK_GSC_MAKE_GENERIC(stmt_call) -XSK_GSC_MAKE_GENERIC(stmt_assign) -XSK_GSC_MAKE_GENERIC(stmt_endon) -XSK_GSC_MAKE_GENERIC(stmt_notify) -XSK_GSC_MAKE_GENERIC(stmt_wait) -XSK_GSC_MAKE_GENERIC(stmt_waittill) -XSK_GSC_MAKE_GENERIC(stmt_waittillmatch) -XSK_GSC_MAKE_GENERIC(stmt_waittillframeend) -XSK_GSC_MAKE_GENERIC(stmt_waitframe) -XSK_GSC_MAKE_GENERIC(stmt_if) -XSK_GSC_MAKE_GENERIC(stmt_ifelse) -XSK_GSC_MAKE_GENERIC(stmt_while) -XSK_GSC_MAKE_GENERIC(stmt_dowhile) -XSK_GSC_MAKE_GENERIC(stmt_for) -XSK_GSC_MAKE_GENERIC(stmt_foreach) -XSK_GSC_MAKE_GENERIC(stmt_switch) -XSK_GSC_MAKE_GENERIC(stmt_case) -XSK_GSC_MAKE_GENERIC(stmt_default) -XSK_GSC_MAKE_GENERIC(stmt_break) -XSK_GSC_MAKE_GENERIC(stmt_continue) -XSK_GSC_MAKE_GENERIC(stmt_return) -XSK_GSC_MAKE_GENERIC(stmt_breakpoint) -XSK_GSC_MAKE_GENERIC(stmt_prof_begin) -XSK_GSC_MAKE_GENERIC(stmt_prof_end) -XSK_GSC_MAKE_GENERIC(stmt_assert) -XSK_GSC_MAKE_GENERIC(stmt_assertex) -XSK_GSC_MAKE_GENERIC(stmt_assertmsg) -XSK_GSC_MAKE_GENERIC(decl_function) -XSK_GSC_MAKE_GENERIC(decl_constant) -XSK_GSC_MAKE_GENERIC(decl_usingtree) -XSK_GSC_MAKE_GENERIC(decl_dev_begin) -XSK_GSC_MAKE_GENERIC(decl_dev_end) -XSK_GSC_MAKE_GENERIC(include) -XSK_GSC_MAKE_GENERIC(program) -XSK_GSC_MAKE_GENERIC(asm_jmp) -XSK_GSC_MAKE_GENERIC(asm_jmp_back) -XSK_GSC_MAKE_GENERIC(asm_jmp_cond) -XSK_GSC_MAKE_GENERIC(asm_jmp_false) -XSK_GSC_MAKE_GENERIC(asm_jmp_true) -XSK_GSC_MAKE_GENERIC(asm_switch) -XSK_GSC_MAKE_GENERIC(asm_endswitch) -XSK_GSC_MAKE_GENERIC(asm_prescriptcall) -XSK_GSC_MAKE_GENERIC(asm_voidcodepos) -XSK_GSC_MAKE_GENERIC(asm_create) -XSK_GSC_MAKE_GENERIC(asm_access) -XSK_GSC_MAKE_GENERIC(asm_remove) -XSK_GSC_MAKE_GENERIC(asm_clear) - -#undef XSK_GSC_MAKE_GENERIC - -} // namespace xsk::gsc::ast +} // namespace xsk::gsc diff --git a/include/xsk/gsc/compiler.hpp b/include/xsk/gsc/compiler.hpp index fbbdda95..7f4ad252 100644 --- a/include/xsk/gsc/compiler.hpp +++ b/include/xsk/gsc/compiler.hpp @@ -45,8 +45,6 @@ private: auto emit_stmt_comp(stmt_comp const& stm, scope& scp, bool last) -> void; auto emit_stmt_dev(stmt_dev const& stm, scope& scp, bool last) -> void; auto emit_stmt_expr(stmt_expr const& stm, scope& scp) -> void; - auto emit_stmt_call(stmt_call const& stm, scope& scp) -> void; - auto emit_stmt_assign(stmt_assign const& stm, scope& scp) -> void; auto emit_stmt_endon(stmt_endon const& stm, scope& scp) -> void; auto emit_stmt_notify(stmt_notify const& stm, scope& scp) -> void; auto emit_stmt_wait(stmt_wait const& stm, scope& scp) -> void; @@ -80,8 +78,6 @@ private: auto emit_expr_decrement(expr_decrement const& exp, scope& scp, bool is_stmt) -> void; auto emit_expr_ternary(expr_ternary const& exp, scope& scp) -> void; auto emit_expr_binary(expr_binary const& exp, scope& scp) -> void; - auto emit_expr_and(expr_and const& exp, scope& scp) -> void; - auto emit_expr_or(expr_or const& exp, scope& scp) -> void; auto emit_expr_complement(expr_complement const& exp, scope& scp) -> void; auto emit_expr_negate(expr_negate const& exp, scope& scp) -> void; auto emit_expr_not(expr_not const& exp, scope& scp) -> void; @@ -128,7 +124,6 @@ private: auto process_stmt_comp(stmt_comp const& stm, scope& scp) -> void; auto process_stmt_dev(stmt_dev const& stm, scope& scp) -> void; auto process_stmt_expr(stmt_expr const& stm, scope& scp) -> void; - auto process_stmt_assign(stmt_assign const& stm, scope& scp) -> void; auto process_stmt_waittill(stmt_waittill const& stm, scope& scp) -> void; auto process_stmt_if(stmt_if const& stm, scope& scp) -> void; auto process_stmt_ifelse(stmt_ifelse const& stm, scope& scp) -> void; diff --git a/include/xsk/gsc/decompiler.hpp b/include/xsk/gsc/decompiler.hpp index d184daec..92afd976 100644 --- a/include/xsk/gsc/decompiler.hpp +++ b/include/xsk/gsc/decompiler.hpp @@ -55,8 +55,6 @@ private: auto process_stmt_comp(stmt_comp& stm, scope& scp) -> void; auto process_stmt_dev(stmt_dev& stm, scope& scp) -> void; auto process_stmt_expr(stmt_expr& stm, scope& scp) -> void; - auto process_stmt_call(stmt_call& stm, scope& scp) -> void; - auto process_stmt_assign(stmt_assign& stm, scope& scp) -> void; auto process_stmt_endon(stmt_endon& stm, scope& scp) -> void; auto process_stmt_notify(stmt_notify& stm, scope& scp) -> void; auto process_stmt_wait(stmt_wait& stm, scope& scp) -> void; @@ -72,24 +70,22 @@ private: auto process_stmt_break(stmt_break& stm, scope& scp) -> void; auto process_stmt_continue(stmt_continue& stm, scope& scp) -> void; auto process_stmt_return(stmt_return& stm, scope& scp) -> void; - auto process_stmt_asm_create(asm_create& stm, scope& scp) -> void; - auto process_stmt_asm_remove(asm_remove& stm, scope& scp) -> void; - auto process_expr(expr& exp, scope& scp) -> void; - auto process_expr_assign(expr_assign::ptr& exp, scope& scp) -> void; + auto process_stmt_create(stmt_create& stm, scope& scp) -> void; + auto process_stmt_remove(stmt_remove& stm, scope& scp) -> void; + auto process_expr(expr::ptr& exp, scope& scp) -> void; auto process_expr_increment(expr_increment& exp, scope& scp) -> void; auto process_expr_decrement(expr_decrement& exp, scope& scp) -> void; + auto process_expr_assign(expr_assign::ptr& exp, scope& scp) -> void; auto process_expr_ternary(expr_ternary& exp, scope& scp) -> void; auto process_expr_binary(expr_binary& exp, scope& scp) -> void; - auto process_expr_and(expr_and& exp, scope& scp) -> void; - auto process_expr_or(expr_or& exp, scope& scp) -> void; auto process_expr_complement(expr_complement& exp, scope& scp) -> void; auto process_expr_not(expr_not& exp, scope& scp) -> void; auto process_expr_call(expr_call& exp, scope& scp) -> void; auto process_expr_method(expr_method& exp, scope& scp) -> void; auto process_expr_call_pointer(expr_pointer& exp, scope& scp) -> void; auto process_expr_call_function(expr_function& exp, scope& scp) -> void; - auto process_expr_method_pointer(expr_pointer& exp, expr& obj, scope& scp) -> void; - auto process_expr_method_function(expr_function& exp, expr& obj, scope& scp) -> void; + auto process_expr_method_pointer(expr_pointer& exp, expr::ptr& obj, scope& scp) -> void; + auto process_expr_method_function(expr_function& exp, expr::ptr& obj, scope& scp) -> void; auto process_expr_arguments(expr_arguments& exp, scope& scp) -> void; auto process_expr_add_array(expr_add_array& exp, scope& scp) -> void; auto process_expr_size(expr_size& exp, scope& scp) -> void; @@ -97,8 +93,8 @@ private: auto process_expr_array(expr_array& exp, scope& scp) -> void; auto process_expr_field(expr_field& exp, scope& scp) -> void; auto process_expr_vector(expr_vector& exp, scope& scp) -> void; - auto process_expr_asm_create(expr& exp, scope& scp) -> void; - auto process_expr_asm_access(expr& exp, scope& scp) -> void; + auto process_expr_var_create(expr::ptr& exp, scope& scp) -> void; + auto process_expr_var_access(expr::ptr& exp, scope& scp) -> void; }; } // namespace xsk::gsc diff --git a/include/xsk/gsc/parser.hpp b/include/xsk/gsc/parser.hpp index f9058036..e126ff51 100644 --- a/include/xsk/gsc/parser.hpp +++ b/include/xsk/gsc/parser.hpp @@ -424,10 +424,10 @@ namespace xsk { namespace gsc { { // expr_function // expr_pointer - char dummy1[sizeof (call)]; + char dummy1[sizeof (call::ptr)]; // declaration - char dummy2[sizeof (decl)]; + char dummy2[sizeof (decl::ptr)]; // decl_constant char dummy3[sizeof (decl_constant::ptr)]; @@ -440,16 +440,16 @@ namespace xsk { namespace gsc { // expr // expr_or_empty - // expr_assign // expr_increment // expr_decrement + // expr_assign // expr_ternary // expr_binary // expr_primitive // expr_tuple // expr_tuple_types // expr_object - char dummy6[sizeof (expr)]; + char dummy6[sizeof (expr::ptr)]; // expr_add_array char dummy7[sizeof (expr_add_array::ptr)]; @@ -571,7 +571,7 @@ namespace xsk { namespace gsc { // stmt // stmt_or_dev - char dummy44[sizeof (stmt)]; + char dummy44[sizeof (stmt::ptr)]; // stmt_assert char dummy45[sizeof (stmt_assert::ptr)]; @@ -582,90 +582,86 @@ namespace xsk { namespace gsc { // stmt_assertmsg char dummy47[sizeof (stmt_assertmsg::ptr)]; - // stmt_assign - char dummy48[sizeof (stmt_assign::ptr)]; - // stmt_break - char dummy49[sizeof (stmt_break::ptr)]; + char dummy48[sizeof (stmt_break::ptr)]; // stmt_breakpoint - char dummy50[sizeof (stmt_breakpoint::ptr)]; - - // stmt_call - char dummy51[sizeof (stmt_call::ptr)]; + char dummy49[sizeof (stmt_breakpoint::ptr)]; // stmt_case - char dummy52[sizeof (stmt_case::ptr)]; + char dummy50[sizeof (stmt_case::ptr)]; // stmt_comp - char dummy53[sizeof (stmt_comp::ptr)]; + char dummy51[sizeof (stmt_comp::ptr)]; // stmt_continue - char dummy54[sizeof (stmt_continue::ptr)]; + char dummy52[sizeof (stmt_continue::ptr)]; // stmt_default - char dummy55[sizeof (stmt_default::ptr)]; + char dummy53[sizeof (stmt_default::ptr)]; // stmt_dev - char dummy56[sizeof (stmt_dev::ptr)]; + char dummy54[sizeof (stmt_dev::ptr)]; // stmt_dowhile - char dummy57[sizeof (stmt_dowhile::ptr)]; + char dummy55[sizeof (stmt_dowhile::ptr)]; // stmt_endon - char dummy58[sizeof (stmt_endon::ptr)]; + char dummy56[sizeof (stmt_endon::ptr)]; // stmt_expr - char dummy59[sizeof (stmt_expr::ptr)]; + // stmt_call + // stmt_assign + char dummy57[sizeof (stmt_expr::ptr)]; // stmt_for - char dummy60[sizeof (stmt_for::ptr)]; + char dummy58[sizeof (stmt_for::ptr)]; // stmt_foreach - char dummy61[sizeof (stmt_foreach::ptr)]; + char dummy59[sizeof (stmt_foreach::ptr)]; // stmt_if - char dummy62[sizeof (stmt_if::ptr)]; + char dummy60[sizeof (stmt_if::ptr)]; // stmt_ifelse - char dummy63[sizeof (stmt_ifelse::ptr)]; + char dummy61[sizeof (stmt_ifelse::ptr)]; // stmt_list // stmt_or_dev_list - char dummy64[sizeof (stmt_list::ptr)]; + char dummy62[sizeof (stmt_list::ptr)]; // stmt_notify - char dummy65[sizeof (stmt_notify::ptr)]; + char dummy63[sizeof (stmt_notify::ptr)]; // stmt_prof_begin - char dummy66[sizeof (stmt_prof_begin::ptr)]; + char dummy64[sizeof (stmt_prof_begin::ptr)]; // stmt_prof_end - char dummy67[sizeof (stmt_prof_end::ptr)]; + char dummy65[sizeof (stmt_prof_end::ptr)]; // stmt_return - char dummy68[sizeof (stmt_return::ptr)]; + char dummy66[sizeof (stmt_return::ptr)]; // stmt_switch - char dummy69[sizeof (stmt_switch::ptr)]; + char dummy67[sizeof (stmt_switch::ptr)]; // stmt_wait - char dummy70[sizeof (stmt_wait::ptr)]; + char dummy68[sizeof (stmt_wait::ptr)]; // stmt_waitframe - char dummy71[sizeof (stmt_waitframe::ptr)]; + char dummy69[sizeof (stmt_waitframe::ptr)]; // stmt_waittill - char dummy72[sizeof (stmt_waittill::ptr)]; + char dummy70[sizeof (stmt_waittill::ptr)]; // stmt_waittillframeend - char dummy73[sizeof (stmt_waittillframeend::ptr)]; + char dummy71[sizeof (stmt_waittillframeend::ptr)]; // stmt_waittillmatch - char dummy74[sizeof (stmt_waittillmatch::ptr)]; + char dummy72[sizeof (stmt_waittillmatch::ptr)]; // stmt_while - char dummy75[sizeof (stmt_while::ptr)]; + char dummy73[sizeof (stmt_while::ptr)]; }; /// The size of the largest semantic type. @@ -1004,9 +1000,9 @@ namespace xsk { namespace gsc { S_stmt_assertmsg = 155, // stmt_assertmsg S_expr = 156, // expr S_expr_or_empty = 157, // expr_or_empty - S_expr_assign = 158, // expr_assign - S_expr_increment = 159, // expr_increment - S_expr_decrement = 160, // expr_decrement + S_expr_increment = 158, // expr_increment + S_expr_decrement = 159, // expr_decrement + S_expr_assign = 160, // expr_assign S_expr_ternary = 161, // expr_ternary S_expr_binary = 162, // expr_binary S_expr_primitive = 163, // expr_primitive @@ -1089,11 +1085,11 @@ namespace xsk { namespace gsc { { case symbol_kind::S_expr_function: // expr_function case symbol_kind::S_expr_pointer: // expr_pointer - value.move< call > (std::move (that.value)); + value.move< call::ptr > (std::move (that.value)); break; case symbol_kind::S_declaration: // declaration - value.move< decl > (std::move (that.value)); + value.move< decl::ptr > (std::move (that.value)); break; case symbol_kind::S_decl_constant: // decl_constant @@ -1110,16 +1106,16 @@ namespace xsk { namespace gsc { case symbol_kind::S_expr: // expr case symbol_kind::S_expr_or_empty: // expr_or_empty - case symbol_kind::S_expr_assign: // expr_assign case symbol_kind::S_expr_increment: // expr_increment case symbol_kind::S_expr_decrement: // expr_decrement + case symbol_kind::S_expr_assign: // expr_assign case symbol_kind::S_expr_ternary: // expr_ternary case symbol_kind::S_expr_binary: // expr_binary case symbol_kind::S_expr_primitive: // expr_primitive case symbol_kind::S_expr_tuple: // expr_tuple case symbol_kind::S_expr_tuple_types: // expr_tuple_types case symbol_kind::S_expr_object: // expr_object - value.move< expr > (std::move (that.value)); + value.move< expr::ptr > (std::move (that.value)); break; case symbol_kind::S_expr_add_array: // expr_add_array @@ -1279,7 +1275,7 @@ namespace xsk { namespace gsc { case symbol_kind::S_stmt: // stmt case symbol_kind::S_stmt_or_dev: // stmt_or_dev - value.move< stmt > (std::move (that.value)); + value.move< stmt::ptr > (std::move (that.value)); break; case symbol_kind::S_stmt_assert: // stmt_assert @@ -1294,10 +1290,6 @@ namespace xsk { namespace gsc { value.move< stmt_assertmsg::ptr > (std::move (that.value)); break; - case symbol_kind::S_stmt_assign: // stmt_assign - value.move< stmt_assign::ptr > (std::move (that.value)); - break; - case symbol_kind::S_stmt_break: // stmt_break value.move< stmt_break::ptr > (std::move (that.value)); break; @@ -1306,10 +1298,6 @@ namespace xsk { namespace gsc { value.move< stmt_breakpoint::ptr > (std::move (that.value)); break; - case symbol_kind::S_stmt_call: // stmt_call - value.move< stmt_call::ptr > (std::move (that.value)); - break; - case symbol_kind::S_stmt_case: // stmt_case value.move< stmt_case::ptr > (std::move (that.value)); break; @@ -1339,6 +1327,8 @@ namespace xsk { namespace gsc { break; case symbol_kind::S_stmt_expr: // stmt_expr + case symbol_kind::S_stmt_call: // stmt_call + case symbol_kind::S_stmt_assign: // stmt_assign value.move< stmt_expr::ptr > (std::move (that.value)); break; @@ -1431,13 +1421,13 @@ namespace xsk { namespace gsc { #endif #if 201103L <= YY_CPLUSPLUS - basic_symbol (typename Base::kind_type t, call&& v, location_type&& l) + basic_symbol (typename Base::kind_type t, call::ptr&& v, location_type&& l) : Base (t) , value (std::move (v)) , location (std::move (l)) {} #else - basic_symbol (typename Base::kind_type t, const call& v, const location_type& l) + basic_symbol (typename Base::kind_type t, const call::ptr& v, const location_type& l) : Base (t) , value (v) , location (l) @@ -1445,13 +1435,13 @@ namespace xsk { namespace gsc { #endif #if 201103L <= YY_CPLUSPLUS - basic_symbol (typename Base::kind_type t, decl&& v, location_type&& l) + basic_symbol (typename Base::kind_type t, decl::ptr&& v, location_type&& l) : Base (t) , value (std::move (v)) , location (std::move (l)) {} #else - basic_symbol (typename Base::kind_type t, const decl& v, const location_type& l) + basic_symbol (typename Base::kind_type t, const decl::ptr& v, const location_type& l) : Base (t) , value (v) , location (l) @@ -1501,13 +1491,13 @@ namespace xsk { namespace gsc { #endif #if 201103L <= YY_CPLUSPLUS - basic_symbol (typename Base::kind_type t, expr&& v, location_type&& l) + basic_symbol (typename Base::kind_type t, expr::ptr&& v, location_type&& l) : Base (t) , value (std::move (v)) , location (std::move (l)) {} #else - basic_symbol (typename Base::kind_type t, const expr& v, const location_type& l) + basic_symbol (typename Base::kind_type t, const expr::ptr& v, const location_type& l) : Base (t) , value (v) , location (l) @@ -2033,13 +2023,13 @@ namespace xsk { namespace gsc { #endif #if 201103L <= YY_CPLUSPLUS - basic_symbol (typename Base::kind_type t, stmt&& v, location_type&& l) + basic_symbol (typename Base::kind_type t, stmt::ptr&& v, location_type&& l) : Base (t) , value (std::move (v)) , location (std::move (l)) {} #else - basic_symbol (typename Base::kind_type t, const stmt& v, const location_type& l) + basic_symbol (typename Base::kind_type t, const stmt::ptr& v, const location_type& l) : Base (t) , value (v) , location (l) @@ -2088,20 +2078,6 @@ namespace xsk { namespace gsc { {} #endif -#if 201103L <= YY_CPLUSPLUS - basic_symbol (typename Base::kind_type t, stmt_assign::ptr&& v, location_type&& l) - : Base (t) - , value (std::move (v)) - , location (std::move (l)) - {} -#else - basic_symbol (typename Base::kind_type t, const stmt_assign::ptr& v, const location_type& l) - : Base (t) - , value (v) - , location (l) - {} -#endif - #if 201103L <= YY_CPLUSPLUS basic_symbol (typename Base::kind_type t, stmt_break::ptr&& v, location_type&& l) : Base (t) @@ -2130,20 +2106,6 @@ namespace xsk { namespace gsc { {} #endif -#if 201103L <= YY_CPLUSPLUS - basic_symbol (typename Base::kind_type t, stmt_call::ptr&& v, location_type&& l) - : Base (t) - , value (std::move (v)) - , location (std::move (l)) - {} -#else - basic_symbol (typename Base::kind_type t, const stmt_call::ptr& v, const location_type& l) - : Base (t) - , value (v) - , location (l) - {} -#endif - #if 201103L <= YY_CPLUSPLUS basic_symbol (typename Base::kind_type t, stmt_case::ptr&& v, location_type&& l) : Base (t) @@ -2506,11 +2468,11 @@ switch (yykind) { case symbol_kind::S_expr_function: // expr_function case symbol_kind::S_expr_pointer: // expr_pointer - value.template destroy< call > (); + value.template destroy< call::ptr > (); break; case symbol_kind::S_declaration: // declaration - value.template destroy< decl > (); + value.template destroy< decl::ptr > (); break; case symbol_kind::S_decl_constant: // decl_constant @@ -2527,16 +2489,16 @@ switch (yykind) case symbol_kind::S_expr: // expr case symbol_kind::S_expr_or_empty: // expr_or_empty - case symbol_kind::S_expr_assign: // expr_assign case symbol_kind::S_expr_increment: // expr_increment case symbol_kind::S_expr_decrement: // expr_decrement + case symbol_kind::S_expr_assign: // expr_assign case symbol_kind::S_expr_ternary: // expr_ternary case symbol_kind::S_expr_binary: // expr_binary case symbol_kind::S_expr_primitive: // expr_primitive case symbol_kind::S_expr_tuple: // expr_tuple case symbol_kind::S_expr_tuple_types: // expr_tuple_types case symbol_kind::S_expr_object: // expr_object - value.template destroy< expr > (); + value.template destroy< expr::ptr > (); break; case symbol_kind::S_expr_add_array: // expr_add_array @@ -2696,7 +2658,7 @@ switch (yykind) case symbol_kind::S_stmt: // stmt case symbol_kind::S_stmt_or_dev: // stmt_or_dev - value.template destroy< stmt > (); + value.template destroy< stmt::ptr > (); break; case symbol_kind::S_stmt_assert: // stmt_assert @@ -2711,10 +2673,6 @@ switch (yykind) value.template destroy< stmt_assertmsg::ptr > (); break; - case symbol_kind::S_stmt_assign: // stmt_assign - value.template destroy< stmt_assign::ptr > (); - break; - case symbol_kind::S_stmt_break: // stmt_break value.template destroy< stmt_break::ptr > (); break; @@ -2723,10 +2681,6 @@ switch (yykind) value.template destroy< stmt_breakpoint::ptr > (); break; - case symbol_kind::S_stmt_call: // stmt_call - value.template destroy< stmt_call::ptr > (); - break; - case symbol_kind::S_stmt_case: // stmt_case value.template destroy< stmt_case::ptr > (); break; @@ -2756,6 +2710,8 @@ switch (yykind) break; case symbol_kind::S_stmt_expr: // stmt_expr + case symbol_kind::S_stmt_call: // stmt_call + case symbol_kind::S_stmt_assign: // stmt_assign value.template destroy< stmt_expr::ptr > (); break; @@ -5057,11 +5013,11 @@ switch (yykind) { case symbol_kind::S_expr_function: // expr_function case symbol_kind::S_expr_pointer: // expr_pointer - value.copy< call > (YY_MOVE (that.value)); + value.copy< call::ptr > (YY_MOVE (that.value)); break; case symbol_kind::S_declaration: // declaration - value.copy< decl > (YY_MOVE (that.value)); + value.copy< decl::ptr > (YY_MOVE (that.value)); break; case symbol_kind::S_decl_constant: // decl_constant @@ -5078,16 +5034,16 @@ switch (yykind) case symbol_kind::S_expr: // expr case symbol_kind::S_expr_or_empty: // expr_or_empty - case symbol_kind::S_expr_assign: // expr_assign case symbol_kind::S_expr_increment: // expr_increment case symbol_kind::S_expr_decrement: // expr_decrement + case symbol_kind::S_expr_assign: // expr_assign case symbol_kind::S_expr_ternary: // expr_ternary case symbol_kind::S_expr_binary: // expr_binary case symbol_kind::S_expr_primitive: // expr_primitive case symbol_kind::S_expr_tuple: // expr_tuple case symbol_kind::S_expr_tuple_types: // expr_tuple_types case symbol_kind::S_expr_object: // expr_object - value.copy< expr > (YY_MOVE (that.value)); + value.copy< expr::ptr > (YY_MOVE (that.value)); break; case symbol_kind::S_expr_add_array: // expr_add_array @@ -5247,7 +5203,7 @@ switch (yykind) case symbol_kind::S_stmt: // stmt case symbol_kind::S_stmt_or_dev: // stmt_or_dev - value.copy< stmt > (YY_MOVE (that.value)); + value.copy< stmt::ptr > (YY_MOVE (that.value)); break; case symbol_kind::S_stmt_assert: // stmt_assert @@ -5262,10 +5218,6 @@ switch (yykind) value.copy< stmt_assertmsg::ptr > (YY_MOVE (that.value)); break; - case symbol_kind::S_stmt_assign: // stmt_assign - value.copy< stmt_assign::ptr > (YY_MOVE (that.value)); - break; - case symbol_kind::S_stmt_break: // stmt_break value.copy< stmt_break::ptr > (YY_MOVE (that.value)); break; @@ -5274,10 +5226,6 @@ switch (yykind) value.copy< stmt_breakpoint::ptr > (YY_MOVE (that.value)); break; - case symbol_kind::S_stmt_call: // stmt_call - value.copy< stmt_call::ptr > (YY_MOVE (that.value)); - break; - case symbol_kind::S_stmt_case: // stmt_case value.copy< stmt_case::ptr > (YY_MOVE (that.value)); break; @@ -5307,6 +5255,8 @@ switch (yykind) break; case symbol_kind::S_stmt_expr: // stmt_expr + case symbol_kind::S_stmt_call: // stmt_call + case symbol_kind::S_stmt_assign: // stmt_assign value.copy< stmt_expr::ptr > (YY_MOVE (that.value)); break; @@ -5408,11 +5358,11 @@ switch (yykind) { case symbol_kind::S_expr_function: // expr_function case symbol_kind::S_expr_pointer: // expr_pointer - value.move< call > (YY_MOVE (s.value)); + value.move< call::ptr > (YY_MOVE (s.value)); break; case symbol_kind::S_declaration: // declaration - value.move< decl > (YY_MOVE (s.value)); + value.move< decl::ptr > (YY_MOVE (s.value)); break; case symbol_kind::S_decl_constant: // decl_constant @@ -5429,16 +5379,16 @@ switch (yykind) case symbol_kind::S_expr: // expr case symbol_kind::S_expr_or_empty: // expr_or_empty - case symbol_kind::S_expr_assign: // expr_assign case symbol_kind::S_expr_increment: // expr_increment case symbol_kind::S_expr_decrement: // expr_decrement + case symbol_kind::S_expr_assign: // expr_assign case symbol_kind::S_expr_ternary: // expr_ternary case symbol_kind::S_expr_binary: // expr_binary case symbol_kind::S_expr_primitive: // expr_primitive case symbol_kind::S_expr_tuple: // expr_tuple case symbol_kind::S_expr_tuple_types: // expr_tuple_types case symbol_kind::S_expr_object: // expr_object - value.move< expr > (YY_MOVE (s.value)); + value.move< expr::ptr > (YY_MOVE (s.value)); break; case symbol_kind::S_expr_add_array: // expr_add_array @@ -5598,7 +5548,7 @@ switch (yykind) case symbol_kind::S_stmt: // stmt case symbol_kind::S_stmt_or_dev: // stmt_or_dev - value.move< stmt > (YY_MOVE (s.value)); + value.move< stmt::ptr > (YY_MOVE (s.value)); break; case symbol_kind::S_stmt_assert: // stmt_assert @@ -5613,10 +5563,6 @@ switch (yykind) value.move< stmt_assertmsg::ptr > (YY_MOVE (s.value)); break; - case symbol_kind::S_stmt_assign: // stmt_assign - value.move< stmt_assign::ptr > (YY_MOVE (s.value)); - break; - case symbol_kind::S_stmt_break: // stmt_break value.move< stmt_break::ptr > (YY_MOVE (s.value)); break; @@ -5625,10 +5571,6 @@ switch (yykind) value.move< stmt_breakpoint::ptr > (YY_MOVE (s.value)); break; - case symbol_kind::S_stmt_call: // stmt_call - value.move< stmt_call::ptr > (YY_MOVE (s.value)); - break; - case symbol_kind::S_stmt_case: // stmt_case value.move< stmt_case::ptr > (YY_MOVE (s.value)); break; @@ -5658,6 +5600,8 @@ switch (yykind) break; case symbol_kind::S_stmt_expr: // stmt_expr + case symbol_kind::S_stmt_call: // stmt_call + case symbol_kind::S_stmt_assign: // stmt_assign value.move< stmt_expr::ptr > (YY_MOVE (s.value)); break; @@ -5793,7 +5737,7 @@ switch (yykind) #line 13 "parser.ypp" } } // xsk::gsc -#line 5797 "parser.hpp" +#line 5741 "parser.hpp" diff --git a/include/xsk/gsc/source.hpp b/include/xsk/gsc/source.hpp index a1060320..c749ffe4 100644 --- a/include/xsk/gsc/source.hpp +++ b/include/xsk/gsc/source.hpp @@ -39,13 +39,13 @@ private: auto dump_decl_usingtree(decl_usingtree const& dec) -> void; auto dump_decl_constant(decl_constant const& dec) -> void; auto dump_decl_function(decl_function const& dec) -> void; + auto dump_decl_empty(decl_empty const& dec) -> void; auto dump_stmt(stmt const& stm) -> void; + auto dump_stmt_empty(stmt_empty const& stm) -> void; auto dump_stmt_list(stmt_list const& stm) -> void; auto dump_stmt_comp(stmt_comp const& stm) -> void; auto dump_stmt_dev(stmt_dev const& stm) -> void; auto dump_stmt_expr(stmt_expr const& stm) -> void; - auto dump_stmt_call(stmt_call const& stm) -> void; - auto dump_stmt_assign(stmt_assign const& stm) -> void; auto dump_stmt_endon(stmt_endon const& stm) -> void; auto dump_stmt_notify(stmt_notify const& stm) -> void; auto dump_stmt_wait(stmt_wait const& stm) -> void; @@ -71,39 +71,22 @@ private: auto dump_stmt_assert(stmt_assert const& stm) -> void; auto dump_stmt_assertex(stmt_assertex const& stm) -> void; auto dump_stmt_assertmsg(stmt_assertmsg const& stm) -> void; + auto dump_stmt_create(stmt_create const& stm) -> void; + auto dump_stmt_remove(stmt_remove const& stm) -> void; + auto dump_stmt_clear(stmt_clear const& stm) -> void; + auto dump_stmt_jmp(stmt_jmp const& stm) -> void; + auto dump_stmt_jmp_back(stmt_jmp_back const& stm) -> void; + auto dump_stmt_jmp_cond(stmt_jmp_cond const& stm) -> void; + auto dump_stmt_jmp_true(stmt_jmp_true const& stm) -> void; + auto dump_stmt_jmp_false(stmt_jmp_false const& stm) -> void; + auto dump_stmt_jmp_switch(stmt_jmp_switch const& stm) -> void; + auto dump_stmt_jmp_endswitch(stmt_jmp_endswitch const& stm) -> void; auto dump_expr(expr const& exp) -> void; auto dump_expr_increment(expr_increment const& exp) -> void; auto dump_expr_decrement(expr_decrement const& exp) -> void; - auto dump_expr_assign_equal(expr_assign_equal const& exp) -> void; - auto dump_expr_assign_add(expr_assign_add const& exp) -> void; - auto dump_expr_assign_sub(expr_assign_sub const& exp) -> void; - auto dump_expr_assign_mul(expr_assign_mul const& exp) -> void; - auto dump_expr_assign_div(expr_assign_div const& exp) -> void; - auto dump_expr_assign_mod(expr_assign_mod const& exp) -> void; - auto dump_expr_assign_shift_left(expr_assign_shift_left const& exp) -> void; - auto dump_expr_assign_shift_right(expr_assign_shift_right const& exp) -> void; - auto dump_expr_assign_bitwise_or(expr_assign_bitwise_or const& exp) -> void; - auto dump_expr_assign_bitwise_and(expr_assign_bitwise_and const& exp) -> void; - auto dump_expr_assign_bitwise_exor(expr_assign_bitwise_exor const& exp) -> void; + auto dump_expr_assign(expr_assign const& exp) -> void; auto dump_expr_ternary(expr_ternary const& exp) -> void; - auto dump_expr_or(expr_or const& exp) -> void; - auto dump_expr_and(expr_and const& exp) -> void; - auto dump_expr_equality(expr_equality const& exp) -> void; - auto dump_expr_inequality(expr_inequality const& exp) -> void; - auto dump_expr_less_equal(expr_less_equal const& exp) -> void; - auto dump_expr_greater_equal(expr_greater_equal const& exp) -> void; - auto dump_expr_less(expr_less const& exp) -> void; - auto dump_expr_greater(expr_greater const& exp) -> void; - auto dump_expr_add(expr_add const& exp) -> void; - auto dump_expr_sub(expr_sub const& exp) -> void; - auto dump_expr_mul(expr_mul const& exp) -> void; - auto dump_expr_div(expr_div const& exp) -> void; - auto dump_expr_mod(expr_mod const& exp) -> void; - auto dump_expr_shift_left(expr_shift_left const& exp) -> void; - auto dump_expr_shift_right(expr_shift_right const& exp) -> void; - auto dump_expr_bitwise_or(expr_bitwise_or const& exp) -> void; - auto dump_expr_bitwise_and(expr_bitwise_and const& exp) -> void; - auto dump_expr_bitwise_exor(expr_bitwise_exor const& exp) -> void; + auto dump_expr_binary(expr_binary const& exp) -> void; auto dump_expr_not(expr_not const& exp) -> void; auto dump_expr_negate(expr_negate const& exp) -> void; auto dump_expr_complement(expr_complement const& exp) -> void; @@ -141,19 +124,8 @@ private: auto dump_expr_integer(expr_integer const& exp) -> void; auto dump_expr_false(expr_false const& exp) -> void; auto dump_expr_true(expr_true const& exp) -> void; - auto dump_asm_jmp(asm_jmp const& exp) -> void; - auto dump_asm_jmp_back(asm_jmp_back const& exp) -> void; - auto dump_asm_jmp_cond(asm_jmp_cond const& exp) -> void; - auto dump_asm_jmp_true(asm_jmp_true const& exp) -> void; - auto dump_asm_jmp_false(asm_jmp_false const& exp) -> void; - auto dump_asm_switch(asm_switch const& exp) -> void; - auto dump_asm_endswitch(asm_endswitch const& exp) -> void; - auto dump_asm_prescriptcall(asm_prescriptcall const& exp) -> void; - auto dump_asm_voidcodepos(asm_voidcodepos const& exp) -> void; - auto dump_asm_create(asm_create const& exp) -> void; - auto dump_asm_access(asm_access const& exp) -> void; - auto dump_asm_remove(asm_remove const& exp) -> void; - auto dump_asm_clear(asm_clear const& exp) -> void; + auto dump_expr_var_create(expr_var_create const& exp) -> void; + auto dump_expr_var_access(expr_var_access const& exp) -> void; }; } // namespace xsk::gsc diff --git a/src/gsc/common/ast.cpp b/src/gsc/common/ast.cpp index 9ca93fe0..a9a417a1 100644 --- a/src/gsc/common/ast.cpp +++ b/src/gsc/common/ast.cpp @@ -72,28 +72,13 @@ auto node::is_special_stmt_dev_noif() -> bool } } -auto node::is_binary() -> bool +auto node::is_assign() -> bool { switch (kind_) { - case type::expr_or: - case type::expr_and: - case type::expr_bitwise_or: - case type::expr_bitwise_exor: - case type::expr_bitwise_and: - case type::expr_equality: - case type::expr_inequality: - case type::expr_less: - case type::expr_greater: - case type::expr_less_equal: - case type::expr_greater_equal: - case type::expr_shift_left: - case type::expr_shift_right: - case type::expr_add: - case type::expr_sub: - case type::expr_mul: - case type::expr_div: - case type::expr_mod: + case type::expr_assign: + case type::expr_increment: + case type::expr_decrement: return true; default: return false; @@ -102,463 +87,686 @@ auto node::is_binary() -> bool auto node::precedence() -> u8 { - switch (kind_) + return 0; +} + +auto expr_binary::precedence() -> u8 +{ + switch (oper) { - case type::expr_or: return 1; - case type::expr_and: return 2; - case type::expr_bitwise_or: return 3; - case type::expr_bitwise_exor: return 4; - case type::expr_bitwise_and: return 5; - case type::expr_equality: return 6; - case type::expr_inequality: return 6; - case type::expr_less: return 7; - case type::expr_greater: return 7; - case type::expr_less_equal: return 7; - case type::expr_greater_equal:return 7; - case type::expr_shift_left: return 8; - case type::expr_shift_right: return 8; - case type::expr_add: return 9; - case type::expr_sub: return 9; - case type::expr_mul: return 10; - case type::expr_div: return 10; - case type::expr_mod: return 10; + case op::bool_or: return 1; + case op::bool_and: return 2; + case op::bwor: return 3; + case op::bwexor: return 4; + case op::bwand: return 5; + case op::eq: return 6; + case op::ne: return 6; + case op::lt: return 7; + case op::gt: return 7; + case op::le: return 7; + case op::ge: return 7; + case op::shl: return 8; + case op::shr: return 8; + case op::add: return 9; + case op::sub: return 9; + case op::mul: return 10; + case op::div: return 10; + case op::mod: return 10; default: return 0; } } -expr_true::expr_true(location const& loc) : node{ type::expr_true, loc } +template +auto node::as(node::ptr) -> std::unique_ptr { + static_assert(std::is_same_v, "invalid cast"); } -expr_false::expr_false(location const& loc) : node{ type::expr_false, loc } +template<> +auto node::as(node::ptr from) -> std::unique_ptr { + return std::unique_ptr(static_cast(from.release())); } -expr_integer::expr_integer(location const& loc, std::string const& value) : node{ type::expr_integer, loc }, value{ std::move(value) } +template<> +auto node::as(node::ptr from) -> std::unique_ptr { + return std::unique_ptr(static_cast(from.release())); } -expr_float::expr_float(location const& loc, std::string const& value) : node{ type::expr_float, loc }, value{ std::move(value) } +expr::expr(type t) : node{ t } {} +expr::expr(type t, location const& loc) : node{ t, loc } {} + +template +auto expr::is() const -> bool { + static_assert(std::is_same_v, "invalid test"); } -expr_vector::expr_vector(location const& loc, expr x, expr y, expr z) : node{ type::expr_vector, loc }, x{ std::move(x) }, y{ std::move(y) }, z{ std::move(z) } +template +auto expr::as() const -> T const& { + static_assert(std::is_same_v, "invalid cast"); } -expr_string::expr_string(location const& loc, const std::string& value) : node{ type::expr_string, loc }, value{ value } +template +auto expr::as() -> T& { + static_assert(std::is_same_v, "invalid cast"); } -expr_istring::expr_istring(location const& loc, const std::string& value) : node{ type::expr_istring, loc }, value{ std::move(value) } +call::call(node::type t) : expr{ t } {} +call::call(node::type t, location const& loc) : expr{ t, loc } {} + +template +auto call::is() const -> bool { + static_assert(std::is_same_v, "invalid test"); } -expr_path::expr_path(location const& loc) : node{ type::expr_path, loc } +template +auto call::as() const -> T const& { + static_assert(std::is_same_v, "invalid cast"); } -expr_path::expr_path(location const& loc, std::string const& value) : node{ type::expr_path, loc }, value{ value } +template +auto call::as() -> T& { + static_assert(std::is_same_v, "invalid cast"); } -expr_identifier::expr_identifier(location const& loc, std::string const& value) : node{ type::expr_identifier, loc }, value{ value } +stmt::stmt(type t) : node{ t } {} +stmt::stmt(type t, location const& loc) : node{ t, loc } {} + +template +auto stmt::is() const -> bool { + static_assert(std::is_same_v, "invalid test"); } -expr_animtree::expr_animtree(location const& loc) : node{ type::expr_animtree, loc } +template +auto stmt::as() const -> T const& { + static_assert(std::is_same_v, "invalid cast"); } -expr_animation::expr_animation(location const& loc, std::string const& value) : node{ type::expr_animation, loc }, value{ value } +template +auto stmt::as() -> T& { + static_assert(std::is_same_v, "invalid cast"); } -expr_level::expr_level(location const& loc) : node{ type::expr_level, loc } +decl::decl(type t) : node{ t } {} +decl::decl(type t, location const& loc) : node{ t, loc } {} + +template +auto decl::is() const -> bool { + static_assert(std::is_same_v, "invalid test"); } -expr_anim::expr_anim(location const& loc) : node{ type::expr_anim, loc } +template +auto decl::as() const -> T const& { + static_assert(std::is_same_v, "invalid cast"); } -expr_self::expr_self(location const& loc) : node{ type::expr_self, loc } +template +auto decl::as() -> T& +{ + static_assert(std::is_same_v, "invalid cast"); +} + +#define XSK_GSC_EXPR_IS(expr_type) \ +template<> \ +auto expr::is() const -> bool \ +{ \ + return kind() == type::expr_type; \ +} \ + \ +template<> \ +auto expr::as() -> gsc::expr_type & \ +{ \ + return static_cast(*this); \ +} \ + \ +template<> \ +auto expr::as() const -> gsc::expr_type const& \ +{ \ + return static_cast(*this); \ +} \ + +#define XSK_GSC_CALL_IS(expr_type) \ +template<> \ +auto call::is() const -> bool \ +{ \ + return kind() == node::type::expr_type; \ +} \ + \ +template<> \ +auto call::as() -> gsc::expr_type & \ +{ \ + return static_cast(*this); \ +} \ + \ +template<> \ +auto call::as() const -> gsc::expr_type const& \ +{ \ + return static_cast(*this); \ +} \ + +#define XSK_GSC_STMT_IS(expr_type) \ +template<> \ +auto stmt::is() const -> bool \ +{ \ + return kind() == type::expr_type; \ +} \ + \ +template<> \ +auto stmt::as() -> gsc::expr_type & \ +{ \ + return static_cast(*this); \ +} \ + \ +template<> \ +auto stmt::as() const -> gsc::expr_type const& \ +{ \ + return static_cast(*this); \ +} \ + +#define XSK_GSC_DECL_IS(expr_type) \ +template<> \ +auto decl::is() const -> bool \ +{ \ + return kind() == type::expr_type; \ +} \ + \ +template<> \ +auto decl::as() -> gsc::expr_type & \ +{ \ + return static_cast(*this); \ +} \ + \ +template<> \ +auto decl::as() const -> gsc::expr_type const& \ +{ \ + return static_cast(*this); \ +} \ + +XSK_GSC_EXPR_IS(expr_empty) +XSK_GSC_EXPR_IS(expr_true) +XSK_GSC_EXPR_IS(expr_false) +XSK_GSC_EXPR_IS(expr_integer) +XSK_GSC_EXPR_IS(expr_float) +XSK_GSC_EXPR_IS(expr_vector) +XSK_GSC_EXPR_IS(expr_string) +XSK_GSC_EXPR_IS(expr_istring) +XSK_GSC_EXPR_IS(expr_path) +XSK_GSC_EXPR_IS(expr_identifier) +XSK_GSC_EXPR_IS(expr_animtree) +XSK_GSC_EXPR_IS(expr_animation) +XSK_GSC_EXPR_IS(expr_level) +XSK_GSC_EXPR_IS(expr_anim) +XSK_GSC_EXPR_IS(expr_self) +XSK_GSC_EXPR_IS(expr_game) +XSK_GSC_EXPR_IS(expr_undefined) +XSK_GSC_EXPR_IS(expr_empty_array) +XSK_GSC_EXPR_IS(expr_thisthread) +XSK_GSC_EXPR_IS(expr_paren) +XSK_GSC_EXPR_IS(expr_size) +XSK_GSC_EXPR_IS(expr_field) +XSK_GSC_EXPR_IS(expr_array) +XSK_GSC_EXPR_IS(expr_tuple) +XSK_GSC_EXPR_IS(expr_reference) +XSK_GSC_EXPR_IS(expr_istrue) +XSK_GSC_EXPR_IS(expr_isdefined) +XSK_GSC_EXPR_IS(expr_arguments) +XSK_GSC_EXPR_IS(expr_parameters) +XSK_GSC_EXPR_IS(expr_add_array) +XSK_GSC_EXPR_IS(expr_pointer) +XSK_GSC_EXPR_IS(expr_function) +XSK_GSC_EXPR_IS(expr_method) +XSK_GSC_EXPR_IS(expr_call) +XSK_GSC_EXPR_IS(expr_complement) +XSK_GSC_EXPR_IS(expr_negate) +XSK_GSC_EXPR_IS(expr_not) +XSK_GSC_EXPR_IS(expr_binary) +XSK_GSC_EXPR_IS(expr_ternary) +XSK_GSC_EXPR_IS(expr_increment) +XSK_GSC_EXPR_IS(expr_decrement) +XSK_GSC_EXPR_IS(expr_assign) +XSK_GSC_EXPR_IS(expr_var_create) +XSK_GSC_EXPR_IS(expr_var_access) + +XSK_GSC_CALL_IS(expr_pointer) +XSK_GSC_CALL_IS(expr_function) + +XSK_GSC_STMT_IS(stmt_empty) +XSK_GSC_STMT_IS(stmt_list) +XSK_GSC_STMT_IS(stmt_comp) +XSK_GSC_STMT_IS(stmt_dev) +XSK_GSC_STMT_IS(stmt_expr) +XSK_GSC_STMT_IS(stmt_endon) +XSK_GSC_STMT_IS(stmt_notify) +XSK_GSC_STMT_IS(stmt_wait) +XSK_GSC_STMT_IS(stmt_waittill) +XSK_GSC_STMT_IS(stmt_waittillmatch) +XSK_GSC_STMT_IS(stmt_waittillframeend) +XSK_GSC_STMT_IS(stmt_waitframe) +XSK_GSC_STMT_IS(stmt_if) +XSK_GSC_STMT_IS(stmt_ifelse) +XSK_GSC_STMT_IS(stmt_while) +XSK_GSC_STMT_IS(stmt_dowhile) +XSK_GSC_STMT_IS(stmt_for) +XSK_GSC_STMT_IS(stmt_foreach) +XSK_GSC_STMT_IS(stmt_switch) +XSK_GSC_STMT_IS(stmt_case) +XSK_GSC_STMT_IS(stmt_default) +XSK_GSC_STMT_IS(stmt_break) +XSK_GSC_STMT_IS(stmt_continue) +XSK_GSC_STMT_IS(stmt_return) +XSK_GSC_STMT_IS(stmt_breakpoint) +XSK_GSC_STMT_IS(stmt_prof_begin) +XSK_GSC_STMT_IS(stmt_prof_end) +XSK_GSC_STMT_IS(stmt_assert) +XSK_GSC_STMT_IS(stmt_assertex) +XSK_GSC_STMT_IS(stmt_assertmsg) +XSK_GSC_STMT_IS(stmt_create) +XSK_GSC_STMT_IS(stmt_remove) +XSK_GSC_STMT_IS(stmt_clear) +XSK_GSC_STMT_IS(stmt_jmp) +XSK_GSC_STMT_IS(stmt_jmp_back) +XSK_GSC_STMT_IS(stmt_jmp_cond) +XSK_GSC_STMT_IS(stmt_jmp_true) +XSK_GSC_STMT_IS(stmt_jmp_false) +XSK_GSC_STMT_IS(stmt_jmp_switch) +XSK_GSC_STMT_IS(stmt_jmp_endswitch) + +XSK_GSC_DECL_IS(decl_empty) +XSK_GSC_DECL_IS(decl_function) +XSK_GSC_DECL_IS(decl_constant) +XSK_GSC_DECL_IS(decl_usingtree) +XSK_GSC_DECL_IS(decl_dev_begin) +XSK_GSC_DECL_IS(decl_dev_end) + +node_prescriptcall::node_prescriptcall(location const& loc) : node{ type::node_prescriptcall, loc } { } -expr_game::expr_game(location const& loc) : node{ type::expr_game, loc } +node_voidcodepos::node_voidcodepos(location const& loc) : node{ type::node_voidcodepos, loc } { } -expr_undefined::expr_undefined(location const& loc) : node{ type::expr_undefined, loc } +expr_empty::expr_empty(location const& loc) : expr{ type::expr_empty, loc } { } -expr_empty_array::expr_empty_array(location const& loc) : node{ type::expr_empty_array, loc } +expr_true::expr_true(location const& loc) : expr{ type::expr_true, loc } { } -expr_thisthread::expr_thisthread(location const& loc) : node{ type::expr_thisthread, loc } +expr_false::expr_false(location const& loc) : expr{ type::expr_false, loc } { } -expr_paren::expr_paren(location const& loc, expr value) : node{ type::expr_paren, loc }, value{ std::move(value) } +expr_integer::expr_integer(location const& loc, std::string const& value) : expr{ type::expr_integer, loc }, value{ std::move(value) } { } -expr_size::expr_size(location const& loc, expr obj) : node{ type::expr_size, loc }, obj{ std::move(obj) } +expr_float::expr_float(location const& loc, std::string const& value) : expr{ type::expr_float, loc }, value{ std::move(value) } { } -expr_field::expr_field(location const& loc, expr obj, expr_identifier::ptr field) : node{ type::expr_field, loc }, obj{ std::move(obj) }, field{ std::move(field) } +expr_vector::expr_vector(location const& loc, expr::ptr x, expr::ptr y, expr::ptr z) : expr{ type::expr_vector, loc }, x{ std::move(x) }, y{ std::move(y) }, z{ std::move(z) } { } -expr_array::expr_array(location const& loc, expr obj, expr key) : node{ type::expr_array, loc }, obj{ std::move(obj) }, key{ std::move(key) } +expr_string::expr_string(location const& loc, const std::string& value) : expr{ type::expr_string, loc }, value{ value } { } -expr_tuple::expr_tuple(location const& loc) : node{ type::expr_tuple, loc } +expr_istring::expr_istring(location const& loc, const std::string& value) : expr{ type::expr_istring, loc }, value{ std::move(value) } { } -expr_reference::expr_reference(location const& loc, expr_path::ptr path, expr_identifier::ptr name) : node{ type::expr_reference, loc }, path{ std::move(path) }, name{ std::move(name) } +expr_path::expr_path(location const& loc) : expr{ type::expr_path, loc } { } -expr_istrue::expr_istrue(location const& loc, expr value) : node{ type::expr_istrue, loc }, value{ std::move(value) } +expr_path::expr_path(location const& loc, std::string const& value) : expr{ type::expr_path, loc }, value{ value } { } -expr_isdefined::expr_isdefined(location const& loc, expr value) : node{ type::expr_isdefined, loc }, value{ std::move(value) } +expr_identifier::expr_identifier(location const& loc, std::string const& value) : expr{ type::expr_identifier, loc }, value{ value } { } -expr_arguments::expr_arguments(location const& loc) : node{ type::expr_arguments, loc } +expr_animtree::expr_animtree(location const& loc) : expr{ type::expr_animtree, loc } { } -expr_parameters::expr_parameters(location const& loc) : node{ type::expr_parameters, loc } +expr_animation::expr_animation(location const& loc, std::string const& value) : expr{ type::expr_animation, loc }, value{ value } { } -expr_add_array::expr_add_array(location const& loc, expr_arguments::ptr args) : node{ type::expr_add_array, loc }, args{ std::move(args) } +expr_level::expr_level(location const& loc) : expr{ type::expr_level, loc } { } -expr_pointer::expr_pointer(location const& loc, expr func, expr_arguments::ptr args, call::mode mode) : node{ type::expr_pointer, loc }, func{ std::move(func) }, args{ std::move(args) }, mode{ mode } +expr_anim::expr_anim(location const& loc) : expr{ type::expr_anim, loc } { } -expr_function::expr_function(location const& loc, expr_path::ptr path, expr_identifier::ptr name, expr_arguments::ptr args, call::mode mode) : node{ type::expr_function, loc }, path{ std::move(path) }, name{ std::move(name) }, args{ std::move(args) }, mode{ mode } +expr_self::expr_self(location const& loc) : expr{ type::expr_self, loc } { } -expr_method::expr_method(location const& loc, expr obj, call value) : node{ type::expr_method, loc }, obj{ std::move(obj) }, value{ std::move(value) } +expr_game::expr_game(location const& loc) : expr{ type::expr_game, loc } { } -expr_call::expr_call(location const& loc, call value) : node{ type::expr_call, loc }, value{ std::move(value) } +expr_undefined::expr_undefined(location const& loc) : expr{ type::expr_undefined, loc } { } -expr_complement::expr_complement(location const& loc, expr rvalue) : node{ type::expr_complement, loc }, rvalue{ std::move(rvalue) } +expr_empty_array::expr_empty_array(location const& loc) : expr{ type::expr_empty_array, loc } { } -expr_negate::expr_negate(location const& loc, expr rvalue) : node{ type::expr_negate, loc }, rvalue{ std::move(rvalue) } +expr_thisthread::expr_thisthread(location const& loc) : expr{ type::expr_thisthread, loc } { } -expr_not::expr_not(location const& loc, expr rvalue) : node{ type::expr_not, loc }, rvalue{ std::move(rvalue) } +expr_paren::expr_paren(location const& loc, expr::ptr value) : expr{ type::expr_paren, loc }, value{ std::move(value) } { } -expr_binary::expr_binary(type t, location const& loc, expr lvalue, expr rvalue) : node{ t, loc }, lvalue{ std::move(lvalue) }, rvalue{ std::move(rvalue) } +expr_size::expr_size(location const& loc, expr::ptr obj) : expr{ type::expr_size, loc }, obj{ std::move(obj) } { } -expr_add::expr_add(location const& loc, expr lvalue, expr rvalue) : expr_binary{ type::expr_add, loc, std::move(lvalue), std::move(rvalue) } +expr_field::expr_field(location const& loc, expr::ptr obj, expr_identifier::ptr field) : expr{ type::expr_field, loc }, obj{ std::move(obj) }, field{ std::move(field) } { } -expr_sub::expr_sub(location const& loc, expr lvalue, expr rvalue) : expr_binary{ type::expr_sub, loc, std::move(lvalue), std::move(rvalue) } +expr_array::expr_array(location const& loc, expr::ptr obj, expr::ptr key) : expr{ type::expr_array, loc }, obj{ std::move(obj) }, key{ std::move(key) } { } -expr_mul::expr_mul(location const& loc, expr lvalue, expr rvalue) : expr_binary{ type::expr_mul, loc, std::move(lvalue), std::move(rvalue) } +expr_tuple::expr_tuple(location const& loc) : expr{ type::expr_tuple, loc } { } -expr_div::expr_div(location const& loc, expr lvalue, expr rvalue) : expr_binary{ type::expr_div, loc, std::move(lvalue), std::move(rvalue) } +expr_reference::expr_reference(location const& loc, expr_path::ptr path, expr_identifier::ptr name) : expr{ type::expr_reference, loc }, path{ std::move(path) }, name{ std::move(name) } { } -expr_mod::expr_mod(location const& loc, expr lvalue, expr rvalue) : expr_binary{ type::expr_mod, loc, std::move(lvalue), std::move(rvalue) } +expr_istrue::expr_istrue(location const& loc, expr::ptr value) : expr{ type::expr_istrue, loc }, value{ std::move(value) } { } -expr_shift_left::expr_shift_left(location const& loc, expr lvalue, expr rvalue) : expr_binary{ type::expr_shift_left, loc, std::move(lvalue), std::move(rvalue) } +expr_isdefined::expr_isdefined(location const& loc, expr::ptr value) : expr{ type::expr_isdefined, loc }, value{ std::move(value) } { } -expr_shift_right::expr_shift_right(location const& loc, expr lvalue, expr rvalue) : expr_binary{ type::expr_shift_right, loc, std::move(lvalue), std::move(rvalue) } +expr_arguments::expr_arguments(location const& loc) : expr{ type::expr_arguments, loc } { } -expr_bitwise_or::expr_bitwise_or(location const& loc, expr lvalue, expr rvalue) : expr_binary{ type::expr_bitwise_or, loc, std::move(lvalue), std::move(rvalue) } +expr_parameters::expr_parameters(location const& loc) : expr{ type::expr_parameters, loc } { } -expr_bitwise_and::expr_bitwise_and(location const& loc, expr lvalue, expr rvalue) : expr_binary{ type::expr_bitwise_and, loc, std::move(lvalue), std::move(rvalue) } +expr_add_array::expr_add_array(location const& loc, expr_arguments::ptr args) : expr{ type::expr_add_array, loc }, args{ std::move(args) } { } -expr_bitwise_exor::expr_bitwise_exor(location const& loc, expr lvalue, expr rvalue) : expr_binary{ type::expr_bitwise_exor, loc, std::move(lvalue), std::move(rvalue) } +expr_pointer::expr_pointer(location const& loc, expr::ptr func, expr_arguments::ptr args, call::mode mode) : call{ node::type::expr_pointer, loc }, func{ std::move(func) }, args{ std::move(args) }, mode{ mode } { } -expr_equality::expr_equality(location const& loc, expr lvalue, expr rvalue) : expr_binary{ type::expr_equality, loc, std::move(lvalue), std::move(rvalue) } +expr_function::expr_function(location const& loc, expr_path::ptr path, expr_identifier::ptr name, expr_arguments::ptr args, call::mode mode) : call{ node::type::expr_function, loc }, path{ std::move(path) }, name{ std::move(name) }, args{ std::move(args) }, mode{ mode } { } -expr_inequality::expr_inequality(location const& loc, expr lvalue, expr rvalue) : expr_binary{ type::expr_inequality, loc, std::move(lvalue), std::move(rvalue) } +expr_method::expr_method(location const& loc, expr::ptr obj, call::ptr value) : expr{ type::expr_method, loc }, obj{ std::move(obj) }, value{ std::move(value) } { } -expr_less_equal::expr_less_equal(location const& loc, expr lvalue, expr rvalue) : expr_binary{ type::expr_less_equal, loc, std::move(lvalue), std::move(rvalue) } +expr_call::expr_call(location const& loc, call::ptr value) : expr{ type::expr_call, loc }, value{ std::move(value) } { } -expr_greater_equal::expr_greater_equal(location const& loc, expr lvalue, expr rvalue) : expr_binary{ type::expr_greater_equal, loc, std::move(lvalue), std::move(rvalue) } +expr_complement::expr_complement(location const& loc, expr::ptr rvalue) : expr{ type::expr_complement, loc }, rvalue{ std::move(rvalue) } { } -expr_less::expr_less(location const& loc, expr lvalue, expr rvalue) : expr_binary{ type::expr_less, loc, std::move(lvalue), std::move(rvalue) } +expr_negate::expr_negate(location const& loc, expr::ptr rvalue) : expr{ type::expr_negate, loc }, rvalue{ std::move(rvalue) } { } -expr_greater::expr_greater(location const& loc, expr lvalue, expr rvalue) : expr_binary{ type::expr_greater, loc, std::move(lvalue), std::move(rvalue) } +expr_not::expr_not(location const& loc, expr::ptr rvalue) : expr{ type::expr_not, loc }, rvalue{ std::move(rvalue) } { } -expr_or::expr_or(location const& loc, expr lvalue, expr rvalue) : expr_binary{ type::expr_or, loc, std::move(lvalue), std::move(rvalue) } +expr_binary::expr_binary(location const& loc, expr::ptr lvalue, expr::ptr rvalue, op oper) : expr{ type::expr_binary, loc }, lvalue{ std::move(lvalue) }, rvalue{ std::move(rvalue) }, oper{ oper } { } -expr_and::expr_and(location const& loc, expr lvalue, expr rvalue) : expr_binary{ type::expr_and, loc, std::move(lvalue), std::move(rvalue) } +expr_ternary::expr_ternary(location const& loc, expr::ptr test, expr::ptr true_expr, expr::ptr false_expr) : expr{ type::expr_ternary, loc }, test{ std::move(test) }, true_expr{ std::move(true_expr) }, false_expr{ std::move(false_expr) } { } -expr_ternary::expr_ternary(location const& loc, expr test, expr true_expr, expr false_expr) : node{ type::expr_ternary, loc }, test{ std::move(test) }, true_expr{ std::move(true_expr) }, false_expr{ std::move(false_expr) } +expr_assign::expr_assign(location const& loc, expr::ptr lvalue, expr::ptr rvalue, op oper) : expr{ type::expr_assign, loc }, lvalue{ std::move(lvalue) }, rvalue{ std::move(rvalue) }, oper{ oper } { } -expr_increment::expr_increment(location const& loc, expr lvalue, bool prefix) : node{ type::expr_increment, loc }, lvalue{ std::move(lvalue) }, prefix{ prefix } +expr_increment::expr_increment(location const& loc, expr::ptr lvalue, bool prefix) : expr{ type::expr_increment, loc }, lvalue{ std::move(lvalue) }, prefix{ prefix } { } -expr_decrement::expr_decrement(location const& loc, expr lvalue, bool prefix) : node{ type::expr_decrement, loc }, lvalue{ std::move(lvalue) }, prefix{ prefix } +expr_decrement::expr_decrement(location const& loc, expr::ptr lvalue, bool prefix) : expr{ type::expr_decrement, loc }, lvalue{ std::move(lvalue) }, prefix{ prefix } { } -expr_assign::expr_assign(type t, location const& loc, expr lvalue, expr rvalue) : node{ t, loc }, lvalue{ std::move(lvalue) }, rvalue{ std::move(rvalue) } +expr_var_create::expr_var_create(location const& loc, std::string const& index) : expr{ type::expr_var_create, loc }, index{ index } { } -expr_assign_equal::expr_assign_equal(location const& loc, expr lvalue, expr rvalue) : expr_assign{ type::expr_assign_equal, loc, std::move(lvalue), std::move(rvalue) } +expr_var_access::expr_var_access(location const& loc, std::string const& index) : expr{ type::expr_var_access, loc }, index{ index } { } -expr_assign_add::expr_assign_add(location const& loc, expr lvalue, expr rvalue) : expr_assign{ type::expr_assign_add, loc, std::move(lvalue), std::move(rvalue) } +stmt_empty::stmt_empty(location const& loc) : stmt{ type::stmt_empty, loc } { } -expr_assign_sub::expr_assign_sub(location const& loc, expr lvalue, expr rvalue) : expr_assign{ type::expr_assign_sub, loc, std::move(lvalue), std::move(rvalue) } +stmt_list::stmt_list(location const& loc) : stmt{ type::stmt_list, loc } { } -expr_assign_mul::expr_assign_mul(location const& loc, expr lvalue, expr rvalue) : expr_assign{ type::expr_assign_mul, loc, std::move(lvalue), std::move(rvalue) } +stmt_comp::stmt_comp(location const& loc, stmt_list::ptr block) : stmt{ type::stmt_comp, loc }, block{ std::move(block) } { } -expr_assign_div::expr_assign_div(location const& loc, expr lvalue, expr rvalue) : expr_assign{ type::expr_assign_div, loc, std::move(lvalue), std::move(rvalue) } +stmt_dev::stmt_dev(location const& loc, stmt_list::ptr block) : stmt{ type::stmt_dev, loc }, block{ std::move(block) } { } -expr_assign_mod::expr_assign_mod(location const& loc, expr lvalue, expr rvalue) : expr_assign{ type::expr_assign_mod, loc, std::move(lvalue), std::move(rvalue) } +stmt_expr::stmt_expr(location const& loc, expr::ptr value) : stmt{ type::stmt_expr, loc }, value{ std::move(value) } { } -expr_assign_shift_left::expr_assign_shift_left(location const& loc, expr lvalue, expr rvalue) : expr_assign{ type::expr_assign_shift_left, loc, std::move(lvalue), std::move(rvalue) } +stmt_endon::stmt_endon(location const& loc, expr::ptr obj, expr::ptr event) : stmt{ type::stmt_endon, loc }, obj{ std::move(obj) }, event{ std::move(event) } { } -expr_assign_shift_right::expr_assign_shift_right(location const& loc, expr lvalue, expr rvalue) : expr_assign{ type::expr_assign_shift_right, loc, std::move(lvalue), std::move(rvalue) } +stmt_notify::stmt_notify(location const& loc, expr::ptr obj, expr::ptr event, expr_arguments::ptr args) : stmt{ type::stmt_notify, loc }, obj{ std::move(obj) }, event{ std::move(event) }, args{ std::move(args) } { } -expr_assign_bitwise_or::expr_assign_bitwise_or(location const& loc, expr lvalue, expr rvalue) : expr_assign{ type::expr_assign_bitwise_or, loc, std::move(lvalue), std::move(rvalue) } +stmt_wait::stmt_wait(location const& loc, expr::ptr time) : stmt{ type::stmt_wait, loc }, time{ std::move(time) } { } -expr_assign_bitwise_and::expr_assign_bitwise_and(location const& loc, expr lvalue, expr rvalue) : expr_assign{ type::expr_assign_bitwise_and, loc, std::move(lvalue), std::move(rvalue) } +stmt_waittill::stmt_waittill(location const& loc, expr::ptr obj, expr::ptr event, expr_arguments::ptr args) : stmt{ type::stmt_waittill, loc }, obj{ std::move(obj) }, event{ std::move(event) }, args{ std::move(args) } { } -expr_assign_bitwise_exor::expr_assign_bitwise_exor(location const& loc, expr lvalue, expr rvalue) : expr_assign{ type::expr_assign_bitwise_exor, loc, std::move(lvalue), std::move(rvalue) } +stmt_waittillmatch::stmt_waittillmatch(location const& loc, expr::ptr obj, expr::ptr event, expr_arguments::ptr args) : stmt{ type::stmt_waittillmatch, loc }, obj{ std::move(obj) }, event{ std::move(event) }, args{ std::move(args) } { } -stmt_list::stmt_list(location const& loc) : node{ type::stmt_list, loc } +stmt_waittillframeend::stmt_waittillframeend(location const& loc) : stmt{ type::stmt_waittillframeend, loc } { } -stmt_comp::stmt_comp(location const& loc, stmt_list::ptr block) : node{ type::stmt_comp, loc }, block{ std::move(block) } +stmt_waitframe::stmt_waitframe(location const& loc) : stmt{ type::stmt_waitframe, loc } { } -stmt_dev::stmt_dev(location const& loc, stmt_list::ptr block) : node{ type::stmt_dev, loc }, block{ std::move(block) } +stmt_if::stmt_if(location const& loc, expr::ptr test, stmt::ptr body) : stmt{ type::stmt_if, loc }, test{ std::move(test) }, body{ std::move(body) } { } -stmt_expr::stmt_expr(location const& loc, expr value) : node{ type::stmt_expr, loc }, value{ std::move(value) } +stmt_ifelse::stmt_ifelse(location const& loc, expr::ptr test, stmt::ptr stmt_if, stmt::ptr stmt_else) : stmt{ type::stmt_ifelse, loc }, test{ std::move(test) }, stmt_if{ std::move(stmt_if) }, stmt_else{ std::move(stmt_else) } { } -stmt_call::stmt_call(location const& loc, expr value) : node{ type::stmt_call, loc }, value{ std::move(value) } +stmt_while::stmt_while(location const& loc, expr::ptr test, stmt::ptr body) : stmt{ type::stmt_while, loc }, test{ std::move(test) }, body{ std::move(body) } { } -stmt_assign::stmt_assign(location const& loc, expr value) : node{ type::stmt_assign, loc }, value{ std::move(value) } +stmt_dowhile::stmt_dowhile(location const& loc, expr::ptr test, stmt::ptr body) : stmt{ type::stmt_dowhile, loc }, test{ std::move(test) }, body{ std::move(body) } { } -stmt_endon::stmt_endon(location const& loc, expr obj, expr event) : node{ type::stmt_endon, loc }, obj{ std::move(obj) }, event{ std::move(event) } +stmt_for::stmt_for(location const& loc, stmt::ptr init, expr::ptr test, stmt::ptr iter, stmt::ptr body) : stmt{ type::stmt_for, loc }, init{ std::move(init) }, test{ std::move(test) }, iter{ std::move(iter) }, body{ std::move(body) } { } -stmt_notify::stmt_notify(location const& loc, expr obj, expr event, expr_arguments::ptr args) : node{ type::stmt_notify, loc }, obj{ std::move(obj) }, event{ std::move(event) }, args{ std::move(args) } +stmt_foreach::stmt_foreach(location const& loc, expr::ptr container, expr::ptr value, expr::ptr index, expr::ptr array, expr::ptr key, stmt::ptr body, bool use_key) : stmt{ type::stmt_foreach, loc }, container{ std::move(container) }, value{ std::move(value) }, index{ std::move(index) }, array{ std::move(array) }, key{ std::move(key) }, body{ std::move(body) }, use_key{ use_key } { } -stmt_wait::stmt_wait(location const& loc, expr time) : node{ type::stmt_wait, loc }, time{ std::move(time) } +stmt_switch::stmt_switch(location const& loc, expr::ptr test, stmt_comp::ptr body) : stmt{ type::stmt_switch, loc }, test{ std::move(test) }, body{ std::move(body) } { } -stmt_waittill::stmt_waittill(location const& loc, expr obj, expr event, expr_arguments::ptr args) : node{ type::stmt_waittill, loc }, obj{ std::move(obj) }, event{ std::move(event) }, args{ std::move(args) } +stmt_case::stmt_case(location const& loc, expr::ptr value) : stmt{ type::stmt_case, loc }, value{ std::move(value) }, body{ nullptr } { } -stmt_waittillmatch::stmt_waittillmatch(location const& loc, expr obj, expr event, expr_arguments::ptr args) : node{ type::stmt_waittillmatch, loc }, obj{ std::move(obj) }, event{ std::move(event) }, args{ std::move(args) } +stmt_case::stmt_case(location const& loc, expr::ptr value, stmt_list::ptr body) : stmt{ type::stmt_case, loc }, value{ std::move(value) }, body{ std::move(body) } { } -stmt_waittillframeend::stmt_waittillframeend(location const& loc) : node{ type::stmt_waittillframeend, loc } +stmt_default::stmt_default(location const& loc) : stmt{ type::stmt_default, loc }, body{ nullptr } { } -stmt_waitframe::stmt_waitframe(location const& loc) : node{ type::stmt_waitframe, loc } +stmt_default::stmt_default(location const& loc, stmt_list::ptr body) : stmt{ type::stmt_default, loc }, body{ std::move(body) } { } -stmt_if::stmt_if(location const& loc, expr test, stmt body) : node{ type::stmt_if, loc }, test{ std::move(test) }, body{ std::move(body) } +stmt_break::stmt_break(location const& loc) : stmt{ type::stmt_break, loc } { } -stmt_ifelse::stmt_ifelse(location const& loc, expr test, stmt stmt_if, stmt stmt_else) : node{ type::stmt_ifelse, loc }, test{ std::move(test) }, stmt_if{ std::move(stmt_if) }, stmt_else{ std::move(stmt_else) } +stmt_continue::stmt_continue(location const& loc) : stmt{ type::stmt_continue, loc } { } -stmt_while::stmt_while(location const& loc, expr test, stmt body) : node{ type::stmt_while, loc }, test{ std::move(test) }, body{ std::move(body) } +stmt_return::stmt_return(location const& loc, expr::ptr value) : stmt{ type::stmt_return, loc }, value{ std::move(value) } { } -stmt_dowhile::stmt_dowhile(location const& loc, expr test, stmt body) : node{ type::stmt_dowhile, loc }, test{ std::move(test) }, body{ std::move(body) } +stmt_breakpoint::stmt_breakpoint(location const& loc) : stmt{ type::stmt_breakpoint, loc } { } -stmt_for::stmt_for(location const& loc, stmt init, expr test, stmt iter, stmt body) : node{ type::stmt_for, loc }, init{ std::move(init) }, test{ std::move(test) }, iter{ std::move(iter) }, body{ std::move(body) } +stmt_prof_begin::stmt_prof_begin(location const& loc, expr_arguments::ptr args) : stmt{ type::stmt_prof_begin, loc }, args{ std::move(args) } { } -stmt_foreach::stmt_foreach(location const& loc, expr container, expr value, expr index, expr array, expr key, stmt body, bool use_key) : node{ type::stmt_foreach, loc }, container{ std::move(container) }, value{ std::move(value) }, index{ std::move(index) }, array{ std::move(array) }, key{ std::move(key) }, body{ std::move(body) }, use_key{ use_key } +stmt_prof_end::stmt_prof_end(location const& loc, expr_arguments::ptr args) : stmt{ type::stmt_prof_end, loc }, args{ std::move(args) } { } -stmt_switch::stmt_switch(location const& loc, expr test, stmt_comp::ptr body) : node{ type::stmt_switch, loc }, test{ std::move(test) }, body{ std::move(body) } +stmt_assert::stmt_assert(location const& loc, expr_arguments::ptr args) : stmt{ type::stmt_assert, loc }, args{ std::move(args) } { } -stmt_case::stmt_case(location const& loc, expr value) : node{ type::stmt_case, loc }, value{ std::move(value) }, body{ nullptr } +stmt_assertex::stmt_assertex(location const& loc, expr_arguments::ptr args) : stmt{ type::stmt_assertex, loc }, args{ std::move(args) } { } -stmt_case::stmt_case(location const& loc, expr value, stmt_list::ptr body) : node{ type::stmt_case, loc }, value{ std::move(value) }, body{ std::move(body) } +stmt_assertmsg::stmt_assertmsg(location const& loc, expr_arguments::ptr args) : stmt{ type::stmt_assertmsg, loc }, args{ std::move(args) } { } -stmt_default::stmt_default(location const& loc) : node{ type::stmt_default, loc }, body{ nullptr } +stmt_create::stmt_create(location const& loc, std::string const& index) : stmt{ type::stmt_create, loc }, index{ index } { } -stmt_default::stmt_default(location const& loc, stmt_list::ptr body) : node{ type::stmt_default, loc }, body{ std::move(body) } +stmt_remove::stmt_remove(location const& loc, std::string const& index) : stmt{ type::stmt_remove, loc }, index{ index } { } -stmt_break::stmt_break(location const& loc) : node{ type::stmt_break, loc } +stmt_clear::stmt_clear(location const& loc, std::string const& index) : stmt{ type::stmt_clear, loc }, index{ index } { } -stmt_continue::stmt_continue(location const& loc) : node{ type::stmt_continue, loc } +stmt_jmp::stmt_jmp(location const& loc, std::string const& value) : stmt{ type::stmt_jmp, loc }, value{ value } { } -stmt_return::stmt_return(location const& loc, expr value) : node{ type::stmt_return, loc }, value{ std::move(value) } +stmt_jmp_back::stmt_jmp_back(location const& loc, std::string const& value) : stmt{ type::stmt_jmp_back, loc }, value{ value } { } -stmt_breakpoint::stmt_breakpoint(location const& loc) : node{ type::stmt_breakpoint, loc } +stmt_jmp_cond::stmt_jmp_cond(location const& loc, expr::ptr test, std::string const& value) : stmt{ type::stmt_jmp_cond, loc }, test{ std::move(test) }, value{ value } { } -stmt_prof_begin::stmt_prof_begin(location const& loc, expr_arguments::ptr args) : node{ type::stmt_prof_begin, loc }, args{ std::move(args) } +stmt_jmp_true::stmt_jmp_true(location const& loc, expr::ptr test, std::string const& value) : stmt{ type::stmt_jmp_true, loc }, test{ std::move(test) }, value{ value } { } -stmt_prof_end::stmt_prof_end(location const& loc, expr_arguments::ptr args) : node{ type::stmt_prof_end, loc }, args{ std::move(args) } +stmt_jmp_false::stmt_jmp_false(location const& loc, expr::ptr test, std::string const& value) : stmt{ type::stmt_jmp_false, loc }, test{ std::move(test) }, value{ value } { } -stmt_assert::stmt_assert(location const& loc, expr_arguments::ptr args) : node{ type::stmt_assert, loc }, args{ std::move(args) } +stmt_jmp_switch::stmt_jmp_switch(location const& loc, expr::ptr test, std::string const& value) : stmt{ type::stmt_jmp_switch, loc }, test{ std::move(test) }, value{ value } { } -stmt_assertex::stmt_assertex(location const& loc, expr_arguments::ptr args) : node{ type::stmt_assertex, loc }, args{ std::move(args) } +stmt_jmp_endswitch::stmt_jmp_endswitch(location const& loc, std::vector data) : stmt{ type::stmt_jmp_endswitch, loc }, data{ std::move(data) } { } -stmt_assertmsg::stmt_assertmsg(location const& loc, expr_arguments::ptr args) : node{ type::stmt_assertmsg, loc }, args{ std::move(args) } +decl_empty::decl_empty(location const& loc) : decl{ type::decl_empty, loc } { } -decl_function::decl_function(location const& loc, expr_identifier::ptr name, expr_parameters::ptr params, stmt_comp::ptr body) : node{ type::decl_function, loc }, name{ std::move(name) }, params{ std::move(params) }, body{ std::move(body) } +decl_function::decl_function(location const& loc, expr_identifier::ptr name, expr_parameters::ptr params, stmt_comp::ptr body) : decl{ type::decl_function, loc }, name{ std::move(name) }, params{ std::move(params) }, body{ std::move(body) } { } -decl_constant::decl_constant(location const& loc, expr_identifier::ptr name, expr value) : node{ type::decl_constant, loc }, name{ std::move(name) }, value{ std::move(value) } +decl_constant::decl_constant(location const& loc, expr_identifier::ptr name, expr::ptr value) : decl{ type::decl_constant, loc }, name{ std::move(name) }, value{ std::move(value) } { } -decl_usingtree::decl_usingtree(location const& loc, expr_string::ptr name) : node{ type::decl_usingtree, loc }, name{ std::move(name) } +decl_usingtree::decl_usingtree(location const& loc, expr_string::ptr name) : decl{ type::decl_usingtree, loc }, name{ std::move(name) } { } -decl_dev_begin::decl_dev_begin(location const& loc) : node{ type::decl_dev_begin, loc } +decl_dev_begin::decl_dev_begin(location const& loc) : decl{ type::decl_dev_begin, loc } { } -decl_dev_end::decl_dev_end(location const& loc) : node{ type::decl_dev_end, loc } +decl_dev_end::decl_dev_end(location const& loc) : decl{ type::decl_dev_end, loc } { } @@ -574,66 +782,37 @@ program::program(location const& loc) : node{ type::program, loc } { } -asm_jmp::asm_jmp(location const& loc, std::string const& value) : node{ type::asm_jmp, loc }, value{ value } +auto operator==(expr const& lhs, expr const& rhs) -> bool { -} + if (!(lhs.kind() == rhs.kind())) return false; -asm_jmp_back::asm_jmp_back(location const& loc, std::string const& value) : node{ type::asm_jmp_back, loc }, value{ value } -{ -} - -asm_jmp_cond::asm_jmp_cond(location const& loc, expr test, std::string const& value) : node{ type::asm_jmp_cond, loc }, test{ std::move(test) }, value{ value } -{ -} - -asm_jmp_true::asm_jmp_true(location const& loc, expr test, std::string const& value) : node{ type::asm_jmp_true, loc }, test{ std::move(test) }, value{ value } -{ -} - -asm_jmp_false::asm_jmp_false(location const& loc, expr test, std::string const& value) : node{ type::asm_jmp_false, loc }, test{ std::move(test) }, value{ value } -{ -} - -asm_switch::asm_switch(location const& loc, expr test, std::string const& value) : node{ type::asm_switch, loc }, test{ std::move(test) }, value{ value } -{ -} - -asm_endswitch::asm_endswitch(location const& loc, std::vector data) : node{ type::asm_endswitch, loc }, data{ std::move(data) } -{ -} - -asm_prescriptcall::asm_prescriptcall(location const& loc) : node{ type::asm_prescriptcall, loc } -{ -} - -asm_voidcodepos::asm_voidcodepos(location const& loc) : node{ type::asm_voidcodepos, loc } -{ -} - -asm_create::asm_create(location const& loc, std::string const& index) : node{ type::asm_create, loc }, index{ index } -{ -} - -asm_access::asm_access(location const& loc, std::string const& index) : node{ type::asm_access, loc }, index{ index } -{ -} - -asm_remove::asm_remove(location const& loc, std::string const& index) : node{ type::asm_remove, loc }, index{ index } -{ -} - -asm_clear::asm_clear(location const& loc, std::string const& index) : node{ type::asm_clear, loc }, index{ index } -{ -} - -auto operator==(node const& n, node::type k) -> bool -{ - return n.kind_ == k; -} - -auto operator==(node const& lhs, node const& rhs) -> bool -{ - return lhs.kind_ == rhs.kind_; + switch (lhs.kind()) + { + case node::expr_empty: return true; + case node::expr_true: return lhs.as() == rhs.as(); + case node::expr_false: return lhs.as() == rhs.as(); + case node::expr_integer: return lhs.as() == rhs.as(); + case node::expr_float: return lhs.as() == rhs.as(); + case node::expr_vector: return lhs.as() == rhs.as(); + case node::expr_string: return lhs.as() == rhs.as(); + case node::expr_istring: return lhs.as() == rhs.as(); + case node::expr_path: return lhs.as() == rhs.as(); + case node::expr_identifier: return lhs.as() == rhs.as(); + case node::expr_animtree: return lhs.as() == rhs.as(); + case node::expr_animation: return lhs.as() == rhs.as(); + case node::expr_level: return lhs.as() == rhs.as(); + case node::expr_anim: return lhs.as() == rhs.as(); + case node::expr_self: return lhs.as() == rhs.as(); + case node::expr_game: return lhs.as() == rhs.as(); + case node::expr_undefined: return lhs.as() == rhs.as(); + case node::expr_empty_array: return lhs.as() == rhs.as(); + case node::expr_thisthread: return lhs.as() == rhs.as(); + case node::expr_paren: return lhs.as() == rhs.as(); + case node::expr_size: return lhs.as() == rhs.as(); + case node::expr_field: return lhs.as() == rhs.as(); + case node::expr_array: return lhs.as() == rhs.as(); + default: return false; + } } auto operator==(expr_true const&, expr_true const&) -> bool @@ -746,352 +925,4 @@ auto operator==(expr_array const& lhs, expr_array const& rhs) -> bool return lhs.obj == rhs.obj && lhs.key == rhs.key; } -call::call() : as_node{ nullptr } -{ -} - -call::call(std::unique_ptr value) : as_node{ std::move(value) } -{ -} - -call::call(call&& value) -{ - new(&as_node) std::unique_ptr{ std::move(value.as_node) }; -} - -call::~call() -{ - if (as_node == nullptr) return; - - switch (as_node->kind()) - { - case node::null: as_node.~unique_ptr(); return; - case node::expr_pointer: as_pointer.~unique_ptr(); return; - case node::expr_function: as_function.~unique_ptr(); return; - default: return; - } -} - -auto operator==(call const& lhs, node::type rhs) -> bool -{ - return *lhs.as_node == rhs; -} - -auto call::loc() const -> location -{ - return as_node->loc(); -} - -auto call::kind() const -> node::type -{ - return as_node->kind(); -} - -auto call::label() const -> std::string -{ - return as_node->label(); -} - -expr::expr() : as_node{ nullptr } -{ -} - -expr::expr(std::unique_ptr value) : as_node{ std::move(value) } -{ -} - -expr::expr(expr&& value) -{ - new(&as_node) std::unique_ptr{ std::move(value.as_node) }; -} - -expr& expr::operator=(expr&& value) -{ - new(&as_node) std::unique_ptr{ std::move(value.as_node) }; - return *(expr*)&as_node; -} - -expr::~expr() -{ - if (as_node == nullptr) return; - - switch (as_node->kind()) - { - case node::null: as_node.~unique_ptr(); return; - case node::expr_true: as_true.~unique_ptr(); return; - case node::expr_false: as_false.~unique_ptr(); return; - case node::expr_integer: as_integer.~unique_ptr(); return; - case node::expr_float: as_float.~unique_ptr(); return; - case node::expr_vector: as_vector.~unique_ptr(); return; - case node::expr_string: as_string.~unique_ptr(); return; - case node::expr_istring: as_istring.~unique_ptr(); return; - case node::expr_path: as_path.~unique_ptr(); return; - case node::expr_identifier: as_identifier.~unique_ptr(); return; - case node::expr_animtree: as_animtree.~unique_ptr(); return; - case node::expr_animation: as_animation.~unique_ptr(); return; - case node::expr_level: as_level.~unique_ptr(); return; - case node::expr_anim: as_anim.~unique_ptr(); return; - case node::expr_self: as_self.~unique_ptr(); return; - case node::expr_game: as_game.~unique_ptr(); return; - case node::expr_undefined: as_undefined.~unique_ptr(); return; - case node::expr_empty_array: as_empty_array.~unique_ptr(); return; - case node::expr_thisthread: as_thisthread.~unique_ptr(); return; - case node::expr_paren: as_paren.~unique_ptr(); return; - case node::expr_size: as_size.~unique_ptr(); return; - case node::expr_field: as_field.~unique_ptr(); return; - case node::expr_array: as_array.~unique_ptr(); return; - case node::expr_tuple: as_tuple.~unique_ptr(); return; - case node::expr_reference: as_reference.~unique_ptr(); return; - case node::expr_istrue: as_istrue.~unique_ptr(); return; - case node::expr_isdefined: as_isdefined.~unique_ptr(); return; - case node::expr_arguments: as_arguments.~unique_ptr(); return; - case node::expr_parameters: as_parameters.~unique_ptr(); return; - case node::expr_add_array: as_add_array.~unique_ptr(); return; - case node::expr_pointer: as_pointer.~unique_ptr(); return; - case node::expr_function: as_function.~unique_ptr(); return; - case node::expr_method: as_method.~unique_ptr(); return; - case node::expr_call: as_call.~unique_ptr(); return; - case node::expr_complement: as_complement.~unique_ptr(); return; - case node::expr_negate: as_negate.~unique_ptr(); return; - case node::expr_not: as_not.~unique_ptr(); return; - case node::expr_add: as_add.~unique_ptr(); return; - case node::expr_sub: as_sub.~unique_ptr(); return; - case node::expr_mul: as_mul.~unique_ptr(); return; - case node::expr_div: as_div.~unique_ptr(); return; - case node::expr_mod: as_mod.~unique_ptr(); return; - case node::expr_shift_left: as_shift_left.~unique_ptr(); return; - case node::expr_shift_right: as_shift_right.~unique_ptr(); return; - case node::expr_bitwise_or: as_bitwise_or.~unique_ptr(); return; - case node::expr_bitwise_and: as_bitwise_and.~unique_ptr(); return; - case node::expr_bitwise_exor: as_bitwise_exor.~unique_ptr(); return; - case node::expr_equality: as_equality.~unique_ptr(); return; - case node::expr_inequality: as_inequality.~unique_ptr(); return; - case node::expr_less_equal: as_less_equal.~unique_ptr(); return; - case node::expr_greater_equal: as_greater_equal.~unique_ptr(); return; - case node::expr_less: as_less.~unique_ptr(); return; - case node::expr_greater: as_greater.~unique_ptr(); return; - case node::expr_or: as_or.~unique_ptr(); return; - case node::expr_and: as_and.~unique_ptr(); return; - case node::expr_ternary: as_ternary.~unique_ptr(); return; - case node::expr_increment: as_increment.~unique_ptr(); return; - case node::expr_decrement: as_decrement.~unique_ptr(); return; - case node::expr_assign_equal: as_assign_equal.~unique_ptr(); return; - case node::expr_assign_add: as_assign_add.~unique_ptr(); return; - case node::expr_assign_sub: as_assign_sub.~unique_ptr(); return; - case node::expr_assign_mul: as_assign_mul.~unique_ptr(); return; - case node::expr_assign_div: as_assign_div.~unique_ptr(); return; - case node::expr_assign_mod: as_assign_mod.~unique_ptr(); return; - case node::expr_assign_shift_left: as_assign_shift_left.~unique_ptr(); return; - case node::expr_assign_shift_right: as_assign_shift_right.~unique_ptr(); return; - case node::expr_assign_bitwise_or: as_assign_bw_or.~unique_ptr(); return; - case node::expr_assign_bitwise_and: as_assign_bw_and.~unique_ptr(); return; - case node::expr_assign_bitwise_exor: as_assign_bw_exor.~unique_ptr(); return; - case node::asm_create: as_asm_create.~unique_ptr(); return; - case node::asm_access: as_asm_access.~unique_ptr(); return; - default: return; - } -} - -auto operator!=(expr const& lhs, node::type rhs) -> bool -{ - return lhs.as_node->kind() != rhs; -} - -auto operator==(expr const& lhs, node::type rhs) -> bool -{ - return *lhs.as_node == rhs; -} - -auto operator==(expr const& lhs, expr const& rhs) -> bool -{ - if (!(*lhs.as_node == *rhs.as_node)) return false; - - switch(lhs.as_node->kind()) - { - case node::expr_true: return *lhs.as_true == *rhs.as_true; - case node::expr_false: return *lhs.as_false == *rhs.as_false; - case node::expr_integer: return *lhs.as_integer == *rhs.as_integer; - case node::expr_float: return *lhs.as_float == *rhs.as_float; - case node::expr_vector: return *lhs.as_vector == *rhs.as_vector; - case node::expr_string: return *lhs.as_string == *rhs.as_string; - case node::expr_istring: return *lhs.as_istring == *rhs.as_istring; - case node::expr_path: return *lhs.as_path == *rhs.as_path; - case node::expr_identifier: return *lhs.as_identifier == *rhs.as_identifier; - case node::expr_animtree: return *lhs.as_animtree == *rhs.as_animtree; - case node::expr_animation: return *lhs.as_animation == *rhs.as_animation; - case node::expr_level: return *lhs.as_level == *rhs.as_level; - case node::expr_anim: return *lhs.as_anim == *rhs.as_anim; - case node::expr_self: return *lhs.as_self == *rhs.as_self; - case node::expr_game: return *lhs.as_game == *rhs.as_game; - case node::expr_undefined: return *lhs.as_undefined == *rhs.as_undefined; - case node::expr_empty_array: return *lhs.as_empty_array == *rhs.as_empty_array; - case node::expr_thisthread: return *lhs.as_thisthread == *rhs.as_thisthread; - case node::expr_paren: return *lhs.as_paren == *rhs.as_paren; - case node::expr_size: return *lhs.as_size == *rhs.as_size; - case node::expr_field: return *lhs.as_field == *rhs.as_field; - case node::expr_array: return *lhs.as_array == *rhs.as_array; - default: return false; - } -} - -auto expr::loc() const -> location -{ - return as_node->loc(); -} - -auto expr::kind() const -> node::type -{ - return as_node->kind(); -} - -auto expr::label() const -> std::string -{ - return as_node->label(); -} - -stmt::stmt() : as_node{ nullptr } -{ -} - -stmt::stmt(std::unique_ptr value) : as_node{ std::move(value) } -{ -} - -stmt::stmt(stmt&& value) -{ - new(&as_node) std::unique_ptr{ std::move(value.as_node) }; -} - -stmt& stmt::operator=(stmt&& value) -{ - new(&as_node) std::unique_ptr{ std::move(value.as_node) }; - return *(stmt*)&as_node; -} - -stmt::~stmt() -{ - if (as_node == nullptr) return; - - switch (as_node->kind()) - { - case node::null: as_node.~unique_ptr(); return; - case node::stmt_list: as_list.~unique_ptr(); return; - case node::stmt_comp: as_comp.~unique_ptr(); return; - case node::stmt_dev: as_dev.~unique_ptr(); return; - case node::stmt_expr: as_expr.~unique_ptr(); return; - case node::stmt_call: as_call.~unique_ptr(); return; - case node::stmt_assign: as_assign.~unique_ptr(); return; - case node::stmt_endon: as_endon.~unique_ptr(); return; - case node::stmt_notify: as_notify.~unique_ptr(); return; - case node::stmt_wait: as_wait.~unique_ptr(); return; - case node::stmt_waittill: as_waittill.~unique_ptr(); return; - case node::stmt_waittillmatch: as_waittillmatch.~unique_ptr(); return; - case node::stmt_waittillframeend: as_waittillframeend.~unique_ptr(); return; - case node::stmt_waitframe: as_waitframe.~unique_ptr(); return; - case node::stmt_if: as_if.~unique_ptr(); return; - case node::stmt_ifelse: as_ifelse.~unique_ptr(); return; - case node::stmt_while: as_while.~unique_ptr(); return; - case node::stmt_dowhile: as_dowhile.~unique_ptr(); return; - case node::stmt_for: as_for.~unique_ptr(); return; - case node::stmt_foreach: as_foreach.~unique_ptr(); return; - case node::stmt_switch: as_switch.~unique_ptr(); return; - case node::stmt_case: as_case.~unique_ptr(); return; - case node::stmt_default: as_default.~unique_ptr(); return; - case node::stmt_break: as_break.~unique_ptr(); return; - case node::stmt_continue: as_continue.~unique_ptr(); return; - case node::stmt_return: as_return.~unique_ptr(); return; - case node::stmt_breakpoint: as_breakpoint.~unique_ptr(); return; - case node::stmt_prof_begin: as_prof_begin.~unique_ptr(); return; - case node::stmt_prof_end: as_prof_end.~unique_ptr(); return; - case node::stmt_assert: as_assert.~unique_ptr(); return; - case node::stmt_assertex: as_assertex.~unique_ptr(); return; - case node::stmt_assertmsg: as_assertmsg.~unique_ptr(); return; - case node::asm_jmp: as_jump.~unique_ptr(); return; - case node::asm_jmp_back: as_jump_back.~unique_ptr(); return; - case node::asm_jmp_cond: as_cond.~unique_ptr(); return; - case node::asm_switch: as_asm_switch.~unique_ptr(); return; - case node::asm_endswitch: as_asm_endswitch.~unique_ptr(); return; - case node::asm_create: as_asm_create.~unique_ptr(); return; - case node::asm_access: as_asm_access.~unique_ptr(); return; - case node::asm_remove: as_asm_remove.~unique_ptr(); return; - case node::asm_clear: as_asm_clear.~unique_ptr(); return; - default: return; - } -} - -auto operator==(stmt const& lhs, node::type rhs) -> bool -{ - return *lhs.as_node == rhs; -} - -auto stmt::loc() const -> location -{ - return as_node->loc(); -} - -auto stmt::kind() const -> node::type -{ - return as_node->kind(); -} - -auto stmt::label() const -> std::string -{ - return as_node->label(); -} - -decl::decl() : as_node{ nullptr } -{ -} - -decl::decl(std::unique_ptr value) : as_node{ std::move(value) } -{ -} - -decl::decl(decl&& value) -{ - new(&as_node) std::unique_ptr{ std::move(value.as_node) }; -} - -decl& decl::operator=(decl&& value) -{ - new(&as_node) std::unique_ptr{ std::move(value.as_node) }; - return *(decl*)&as_node; -} - -decl::~decl() -{ - if (as_node == nullptr) return; - - switch (as_node->kind()) - { - case node::null: as_node.~unique_ptr(); return; - case node::decl_dev_begin: as_dev_begin.~unique_ptr(); return; - case node::decl_dev_end: as_dev_end.~unique_ptr(); return; - case node::decl_function: as_function.~unique_ptr(); return; - case node::decl_constant: as_constant.~unique_ptr(); return; - case node::decl_usingtree: as_usingtree.~unique_ptr(); return; - default: return; - } -} - -auto operator==(decl const& lhs, node::type rhs) -> bool -{ - return *lhs.as_node == rhs; -} - -auto decl::loc() const -> location -{ - return as_node->loc(); -} - -auto decl::kind() const -> node::type -{ - return as_node->kind(); -} - -auto decl::label() const -> std::string -{ - return as_node->label(); -} - } // namespace xsk::gsc diff --git a/src/gsc/compiler.cpp b/src/gsc/compiler.cpp index 8da9917a..23fb0ae0 100644 --- a/src/gsc/compiler.cpp +++ b/src/gsc/compiler.cpp @@ -50,28 +50,28 @@ auto compiler::emit_program(program const& prog) -> void for (auto const& dec : prog.declarations) { - if (dec == node::decl_function) + if (dec->is()) { - auto const& name = dec.as_function->name->value; + auto const& name = dec->as().name->value; if (ctx_->func_exists(name) || ctx_->meth_exists(name)) { - throw comp_error(dec.loc(), fmt::format("function name '{}' already defined as builtin", name)); + throw comp_error(dec->loc(), fmt::format("function name '{}' already defined as builtin", name)); } for (auto const& entry : localfuncs_) { if (entry == name) - throw comp_error(dec.loc(), fmt::format("function name '{}' already defined as local function", name)); + throw comp_error(dec->loc(), fmt::format("function name '{}' already defined as local function", name)); } - localfuncs_.push_back(dec.as_function->name->value); + localfuncs_.push_back(dec->as().name->value); } } for (auto const& dec : prog.declarations) { - emit_decl(dec); + emit_decl(*dec); } } @@ -86,13 +86,13 @@ auto compiler::emit_decl(decl const& dec) -> void developer_thread_ = false; break; case node::decl_usingtree: - emit_decl_usingtree(*dec.as_usingtree); + emit_decl_usingtree(dec.as()); break; case node::decl_constant: - emit_decl_constant(*dec.as_constant); + emit_decl_constant(dec.as()); break; case node::decl_function: - emit_decl_function(*dec.as_function); + emit_decl_function(dec.as()); break; default: throw comp_error(dec.loc(), "unknown declaration"); @@ -115,7 +115,7 @@ auto compiler::emit_decl_constant(decl_constant const& constant) -> void if (it != constants_.end()) throw comp_error(constant.loc(), fmt::format("duplicated constant '{}'", constant.name->value)); - constants_.insert({ constant.name->value, &constant.value }); + constants_.insert({ constant.name->value, constant.value.get() }); } auto compiler::emit_decl_function(decl_function const& func) -> void @@ -150,97 +150,91 @@ auto compiler::emit_stmt(stmt const& stm, scope& scp, bool last) -> void switch (stm.kind()) { case node::stmt_list: - emit_stmt_list(*stm.as_list, scp, last); + emit_stmt_list(stm.as(), scp, last); break; case node::stmt_comp: - emit_stmt_comp(*stm.as_comp, scp, last); + emit_stmt_comp(stm.as(), scp, last); break; case node::stmt_dev: - emit_stmt_dev(*stm.as_dev, scp, last); + emit_stmt_dev(stm.as(), scp, last); break; case node::stmt_expr: - emit_stmt_expr(*stm.as_expr, scp); - break; - case node::stmt_call: - emit_stmt_call(*stm.as_call, scp); - break; - case node::stmt_assign: - emit_stmt_assign(*stm.as_assign, scp); + emit_stmt_expr(stm.as(), scp); break; case node::stmt_endon: - emit_stmt_endon(*stm.as_endon, scp); + emit_stmt_endon(stm.as(), scp); break; case node::stmt_notify: - emit_stmt_notify(*stm.as_notify, scp); + emit_stmt_notify(stm.as(), scp); break; case node::stmt_wait: - emit_stmt_wait(*stm.as_wait, scp); + emit_stmt_wait(stm.as(), scp); break; case node::stmt_waittill: - emit_stmt_waittill(*stm.as_waittill, scp); + emit_stmt_waittill(stm.as(), scp); break; case node::stmt_waittillmatch: - emit_stmt_waittillmatch(*stm.as_waittillmatch, scp); + emit_stmt_waittillmatch(stm.as(), scp); break; case node::stmt_waittillframeend: - emit_stmt_waittillframeend(*stm.as_waittillframeend, scp); + emit_stmt_waittillframeend(stm.as(), scp); break; case node::stmt_waitframe: - emit_stmt_waitframe(*stm.as_waitframe, scp); + emit_stmt_waitframe(stm.as(), scp); break; case node::stmt_if: - emit_stmt_if(*stm.as_if, scp, last); + emit_stmt_if(stm.as(), scp, last); break; case node::stmt_ifelse: - emit_stmt_ifelse(*stm.as_ifelse, scp, last); + emit_stmt_ifelse(stm.as(), scp, last); break; case node::stmt_while: - emit_stmt_while(*stm.as_while, scp); + emit_stmt_while(stm.as(), scp); break; case node::stmt_dowhile: - emit_stmt_dowhile(*stm.as_dowhile, scp); + emit_stmt_dowhile(stm.as(), scp); break; case node::stmt_for: - emit_stmt_for(*stm.as_for, scp); + emit_stmt_for(stm.as(), scp); break; case node::stmt_foreach: - emit_stmt_foreach(*stm.as_foreach, scp); + emit_stmt_foreach(stm.as(), scp); break; case node::stmt_switch: - emit_stmt_switch(*stm.as_switch, scp); + emit_stmt_switch(stm.as(), scp); break; case node::stmt_case: - emit_stmt_case(*stm.as_case, scp); + emit_stmt_case(stm.as(), scp); break; case node::stmt_default: - emit_stmt_default(*stm.as_default, scp); + emit_stmt_default(stm.as(), scp); break; case node::stmt_break: - emit_stmt_break(*stm.as_break, scp); + emit_stmt_break(stm.as(), scp); break; case node::stmt_continue: - emit_stmt_continue(*stm.as_continue, scp); + emit_stmt_continue(stm.as(), scp); break; case node::stmt_return: - emit_stmt_return(*stm.as_return, scp); + emit_stmt_return(stm.as(), scp); break; case node::stmt_breakpoint: - emit_stmt_breakpoint(*stm.as_breakpoint, scp); + emit_stmt_breakpoint(stm.as(), scp); break; case node::stmt_prof_begin: - emit_stmt_prof_begin(*stm.as_prof_begin, scp); + emit_stmt_prof_begin(stm.as(), scp); break; case node::stmt_prof_end: - emit_stmt_prof_end(*stm.as_prof_end, scp); + emit_stmt_prof_end(stm.as(), scp); break; case node::stmt_assert: - emit_stmt_assert(*stm.as_assert, scp); + emit_stmt_assert(stm.as(), scp); break; case node::stmt_assertex: - emit_stmt_assertex(*stm.as_assertex, scp); + emit_stmt_assertex(stm.as(), scp); break; case node::stmt_assertmsg: - emit_stmt_assertmsg(*stm.as_assertmsg, scp); + emit_stmt_assertmsg(stm.as(), scp); break; default: throw comp_error(stm.loc(), "unknown statement"); @@ -251,7 +245,7 @@ auto compiler::emit_stmt_list(stmt_list const& stm, scope& scp, bool last) -> vo { for (auto const& entry : stm.list) { - emit_stmt(entry, scp, (&entry == &stm.list.back() && last) ? true : false); + emit_stmt(*entry, scp, (&entry == &stm.list.back() && last) ? true : false); } } @@ -267,76 +261,34 @@ auto compiler::emit_stmt_dev(stmt_dev const& stm, scope& scp, bool last) -> void auto compiler::emit_stmt_expr(stmt_expr const& stm, scope& scp) -> void { - switch (stm.value.kind()) + switch (stm.value->kind()) { case node::expr_increment: - emit_expr_increment(*stm.value.as_increment, scp, true); + emit_expr_increment(stm.value->as(), scp, true); break; case node::expr_decrement: - emit_expr_decrement(*stm.value.as_decrement, scp, true); + emit_expr_decrement(stm.value->as(), scp, true); break; - case node::expr_assign_equal: - case node::expr_assign_add: - case node::expr_assign_sub: - case node::expr_assign_mul: - case node::expr_assign_div: - case node::expr_assign_mod: - case node::expr_assign_shift_left: - case node::expr_assign_shift_right: - case node::expr_assign_bitwise_or: - case node::expr_assign_bitwise_and: - case node::expr_assign_bitwise_exor: - emit_expr_assign(*stm.value.as_assign, scp); + case node::expr_assign: + emit_expr_assign(stm.value->as(), scp); break; - case node::null: + case node::expr_call: + emit_expr_call(stm.value->as(), scp, true); + break; + case node::expr_method: + emit_expr_method(stm.value->as(), scp, true); + break; + case node::expr_empty: break; default: throw comp_error(stm.loc(), "unknown expr statement expression"); } } -auto compiler::emit_stmt_call(stmt_call const& stm, scope& scp) -> void -{ - if (stm.value == node::expr_call) - emit_expr_call(*stm.value.as_call, scp, true); - else if (stm.value == node::expr_method) - emit_expr_method(*stm.value.as_method, scp, true); - else - throw comp_error(stm.loc(), "unknown call statement expression"); -} - -auto compiler::emit_stmt_assign(stmt_assign const& stm, scope& scp) -> void -{ - switch (stm.value.kind()) - { - case node::expr_increment: - emit_expr_increment(*stm.value.as_increment, scp, true); - break; - case node::expr_decrement: - emit_expr_decrement(*stm.value.as_decrement, scp, true); - break; - case node::expr_assign_equal: - case node::expr_assign_add: - case node::expr_assign_sub: - case node::expr_assign_mul: - case node::expr_assign_div: - case node::expr_assign_mod: - case node::expr_assign_shift_left: - case node::expr_assign_shift_right: - case node::expr_assign_bitwise_or: - case node::expr_assign_bitwise_and: - case node::expr_assign_bitwise_exor: - emit_expr_assign(*stm.value.as_assign, scp); - break; - default: - throw comp_error(stm.loc(), "unknown assign statement expression"); - } -} - auto compiler::emit_stmt_endon(stmt_endon const& stm, scope& scp) -> void { - emit_expr(stm.event, scp); - emit_expr(stm.obj, scp); + emit_expr(*stm.event, scp); + emit_expr(*stm.obj, scp); emit_opcode(opcode::OP_endon); } @@ -344,38 +296,31 @@ auto compiler::emit_stmt_notify(stmt_notify const& stm, scope& scp) -> void { emit_opcode(opcode::OP_voidCodepos); - // std::reverse(stm.args->list.begin(), stm.args->list.end()); - - // for (auto const& arg : stm.args->list) // use reverse range later!! - // { - // emit_expr(arg, scp); - // } - - for (auto it = stm.args->list.rbegin(); it != stm.args->list.rend(); ++it) + for (auto it = stm.args->list.rbegin(); it != stm.args->list.rend(); it++) { - emit_expr(*it, scp); + emit_expr(**it, scp); } - emit_expr(stm.event, scp); - emit_expr(stm.obj, scp); + emit_expr(*stm.event, scp); + emit_expr(*stm.obj, scp); emit_opcode(opcode::OP_notify); } auto compiler::emit_stmt_wait(stmt_wait const& stm, scope& scp) -> void { - emit_expr(stm.time, scp); + emit_expr(*stm.time, scp); emit_opcode(opcode::OP_wait); } auto compiler::emit_stmt_waittill(stmt_waittill const& stm, scope& scp) -> void { - emit_expr(stm.event, scp); - emit_expr(stm.obj, scp); + emit_expr(*stm.event, scp); + emit_expr(*stm.obj, scp); emit_opcode(opcode::OP_waittill); for (auto const& entry : stm.args->list) { - emit_opcode(opcode::OP_SafeSetWaittillVariableFieldCached, fmt::format("{}", variable_create(*entry.as_identifier, scp))); + emit_opcode(opcode::OP_SafeSetWaittillVariableFieldCached, fmt::format("{}", variable_create(entry->as(), scp))); } emit_opcode(opcode::OP_clearparams); @@ -384,8 +329,8 @@ auto compiler::emit_stmt_waittill(stmt_waittill const& stm, scope& scp) -> void auto compiler::emit_stmt_waittillmatch(stmt_waittillmatch const& stm, scope& scp) -> void { emit_expr_arguments(*stm.args, scp); - emit_expr(stm.event, scp); - emit_expr(stm.obj, scp); + emit_expr(*stm.event, scp); + emit_expr(*stm.obj, scp); emit_opcode(opcode::OP_waittillmatch, fmt::format("{}", stm.args->list.size())); emit_opcode(opcode::OP_waittillmatch2); emit_opcode(opcode::OP_clearparams); @@ -405,22 +350,22 @@ auto compiler::emit_stmt_if(stmt_if const& stm, scope& scp, bool last) -> void { auto end_loc = create_label(); - if (stm.test == node::expr_not) + if (stm.test->is()) { - emit_expr(stm.test.as_not->rvalue, scp); + emit_expr(*stm.test->as().rvalue, scp); emit_opcode(opcode::OP_JumpOnTrue, end_loc); } else { - emit_expr(stm.test, scp); + emit_expr(*stm.test, scp); emit_opcode(opcode::OP_JumpOnFalse, end_loc); } - auto& scp_body = scopes_.at(stm.body.as_node.get()); + auto& scp_body = scopes_.at(stm.body.get()); scp.transfer(scp_body); - emit_stmt(stm.body, *scp_body, last); + emit_stmt(*stm.body, *scp_body, last); last ? emit_opcode(opcode::OP_End) : emit_remove_local_vars(*scp_body); @@ -433,22 +378,22 @@ auto compiler::emit_stmt_ifelse(stmt_ifelse const& stm, scope& scp, bool last) - auto else_loc = create_label(); auto end_loc = create_label(); - if (stm.test == node::expr_not) + if (stm.test->is()) { - emit_expr(stm.test.as_not->rvalue, scp); + emit_expr(*stm.test->as().rvalue, scp); emit_opcode(opcode::OP_JumpOnTrue, else_loc); } else { - emit_expr(stm.test, scp); + emit_expr(*stm.test, scp); emit_opcode(opcode::OP_JumpOnFalse, else_loc); } - auto& scp_then = scopes_.at(stm.stmt_if.as_node.get()); + auto& scp_then = scopes_.at(stm.stmt_if.get()); scp.transfer(scp_then); - emit_stmt(stm.stmt_if, *scp_then, last); + emit_stmt(*stm.stmt_if, *scp_then, last); emit_remove_local_vars(*scp_then); @@ -459,11 +404,11 @@ auto compiler::emit_stmt_ifelse(stmt_ifelse const& stm, scope& scp, bool last) - insert_label(else_loc); - auto& scp_else = scopes_.at(stm.stmt_else.as_node.get()); + auto& scp_else = scopes_.at(stm.stmt_else.get()); scp.transfer(scp_else); - emit_stmt(stm.stmt_else, *scp_else, last); + emit_stmt(*stm.stmt_else, *scp_else, last); last ? emit_opcode(opcode::OP_End) : emit_remove_local_vars(*scp_else); @@ -489,7 +434,7 @@ auto compiler::emit_stmt_while(stmt_while const& stm, scope& scp) -> void auto break_loc = create_label(); auto continue_loc = create_label(); - auto& scp_body = scopes_.at(stm.body.as_node.get()); + auto& scp_body = scopes_.at(stm.body.get()); scp.transfer(scp_body); scp_body->loc_break = break_loc; @@ -501,23 +446,23 @@ auto compiler::emit_stmt_while(stmt_while const& stm, scope& scp) -> void auto begin_loc = insert_label(); - bool const_cond = is_constant_condition(stm.test); + bool const_cond = is_constant_condition(*stm.test); if (!const_cond) { - if (stm.test == node::expr_not) + if (stm.test->is()) { - emit_expr(stm.test.as_not->rvalue, scp); + emit_expr(*stm.test->as().rvalue, scp); emit_opcode(opcode::OP_JumpOnTrue, break_loc); } else { - emit_expr(stm.test, scp); + emit_expr(*stm.test, scp); emit_opcode(opcode::OP_JumpOnFalse, break_loc); } } - emit_stmt(stm.body, *scp_body, false); + emit_stmt(*stm.body, *scp_body, false); insert_label(continue_loc); emit_opcode(opcode::OP_jumpback, begin_loc); @@ -547,7 +492,7 @@ auto compiler::emit_stmt_dowhile(stmt_dowhile const& stm, scope& scp) -> void auto break_loc = create_label(); auto continue_loc = create_label(); - auto& scp_body = scopes_.at(stm.body.as_node.get()); + auto& scp_body = scopes_.at(stm.body.get()); scp.transfer(scp_body); scp_body->loc_break = break_loc; @@ -559,22 +504,22 @@ auto compiler::emit_stmt_dowhile(stmt_dowhile const& stm, scope& scp) -> void auto begin_loc = insert_label(); - emit_stmt(stm.body, *scp_body, false); + emit_stmt(*stm.body, *scp_body, false); insert_label(continue_loc); - bool const_cond = is_constant_condition(stm.test); + bool const_cond = is_constant_condition(*stm.test); if (!const_cond) { - if (stm.test == node::expr_not) + if (stm.test->is()) { - emit_expr(stm.test.as_not->rvalue, scp); + emit_expr(*stm.test->as().rvalue, scp); emit_opcode(opcode::OP_JumpOnTrue, break_loc); } else { - emit_expr(stm.test, scp); + emit_expr(*stm.test, scp); emit_opcode(opcode::OP_JumpOnFalse, break_loc); } } @@ -606,9 +551,9 @@ auto compiler::emit_stmt_for(stmt_for const& stm, scope& scp) -> void auto break_loc = create_label(); auto continue_loc = create_label(); - emit_stmt(stm.init, scp, false); + emit_stmt(*stm.init, scp, false); - auto& scp_body = scopes_.at(stm.body.as_node.get()); + auto& scp_body = scopes_.at(stm.body.get()); scp.transfer(scp_body); scp_body->loc_break = break_loc; @@ -618,24 +563,24 @@ auto compiler::emit_stmt_for(stmt_for const& stm, scope& scp) -> void scp.init(scp_body); - auto& scp_iter = scopes_.at(stm.iter.as_node.get()); + auto& scp_iter = scopes_.at(stm.iter.get()); scp.transfer(scp_iter); auto begin_loc = insert_label(); - bool const_cond = is_constant_condition(stm.test); + bool const_cond = is_constant_condition(*stm.test); if (!const_cond) { - if (stm.test == node::expr_not) + if (stm.test->is()) { - emit_expr(stm.test.as_not->rvalue, scp); + emit_expr(*stm.test->as().rvalue, scp); emit_opcode(opcode::OP_JumpOnTrue, break_loc); } else { - emit_expr(stm.test, scp); + emit_expr(*stm.test, scp); emit_opcode(opcode::OP_JumpOnFalse, break_loc); } } @@ -643,7 +588,7 @@ auto compiler::emit_stmt_for(stmt_for const& stm, scope& scp) -> void can_break_ = true; can_continue_ = true; - emit_stmt(stm.body, *scp_body, false); + emit_stmt(*stm.body, *scp_body, false); if (scp_body->abort == scope::abort_none) continue_blks_.push_back(scp_body.get()); @@ -655,7 +600,7 @@ auto compiler::emit_stmt_for(stmt_for const& stm, scope& scp) -> void scp_iter->init(continue_blks_); - emit_stmt(stm.iter, *scp_iter, false); + emit_stmt(*stm.iter, *scp_iter, false); emit_opcode(opcode::OP_jumpback, begin_loc); insert_label(break_loc); @@ -683,25 +628,25 @@ auto compiler::emit_stmt_foreach(stmt_foreach const& stm, scope& scp) -> void auto break_loc = create_label(); auto continue_loc = create_label(); - emit_expr(stm.container, scp); - emit_expr_variable_ref(stm.array, scp, true); - emit_expr_variable(stm.array, scp); + emit_expr(*stm.container, scp); + emit_expr_variable_ref(*stm.array, scp, true); + emit_expr_variable(*stm.array, scp); if (ctx_->props() & props::farcall) emit_opcode(opcode::OP_CallBuiltin, { "getfirstarraykey"s, "1"s }); else emit_opcode(opcode::OP_CallBuiltin1, "getfirstarraykey"); - emit_expr_variable_ref(stm.key, scp, true); + emit_expr_variable_ref(*stm.key, scp, true); if (ctx_->props() & props::foreach && stm.use_key) { emit_opcode(opcode::OP_GetUndefined); - emit_expr_variable_ref(stm.index, scp, true); + emit_expr_variable_ref(*stm.index, scp, true); } - auto& scp_body = scopes_.at(stm.body.as_node.get()); - auto& scp_iter = scopes_.at(stm.key.as_node.get()); + auto& scp_body = scopes_.at(stm.body.get()); + auto& scp_iter = scopes_.at(stm.key.get()); scp.transfer(scp_body); scp_body->loc_break = break_loc; @@ -715,7 +660,7 @@ auto compiler::emit_stmt_foreach(stmt_foreach const& stm, scope& scp) -> void auto begin_loc = insert_label(); - emit_expr_variable(stm.key, scp); + emit_expr_variable(*stm.key, scp); if (ctx_->props() & props::boolfuncs) emit_opcode(opcode::OP_IsDefined); @@ -727,17 +672,17 @@ auto compiler::emit_stmt_foreach(stmt_foreach const& stm, scope& scp) -> void can_break_ = true; can_continue_ = true; - emit_expr_variable(stm.key, *scp_body); - emit_opcode(opcode::OP_EvalLocalArrayCached, fmt::format("{}", variable_access(*stm.array.as_identifier, *scp_body))); - emit_expr_variable_ref(stm.value, *scp_body, true); + emit_expr_variable(*stm.key, *scp_body); + emit_opcode(opcode::OP_EvalLocalArrayCached, fmt::format("{}", variable_access(stm.array->as(), *scp_body))); + emit_expr_variable_ref(*stm.value, *scp_body, true); if (ctx_->props() & props::foreach && stm.use_key) { - emit_expr_variable(stm.key, *scp_body); - emit_expr_variable_ref(stm.index, *scp_body, true); + emit_expr_variable(*stm.key, *scp_body); + emit_expr_variable_ref(*stm.index, *scp_body, true); } - emit_stmt(stm.body, *scp_body, false); + emit_stmt(*stm.body, *scp_body, false); if (scp_body->abort == scope::abort_none) continue_blks_.push_back(scp_body.get()); @@ -749,20 +694,20 @@ auto compiler::emit_stmt_foreach(stmt_foreach const& stm, scope& scp) -> void scp_iter->init(continue_blks_); - emit_expr_variable(stm.key, *scp_iter); - emit_expr_variable(stm.array, *scp_iter); + emit_expr_variable(*stm.key, *scp_iter); + emit_expr_variable(*stm.array, *scp_iter); if (ctx_->props() & props::farcall) emit_opcode(opcode::OP_CallBuiltin, { "getnextarraykey"s, "2"s }); else emit_opcode(opcode::OP_CallBuiltin2, "getnextarraykey"); - emit_expr_variable_ref(stm.key, *scp_iter, true); + emit_expr_variable_ref(*stm.key, *scp_iter, true); emit_opcode(opcode::OP_jumpback, begin_loc); insert_label(break_loc); - emit_expr_clear_local(*stm.array.as_identifier, scp); - if (ctx_->props() & props::foreach || !stm.use_key) emit_expr_clear_local(*stm.key.as_identifier, scp); + emit_expr_clear_local(stm.array->as(), scp); + if (ctx_->props() & props::foreach || !stm.use_key) emit_expr_clear_local(stm.key->as(), scp); can_break_ = old_break; can_continue_ = old_continue; @@ -780,7 +725,7 @@ auto compiler::emit_stmt_switch(stmt_switch const& stm, scope& scp) -> void auto table_loc = create_label(); auto break_loc = create_label(); - emit_expr(stm.test, scp); + emit_expr(*stm.test, scp); emit_opcode(opcode::OP_switch, table_loc); can_break_ = true; @@ -797,11 +742,11 @@ auto compiler::emit_stmt_switch(stmt_switch const& stm, scope& scp) -> void { auto const& entry = stm.body->block->list[i]; - if (entry == node::stmt_case) + if (entry->is()) { data.push_back("case"); - if (entry.as_case->value == node::expr_integer) + if (entry->as().value->is()) { if (ctx_->engine() == engine::iw9) { @@ -811,16 +756,16 @@ auto compiler::emit_stmt_switch(stmt_switch const& stm, scope& scp) -> void { if (type == switch_type::string) { - throw comp_error(entry.loc(), "switch cases with different types"); + throw comp_error(entry->loc(), "switch cases with different types"); } type = switch_type::integer; } - data.push_back(entry.as_case->value.as_integer->value); + data.push_back(entry->as().value->as().value); data.push_back(insert_label()); } - else if (entry.as_case->value == node::expr_string) + else if (entry->as().value->is()) { if (ctx_->engine() == engine::iw9) { @@ -830,48 +775,48 @@ auto compiler::emit_stmt_switch(stmt_switch const& stm, scope& scp) -> void { if (type == switch_type::integer) { - throw comp_error(entry.loc(), "switch cases with different types"); + throw comp_error(entry->loc(), "switch cases with different types"); } type = switch_type::string; } - data.push_back(entry.as_case->value.as_string->value); + data.push_back(entry->as().value->as().value); data.push_back(insert_label()); } else { - throw comp_error(entry.loc(), "case type must be int or string"); + throw comp_error(entry->loc(), "case type must be int or string"); } - auto& scp_body = scopes_.at(entry.as_case->body.get()); + auto& scp_body = scopes_.at(entry->as().body.get()); scp.transfer(scp_body); scp_body->loc_break = break_loc; - emit_stmt_list(*entry.as_case->body, *scp_body, false); + emit_stmt_list(*entry->as().body, *scp_body, false); - if (entry.as_case->body->list.size() > 0) + if (entry->as().body->list.size() > 0) emit_remove_local_vars(*scp_body); } - else if (entry == node::stmt_default) + else if (entry->is()) { loc_default = insert_label(); has_default = true; - auto& scp_body = scopes_.at(entry.as_default->body.get()); + auto& scp_body = scopes_.at(entry->as().body.get()); default_ctx = scp_body.get(); scp.transfer(scp_body); scp_body->loc_break = break_loc; - emit_stmt_list(*entry.as_default->body, *scp_body, false); + emit_stmt_list(*entry->as().body, *scp_body, false); - if (entry.as_default->body->list.size() > 0) + if (entry->as().body->list.size() > 0) emit_remove_local_vars(*scp_body); } else { - throw comp_error(entry.loc(), "missing case statement"); + throw comp_error(entry->loc(), "missing case statement"); } } @@ -939,9 +884,9 @@ auto compiler::emit_stmt_return(stmt_return const& stm, scope& scp) -> void if (scp.abort == scope::abort_none) scp.abort = scope::abort_return; - if (stm.value != node::null) + if (!stm.value->is()) { - emit_expr(stm.value, scp); + emit_expr(*stm.value, scp); emit_opcode(opcode::OP_Return); } else @@ -983,70 +928,49 @@ auto compiler::emit_expr(expr const& exp, scope& scp) -> void switch (exp.kind()) { case node::expr_paren: - emit_expr(exp.as_paren->value, scp); + emit_expr(*exp.as().value, scp); break; case node::expr_ternary: - emit_expr_ternary(*exp.as_ternary, scp); + emit_expr_ternary(exp.as(), scp); break; - case node::expr_and: - emit_expr_and(*exp.as_and, scp); - break; - case node::expr_or: - emit_expr_or(*exp.as_or, scp); - break; - case node::expr_equality: - case node::expr_inequality: - case node::expr_less: - case node::expr_greater: - case node::expr_less_equal: - case node::expr_greater_equal: - case node::expr_bitwise_or: - case node::expr_bitwise_and: - case node::expr_bitwise_exor: - case node::expr_shift_left: - case node::expr_shift_right: - case node::expr_add: - case node::expr_sub: - case node::expr_mul: - case node::expr_div: - case node::expr_mod: - emit_expr_binary(*exp.as_binary, scp); + case node::expr_binary: + emit_expr_binary(exp.as(), scp); break; case node::expr_complement: - emit_expr_complement(*exp.as_complement, scp); + emit_expr_complement(exp.as(), scp); break; case node::expr_negate: - emit_expr_negate(*exp.as_negate, scp); + emit_expr_negate(exp.as(), scp); break; case node::expr_not: - emit_expr_not(*exp.as_not, scp); + emit_expr_not(exp.as(), scp); break; case node::expr_call: - emit_expr_call(*exp.as_call, scp, false); + emit_expr_call(exp.as(), scp, false); break; case node::expr_method: - emit_expr_method(*exp.as_method, scp, false); + emit_expr_method(exp.as(), scp, false); break; case node::expr_isdefined: - emit_expr_isdefined(*exp.as_isdefined, scp); + emit_expr_isdefined(exp.as(), scp); break; case node::expr_istrue: - emit_expr_istrue(*exp.as_istrue, scp); + emit_expr_istrue(exp.as(), scp); break; case node::expr_reference: - emit_expr_reference(*exp.as_reference, scp); + emit_expr_reference(exp.as(), scp); break; case node::expr_add_array: - emit_expr_add_array(*exp.as_add_array, scp); + emit_expr_add_array(exp.as(), scp); break; case node::expr_array: - emit_expr_array(*exp.as_array, scp); + emit_expr_array(exp.as(), scp); break; case node::expr_field: - emit_expr_field(*exp.as_field, scp); + emit_expr_field(exp.as(), scp); break; case node::expr_size: - emit_expr_size(*exp.as_size, scp); + emit_expr_size(exp.as(), scp); break; case node::expr_thisthread: emit_opcode(opcode::OP_GetThisthread); @@ -1070,36 +994,36 @@ auto compiler::emit_expr(expr const& exp, scope& scp) -> void emit_opcode(opcode::OP_GetLevel); break; case node::expr_animation: - emit_expr_animation(*exp.as_animation); + emit_expr_animation(exp.as()); break; case node::expr_animtree: - emit_expr_animtree(*exp.as_animtree); + emit_expr_animtree(exp.as()); break; case node::expr_identifier: - emit_expr_local(*exp.as_identifier, scp); + emit_expr_local(exp.as(), scp); break; case node::expr_istring: - emit_expr_istring(*exp.as_istring); + emit_expr_istring(exp.as()); break; case node::expr_string: - emit_expr_string(*exp.as_string); + emit_expr_string(exp.as()); break; case node::expr_vector: - emit_expr_vector(*exp.as_vector, scp); + emit_expr_vector(exp.as(), scp); break; case node::expr_float: - emit_expr_float(*exp.as_float); + emit_expr_float(exp.as()); break; case node::expr_integer: - emit_expr_integer(*exp.as_integer); + emit_expr_integer(exp.as()); break; case node::expr_false: - emit_expr_false(*exp.as_false); + emit_expr_false(exp.as()); break; case node::expr_true: - emit_expr_true(*exp.as_true); + emit_expr_true(exp.as()); break; - case node::null: + case node::expr_empty: break; default: throw comp_error(exp.loc(), "unknown expression"); @@ -1108,66 +1032,66 @@ auto compiler::emit_expr(expr const& exp, scope& scp) -> void auto compiler::emit_expr_assign(expr_assign const& exp, scope& scp) -> void { - if (exp.kind() == node::expr_assign_equal) + if (exp.oper == expr_assign::op::eq) { - if (exp.rvalue == node::expr_undefined) + if (exp.rvalue->is()) { - emit_expr_clear(exp.lvalue, scp); + emit_expr_clear(*exp.lvalue, scp); } - else if (exp.lvalue == node::expr_tuple) + else if (exp.lvalue->is()) { - emit_expr(exp.rvalue, scp); - emit_expr_tuple(*exp.lvalue.as_tuple, scp); + emit_expr(*exp.rvalue, scp); + emit_expr_tuple(exp.lvalue->as(), scp); } else { - emit_expr(exp.rvalue, scp); - emit_expr_variable_ref(exp.lvalue, scp, true); + emit_expr(*exp.rvalue, scp); + emit_expr_variable_ref(*exp.lvalue, scp, true); } return; } - emit_expr(exp.lvalue, scp); - emit_expr(exp.rvalue, scp); + emit_expr(*exp.lvalue, scp); + emit_expr(*exp.rvalue, scp); - switch (exp.kind()) + switch (exp.oper) { - case node::expr_assign_add: + case expr_assign::op::add: emit_opcode(opcode::OP_plus); break; - case node::expr_assign_sub: + case expr_assign::op::sub: emit_opcode(opcode::OP_minus); break; - case node::expr_assign_mul: + case expr_assign::op::mul: emit_opcode(opcode::OP_multiply); break; - case node::expr_assign_div: + case expr_assign::op::div: emit_opcode(opcode::OP_divide); break; - case node::expr_assign_mod: + case expr_assign::op::mod: emit_opcode(opcode::OP_mod); break; - case node::expr_assign_shift_left: + case expr_assign::op::shl: emit_opcode(opcode::OP_shift_left); break; - case node::expr_assign_shift_right: + case expr_assign::op::shr: emit_opcode(opcode::OP_shift_right); break; - case node::expr_assign_bitwise_or: + case expr_assign::op::bwor: emit_opcode(opcode::OP_bit_or); break; - case node::expr_assign_bitwise_and: + case expr_assign::op::bwand: emit_opcode(opcode::OP_bit_and); break; - case node::expr_assign_bitwise_exor: + case expr_assign::op::bwexor: emit_opcode(opcode::OP_bit_ex_or); break; default: throw comp_error(exp.loc(), "unknown assign operation"); } - emit_expr_variable_ref(exp.lvalue, scp, true); + emit_expr_variable_ref(*exp.lvalue, scp, true); } auto compiler::emit_expr_clear(expr const& exp, scope& scp) -> void @@ -1175,17 +1099,17 @@ auto compiler::emit_expr_clear(expr const& exp, scope& scp) -> void switch (exp.kind()) { case node::expr_array: - emit_expr(exp.as_array->key, scp); - exp.as_array->obj == node::expr_game ? emit_opcode(opcode::OP_GetGameRef) : emit_expr_variable_ref(exp.as_array->obj, scp, false); + emit_expr(*exp.as().key, scp); + exp.as().obj->is() ? emit_opcode(opcode::OP_GetGameRef) : emit_expr_variable_ref(*exp.as().obj, scp, false); emit_opcode(opcode::OP_ClearArray); break; case node::expr_field: - emit_expr_object(exp.as_field->obj, scp); - emit_opcode(opcode::OP_ClearFieldVariable, exp.as_field->field->value); + emit_expr_object(*exp.as().obj, scp); + emit_opcode(opcode::OP_ClearFieldVariable, exp.as().field->value); break; case node::expr_identifier: emit_opcode(opcode::OP_GetUndefined); - emit_expr_local_ref(*exp.as_identifier, scp, true); + emit_expr_local_ref(exp.as(), scp, true); break; default: throw comp_error(exp.loc(), "unknown clear variable lvalue"); @@ -1206,7 +1130,7 @@ auto compiler::emit_expr_increment(expr_increment const& exp, scope& scp, bool i { if (is_stmt) { - emit_expr_variable_ref(exp.lvalue, scp, false); + emit_expr_variable_ref(*exp.lvalue, scp, false); emit_opcode(opcode::OP_inc); emit_opcode(opcode::OP_SetVariableField); } @@ -1220,7 +1144,7 @@ auto compiler::emit_expr_decrement(expr_decrement const& exp, scope& scp, bool i { if (is_stmt) { - emit_expr_variable_ref(exp.lvalue, scp, false); + emit_expr_variable_ref(*exp.lvalue, scp, false); emit_opcode(opcode::OP_dec); emit_opcode(opcode::OP_SetVariableField); } @@ -1235,152 +1159,153 @@ auto compiler::emit_expr_ternary(expr_ternary const& exp, scope& scp) -> void auto else_loc = create_label(); auto end_loc = create_label(); - if (exp.test == node::expr_not) + if (exp.test->is()) { - emit_expr(exp.test.as_not->rvalue, scp); + emit_expr(*exp.test->as().rvalue, scp); emit_opcode(opcode::OP_JumpOnTrue, else_loc); } else { - emit_expr(exp.test, scp); + emit_expr(*exp.test, scp); emit_opcode(opcode::OP_JumpOnFalse, else_loc); } - emit_expr(exp.true_expr, scp); + emit_expr(*exp.true_expr, scp); emit_opcode(opcode::OP_jump, end_loc); insert_label(else_loc); - emit_expr(exp.false_expr, scp); + emit_expr(*exp.false_expr, scp); insert_label(end_loc); } auto compiler::emit_expr_binary(expr_binary const& exp, scope& scp) -> void { - emit_expr(exp.lvalue, scp); - emit_expr(exp.rvalue, scp); - - switch (exp.kind()) + if (exp.oper == expr_binary::op::bool_and) { - case node::expr_equality: - emit_opcode(opcode::OP_equality); - break; - case node::expr_inequality: - emit_opcode(opcode::OP_inequality); - break; - case node::expr_less: - emit_opcode(opcode::OP_less); - break; - case node::expr_greater: - emit_opcode(opcode::OP_greater); - break; - case node::expr_less_equal: - emit_opcode(opcode::OP_less_equal); - break; - case node::expr_greater_equal: - emit_opcode(opcode::OP_greater_equal); - break; - case node::expr_bitwise_or: - emit_opcode(opcode::OP_bit_or); - break; - case node::expr_bitwise_and: - emit_opcode(opcode::OP_bit_and); - break; - case node::expr_bitwise_exor: - emit_opcode(opcode::OP_bit_ex_or); - break; - case node::expr_shift_left: - emit_opcode(opcode::OP_shift_left); - break; - case node::expr_shift_right: - emit_opcode(opcode::OP_shift_right); - break; - case node::expr_add: - emit_opcode(opcode::OP_plus); - break; - case node::expr_sub: - emit_opcode(opcode::OP_minus); - break; - case node::expr_mul: - emit_opcode(opcode::OP_multiply); - break; - case node::expr_div: - emit_opcode(opcode::OP_divide); - break; - case node::expr_mod: - emit_opcode(opcode::OP_mod); - break; - default: - throw comp_error(exp.loc(), "unknown binary expression"); + auto label = create_label(); + + emit_expr(*exp.lvalue, scp); + emit_opcode(opcode::OP_JumpOnFalseExpr, label); + + if (exp.rvalue->is() && (ctx_->props() & props::boolnotand)) + { + emit_expr(*exp.rvalue->as().rvalue, scp); + emit_opcode(opcode::OP_BoolNotAfterAnd); + } + else + { + emit_expr(*exp.rvalue, scp); + emit_opcode(opcode::OP_CastBool); + } + + insert_label(label); } -} - -auto compiler::emit_expr_and(expr_and const& exp, scope& scp) -> void -{ - auto label = create_label(); - - emit_expr(exp.lvalue, scp); - emit_opcode(opcode::OP_JumpOnFalseExpr, label); - - if (exp.rvalue == node::expr_not && (ctx_->props() & props::boolnotand)) + else if (exp.oper == expr_binary::op::bool_or) { - emit_expr(exp.rvalue.as_not->rvalue, scp); - emit_opcode(opcode::OP_BoolNotAfterAnd); + auto label = create_label(); + + emit_expr(*exp.lvalue, scp); + emit_opcode(opcode::OP_JumpOnTrueExpr, label); + + if (exp.rvalue->is() && (ctx_->props() & props::boolnotand)) + { + emit_expr(*exp.rvalue->as().rvalue, scp); + emit_opcode(opcode::OP_BoolNotAfterAnd); + } + else + { + emit_expr(*exp.rvalue, scp); + emit_opcode(opcode::OP_CastBool); + } + + insert_label(label); } else { - emit_expr(exp.rvalue, scp); - emit_opcode(opcode::OP_CastBool); + emit_expr(*exp.lvalue, scp); + emit_expr(*exp.rvalue, scp); + + switch (exp.oper) + { + case expr_binary::op::eq: + emit_opcode(opcode::OP_equality); + break; + case expr_binary::op::ne: + emit_opcode(opcode::OP_inequality); + break; + case expr_binary::op::lt: + emit_opcode(opcode::OP_less); + break; + case expr_binary::op::gt: + emit_opcode(opcode::OP_greater); + break; + case expr_binary::op::le: + emit_opcode(opcode::OP_less_equal); + break; + case expr_binary::op::ge: + emit_opcode(opcode::OP_greater_equal); + break; + case expr_binary::op::bwor: + emit_opcode(opcode::OP_bit_or); + break; + case expr_binary::op::bwand: + emit_opcode(opcode::OP_bit_and); + break; + case expr_binary::op::bwexor: + emit_opcode(opcode::OP_bit_ex_or); + break; + case expr_binary::op::shl: + emit_opcode(opcode::OP_shift_left); + break; + case expr_binary::op::shr: + emit_opcode(opcode::OP_shift_right); + break; + case expr_binary::op::add: + emit_opcode(opcode::OP_plus); + break; + case expr_binary::op::sub: + emit_opcode(opcode::OP_minus); + break; + case expr_binary::op::mul: + emit_opcode(opcode::OP_multiply); + break; + case expr_binary::op::div: + emit_opcode(opcode::OP_divide); + break; + case expr_binary::op::mod: + emit_opcode(opcode::OP_mod); + break; + default: + throw comp_error(exp.loc(), "unknown binary expression"); + } } - - insert_label(label); -} - -auto compiler::emit_expr_or(expr_or const& exp, scope& scp) -> void -{ - auto label = create_label(); - - emit_expr(exp.lvalue, scp); - emit_opcode(opcode::OP_JumpOnTrueExpr, label); - - if (exp.rvalue == node::expr_not && (ctx_->props() & props::boolnotand)) - { - emit_expr(exp.rvalue.as_not->rvalue, scp); - emit_opcode(opcode::OP_BoolNotAfterAnd); - } - else - { - emit_expr(exp.rvalue, scp); - emit_opcode(opcode::OP_CastBool); - } - - insert_label(label); } auto compiler::emit_expr_complement(expr_complement const& exp, scope& scp) -> void { - emit_expr(exp.rvalue, scp); + emit_expr(*exp.rvalue, scp); emit_opcode(opcode::OP_BoolComplement); } auto compiler::emit_expr_negate(expr_negate const& exp, scope& scp) -> void { emit_opcode(opcode::OP_GetZero); - emit_expr(exp.rvalue, scp); + emit_expr(*exp.rvalue, scp); emit_opcode(opcode::OP_minus); } auto compiler::emit_expr_not(expr_not const& exp, scope& scp) -> void { - emit_expr(exp.rvalue, scp); + emit_expr(*exp.rvalue, scp); emit_opcode(opcode::OP_BoolNot); } auto compiler::emit_expr_call(expr_call const& exp, scope& scp, bool is_stmt) -> void { - if (exp.value == node::expr_pointer) - emit_expr_call_pointer(*exp.value.as_pointer, scp, is_stmt); - else if (exp.value == node::expr_function) - emit_expr_call_function(*exp.value.as_function, scp, is_stmt); + if (exp.value->is()) + emit_expr_call_pointer(exp.value->as(), scp, is_stmt); + else if (exp.value->is()) + emit_expr_call_function(exp.value->as(), scp, is_stmt); else throw comp_error(exp.loc(), "unknown function call expression"); } @@ -1391,7 +1316,7 @@ auto compiler::emit_expr_call_pointer(expr_pointer const& exp, scope& scp, bool emit_opcode(opcode::OP_PreScriptCall); emit_expr_arguments(*exp.args, scp); - emit_expr(exp.func, scp); + emit_expr(*exp.func, scp); auto argcount = fmt::format("{}", exp.args->list.size()); @@ -1518,10 +1443,10 @@ auto compiler::emit_expr_call_function(expr_function const& exp, scope& scp, boo auto compiler::emit_expr_method(expr_method const& exp, scope& scp, bool is_stmt) -> void { - if (exp.value == node::expr_pointer) - emit_expr_method_pointer(*exp.value.as_pointer, exp.obj, scp, is_stmt); - else if (exp.value == node::expr_function) - emit_expr_method_function(*exp.value.as_function, exp.obj, scp, is_stmt); + if (exp.value->is()) + emit_expr_method_pointer(exp.value->as(), *exp.obj, scp, is_stmt); + else if (exp.value->is()) + emit_expr_method_function(exp.value->as(), *exp.obj, scp, is_stmt); else throw comp_error(exp.loc(), "unknown method call expression"); } @@ -1533,7 +1458,7 @@ auto compiler::emit_expr_method_pointer(expr_pointer const& exp, expr const& obj emit_expr_arguments(*exp.args, scp); emit_expr(obj, scp); - emit_expr(exp.func, scp); + emit_expr(*exp.func, scp); auto argcount = fmt::format("{}", exp.args->list.size()); @@ -1659,7 +1584,7 @@ auto compiler::emit_expr_add_array(expr_add_array const& exp, scope& scp) -> voi for (auto const& arg : exp.args->list) { - emit_expr(arg, scp); + emit_expr(*arg, scp); emit_opcode(opcode::OP_AddArray); } } @@ -1705,28 +1630,21 @@ auto compiler::emit_expr_parameters(expr_parameters const& exp, scope& scp) -> v auto compiler::emit_expr_arguments(expr_arguments const& exp, scope& scp) -> void { - //std::reverse(exp.list.begin(), exp.list.end()); // use reverse range - - // for (auto const& entry : exp.list) - // { - // emit_expr(entry, scp); - // } - for (auto it = exp.list.rbegin(); it != exp.list.rend(); ++it) { - emit_expr(*it, scp); + emit_expr(**it, scp); } } auto compiler::emit_expr_isdefined(expr_isdefined const& exp, scope& scp) -> void { - emit_expr(exp.value, scp); + emit_expr(*exp.value, scp); emit_opcode(opcode::OP_IsDefined); } auto compiler::emit_expr_istrue(expr_istrue const& exp, scope& scp) -> void { - emit_expr(exp.value, scp); + emit_expr(*exp.value, scp); emit_opcode(opcode::OP_IsTrue); } @@ -1760,13 +1678,13 @@ auto compiler::emit_expr_reference(expr_reference const& exp, scope&) -> void auto compiler::emit_expr_size(expr_size const& exp, scope& scp) -> void { - emit_expr(exp.obj, scp); + emit_expr(*exp.obj, scp); emit_opcode(opcode::OP_size); } auto compiler::emit_expr_tuple(expr_tuple const& exp, scope& scp) -> void { - emit_expr_variable_ref(exp.temp, scp, true); + emit_expr_variable_ref(*exp.temp, scp, true); auto index = 0u; @@ -1779,12 +1697,12 @@ auto compiler::emit_expr_tuple(expr_tuple const& exp, scope& scp) -> void index++; - emit_opcode(opcode::OP_EvalLocalArrayCached, fmt::format("{}", variable_access(*exp.temp.as_identifier, scp))); + emit_opcode(opcode::OP_EvalLocalArrayCached, fmt::format("{}", variable_access(exp.temp->as(), scp))); - emit_expr_variable_ref(entry, scp, true); + emit_expr_variable_ref(*entry, scp, true); } - emit_expr_clear_local(*exp.temp.as_identifier, scp); + emit_expr_clear_local(exp.temp->as(), scp); } auto compiler::emit_expr_variable_ref(expr const& exp, scope& scp, bool set) -> void @@ -1792,13 +1710,13 @@ auto compiler::emit_expr_variable_ref(expr const& exp, scope& scp, bool set) -> switch (exp.kind()) { case node::expr_array: - emit_expr_array_ref(*exp.as_array, scp, set); + emit_expr_array_ref(exp.as(), scp, set); break; case node::expr_field: - emit_expr_field_ref(*exp.as_field, scp, set); + emit_expr_field_ref(exp.as(), scp, set); break; case node::expr_identifier: - emit_expr_local_ref(*exp.as_identifier, scp, set); + emit_expr_local_ref(exp.as(), scp, set); break; default: throw comp_error(exp.loc(), "invalid lvalue"); @@ -1807,9 +1725,9 @@ auto compiler::emit_expr_variable_ref(expr const& exp, scope& scp, bool set) -> auto compiler::emit_expr_array_ref(expr_array const& exp, scope& scp, bool set) -> void { - emit_expr(exp.key, scp); + emit_expr(*exp.key, scp); - switch (exp.obj.kind()) + switch (exp.obj->kind()) { case node::expr_game: emit_opcode(opcode::OP_GetGameRef); @@ -1818,22 +1736,22 @@ auto compiler::emit_expr_array_ref(expr_array const& exp, scope& scp, bool set) break; case node::expr_array: case node::expr_field: - emit_expr_variable_ref(exp.obj, scp, false); + emit_expr_variable_ref(*exp.obj, scp, false); emit_opcode(opcode::OP_EvalArrayRef); if (set) emit_opcode(opcode::OP_SetVariableField); break; case node::expr_identifier: { - if (!variable_initialized(*exp.obj.as_identifier, scp)) + if (!variable_initialized(exp.obj->as(), scp)) { - auto index = variable_initialize(*exp.obj.as_identifier, scp); - emit_opcode(opcode::OP_EvalNewLocalArrayRefCached0, (ctx_->props() & props::hash) ? exp.obj.as_identifier->value : fmt::format("{}", index)); + auto index = variable_initialize(exp.obj->as(), scp); + emit_opcode(opcode::OP_EvalNewLocalArrayRefCached0, (ctx_->props() & props::hash) ? exp.obj->as().value : fmt::format("{}", index)); if (!set) throw comp_error(exp.loc(), "INTERNAL: VAR CREATED BUT NOT SET"); } else { - auto index = variable_access(*exp.obj.as_identifier, scp); + auto index = variable_access(exp.obj->as(), scp); if (index == 0) emit_opcode(opcode::OP_EvalLocalArrayRefCached0); @@ -1855,7 +1773,7 @@ auto compiler::emit_expr_field_ref(expr_field const& exp, scope& scp, bool set) { auto const& field = exp.field->value; - switch (exp.obj.kind()) + switch (exp.obj->kind()) { case node::expr_level: set ? emit_opcode(opcode::OP_SetLevelFieldVariableField, field) : emit_opcode(opcode::OP_EvalLevelFieldVariableRef, field); @@ -1867,36 +1785,36 @@ auto compiler::emit_expr_field_ref(expr_field const& exp, scope& scp, bool set) set ? emit_opcode(opcode::OP_SetSelfFieldVariableField, field) : emit_opcode(opcode::OP_EvalSelfFieldVariableRef, field); break; case node::expr_array: - emit_expr_array(*exp.obj.as_array, scp); + emit_expr_array(exp.obj->as(), scp); emit_opcode(opcode::OP_CastFieldObject); emit_opcode(opcode::OP_EvalFieldVariableRef, field); if (set) emit_opcode(opcode::OP_SetVariableField); break; case node::expr_field: - emit_expr_field(*exp.obj.as_field, scp); + emit_expr_field(exp.obj->as(), scp); emit_opcode(opcode::OP_CastFieldObject); emit_opcode(opcode::OP_EvalFieldVariableRef, field); if (set) emit_opcode(opcode::OP_SetVariableField); break; case node::expr_identifier: - emit_opcode(opcode::OP_EvalLocalVariableObjectCached, fmt::format("{}", variable_access(*exp.obj.as_identifier, scp))); + emit_opcode(opcode::OP_EvalLocalVariableObjectCached, fmt::format("{}", variable_access(exp.obj->as(), scp))); emit_opcode(opcode::OP_EvalFieldVariableRef, field); if (set) emit_opcode(opcode::OP_SetVariableField); break; case node::expr_call: - emit_expr_call(*exp.obj.as_call, scp, false); + emit_expr_call(exp.obj->as(), scp, false); emit_opcode(opcode::OP_CastFieldObject); emit_opcode(opcode::OP_EvalFieldVariableRef, field); if (set) emit_opcode(opcode::OP_SetVariableField); break; case node::expr_method: - emit_expr_method(*exp.obj.as_method, scp, false); + emit_expr_method(exp.obj->as(), scp, false); emit_opcode(opcode::OP_CastFieldObject); emit_opcode(opcode::OP_EvalFieldVariableRef, field); if (set) emit_opcode(opcode::OP_SetVariableField); break; default: - throw comp_error(exp.obj.loc(), "not an object"); + throw comp_error(exp.obj->loc(), "not an object"); } } @@ -1942,13 +1860,13 @@ auto compiler::emit_expr_variable(expr const& exp, scope& scp) -> void switch (exp.kind()) { case node::expr_array: - emit_expr_array(*exp.as_array, scp); + emit_expr_array(exp.as(), scp); break; case node::expr_field: - emit_expr_field(*exp.as_field, scp); + emit_expr_field(exp.as(), scp); break; case node::expr_identifier: - emit_expr_local(*exp.as_identifier, scp); + emit_expr_local(exp.as(), scp); break; default: throw comp_error(exp.loc(), "invalid variable type."); @@ -1957,15 +1875,15 @@ auto compiler::emit_expr_variable(expr const& exp, scope& scp) -> void auto compiler::emit_expr_array(expr_array const& exp, scope& scp) -> void { - emit_expr(exp.key, scp); + emit_expr(*exp.key, scp); - if (exp.obj == node::expr_identifier) + if (exp.obj->is()) { - emit_opcode(opcode::OP_EvalLocalArrayCached, fmt::format("{}", variable_access(*exp.obj.as_identifier, scp))); + emit_opcode(opcode::OP_EvalLocalArrayCached, fmt::format("{}", variable_access(exp.obj->as(), scp))); } else { - emit_expr(exp.obj, scp); + emit_expr(*exp.obj, scp); emit_opcode(opcode::OP_EvalArray); } } @@ -1974,7 +1892,7 @@ auto compiler::emit_expr_field(expr_field const& exp, scope& scp) -> void { auto const& field = exp.field->value; - switch (exp.obj.kind()) + switch (exp.obj->kind()) { case node::expr_level: emit_opcode(opcode::OP_EvalLevelFieldVariable, field); @@ -1986,27 +1904,27 @@ auto compiler::emit_expr_field(expr_field const& exp, scope& scp) -> void emit_opcode(opcode::OP_EvalSelfFieldVariable, field); break; case node::expr_array: - emit_expr_array(*exp.obj.as_array, scp); + emit_expr_array(exp.obj->as(), scp); emit_opcode(opcode::OP_CastFieldObject); emit_opcode(opcode::OP_EvalFieldVariable, field); break; case node::expr_field: - emit_expr_field(*exp.obj.as_field, scp); + emit_expr_field(exp.obj->as(), scp); emit_opcode(opcode::OP_CastFieldObject); emit_opcode(opcode::OP_EvalFieldVariable, field); break; case node::expr_call: - emit_expr_call(*exp.obj.as_call, scp, false); + emit_expr_call(exp.obj->as(), scp, false); emit_opcode(opcode::OP_CastFieldObject); emit_opcode(opcode::OP_EvalFieldVariable, field); break; case node::expr_method: - emit_expr_method(*exp.obj.as_method, scp, false); + emit_expr_method(exp.obj->as(), scp, false); emit_opcode(opcode::OP_CastFieldObject); emit_opcode(opcode::OP_EvalFieldVariable, field); break; case node::expr_identifier: - emit_opcode(opcode::OP_EvalLocalVariableObjectCached, fmt::format("{}", variable_access(*exp.obj.as_identifier, scp))); + emit_opcode(opcode::OP_EvalLocalVariableObjectCached, fmt::format("{}", variable_access(exp.obj->as(), scp))); emit_opcode(opcode::OP_EvalFieldVariable, field); break; default: @@ -2067,23 +1985,23 @@ auto compiler::emit_expr_object(expr const& exp, scope& scp) -> void emit_opcode(opcode::OP_GetSelfObject); break; case node::expr_array: - emit_expr_array(*exp.as_array, scp); + emit_expr_array(exp.as(), scp); emit_opcode(opcode::OP_CastFieldObject); break; case node::expr_field: - emit_expr_field(*exp.as_field, scp); + emit_expr_field(exp.as(), scp); emit_opcode(opcode::OP_CastFieldObject); break; case node::expr_call: - emit_expr_call(*exp.as_call, scp, false); + emit_expr_call(exp.as(), scp, false); emit_opcode(opcode::OP_CastFieldObject); break; case node::expr_method: - emit_expr_method(*exp.as_method, scp, false); + emit_expr_method(exp.as(), scp, false); emit_opcode(opcode::OP_CastFieldObject); break; case node::expr_identifier: - emit_opcode(opcode::OP_EvalLocalVariableObjectCached, fmt::format("{}", variable_access(*exp.as_identifier, scp))); + emit_opcode(opcode::OP_EvalLocalVariableObjectCached, fmt::format("{}", variable_access(exp.as(), scp))); break; default: throw comp_error(exp.loc(), "not an object"); @@ -2095,22 +2013,22 @@ auto compiler::emit_expr_vector(expr_vector const& exp, scope& scp) -> void auto data = std::vector{}; auto isexpr = false; - if (exp.x == node::expr_integer) - data.push_back(exp.x.as_integer->value); - else if (exp.x == node::expr_float) - data.push_back(exp.x.as_float->value); + if (exp.x->is()) + data.push_back(exp.x->as().value); + else if (exp.x->is()) + data.push_back(exp.x->as().value); else isexpr = true; - if (exp.y == node::expr_integer) - data.push_back(exp.y.as_integer->value); - else if (exp.y == node::expr_float) - data.push_back(exp.y.as_float->value); + if (exp.y->is()) + data.push_back(exp.y->as().value); + else if (exp.y->is()) + data.push_back(exp.y->as().value); else isexpr = true; - if (exp.z == node::expr_integer) - data.push_back(exp.z.as_integer->value); - else if (exp.z == node::expr_float) - data.push_back(exp.z.as_float->value); + if (exp.z->is()) + data.push_back(exp.z->as().value); + else if (exp.z->is()) + data.push_back(exp.z->as().value); else isexpr = true; if (!isexpr) @@ -2128,9 +2046,9 @@ auto compiler::emit_expr_vector(expr_vector const& exp, scope& scp) -> void } else { - emit_expr(exp.z, scp); - emit_expr(exp.y, scp); - emit_expr(exp.x, scp); + emit_expr(*exp.z, scp); + emit_expr(*exp.y, scp); + emit_expr(*exp.x, scp); emit_opcode(opcode::OP_vector); } } @@ -2323,54 +2241,50 @@ auto compiler::process_stmt(stmt const& stm, scope& scp) -> void switch (stm.kind()) { case node::stmt_list: - process_stmt_list(*stm.as_list, scp); + process_stmt_list(stm.as(), scp); break; case node::stmt_comp: - process_stmt_comp(*stm.as_comp, scp); + process_stmt_comp(stm.as(), scp); break; case node::stmt_dev: - process_stmt_dev(*stm.as_dev, scp); + process_stmt_dev(stm.as(), scp); break; case node::stmt_expr: - process_stmt_expr(*stm.as_expr, scp); - break; - case node::stmt_assign: - process_stmt_assign(*stm.as_assign, scp); + process_stmt_expr(stm.as(), scp); break; case node::stmt_waittill: - process_stmt_waittill(*stm.as_waittill, scp); + process_stmt_waittill(stm.as(), scp); break; case node::stmt_if: - process_stmt_if(*stm.as_if, scp); + process_stmt_if(stm.as(), scp); break; case node::stmt_ifelse: - process_stmt_ifelse(*stm.as_ifelse, scp); + process_stmt_ifelse(stm.as(), scp); break; case node::stmt_while: - process_stmt_while(*stm.as_while, scp); + process_stmt_while(stm.as(), scp); break; case node::stmt_dowhile: - process_stmt_dowhile(*stm.as_dowhile, scp); + process_stmt_dowhile(stm.as(), scp); break; case node::stmt_for: - process_stmt_for(*stm.as_for, scp); + process_stmt_for(stm.as(), scp); break; case node::stmt_foreach: - process_stmt_foreach(*stm.as_foreach, scp); + process_stmt_foreach(stm.as(), scp); break; case node::stmt_switch: - process_stmt_switch(*stm.as_switch, scp); + process_stmt_switch(stm.as(), scp); break; case node::stmt_break: - process_stmt_break(*stm.as_break, scp); + process_stmt_break(stm.as(), scp); break; case node::stmt_continue: - process_stmt_continue(*stm.as_continue, scp); + process_stmt_continue(stm.as(), scp); break; case node::stmt_return: - process_stmt_return(*stm.as_return, scp); + process_stmt_return(stm.as(), scp); break; - case node::stmt_call: case node::stmt_endon: case node::stmt_notify: case node::stmt_wait: @@ -2395,7 +2309,7 @@ auto compiler::process_stmt_list(stmt_list const& stm, scope& scp) -> void { for (auto const& entry : stm.list) { - process_stmt(entry, scp); + process_stmt(*entry, scp); } } @@ -2411,82 +2325,46 @@ auto compiler::process_stmt_dev(stmt_dev const& stm, scope& scp) -> void auto compiler::process_stmt_expr(stmt_expr const& stm, scope& scp) -> void { - switch (stm.value.kind()) + switch (stm.value->kind()) { case node::expr_increment: - process_expr(stm.value.as_increment->lvalue, scp); + process_expr(*stm.value->as().lvalue, scp); break; case node::expr_decrement: - process_expr(stm.value.as_decrement->lvalue, scp); + process_expr(*stm.value->as().lvalue, scp); break; - case node::expr_assign_equal: - case node::expr_assign_add: - case node::expr_assign_sub: - case node::expr_assign_mul: - case node::expr_assign_div: - case node::expr_assign_mod: - case node::expr_assign_shift_left: - case node::expr_assign_shift_right: - case node::expr_assign_bitwise_or: - case node::expr_assign_bitwise_and: - case node::expr_assign_bitwise_exor: - process_expr(stm.value.as_assign->lvalue, scp); + case node::expr_assign: + process_expr(*stm.value->as().lvalue, scp); break; - case node::null: + case node::expr_call: + case node::expr_method: + case node::expr_empty: break; default: throw comp_error(stm.loc(), "unknown expr statement expression"); } } -auto compiler::process_stmt_assign(stmt_assign const& stm, scope& scp) -> void -{ - switch (stm.value.kind()) - { - case node::expr_increment: - process_expr(stm.value.as_increment->lvalue, scp); - break; - case node::expr_decrement: - process_expr(stm.value.as_decrement->lvalue, scp); - break; - case node::expr_assign_equal: - case node::expr_assign_add: - case node::expr_assign_sub: - case node::expr_assign_mul: - case node::expr_assign_div: - case node::expr_assign_mod: - case node::expr_assign_shift_left: - case node::expr_assign_shift_right: - case node::expr_assign_bitwise_or: - case node::expr_assign_bitwise_and: - case node::expr_assign_bitwise_exor: - process_expr(stm.value.as_assign->lvalue, scp); - break; - default: - throw comp_error(stm.loc(), "unknown assign statement expression"); - } -} - auto compiler::process_stmt_waittill(stmt_waittill const& stm, scope& scp) -> void { for (auto const& entry : stm.args->list) { - if (entry != node::expr_identifier) + if (!entry->is()) { - throw comp_error(entry.loc(), "illegal waittill param, must be a local variable"); + throw comp_error(entry->loc(), "illegal waittill param, must be a local variable"); } - variable_register(*entry.as_identifier, scp); + variable_register(entry->as(), scp); } } auto compiler::process_stmt_if(stmt_if const& stm, scope& scp) -> void { - auto ins = scopes_.insert({ stm.body.as_node.get(), make_scope() }); + auto ins = scopes_.insert({ stm.body.get(), make_scope() }); auto& scp_then = ins.first->second; scp.copy(scp_then); - process_stmt(stm.body, *scp_then); + process_stmt(*stm.body, *scp_then); std::vector childs({ scp_then.get() }); scp.merge(childs); @@ -2497,13 +2375,13 @@ auto compiler::process_stmt_ifelse(stmt_ifelse const& stm, scope& scp) -> void auto childs = std::vector{}; auto abort = scope::abort_return; - auto ins1 = scopes_.insert({ stm.stmt_if.as_node.get(), make_scope() }); - auto ins2 = scopes_.insert({ stm.stmt_else.as_node.get(), make_scope() }); + auto ins1 = scopes_.insert({ stm.stmt_if.get(), make_scope() }); + auto ins2 = scopes_.insert({ stm.stmt_else.get(), make_scope() }); auto& scp_then = ins1.first->second; auto& scp_else = ins2.first->second; scp.copy(scp_then); - process_stmt(stm.stmt_if, *scp_then); + process_stmt(*stm.stmt_if, *scp_then); if (scp_then->abort <= scope::abort_return) { @@ -2513,7 +2391,7 @@ auto compiler::process_stmt_ifelse(stmt_ifelse const& stm, scope& scp) -> void } scp.copy(scp_else); - process_stmt(stm.stmt_else, *scp_else); + process_stmt(*stm.stmt_else, *scp_else); if (scp_else->abort <= abort) { @@ -2531,18 +2409,18 @@ auto compiler::process_stmt_ifelse(stmt_ifelse const& stm, scope& scp) -> void auto compiler::process_stmt_while(stmt_while const& stm, scope& scp) -> void { - bool const_cond = is_constant_condition(stm.test); + bool const_cond = is_constant_condition(*stm.test); auto old_breaks = break_blks_; auto old_continues = continue_blks_; break_blks_.clear(); continue_blks_.clear(); - auto ins = scopes_.insert({ stm.body.as_node.get(), make_scope() }); + auto ins = scopes_.insert({ stm.body.get(), make_scope() }); auto& scp_body = ins.first->second; scp.copy(scp_body); - process_stmt(stm.body, *scp_body); + process_stmt(*stm.body, *scp_body); continue_blks_.push_back(scp_body.get()); @@ -2559,18 +2437,18 @@ auto compiler::process_stmt_while(stmt_while const& stm, scope& scp) -> void auto compiler::process_stmt_dowhile(stmt_dowhile const& stm, scope& scp) -> void { - bool const_cond = is_constant_condition(stm.test); + bool const_cond = is_constant_condition(*stm.test); auto old_breaks = break_blks_; auto old_continues = continue_blks_; break_blks_.clear(); continue_blks_.clear(); - auto ins = scopes_.insert({ stm.body.as_node.get(), make_scope() }); + auto ins = scopes_.insert({ stm.body.get(), make_scope() }); auto& scp_body = ins.first->second; scp.copy(scp_body); - process_stmt(stm.body, *scp_body); + process_stmt(*stm.body, *scp_body); continue_blks_.push_back(scp_body.get()); @@ -2587,14 +2465,14 @@ auto compiler::process_stmt_dowhile(stmt_dowhile const& stm, scope& scp) -> void auto compiler::process_stmt_for(stmt_for const& stm, scope& scp) -> void { - bool const_cond = is_constant_condition(stm.test); + bool const_cond = is_constant_condition(*stm.test); - auto ins1 = scopes_.insert({ stm.body.as_node.get(), make_scope() }); - auto ins2 = scopes_.insert({ stm.iter.as_node.get(), make_scope() }); + auto ins1 = scopes_.insert({ stm.body.get(), make_scope() }); + auto ins2 = scopes_.insert({ stm.iter.get(), make_scope() }); auto& scp_body = ins1.first->second; auto& scp_iter = ins2.first->second; - process_stmt(stm.init, scp); + process_stmt(*stm.init, scp); auto old_breaks = break_blks_; auto old_continues = continue_blks_; @@ -2604,14 +2482,14 @@ auto compiler::process_stmt_for(stmt_for const& stm, scope& scp) -> void scp.copy(scp_body); scp.copy(scp_iter); - process_stmt(stm.body, *scp_body); + process_stmt(*stm.body, *scp_body); continue_blks_.push_back(scp_body.get()); for (auto i = 0u; i < continue_blks_.size(); i++) scp.append({ continue_blks_.at(i) }); - process_stmt(stm.iter, *scp_iter); + process_stmt(*stm.iter, *scp_iter); scp.append({ scp_iter.get() }); scp.merge({ scp_iter.get() }); @@ -2626,18 +2504,18 @@ auto compiler::process_stmt_for(stmt_for const& stm, scope& scp) -> void auto compiler::process_stmt_foreach(stmt_foreach const& stm, scope& scp) -> void { - auto ins1 = scopes_.insert({ stm.body.as_node.get(), make_scope() }); - auto ins2 = scopes_.insert({ stm.key.as_node.get(), make_scope() }); + auto ins1 = scopes_.insert({ stm.body.get(), make_scope() }); + auto ins2 = scopes_.insert({ stm.key.get(), make_scope() }); auto& scp_body = ins1.first->second; auto& scp_iter = ins2.first->second; - process_expr(stm.array, scp); + process_expr(*stm.array, scp); if (ctx_->props() & props::foreach) - process_expr(stm.key, scp); + process_expr(*stm.key, scp); if (ctx_->props() & props::foreach && stm.use_key) - process_expr(stm.index, scp); + process_expr(*stm.index, scp); auto old_breaks = break_blks_; auto old_continues = continue_blks_; @@ -2647,8 +2525,8 @@ auto compiler::process_stmt_foreach(stmt_foreach const& stm, scope& scp) -> void scp.copy(scp_body); scp.copy(scp_iter); - process_expr(stm.value, *scp_body); - process_stmt(stm.body, *scp_body); + process_expr(*stm.value, *scp_body); + process_stmt(*stm.body, *scp_body); continue_blks_.push_back(scp_body.get()); @@ -2656,7 +2534,7 @@ auto compiler::process_stmt_foreach(stmt_foreach const& stm, scope& scp) -> void scp.append({ continue_blks_.at(i) }); if (!(ctx_->props() & props::foreach)) - process_expr(stm.key, *scp_iter); + process_expr(*stm.key, *scp_iter); scp.append({ scp_iter.get() }); scp.merge({ scp_iter.get() }); @@ -2679,13 +2557,13 @@ auto compiler::process_stmt_switch(stmt_switch const& stm, scope& scp) -> void { auto& entry = stm.body->block->list[i]; - if (entry == node::stmt_case) + if (entry->is()) { - auto ins = scopes_.insert({ entry.as_case->body.get(), make_scope() }); + auto ins = scopes_.insert({ entry->as().body.get(), make_scope() }); auto& scp_body = ins.first->second; scp.copy(scp_body); - process_stmt_list(*entry.as_case->body, *scp_body); + process_stmt_list(*entry->as().body, *scp_body); if (scp_body->abort != scope::abort_none) { @@ -2701,13 +2579,13 @@ auto compiler::process_stmt_switch(stmt_switch const& stm, scope& scp) -> void } } } - else if (entry == node::stmt_default) + else if (entry->is()) { - auto ins = scopes_.insert({ entry.as_default->body.get(), make_scope() }); + auto ins = scopes_.insert({ entry->as().body.get(), make_scope() }); auto& scp_body = ins.first->second; scp.copy(scp_body); - process_stmt_list(*entry.as_default->body, *scp_body); + process_stmt_list(*entry->as().body, *scp_body); has_default = true; default_ctx = scp_body.get(); @@ -2772,27 +2650,27 @@ auto compiler::process_stmt_return(stmt_return const&, scope& scp) -> void auto compiler::process_expr(expr const& exp, scope& scp) -> void { - if (exp == node::expr_identifier) + if (exp.is()) { - variable_register(*exp.as_identifier, scp); + variable_register(exp.as(), scp); } - else if (exp == node::expr_array) + else if (exp.is()) { - process_expr(exp.as_array->obj, scp); + process_expr(*exp.as().obj, scp); } - else if (exp == node::expr_tuple) + else if (exp.is()) { - process_expr_tuple(*exp.as_tuple, scp); + process_expr_tuple(exp.as(), scp); } } auto compiler::process_expr_tuple(expr_tuple const& exp, scope& scp) -> void { - process_expr(exp.temp, scp); + process_expr(*exp.temp, scp); for (auto const& entry : exp.list) { - process_expr(entry, scp); + process_expr(*entry, scp); } } @@ -2973,14 +2851,14 @@ auto compiler::is_constant_condition(expr const& exp) -> bool { switch (exp.kind()) { - case node::null: + case node::expr_empty: case node::expr_true: return true; case node::expr_false: throw comp_error(exp.loc(), "condition can't be always false"); case node::expr_integer: { - auto num = std::stoi(exp.as_integer->value); + auto num = std::stoi(exp.as().value); if (num != 0) return true; else diff --git a/src/gsc/context.cpp b/src/gsc/context.cpp index 6c3ecf3d..974f5f79 100644 --- a/src/gsc/context.cpp +++ b/src/gsc/context.cpp @@ -725,9 +725,9 @@ auto context::load_include(std::string const& name) -> bool for (auto const& dec : prog->declarations) { - if (dec == node::decl_function) + if (dec->is()) { - funcs.push_back(dec.as_function->name->value); + funcs.push_back(dec->as().name->value); } } diff --git a/src/gsc/decompiler.cpp b/src/gsc/decompiler.cpp index 8478bfd0..00787d68 100644 --- a/src/gsc/decompiler.cpp +++ b/src/gsc/decompiler.cpp @@ -17,7 +17,7 @@ decompiler::decompiler(context const* ctx) : ctx_{ ctx } auto decompiler::decompile(assembly const& data) -> program::ptr { - program_ = make_program(); + program_ = program::make(); for (auto const& func : data.functions) { @@ -37,10 +37,10 @@ auto decompiler::decompile_function(function const& func) -> void stack_ = {}; auto loc = location{ nullptr, static_cast(func.index) }; - auto name = make_expr_identifier(loc, func.name); - auto prms = make_expr_parameters(loc); - auto body = make_stmt_comp(loc, make_stmt_list(loc)); - func_ = make_decl_function(loc, std::move(name), std::move(prms), std::move(body)); + auto name = expr_identifier::make(loc, func.name); + auto prms = expr_parameters::make(loc); + auto body = stmt_comp::make(loc, stmt_list::make(loc)); + func_ = decl_function::make(loc, std::move(name), std::move(prms), std::move(body)); for (auto const& inst : func.instructions) { @@ -53,13 +53,13 @@ auto decompiler::decompile_function(function const& func) -> void } locs_.last = true; - locs_.end = func_->body->block->list.back().label(); + locs_.end = func_->body->block->list.back()->label(); func_->body->block->list.pop_back(); decompile_statements(*func_->body->block); process_function(*func_); - program_->declarations.push_back(decl{ std::move(func_) }); + program_->declarations.push_back(std::move(func_)); } auto decompiler::decompile_instruction(instruction const& inst) -> void @@ -72,18 +72,18 @@ auto decompiler::decompile_instruction(instruction const& inst) -> void { case opcode::OP_End: { - func_->body->block->list.push_back(stmt{ make_stmt_return(loc, expr{ make_node(loc) }) }); + func_->body->block->list.push_back(stmt_return::make(loc, expr_empty::make(loc))); break; } case opcode::OP_Return: { - auto value = expr{ std::move(stack_.top()) }; stack_.pop(); - func_->body->block->list.push_back(stmt{ make_stmt_return(value.loc(), std::move(value)) }); + auto value = node::as(std::move(stack_.top())); stack_.pop(); + func_->body->block->list.push_back(stmt_return::make(value->loc(), std::move(value))); break; } case opcode::OP_GetZero: { - stack_.push(make_expr_integer(loc, "0")); + stack_.push(expr_integer::make(loc, "0")); break; } case opcode::OP_GetByte: @@ -92,237 +92,237 @@ auto decompiler::decompile_instruction(instruction const& inst) -> void case opcode::OP_GetInteger: case opcode::OP_GetInteger64: { - stack_.push(make_expr_integer(loc, inst.data[0])); + stack_.push(expr_integer::make(loc, inst.data[0])); break; } case opcode::OP_GetNegByte: case opcode::OP_GetNegUnsignedShort: case opcode::OP_GetNegUnsignedInt: { - stack_.push(make_expr_integer(loc, "-" + inst.data[0])); + stack_.push(expr_integer::make(loc, "-" + inst.data[0])); break; } case opcode::OP_GetFloat: { - stack_.push(make_expr_float(loc, inst.data[0])); + stack_.push(expr_float::make(loc, inst.data[0])); break; } case opcode::OP_GetVector: { - auto x = expr{ make_expr_float(loc, inst.data[0]) }; - auto y = expr{ make_expr_float(loc, inst.data[1]) }; - auto z = expr{ make_expr_float(loc, inst.data[2]) }; - stack_.push(make_expr_vector(loc, std::move(x), std::move(y), std::move(z))); + auto x = expr_float::make(loc, inst.data[0]); + auto y = expr_float::make(loc, inst.data[1]); + auto z = expr_float::make(loc, inst.data[2]); + stack_.push(expr_vector::make(loc, std::move(x), std::move(y), std::move(z))); break; } case opcode::OP_GetString: { - stack_.push(make_expr_string(loc, inst.data[0])); + stack_.push(expr_string::make(loc, inst.data[0])); break; } case opcode::OP_GetIString: { - stack_.push(make_expr_istring(loc, inst.data[0])); + stack_.push(expr_istring::make(loc, inst.data[0])); break; } case opcode::OP_GetUndefined: { - stack_.push(make_expr_undefined(loc)); + stack_.push(expr_undefined::make(loc)); break; } case opcode::OP_EmptyArray: { - stack_.push(make_expr_empty_array(loc)); + stack_.push(expr_empty_array::make(loc)); break; } case opcode::OP_GetLevel: case opcode::OP_GetLevelObject: { - stack_.push(make_expr_level(loc)); + stack_.push(expr_level::make(loc)); break; } case opcode::OP_GetAnim: case opcode::OP_GetAnimObject: { - stack_.push(make_expr_anim(loc)); + stack_.push(expr_anim::make(loc)); break; } case opcode::OP_GetSelf: case opcode::OP_GetSelfObject: { - stack_.push(make_expr_self(loc)); + stack_.push(expr_self::make(loc)); break; } case opcode::OP_GetGame: case opcode::OP_GetGameRef: { - stack_.push(make_expr_game(loc)); + stack_.push(expr_game::make(loc)); break; } case opcode::OP_GetAnimation: { if (!inst.data[0].empty()) { - auto dec = make_decl_usingtree(loc, make_expr_string(loc, inst.data[0])); - program_->declarations.push_back(decl{ std::move(dec) }); + auto dec = decl_usingtree::make(loc, expr_string::make(loc, inst.data[0])); + program_->declarations.push_back(std::move(dec)); } - stack_.push(make_expr_animation(loc, inst.data[1])); + stack_.push(expr_animation::make(loc, inst.data[1])); break; } case opcode::OP_GetAnimTree: { if (!inst.data[0].empty()) { - auto dec = make_decl_usingtree(loc, make_expr_string(loc, inst.data[0])); - program_->declarations.push_back(decl{ std::move(dec) }); + auto dec = decl_usingtree::make(loc, expr_string::make(loc, inst.data[0])); + program_->declarations.push_back(std::move(dec)); } - stack_.push(make_expr_animtree(loc)); + stack_.push(expr_animtree::make(loc)); break; } case opcode::OP_GetThisthread: { - stack_.push(make_expr_thisthread(loc)); + stack_.push(expr_thisthread::make(loc)); break; } case opcode::OP_GetBuiltinFunction: case opcode::OP_GetBuiltinMethod: { - auto path = make_expr_path(loc); - auto name = make_expr_identifier(loc, inst.data[0]); - stack_.push(make_expr_reference(loc, std::move(path), std::move(name))); + auto path = expr_path::make(loc); + auto name = expr_identifier::make(loc, inst.data[0]); + stack_.push(expr_reference::make(loc, std::move(path), std::move(name))); break; } case opcode::OP_GetLocalFunction: { - auto path = make_expr_path(loc); - auto name = make_expr_identifier(loc, inst.data[0]); - stack_.push(make_expr_reference(loc, std::move(path), std::move(name))); + auto path = expr_path::make(loc); + auto name = expr_identifier::make(loc, inst.data[0]); + stack_.push(expr_reference::make(loc, std::move(path), std::move(name))); break; } case opcode::OP_GetFarFunction: { - auto path = make_expr_path(loc, inst.data[0]); - auto name = make_expr_identifier(loc, inst.data[1]); - stack_.push(make_expr_reference(loc, std::move(path), std::move(name))); + auto path = expr_path::make(loc, inst.data[0]); + auto name = expr_identifier::make(loc, inst.data[1]); + stack_.push(expr_reference::make(loc, std::move(path), std::move(name))); break; } case opcode::OP_CreateLocalVariable: { if (in_waittill_) { - stack_.push(make_asm_create(loc, inst.data[0])); + stack_.push(expr_var_create::make(loc, inst.data[0])); } else { - func_->body->block->list.push_back(stmt{ make_asm_create(loc, inst.data[0]) }); + func_->body->block->list.push_back(stmt_create::make(loc, inst.data[0])); } break; } case opcode::OP_RemoveLocalVariables: { - func_->body->block->list.push_back(stmt{ make_asm_remove(loc, inst.data[0]) }); + func_->body->block->list.push_back(stmt_remove::make(loc, inst.data[0])); break; } case opcode::OP_EvalLocalVariableCached0: { - stack_.push(make_asm_access(loc, "0")); + stack_.push(expr_var_access::make(loc, "0")); break; } case opcode::OP_EvalLocalVariableCached1: { - stack_.push(make_asm_access(loc, "1")); + stack_.push(expr_var_access::make(loc, "1")); break; } case opcode::OP_EvalLocalVariableCached2: { - stack_.push(make_asm_access(loc, "2")); + stack_.push(expr_var_access::make(loc, "2")); break; } case opcode::OP_EvalLocalVariableCached3: { - stack_.push(make_asm_access(loc, "3")); + stack_.push(expr_var_access::make(loc, "3")); break; } case opcode::OP_EvalLocalVariableCached4: { - stack_.push(make_asm_access(loc, "4")); + stack_.push(expr_var_access::make(loc, "4")); break; } case opcode::OP_EvalLocalVariableCached5: { - stack_.push(make_asm_access(loc, "5")); + stack_.push(expr_var_access::make(loc, "5")); break; } case opcode::OP_EvalLocalVariableCached: { - stack_.push(make_asm_access(loc, inst.data[0])); + stack_.push(expr_var_access::make(loc, inst.data[0])); break; } case opcode::OP_EvalLocalArrayCached: { - auto key = expr{ std::move(stack_.top()) }; stack_.pop(); - auto obj = expr{ make_asm_access(loc, inst.data[0]) }; - stack_.push(make_expr_array(key.loc(), std::move(obj), std::move(key))); + auto key = node::as(std::move(stack_.top())); stack_.pop(); + auto obj = expr_var_access::make(loc, inst.data[0]); + stack_.push(expr_array::make(key->loc(), std::move(obj), std::move(key))); break; } case opcode::OP_EvalArray: { - auto obj = expr{ std::move(stack_.top()) }; stack_.pop(); - auto key = expr{ std::move(stack_.top()) }; stack_.pop(); - stack_.push(make_expr_array(key.loc(), std::move(obj), std::move(key))); + auto obj = node::as(std::move(stack_.top())); stack_.pop(); + auto key = node::as(std::move(stack_.top())); stack_.pop(); + stack_.push(expr_array::make(key->loc(), std::move(obj), std::move(key))); break; } case opcode::OP_EvalNewLocalArrayRefCached0: { - auto key = expr{ std::move(stack_.top()) }; stack_.pop(); - auto obj = expr{ make_asm_create(loc, inst.data[0]) }; - stack_.push(make_expr_array(key.loc(), std::move(obj), std::move(key))); + auto key = node::as(std::move(stack_.top())); stack_.pop(); + auto obj = expr_var_create::make(loc, inst.data[0]); + stack_.push(expr_array::make(key->loc(), std::move(obj), std::move(key))); break; } case opcode::OP_EvalLocalArrayRefCached0: { - auto key = expr{ std::move(stack_.top()) }; stack_.pop(); - auto obj = expr{ make_asm_access(loc, "0") }; - stack_.push(make_expr_array(key.loc(), std::move(obj), std::move(key))); + auto key = node::as(std::move(stack_.top())); stack_.pop(); + auto obj = expr_var_access::make(loc, "0"); + stack_.push(expr_array::make(key->loc(), std::move(obj), std::move(key))); break; } case opcode::OP_EvalLocalArrayRefCached: { - auto key = expr{ std::move(stack_.top()) }; stack_.pop(); - auto obj = expr{ make_asm_access(loc, inst.data[0]) }; - stack_.push(make_expr_array(key.loc(), std::move(obj), std::move(key))); + auto key = node::as(std::move(stack_.top())); stack_.pop(); + auto obj = expr_var_access::make(loc, inst.data[0]); + stack_.push(expr_array::make(key->loc(), std::move(obj), std::move(key))); break; } case opcode::OP_EvalArrayRef: { - auto obj = expr{ std::move(stack_.top()) }; stack_.pop(); - auto key = expr{ std::move(stack_.top()) }; stack_.pop(); - stack_.push(make_expr_array(key.loc(), std::move(obj), std::move(key))); + auto obj = node::as(std::move(stack_.top())); stack_.pop(); + auto key = node::as(std::move(stack_.top())); stack_.pop(); + stack_.push(expr_array::make(key->loc(), std::move(obj), std::move(key))); break; } case opcode::OP_ClearArray: { - auto obj = expr{ std::move(stack_.top()) }; stack_.pop(); - auto key = expr{ std::move(stack_.top()) }; stack_.pop(); - loc = key.loc(); - auto lvalue = expr{ make_expr_array(loc, std::move(obj), std::move(key)) }; - auto rvalue = expr{ make_expr_undefined(loc) }; - auto exp = expr{ make_expr_assign_equal(loc, std::move(lvalue), std::move(rvalue)) }; - func_->body->block->list.push_back(stmt{ make_stmt_assign(loc, std::move(exp)) }); + auto obj = node::as(std::move(stack_.top())); stack_.pop(); + auto key = node::as(std::move(stack_.top())); stack_.pop(); + loc = key->loc(); + auto lvalue = expr_array::make(loc, std::move(obj), std::move(key)); + auto rvalue = expr_undefined::make(loc); + auto exp = expr_assign::make(loc, std::move(lvalue), std::move(rvalue), expr_assign::op::eq); + func_->body->block->list.push_back(stmt_expr::make(loc, std::move(exp))); break; } case opcode::OP_AddArray: { - auto value = expr{ std::move(stack_.top()) }; stack_.pop(); + auto value = node::as(std::move(stack_.top())); stack_.pop(); auto array = std::move(stack_.top()); stack_.pop(); if (array->kind() == node::expr_empty_array) { - auto args = make_expr_arguments(loc); + auto args = expr_arguments::make(loc); args->list.push_back(std::move(value)); - stack_.push(make_expr_add_array(array->loc(), std::move(args))); + stack_.push(expr_add_array::make(array->loc(), std::move(args))); } else if (array->kind() == node::expr_add_array) { @@ -337,780 +337,780 @@ auto decompiler::decompile_instruction(instruction const& inst) -> void } case opcode::OP_PreScriptCall: { - stack_.push(make_asm_prescriptcall(loc)); + stack_.push(node_prescriptcall::make(loc)); break; } case opcode::OP_ScriptLocalFunctionCall2: { - auto args = make_expr_arguments(loc); - auto path = make_expr_path(loc); - auto name = make_expr_identifier(loc, inst.data[0]); - stack_.push(make_expr_call(loc, call{ make_expr_function(loc, std::move(path), std::move(name), std::move(args), call::mode::normal) })); + auto args = expr_arguments::make(loc); + auto path = expr_path::make(loc); + auto name = expr_identifier::make(loc, inst.data[0]); + stack_.push(expr_call::make(loc, expr_function::make(loc, std::move(path), std::move(name), std::move(args), call::mode::normal))); break; } case opcode::OP_ScriptLocalFunctionCall: { - auto args = make_expr_arguments(loc); - auto path = make_expr_path(loc); - auto name = make_expr_identifier(loc, inst.data[0]); + auto args = expr_arguments::make(loc); + auto path = expr_path::make(loc); + auto name = expr_identifier::make(loc, inst.data[0]); auto var = std::move(stack_.top()); stack_.pop(); loc = var->loc(); - while (var->kind() != node::asm_prescriptcall) + while (var->kind() != node::node_prescriptcall) { - args->list.push_back(std::move(var)); + args->list.push_back(node::as(std::move(var))); var = std::move(stack_.top()); stack_.pop(); loc = var->loc(); } - stack_.push(make_expr_call(loc, call{ make_expr_function(loc, std::move(path), std::move(name), std::move(args), call::mode::normal) })); + stack_.push(expr_call::make(loc, expr_function::make(loc, std::move(path), std::move(name), std::move(args), call::mode::normal))); break; } case opcode::OP_ScriptLocalMethodCall: { - auto obj = expr{ std::move(stack_.top()) }; stack_.pop(); - loc = obj.loc(); + auto obj = node::as(std::move(stack_.top())); stack_.pop(); + loc = obj->loc(); - auto args = make_expr_arguments(loc); - auto path = make_expr_path(loc); - auto name = make_expr_identifier(loc, inst.data[0]); + auto args = expr_arguments::make(loc); + auto path = expr_path::make(loc); + auto name = expr_identifier::make(loc, inst.data[0]); auto var = std::move(stack_.top()); stack_.pop(); loc = var->loc(); - while (var->kind() != node::asm_prescriptcall) + while (var->kind() != node::node_prescriptcall) { - args->list.push_back(std::move(var)); + args->list.push_back(node::as(std::move(var))); var = std::move(stack_.top()); stack_.pop(); loc = var->loc(); } - stack_.push(make_expr_method(loc, std::move(obj), call{ make_expr_function(loc, std::move(path), std::move(name), std::move(args), call::mode::normal) })); + stack_.push(expr_method::make(loc, std::move(obj), expr_function::make(loc, std::move(path), std::move(name), std::move(args), call::mode::normal))); break; } case opcode::OP_ScriptLocalThreadCall: { - auto args = make_expr_arguments(loc); - auto path = make_expr_path(loc); - auto name = make_expr_identifier(loc, inst.data[0]); + auto args = expr_arguments::make(loc); + auto path = expr_path::make(loc); + auto name = expr_identifier::make(loc, inst.data[0]); for (auto i = std::stoul(inst.data[1]); i > 0; i--) { auto var = std::move(stack_.top()); stack_.pop(); loc = var->loc(); - args->list.push_back(std::move(var)); + args->list.push_back(node::as(std::move(var))); } - stack_.push(make_expr_call(loc, call{ make_expr_function(loc, std::move(path), std::move(name), std::move(args), call::mode::thread) })); + stack_.push(expr_call::make(loc, expr_function::make(loc, std::move(path), std::move(name), std::move(args), call::mode::thread))); break; } case opcode::OP_ScriptLocalChildThreadCall: { - auto args = make_expr_arguments(loc); - auto path = make_expr_path(loc); - auto name = make_expr_identifier(loc, inst.data[0]); + auto args = expr_arguments::make(loc); + auto path = expr_path::make(loc); + auto name = expr_identifier::make(loc, inst.data[0]); for (auto i = std::stoul(inst.data[1]); i > 0; i--) { auto var = std::move(stack_.top()); stack_.pop(); loc = var->loc(); - args->list.push_back(std::move(var)); + args->list.push_back(node::as(std::move(var))); } - stack_.push(make_expr_call(loc, call{ make_expr_function(loc, std::move(path), std::move(name), std::move(args), call::mode::childthread) })); + stack_.push(expr_call::make(loc, expr_function::make(loc, std::move(path), std::move(name), std::move(args), call::mode::childthread))); break; } case opcode::OP_ScriptLocalMethodThreadCall: { - auto obj = expr{ std::move(stack_.top()) }; stack_.pop(); - loc = obj.loc(); + auto obj = node::as(std::move(stack_.top())); stack_.pop(); + loc = obj->loc(); - auto args = make_expr_arguments(loc); - auto path = make_expr_path(loc); - auto name = make_expr_identifier(loc, inst.data[0]); + auto args = expr_arguments::make(loc); + auto path = expr_path::make(loc); + auto name = expr_identifier::make(loc, inst.data[0]); for (auto i = std::stoul(inst.data[1]); i > 0; i--) { auto var = std::move(stack_.top()); stack_.pop(); loc = var->loc(); - args->list.push_back(std::move(var)); + args->list.push_back(node::as(std::move(var))); } - stack_.push(make_expr_method(loc, std::move(obj), call{ make_expr_function(loc, std::move(path), std::move(name), std::move(args), call::mode::thread) })); + stack_.push(expr_method::make(loc, std::move(obj), expr_function::make(loc, std::move(path), std::move(name), std::move(args), call::mode::thread))); break; } case opcode::OP_ScriptLocalMethodChildThreadCall: { - auto obj = expr{ std::move(stack_.top()) }; stack_.pop(); - loc = obj.loc(); + auto obj = node::as(std::move(stack_.top())); stack_.pop(); + loc = obj->loc(); - auto args = make_expr_arguments(loc); - auto path = make_expr_path(loc); - auto name = make_expr_identifier(loc, inst.data[0]); + auto args = expr_arguments::make(loc); + auto path = expr_path::make(loc); + auto name = expr_identifier::make(loc, inst.data[0]); for (auto i = std::stoul(inst.data[1]); i > 0; i--) { auto var = std::move(stack_.top()); stack_.pop(); loc = var->loc(); - args->list.push_back(std::move(var)); + args->list.push_back(node::as(std::move(var))); } - stack_.push(make_expr_method(loc, std::move(obj), call{ make_expr_function(loc, std::move(path), std::move(name), std::move(args), call::mode::childthread) })); + stack_.push(expr_method::make(loc, std::move(obj), expr_function::make(loc, std::move(path), std::move(name), std::move(args), call::mode::childthread))); break; } case opcode::OP_ScriptFarFunctionCall2: { - auto args = make_expr_arguments(loc); - auto path = make_expr_path(loc, inst.data[0]); - auto name = make_expr_identifier(loc, inst.data[1]); - stack_.push(make_expr_call(loc, call{ make_expr_function(loc, std::move(path), std::move(name), std::move(args), call::mode::normal) })); + auto args = expr_arguments::make(loc); + auto path = expr_path::make(loc, inst.data[0]); + auto name = expr_identifier::make(loc, inst.data[1]); + stack_.push(expr_call::make(loc, expr_function::make(loc, std::move(path), std::move(name), std::move(args), call::mode::normal))); break; } case opcode::OP_ScriptFarFunctionCall: { - auto args = make_expr_arguments(loc); - auto path = make_expr_path(loc, inst.data[0]); - auto name = make_expr_identifier(loc, inst.data[1]); + auto args = expr_arguments::make(loc); + auto path = expr_path::make(loc, inst.data[0]); + auto name = expr_identifier::make(loc, inst.data[1]); auto var = std::move(stack_.top()); stack_.pop(); loc = var->loc(); - while (var->kind() != node::asm_prescriptcall) + while (var->kind() != node::node_prescriptcall) { - args->list.push_back(std::move(var)); + args->list.push_back(node::as(std::move(var))); var = std::move(stack_.top()); stack_.pop(); loc = var->loc(); } - stack_.push(make_expr_call(loc, call{ make_expr_function(loc, std::move(path), std::move(name), std::move(args), call::mode::normal) })); + stack_.push(expr_call::make(loc, expr_function::make(loc, std::move(path), std::move(name), std::move(args), call::mode::normal))); break; } case opcode::OP_ScriptFarMethodCall: { - auto obj = expr{ std::move(stack_.top()) }; stack_.pop(); - loc = obj.loc(); + auto obj = node::as(std::move(stack_.top())); stack_.pop(); + loc = obj->loc(); - auto args = make_expr_arguments(loc); - auto path = make_expr_path(loc, inst.data[0]); - auto name = make_expr_identifier(loc, inst.data[1]); + auto args = expr_arguments::make(loc); + auto path = expr_path::make(loc, inst.data[0]); + auto name = expr_identifier::make(loc, inst.data[1]); auto var = std::move(stack_.top()); stack_.pop(); loc = var->loc(); - while (var->kind() != node::asm_prescriptcall) + while (var->kind() != node::node_prescriptcall) { - args->list.push_back(std::move(var)); + args->list.push_back(node::as(std::move(var))); var = std::move(stack_.top()); stack_.pop(); loc = var->loc(); } - stack_.push(make_expr_method(loc, std::move(obj), call{ make_expr_function(loc, std::move(path), std::move(name), std::move(args), call::mode::normal) })); + stack_.push(expr_method::make(loc, std::move(obj), expr_function::make(loc, std::move(path), std::move(name), std::move(args), call::mode::normal))); break; } case opcode::OP_ScriptFarThreadCall: { - auto args = make_expr_arguments(loc); - auto path = make_expr_path(loc, inst.data[0]); - auto name = make_expr_identifier(loc, inst.data[1]); + auto args = expr_arguments::make(loc); + auto path = expr_path::make(loc, inst.data[0]); + auto name = expr_identifier::make(loc, inst.data[1]); for (auto i = std::stoul(inst.data[2]); i > 0; i--) { auto var = std::move(stack_.top()); stack_.pop(); loc = var->loc(); - args->list.push_back(std::move(var)); + args->list.push_back(node::as(std::move(var))); } - stack_.push(make_expr_call(loc, call{ make_expr_function(loc, std::move(path), std::move(name), std::move(args), call::mode::thread) })); + stack_.push(expr_call::make(loc, expr_function::make(loc, std::move(path), std::move(name), std::move(args), call::mode::thread))); break; } case opcode::OP_ScriptFarChildThreadCall: { - auto args = make_expr_arguments(loc); - auto path = make_expr_path(loc, inst.data[0]); - auto name = make_expr_identifier(loc, inst.data[1]); + auto args = expr_arguments::make(loc); + auto path = expr_path::make(loc, inst.data[0]); + auto name = expr_identifier::make(loc, inst.data[1]); for (auto i = std::stoul(inst.data[2]); i > 0; i--) { auto var = std::move(stack_.top()); stack_.pop(); loc = var->loc(); - args->list.push_back(std::move(var)); + args->list.push_back(node::as(std::move(var))); } - stack_.push(make_expr_call(loc, call{ make_expr_function(loc, std::move(path), std::move(name), std::move(args), call::mode::childthread) })); + stack_.push(expr_call::make(loc, expr_function::make(loc, std::move(path), std::move(name), std::move(args), call::mode::childthread))); break; } case opcode::OP_ScriptFarMethodThreadCall: { - auto obj = expr{ std::move(stack_.top()) }; stack_.pop(); - loc = obj.loc(); + auto obj = node::as(std::move(stack_.top())); stack_.pop(); + loc = obj->loc(); - auto args = make_expr_arguments(loc); - auto path = make_expr_path(loc, inst.data[0]); - auto name = make_expr_identifier(loc, inst.data[1]); + auto args = expr_arguments::make(loc); + auto path = expr_path::make(loc, inst.data[0]); + auto name = expr_identifier::make(loc, inst.data[1]); for (auto i = std::stoul(inst.data[2]); i > 0; i--) { auto var = std::move(stack_.top()); stack_.pop(); loc = var->loc(); - args->list.push_back(std::move(var)); + args->list.push_back(node::as(std::move(var))); } - stack_.push(make_expr_method(loc, std::move(obj), call{ make_expr_function(loc, std::move(path), std::move(name), std::move(args), call::mode::thread) })); + stack_.push(expr_method::make(loc, std::move(obj), expr_function::make(loc, std::move(path), std::move(name), std::move(args), call::mode::thread))); break; } case opcode::OP_ScriptFarMethodChildThreadCall: { - auto obj = expr{ std::move(stack_.top()) }; stack_.pop(); - loc = obj.loc(); + auto obj = node::as(std::move(stack_.top())); stack_.pop(); + loc = obj->loc(); - auto args = make_expr_arguments(loc); - auto path = make_expr_path(loc, inst.data[0]); - auto name = make_expr_identifier(loc, inst.data[1]); + auto args = expr_arguments::make(loc); + auto path = expr_path::make(loc, inst.data[0]); + auto name = expr_identifier::make(loc, inst.data[1]); for (auto i = std::stoul(inst.data[2]); i > 0; i--) { auto var = std::move(stack_.top()); stack_.pop(); loc = var->loc(); - args->list.push_back(std::move(var)); + args->list.push_back(node::as(std::move(var))); } - stack_.push(make_expr_method(loc, std::move(obj), call{ make_expr_function(loc, std::move(path), std::move(name), std::move(args), call::mode::childthread) })); + stack_.push(expr_method::make(loc, std::move(obj), expr_function::make(loc, std::move(path), std::move(name), std::move(args), call::mode::childthread))); break; } case opcode::OP_ScriptFunctionCallPointer: { - auto args = make_expr_arguments(loc); - auto func = expr{ std::move(stack_.top()) }; stack_.pop(); + auto args = expr_arguments::make(loc); + auto func = node::as(std::move(stack_.top())); stack_.pop(); auto var = std::move(stack_.top()); stack_.pop(); loc = var->loc(); - while (var->kind() != node::asm_prescriptcall) + while (var->kind() != node::node_prescriptcall) { - args->list.push_back(std::move(var)); + args->list.push_back(node::as(std::move(var))); var = std::move(stack_.top()); stack_.pop(); loc = var->loc(); } - stack_.push(make_expr_call(loc, call{ make_expr_pointer(loc, std::move(func), std::move(args), call::mode::normal) })); + stack_.push(expr_call::make(loc, expr_pointer::make(loc, std::move(func), std::move(args), call::mode::normal))); break; } case opcode::OP_ScriptMethodCallPointer: { - auto args = make_expr_arguments(loc); - auto func = expr{ std::move(stack_.top()) }; stack_.pop(); - auto obj = expr{ std::move(stack_.top()) }; stack_.pop(); + auto args = expr_arguments::make(loc); + auto func = node::as(std::move(stack_.top())); stack_.pop(); + auto obj = node::as(std::move(stack_.top())); stack_.pop(); auto var = std::move(stack_.top()); stack_.pop(); loc = var->loc(); - while (var->kind() != node::asm_prescriptcall) + while (var->kind() != node::node_prescriptcall) { - args->list.push_back(std::move(var)); + args->list.push_back(node::as(std::move(var))); var = std::move(stack_.top()); stack_.pop(); loc = var->loc(); } - stack_.push(make_expr_method(loc, std::move(obj), call{ make_expr_pointer(loc, std::move(func), std::move(args), call::mode::normal) })); + stack_.push(expr_method::make(loc, std::move(obj), expr_pointer::make(loc, std::move(func), std::move(args), call::mode::normal))); break; } case opcode::OP_ScriptThreadCallPointer: { - auto args = make_expr_arguments(loc); - auto func = expr{ std::move(stack_.top()) }; stack_.pop(); - loc = func.loc(); + auto args = expr_arguments::make(loc); + auto func = node::as(std::move(stack_.top())); stack_.pop(); + loc = func->loc(); for (auto i = std::stoul(inst.data[0]); i > 0; i--) { auto var = std::move(stack_.top()); stack_.pop(); loc = var->loc(); - args->list.push_back(std::move(var)); + args->list.push_back(node::as(std::move(var))); } - stack_.push(make_expr_call(loc, call{ make_expr_pointer(loc, std::move(func), std::move(args), call::mode::thread) })); + stack_.push(expr_call::make(loc, expr_pointer::make(loc, std::move(func), std::move(args), call::mode::thread))); break; } case opcode::OP_ScriptChildThreadCallPointer: { - auto args = make_expr_arguments(loc); - auto func = expr{ std::move(stack_.top()) }; stack_.pop(); - loc = func.loc(); + auto args = expr_arguments::make(loc); + auto func = node::as(std::move(stack_.top())); stack_.pop(); + loc = func->loc(); for (auto i = std::stoul(inst.data[0]); i > 0; i--) { auto var = std::move(stack_.top()); stack_.pop(); loc = var->loc(); - args->list.push_back(std::move(var)); + args->list.push_back(node::as(std::move(var))); } - stack_.push(make_expr_call(loc, call{ make_expr_pointer(loc, std::move(func), std::move(args), call::mode::childthread) })); + stack_.push(expr_call::make(loc, expr_pointer::make(loc, std::move(func), std::move(args), call::mode::childthread))); break; } case opcode::OP_ScriptMethodThreadCallPointer: { - auto args = make_expr_arguments(loc); - auto func = expr{ std::move(stack_.top()) }; stack_.pop(); - auto obj = expr{ std::move(stack_.top()) }; stack_.pop(); - loc = obj.loc(); + auto args = expr_arguments::make(loc); + auto func = node::as(std::move(stack_.top())); stack_.pop(); + auto obj = node::as(std::move(stack_.top())); stack_.pop(); + loc = obj->loc(); for (auto i = std::stoul(inst.data[0]); i > 0; i--) { auto var = std::move(stack_.top()); stack_.pop(); loc = var->loc(); - args->list.push_back(std::move(var)); + args->list.push_back(node::as(std::move(var))); } - stack_.push(make_expr_method(loc, std::move(obj), call{ make_expr_pointer(loc, std::move(func), std::move(args), call::mode::thread) })); + stack_.push(expr_method::make(loc, std::move(obj), expr_pointer::make(loc, std::move(func), std::move(args), call::mode::thread))); break; } case opcode::OP_ScriptMethodChildThreadCallPointer: { - auto args = make_expr_arguments(loc); - auto func = expr{ std::move(stack_.top()) }; stack_.pop(); - auto obj = expr{ std::move(stack_.top()) }; stack_.pop(); - loc = obj.loc(); + auto args = expr_arguments::make(loc); + auto func = node::as(std::move(stack_.top())); stack_.pop(); + auto obj = node::as(std::move(stack_.top())); stack_.pop(); + loc = obj->loc(); for (auto i = std::stoul(inst.data[0]); i > 0; i--) { auto var = std::move(stack_.top()); stack_.pop(); loc = var->loc(); - args->list.push_back(std::move(var)); + args->list.push_back(node::as(std::move(var))); } - stack_.push(make_expr_method(loc, std::move(obj), call{ make_expr_pointer(loc, std::move(func), std::move(args), call::mode::childthread) })); + stack_.push(expr_method::make(loc, std::move(obj), expr_pointer::make(loc, std::move(func), std::move(args), call::mode::childthread))); break; } case opcode::OP_CallBuiltinPointer: { - auto args = make_expr_arguments(loc); - auto func = expr{ std::move(stack_.top()) }; stack_.pop(); - loc = func.loc(); + auto args = expr_arguments::make(loc); + auto func = node::as(std::move(stack_.top())); stack_.pop(); + loc = func->loc(); for (auto i = std::stoul(inst.data[0]); i > 0; i--) { auto var = std::move(stack_.top()); stack_.pop(); loc = var->loc(); - args->list.push_back(std::move(var)); + args->list.push_back(node::as(std::move(var))); } - stack_.push(make_expr_call(loc, call{ make_expr_pointer(loc, std::move(func), std::move(args), call::mode::builtin) })); + stack_.push(expr_call::make(loc, expr_pointer::make(loc, std::move(func), std::move(args), call::mode::builtin))); break; } case opcode::OP_CallBuiltinMethodPointer: { - auto args = make_expr_arguments(loc); - auto func = expr{ std::move(stack_.top()) }; stack_.pop(); - auto obj = expr{ std::move(stack_.top()) }; stack_.pop(); - loc = obj.loc(); + auto args = expr_arguments::make(loc); + auto func = node::as(std::move(stack_.top())); stack_.pop(); + auto obj = node::as(std::move(stack_.top())); stack_.pop(); + loc = obj->loc(); for (auto i = std::stoul(inst.data[0]); i > 0; i--) { auto var = std::move(stack_.top()); stack_.pop(); loc = var->loc(); - args->list.push_back(std::move(var)); + args->list.push_back(node::as(std::move(var))); } - stack_.push(make_expr_method(loc, std::move(obj), call{ make_expr_pointer(loc, std::move(func), std::move(args), call::mode::builtin) })); + stack_.push(expr_method::make(loc, std::move(obj), expr_pointer::make(loc, std::move(func), std::move(args), call::mode::builtin))); break; } case opcode::OP_CallBuiltin0: { - auto args = make_expr_arguments(loc); - auto path = make_expr_path(loc); - auto name = make_expr_identifier(loc, inst.data[0]); - stack_.push(make_expr_call(loc, call{ make_expr_function(loc, std::move(path), std::move(name), std::move(args), call::mode::builtin) })); + auto args = expr_arguments::make(loc); + auto path = expr_path::make(loc); + auto name = expr_identifier::make(loc, inst.data[0]); + stack_.push(expr_call::make(loc, expr_function::make(loc, std::move(path), std::move(name), std::move(args), call::mode::builtin))); break; } case opcode::OP_CallBuiltin1: { - auto args = make_expr_arguments(loc); - auto path = make_expr_path(loc); - auto name = make_expr_identifier(loc, inst.data[0]); + auto args = expr_arguments::make(loc); + auto path = expr_path::make(loc); + auto name = expr_identifier::make(loc, inst.data[0]); for (auto i = 1u; i > 0; i--) { - auto var = std::move(stack_.top()); stack_.pop(); + auto var = node::as(std::move(stack_.top())); stack_.pop(); loc = var->loc(); args->list.push_back(std::move(var)); } - stack_.push(make_expr_call(loc, call{ make_expr_function(loc, std::move(path), std::move(name), std::move(args), call::mode::builtin) })); + stack_.push(expr_call::make(loc, expr_function::make(loc, std::move(path), std::move(name), std::move(args), call::mode::builtin))); break; } case opcode::OP_CallBuiltin2: { - auto args = make_expr_arguments(loc); - auto path = make_expr_path(loc); - auto name = make_expr_identifier(loc, inst.data[0]); + auto args = expr_arguments::make(loc); + auto path = expr_path::make(loc); + auto name = expr_identifier::make(loc, inst.data[0]); for (auto i = 2u; i > 0; i--) { - auto var = std::move(stack_.top()); stack_.pop(); + auto var = node::as(std::move(stack_.top())); stack_.pop(); loc = var->loc(); args->list.push_back(std::move(var)); } - stack_.push(make_expr_call(loc, call{ make_expr_function(loc, std::move(path), std::move(name), std::move(args), call::mode::builtin) })); + stack_.push(expr_call::make(loc, expr_function::make(loc, std::move(path), std::move(name), std::move(args), call::mode::builtin))); break; } case opcode::OP_CallBuiltin3: { - auto args = make_expr_arguments(loc); - auto path = make_expr_path(loc); - auto name = make_expr_identifier(loc, inst.data[0]); + auto args = expr_arguments::make(loc); + auto path = expr_path::make(loc); + auto name = expr_identifier::make(loc, inst.data[0]); for (auto i = 3u; i > 0; i--) { - auto var = std::move(stack_.top()); stack_.pop(); + auto var = node::as(std::move(stack_.top())); stack_.pop(); loc = var->loc(); args->list.push_back(std::move(var)); } - stack_.push(make_expr_call(loc, call{ make_expr_function(loc, std::move(path), std::move(name), std::move(args), call::mode::builtin) })); + stack_.push(expr_call::make(loc, expr_function::make(loc, std::move(path), std::move(name), std::move(args), call::mode::builtin))); break; } case opcode::OP_CallBuiltin4: { - auto args = make_expr_arguments(loc); - auto path = make_expr_path(loc); - auto name = make_expr_identifier(loc, inst.data[0]); + auto args = expr_arguments::make(loc); + auto path = expr_path::make(loc); + auto name = expr_identifier::make(loc, inst.data[0]); for (auto i = 4u; i > 0; i--) { - auto var = std::move(stack_.top()); stack_.pop(); + auto var = node::as(std::move(stack_.top())); stack_.pop(); loc = var->loc(); args->list.push_back(std::move(var)); } - stack_.push(make_expr_call(loc, call{ make_expr_function(loc, std::move(path), std::move(name), std::move(args), call::mode::builtin) })); + stack_.push(expr_call::make(loc, expr_function::make(loc, std::move(path), std::move(name), std::move(args), call::mode::builtin))); break; } case opcode::OP_CallBuiltin5: { - auto args = make_expr_arguments(loc); - auto path = make_expr_path(loc); - auto name = make_expr_identifier(loc, inst.data[0]); + auto args = expr_arguments::make(loc); + auto path = expr_path::make(loc); + auto name = expr_identifier::make(loc, inst.data[0]); for (auto i = 5u; i > 0; i--) { - auto var = std::move(stack_.top()); stack_.pop(); + auto var = node::as(std::move(stack_.top())); stack_.pop(); loc = var->loc(); args->list.push_back(std::move(var)); } - stack_.push(make_expr_call(loc, call{ make_expr_function(loc, std::move(path), std::move(name), std::move(args), call::mode::builtin) })); + stack_.push(expr_call::make(loc, expr_function::make(loc, std::move(path), std::move(name), std::move(args), call::mode::builtin))); break; } case opcode::OP_CallBuiltin: { - auto args = make_expr_arguments(loc); - auto path = make_expr_path(loc); - auto name = make_expr_identifier(loc, inst.data[0]); + auto args = expr_arguments::make(loc); + auto path = expr_path::make(loc); + auto name = expr_identifier::make(loc, inst.data[0]); for (auto i = std::stoul(inst.data[1]); i > 0; i--) { - auto var = std::move(stack_.top()); stack_.pop(); + auto var = node::as(std::move(stack_.top())); stack_.pop(); loc = var->loc(); args->list.push_back(std::move(var)); } - stack_.push(make_expr_call(loc, call{ make_expr_function(loc, std::move(path), std::move(name), std::move(args), call::mode::builtin) })); + stack_.push(expr_call::make(loc, expr_function::make(loc, std::move(path), std::move(name), std::move(args), call::mode::builtin))); break; } case opcode::OP_CallBuiltinMethod0: { - auto obj = expr{ std::move(stack_.top()) }; stack_.pop(); - loc = obj.loc(); - auto args = make_expr_arguments(loc); - auto path = make_expr_path(loc); - auto name = make_expr_identifier(loc, inst.data[0]); - stack_.push(make_expr_method(loc, std::move(obj), call{ make_expr_function(loc, std::move(path), std::move(name), std::move(args), call::mode::builtin) })); + auto obj = node::as(std::move(stack_.top())); stack_.pop(); + loc = obj->loc(); + auto args = expr_arguments::make(loc); + auto path = expr_path::make(loc); + auto name = expr_identifier::make(loc, inst.data[0]); + stack_.push(expr_method::make(loc, std::move(obj), expr_function::make(loc, std::move(path), std::move(name), std::move(args), call::mode::builtin))); break; } case opcode::OP_CallBuiltinMethod1: { - auto obj = expr{ std::move(stack_.top()) }; stack_.pop(); - auto args = make_expr_arguments(loc); - auto path = make_expr_path(loc); - auto name = make_expr_identifier(loc, inst.data[0]); + auto obj = node::as(std::move(stack_.top())); stack_.pop(); + auto args = expr_arguments::make(loc); + auto path = expr_path::make(loc); + auto name = expr_identifier::make(loc, inst.data[0]); for (auto i = 1u; i > 0; i--) { - auto var = std::move(stack_.top()); stack_.pop(); + auto var = node::as(std::move(stack_.top())); stack_.pop(); loc = var->loc(); args->list.push_back(std::move(var)); } - stack_.push(make_expr_method(loc, std::move(obj), call{ make_expr_function(loc, std::move(path), std::move(name), std::move(args), call::mode::builtin) })); + stack_.push(expr_method::make(loc, std::move(obj), expr_function::make(loc, std::move(path), std::move(name), std::move(args), call::mode::builtin))); break; } case opcode::OP_CallBuiltinMethod2: { - auto obj = expr{ std::move(stack_.top()) }; stack_.pop(); - auto args = make_expr_arguments(loc); - auto path = make_expr_path(loc); - auto name = make_expr_identifier(loc, inst.data[0]); + auto obj = node::as(std::move(stack_.top())); stack_.pop(); + auto args = expr_arguments::make(loc); + auto path = expr_path::make(loc); + auto name = expr_identifier::make(loc, inst.data[0]); for (auto i = 2u; i > 0; i--) { - auto var = std::move(stack_.top()); stack_.pop(); + auto var = node::as(std::move(stack_.top())); stack_.pop(); loc = var->loc(); args->list.push_back(std::move(var)); } - stack_.push(make_expr_method(loc, std::move(obj), call{ make_expr_function(loc, std::move(path), std::move(name), std::move(args), call::mode::builtin) })); + stack_.push(expr_method::make(loc, std::move(obj), expr_function::make(loc, std::move(path), std::move(name), std::move(args), call::mode::builtin))); break; } case opcode::OP_CallBuiltinMethod3: { - auto obj = expr{ std::move(stack_.top()) }; stack_.pop(); - auto args = make_expr_arguments(loc); - auto path = make_expr_path(loc); - auto name = make_expr_identifier(loc, inst.data[0]); + auto obj = node::as(std::move(stack_.top())); stack_.pop(); + auto args = expr_arguments::make(loc); + auto path = expr_path::make(loc); + auto name = expr_identifier::make(loc, inst.data[0]); for (auto i = 3u; i > 0; i--) { - auto var = std::move(stack_.top()); stack_.pop(); + auto var = node::as(std::move(stack_.top())); stack_.pop(); loc = var->loc(); args->list.push_back(std::move(var)); } - stack_.push(make_expr_method(loc, std::move(obj), call{ make_expr_function(loc, std::move(path), std::move(name), std::move(args), call::mode::builtin) })); + stack_.push(expr_method::make(loc, std::move(obj), expr_function::make(loc, std::move(path), std::move(name), std::move(args), call::mode::builtin))); break; } case opcode::OP_CallBuiltinMethod4: { - auto obj = expr{ std::move(stack_.top()) }; stack_.pop(); - auto args = make_expr_arguments(loc); - auto path = make_expr_path(loc); - auto name = make_expr_identifier(loc, inst.data[0]); + auto obj = node::as(std::move(stack_.top())); stack_.pop(); + auto args = expr_arguments::make(loc); + auto path = expr_path::make(loc); + auto name = expr_identifier::make(loc, inst.data[0]); for (auto i = 4u; i > 0; i--) { - auto var = std::move(stack_.top()); stack_.pop(); + auto var = node::as(std::move(stack_.top())); stack_.pop(); loc = var->loc(); args->list.push_back(std::move(var)); } - stack_.push(make_expr_method(loc, std::move(obj), call{ make_expr_function(loc, std::move(path), std::move(name), std::move(args), call::mode::builtin) })); + stack_.push(expr_method::make(loc, std::move(obj), expr_function::make(loc, std::move(path), std::move(name), std::move(args), call::mode::builtin))); break; } case opcode::OP_CallBuiltinMethod5: { - auto obj = expr{ std::move(stack_.top()) }; stack_.pop(); - auto args = make_expr_arguments(loc); - auto path = make_expr_path(loc); - auto name = make_expr_identifier(loc, inst.data[0]); + auto obj = node::as(std::move(stack_.top())); stack_.pop(); + auto args = expr_arguments::make(loc); + auto path = expr_path::make(loc); + auto name = expr_identifier::make(loc, inst.data[0]); for (auto i = 5u; i > 0; i--) { - auto var = std::move(stack_.top()); stack_.pop(); + auto var = node::as(std::move(stack_.top())); stack_.pop(); loc = var->loc(); args->list.push_back(std::move(var)); } - stack_.push(make_expr_method(loc, std::move(obj), call{ make_expr_function(loc, std::move(path), std::move(name), std::move(args), call::mode::builtin) })); + stack_.push(expr_method::make(loc, std::move(obj), expr_function::make(loc, std::move(path), std::move(name), std::move(args), call::mode::builtin))); break; } case opcode::OP_CallBuiltinMethod: { - auto obj = expr{ std::move(stack_.top()) }; stack_.pop(); - loc = obj.loc(); - auto args = make_expr_arguments(loc); - auto path = make_expr_path(loc); - auto name = make_expr_identifier(loc, inst.data[0]); + auto obj = node::as(std::move(stack_.top())); stack_.pop(); + loc = obj->loc(); + auto args = expr_arguments::make(loc); + auto path = expr_path::make(loc); + auto name = expr_identifier::make(loc, inst.data[0]); for (auto i = std::stoul(inst.data[1]); i > 0; i--) { - auto var = std::move(stack_.top()); stack_.pop(); + auto var = node::as(std::move(stack_.top())); stack_.pop(); loc = var->loc(); args->list.push_back(std::move(var)); } - stack_.push(make_expr_method(loc, std::move(obj), call{ make_expr_function(loc, std::move(path), std::move(name), std::move(args), call::mode::builtin) })); + stack_.push(expr_method::make(loc, std::move(obj), expr_function::make(loc, std::move(path), std::move(name), std::move(args), call::mode::builtin))); break; } case opcode::OP_DecTop: { - auto exp = expr{ std::move(stack_.top()) }; stack_.pop(); - func_->body->block->list.push_back(stmt{ make_stmt_call(exp.loc(), std::move(exp)) }); + auto exp = node::as(std::move(stack_.top())); stack_.pop(); + func_->body->block->list.push_back(stmt_expr::make(exp->loc(), std::move(exp))); break; } case opcode::OP_inc: { - auto lvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - stack_.push(make_expr_increment(lvalue.loc(), std::move(lvalue), false)); + auto lvalue = node::as(std::move(stack_.top())); stack_.pop(); + stack_.push(expr_increment::make(lvalue->loc(), std::move(lvalue), false)); break; } case opcode::OP_dec: { - auto lvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - stack_.push(make_expr_decrement(lvalue.loc(), std::move(lvalue), false)); + auto lvalue = node::as(std::move(stack_.top())); stack_.pop(); + stack_.push(expr_decrement::make(lvalue->loc(), std::move(lvalue), false)); break; } case opcode::OP_bit_or: { - auto rvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - auto lvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - stack_.push(make_expr_bitwise_or(lvalue.loc(), std::move(lvalue), std::move(rvalue))); + auto rvalue = node::as(std::move(stack_.top())); stack_.pop(); + auto lvalue = node::as(std::move(stack_.top())); stack_.pop(); + stack_.push(expr_binary::make(lvalue->loc(), std::move(lvalue), std::move(rvalue), expr_binary::op::bwor)); break; } case opcode::OP_bit_ex_or: { - auto rvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - auto lvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - stack_.push(make_expr_bitwise_exor(lvalue.loc(), std::move(lvalue), std::move(rvalue))); + auto rvalue = node::as(std::move(stack_.top())); stack_.pop(); + auto lvalue = node::as(std::move(stack_.top())); stack_.pop(); + stack_.push(expr_binary::make(lvalue->loc(), std::move(lvalue), std::move(rvalue), expr_binary::op::bwexor)); break; } case opcode::OP_bit_and: { - auto rvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - auto lvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - stack_.push(make_expr_bitwise_and(lvalue.loc(), std::move(lvalue), std::move(rvalue))); + auto rvalue = node::as(std::move(stack_.top())); stack_.pop(); + auto lvalue = node::as(std::move(stack_.top())); stack_.pop(); + stack_.push(expr_binary::make(lvalue->loc(), std::move(lvalue), std::move(rvalue), expr_binary::op::bwand)); break; } case opcode::OP_equality: { - auto rvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - auto lvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - stack_.push(make_expr_equality(lvalue.loc(), std::move(lvalue), std::move(rvalue))); + auto rvalue = node::as(std::move(stack_.top())); stack_.pop(); + auto lvalue = node::as(std::move(stack_.top())); stack_.pop(); + stack_.push(expr_binary::make(lvalue->loc(), std::move(lvalue), std::move(rvalue), expr_binary::op::eq)); break; } case opcode::OP_inequality: { - auto rvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - auto lvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - stack_.push(make_expr_inequality(lvalue.loc(), std::move(lvalue), std::move(rvalue))); + auto rvalue = node::as(std::move(stack_.top())); stack_.pop(); + auto lvalue = node::as(std::move(stack_.top())); stack_.pop(); + stack_.push(expr_binary::make(lvalue->loc(), std::move(lvalue), std::move(rvalue), expr_binary::op::ne)); break; } case opcode::OP_less: { - auto rvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - auto lvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - stack_.push(make_expr_less(lvalue.loc(), std::move(lvalue), std::move(rvalue))); + auto rvalue = node::as(std::move(stack_.top())); stack_.pop(); + auto lvalue = node::as(std::move(stack_.top())); stack_.pop(); + stack_.push(expr_binary::make(lvalue->loc(), std::move(lvalue), std::move(rvalue), expr_binary::op::lt)); break; } case opcode::OP_greater: { - auto rvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - auto lvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - stack_.push(make_expr_greater(lvalue.loc(), std::move(lvalue), std::move(rvalue))); + auto rvalue = node::as(std::move(stack_.top())); stack_.pop(); + auto lvalue = node::as(std::move(stack_.top())); stack_.pop(); + stack_.push(expr_binary::make(lvalue->loc(), std::move(lvalue), std::move(rvalue), expr_binary::op::gt)); break; } case opcode::OP_less_equal: { - auto rvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - auto lvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - stack_.push(make_expr_less_equal(lvalue.loc(), std::move(lvalue), std::move(rvalue))); + auto rvalue = node::as(std::move(stack_.top())); stack_.pop(); + auto lvalue = node::as(std::move(stack_.top())); stack_.pop(); + stack_.push(expr_binary::make(lvalue->loc(), std::move(lvalue), std::move(rvalue), expr_binary::op::le)); break; } case opcode::OP_greater_equal: { - auto rvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - auto lvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - stack_.push(make_expr_greater_equal(lvalue.loc(), std::move(lvalue), std::move(rvalue))); + auto rvalue = node::as(std::move(stack_.top())); stack_.pop(); + auto lvalue = node::as(std::move(stack_.top())); stack_.pop(); + stack_.push(expr_binary::make(lvalue->loc(), std::move(lvalue), std::move(rvalue), expr_binary::op::ge)); break; } case opcode::OP_shift_left: { - auto rvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - auto lvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - stack_.push(make_expr_shift_left(lvalue.loc(), std::move(lvalue), std::move(rvalue))); + auto rvalue = node::as(std::move(stack_.top())); stack_.pop(); + auto lvalue = node::as(std::move(stack_.top())); stack_.pop(); + stack_.push(expr_binary::make(lvalue->loc(), std::move(lvalue), std::move(rvalue), expr_binary::op::shl)); break; } case opcode::OP_shift_right: { - auto rvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - auto lvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - stack_.push(make_expr_shift_right(lvalue.loc(), std::move(lvalue), std::move(rvalue))); + auto rvalue = node::as(std::move(stack_.top())); stack_.pop(); + auto lvalue = node::as(std::move(stack_.top())); stack_.pop(); + stack_.push(expr_binary::make(lvalue->loc(), std::move(lvalue), std::move(rvalue), expr_binary::op::shr)); break; } case opcode::OP_plus: { - auto rvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - auto lvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - stack_.push(make_expr_add(lvalue.loc(), std::move(lvalue), std::move(rvalue))); + auto rvalue = node::as(std::move(stack_.top())); stack_.pop(); + auto lvalue = node::as(std::move(stack_.top())); stack_.pop(); + stack_.push(expr_binary::make(lvalue->loc(), std::move(lvalue), std::move(rvalue), expr_binary::op::add)); break; } case opcode::OP_minus: { - auto rvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - auto lvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - stack_.push(make_expr_sub(lvalue.loc(), std::move(lvalue), std::move(rvalue))); + auto rvalue = node::as(std::move(stack_.top())); stack_.pop(); + auto lvalue = node::as(std::move(stack_.top())); stack_.pop(); + stack_.push(expr_binary::make(lvalue->loc(), std::move(lvalue), std::move(rvalue), expr_binary::op::sub)); break; } case opcode::OP_multiply: { - auto rvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - auto lvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - stack_.push(make_expr_mul(lvalue.loc(), std::move(lvalue), std::move(rvalue))); + auto rvalue = node::as(std::move(stack_.top())); stack_.pop(); + auto lvalue = node::as(std::move(stack_.top())); stack_.pop(); + stack_.push(expr_binary::make(lvalue->loc(), std::move(lvalue), std::move(rvalue), expr_binary::op::mul)); break; } case opcode::OP_divide: { - auto rvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - auto lvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - stack_.push(make_expr_div(lvalue.loc(), std::move(lvalue), std::move(rvalue))); + auto rvalue = node::as(std::move(stack_.top())); stack_.pop(); + auto lvalue = node::as(std::move(stack_.top())); stack_.pop(); + stack_.push(expr_binary::make(lvalue->loc(), std::move(lvalue), std::move(rvalue), expr_binary::op::div)); break; } case opcode::OP_mod: { - auto rvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - auto lvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - stack_.push(make_expr_mod(lvalue.loc(), std::move(lvalue), std::move(rvalue))); + auto rvalue = node::as(std::move(stack_.top())); stack_.pop(); + auto lvalue = node::as(std::move(stack_.top())); stack_.pop(); + stack_.push(expr_binary::make(lvalue->loc(), std::move(lvalue), std::move(rvalue), expr_binary::op::mod)); break; } case opcode::OP_wait: { - auto exp = expr{ std::move(stack_.top()) }; stack_.pop(); - func_->body->block->list.push_back(stmt{ make_stmt_wait(exp.loc(), std::move(exp)) }); + auto exp = node::as(std::move(stack_.top())); stack_.pop(); + func_->body->block->list.push_back(stmt_wait::make(exp->loc(), std::move(exp))); break; } case opcode::OP_waittillFrameEnd: { - func_->body->block->list.push_back(stmt{ make_stmt_waittillframeend(loc) }); + func_->body->block->list.push_back(stmt_waittillframeend::make(loc)); break; } case opcode::OP_waitframe: { - func_->body->block->list.push_back(stmt{ make_stmt_waitframe(loc) }); + func_->body->block->list.push_back(stmt_waitframe::make(loc)); break; } case opcode::OP_waittill: { - auto args = make_expr_arguments(loc); - auto obj = expr{ std::move(stack_.top()) }; stack_.pop(); - auto event = expr{ std::move(stack_.top()) }; stack_.pop(); - stack_.push(make_stmt_waittill(event.loc(), std::move(obj), std::move(event), std::move(args))); + auto args = expr_arguments::make(loc); + auto obj = node::as(std::move(stack_.top())); stack_.pop(); + auto event = node::as(std::move(stack_.top())); stack_.pop(); + stack_.push(stmt_waittill::make(event->loc(), std::move(obj), std::move(event), std::move(args))); in_waittill_ = true; break; } case opcode::OP_waittillmatch: { - auto args = make_expr_arguments(loc); - auto obj = expr{ std::move(stack_.top()) }; stack_.pop(); - auto event = expr{ std::move(stack_.top()) }; stack_.pop(); - loc = event.loc(); + auto args = expr_arguments::make(loc); + auto obj = node::as(std::move(stack_.top())); stack_.pop(); + auto event = node::as(std::move(stack_.top())); stack_.pop(); + loc = event->loc(); for (auto i = std::stoul(inst.data[0]); i > 0; i--) { - auto arg = std::move(stack_.top()); stack_.pop(); + auto arg = node::as(std::move(stack_.top())); stack_.pop(); loc = arg->loc(); args->list.push_back(std::move(arg)); } - func_->body->block->list.push_back(stmt{ make_stmt_waittillmatch(loc, std::move(obj), std::move(event), std::move(args)) }); + func_->body->block->list.push_back(stmt_waittillmatch::make(loc, std::move(obj), std::move(event), std::move(args))); break; } case opcode::OP_clearparams: { if (in_waittill_) { - auto args = make_expr_arguments(loc); + auto args = expr_arguments::make(loc); auto arg = std::move(stack_.top()); stack_.pop(); while (arg->kind() != node::stmt_waittill) { - args->list.push_back(std::move(arg)); + args->list.push_back(node::as(std::move(arg))); arg = std::move(stack_.top()); stack_.pop(); } @@ -1121,235 +1121,235 @@ auto decompiler::decompile_instruction(instruction const& inst) -> void in_waittill_ = false; } - func_->body->block->list.push_back(stmt{ std::move(arg) }); + func_->body->block->list.push_back(node::as(std::move(arg))); } break; } case opcode::OP_notify: { - auto args = make_expr_arguments(loc); - auto obj = expr{ std::move(stack_.top()) }; stack_.pop(); - auto event = expr{ std::move(stack_.top()) }; stack_.pop(); + auto args = expr_arguments::make(loc); + auto obj = node::as(std::move(stack_.top())); stack_.pop(); + auto event = node::as(std::move(stack_.top())); stack_.pop(); auto var = std::move(stack_.top()); stack_.pop(); loc = var->loc(); - while (var->kind() != node::asm_voidcodepos) + while (var->kind() != node::node_voidcodepos) { - args->list.push_back(std::move(var)); + args->list.push_back(node::as(std::move(var))); var = std::move(stack_.top()); stack_.pop(); loc = var->loc(); } - func_->body->block->list.push_back(stmt{ make_stmt_notify(loc, std::move(obj), std::move(event), std::move(args)) }); + func_->body->block->list.push_back(stmt_notify::make(loc, std::move(obj), std::move(event), std::move(args))); break; } case opcode::OP_endon: { - auto obj = expr{ std::move(stack_.top()) }; stack_.pop(); - auto event = expr{ std::move(stack_.top()) }; stack_.pop(); - func_->body->block->list.push_back(stmt{ make_stmt_endon(event.loc(), std::move(obj), std::move(event)) }); + auto obj = node::as(std::move(stack_.top())); stack_.pop(); + auto event = node::as(std::move(stack_.top())); stack_.pop(); + func_->body->block->list.push_back(stmt_endon::make(event->loc(), std::move(obj), std::move(event))); break; } case opcode::OP_voidCodepos: { - stack_.push(make_asm_voidcodepos(loc)); + stack_.push(node_voidcodepos::make(loc)); break; } case opcode::OP_vector: { - auto x = expr{ std::move(stack_.top()) }; stack_.pop(); - auto y = expr{ std::move(stack_.top()) }; stack_.pop(); - auto z = expr{ std::move(stack_.top()) }; stack_.pop(); - stack_.push(make_expr_vector(z.loc(), std::move(x), std::move(y), std::move(z))); + auto x = node::as(std::move(stack_.top())); stack_.pop(); + auto y = node::as(std::move(stack_.top())); stack_.pop(); + auto z = node::as(std::move(stack_.top())); stack_.pop(); + stack_.push(expr_vector::make(z->loc(), std::move(x), std::move(y), std::move(z))); break; } case opcode::OP_size: { - auto lvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - stack_.push(make_expr_size(lvalue.loc(), std::move(lvalue))); + auto lvalue = node::as(std::move(stack_.top())); stack_.pop(); + stack_.push(expr_size::make(lvalue->loc(), std::move(lvalue))); break; } case opcode::OP_EvalLevelFieldVariable: { - auto obj = expr{ make_expr_level(loc) }; - auto field = make_expr_identifier(loc, inst.data[0]); - stack_.push(make_expr_field(loc, std::move(obj), std::move(field))); + auto obj = expr_level::make(loc); + auto field = expr_identifier::make(loc, inst.data[0]); + stack_.push(expr_field::make(loc, std::move(obj), std::move(field))); break; } case opcode::OP_EvalAnimFieldVariable: { - auto obj = expr{ make_expr_anim(loc) }; - auto field = make_expr_identifier(loc, inst.data[0]); - stack_.push(make_expr_field(loc, std::move(obj), std::move(field))); + auto obj = expr_anim::make(loc); + auto field = expr_identifier::make(loc, inst.data[0]); + stack_.push(expr_field::make(loc, std::move(obj), std::move(field))); break; } case opcode::OP_EvalSelfFieldVariable: { - auto obj = expr{ make_expr_self(loc) }; - auto field = make_expr_identifier(loc, inst.data[0]); - stack_.push(make_expr_field(loc, std::move(obj), std::move(field))); + auto obj = expr_self::make(loc); + auto field = expr_identifier::make(loc, inst.data[0]); + stack_.push(expr_field::make(loc, std::move(obj), std::move(field))); break; } case opcode::OP_EvalFieldVariable: { - auto obj = expr{ std::move(stack_.top()) }; stack_.pop(); - auto field = make_expr_identifier(loc, inst.data[0]); - stack_.push(make_expr_field(obj.loc(), std::move(obj), std::move(field))); + auto obj = node::as(std::move(stack_.top())); stack_.pop(); + auto field = expr_identifier::make(loc, inst.data[0]); + stack_.push(expr_field::make(obj->loc(), std::move(obj), std::move(field))); break; } case opcode::OP_EvalLevelFieldVariableRef: { - auto obj = expr{ make_expr_level(loc) }; - auto field = make_expr_identifier(loc, inst.data[0]); - stack_.push(make_expr_field(loc, std::move(obj), std::move(field))); + auto obj = expr_level::make(loc); + auto field = expr_identifier::make(loc, inst.data[0]); + stack_.push(expr_field::make(loc, std::move(obj), std::move(field))); break; } case opcode::OP_EvalAnimFieldVariableRef: { - auto obj = expr{ make_expr_anim(loc) }; - auto field = make_expr_identifier(loc, inst.data[0]); - stack_.push(make_expr_field(loc, std::move(obj), std::move(field))); + auto obj = expr_anim::make(loc); + auto field = expr_identifier::make(loc, inst.data[0]); + stack_.push(expr_field::make(loc, std::move(obj), std::move(field))); break; } case opcode::OP_EvalSelfFieldVariableRef: { - auto obj = expr{ make_expr_self(loc) }; - auto field = make_expr_identifier(loc, inst.data[0]); - stack_.push(make_expr_field(loc, std::move(obj), std::move(field))); + auto obj = expr_self::make(loc); + auto field = expr_identifier::make(loc, inst.data[0]); + stack_.push(expr_field::make(loc, std::move(obj), std::move(field))); break; } case opcode::OP_EvalFieldVariableRef: { - auto obj = expr{ std::move(stack_.top()) }; stack_.pop(); - auto field = make_expr_identifier(loc, inst.data[0]); - stack_.push(make_expr_field(obj.loc(), std::move(obj), std::move(field))); + auto obj = node::as(std::move(stack_.top())); stack_.pop(); + auto field = expr_identifier::make(loc, inst.data[0]); + stack_.push(expr_field::make(obj->loc(), std::move(obj), std::move(field))); break; } case opcode::OP_ClearFieldVariable: { - auto obj = expr{ std::move(stack_.top()) }; stack_.pop(); - loc = obj.loc(); - auto name = make_expr_identifier(loc, inst.data[0]); - auto field = expr{ make_expr_field(loc, std::move(obj), std::move(name)) }; - auto undef = expr{ make_expr_undefined(loc) }; - auto exp = expr{ make_expr_assign_equal(loc, std::move(field), std::move(undef)) }; - func_->body->block->list.push_back(stmt{ make_stmt_assign(loc, std::move(exp)) }); + auto obj = node::as(std::move(stack_.top())); stack_.pop(); + loc = obj->loc(); + auto name = expr_identifier::make(loc, inst.data[0]); + auto field = expr_field::make(loc, std::move(obj), std::move(name)); + auto undef = expr_undefined::make(loc); + auto exp = expr_assign::make(loc, std::move(field), std::move(undef), expr_assign::op::eq); + func_->body->block->list.push_back(stmt_expr::make(loc, std::move(exp))); break; } case opcode::OP_SafeCreateVariableFieldCached: { auto name = (ctx_->props() & props::hash) ? inst.data[0] : fmt::format("var_{}", inst.data[0]); - func_->params->list.push_back(make_expr_identifier(loc, name)); + func_->params->list.push_back(expr_identifier::make(loc, name)); break; } case opcode::OP_SafeSetWaittillVariableFieldCached: { - if (stack_.top()->kind() != node::asm_create) + if (stack_.top()->kind() != node::expr_var_create) { - stack_.push(make_asm_access(loc, inst.data[0])); + stack_.push(expr_var_access::make(loc, inst.data[0])); } break; } case opcode::OP_SafeSetVariableFieldCached0: { - func_->params->list.push_back(make_expr_identifier(loc, "var_0")); + func_->params->list.push_back(expr_identifier::make(loc, "var_0")); break; } case opcode::OP_SafeSetVariableFieldCached: { - func_->params->list.push_back(make_expr_identifier(loc, "var_" + inst.data[0])); + func_->params->list.push_back(expr_identifier::make(loc, "var_" + inst.data[0])); break; } case opcode::OP_EvalLocalVariableRefCached0: { - stack_.push(make_asm_access(loc, "0")); + stack_.push(expr_var_access::make(loc, "0")); break; } case opcode::OP_EvalLocalVariableRefCached: { - stack_.push(make_asm_access(loc, inst.data[0])); + stack_.push(expr_var_access::make(loc, inst.data[0])); break; } case opcode::OP_SetLevelFieldVariableField: { - auto rvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - loc = rvalue.loc(); - auto obj = expr{ make_expr_level(loc) }; - auto field = make_expr_identifier(loc, inst.data[0]); - auto lvalue = expr{ make_expr_field(loc, std::move(obj), std::move(field)) }; - auto exp = expr{ make_expr_assign_equal(loc, std::move(lvalue), std::move(rvalue)) }; - func_->body->block->list.push_back(stmt{ make_stmt_assign(loc, std::move(exp)) }); + auto rvalue = node::as(std::move(stack_.top())); stack_.pop(); + loc = rvalue->loc(); + auto obj = expr_level::make(loc); + auto field = expr_identifier::make(loc, inst.data[0]); + auto lvalue = expr_field::make(loc, std::move(obj), std::move(field)); + auto exp = expr_assign::make(loc, std::move(lvalue), std::move(rvalue), expr_assign::op::eq); + func_->body->block->list.push_back(stmt_expr::make(loc, std::move(exp))); break; } case opcode::OP_SetVariableField: { - auto lvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - loc = lvalue.loc(); + auto lvalue = node::as(std::move(stack_.top())); stack_.pop(); + loc = lvalue->loc(); - if (lvalue == node::expr_increment) + if (lvalue->is()) { - func_->body->block->list.push_back(stmt{ make_stmt_assign(loc, std::move(lvalue)) }); + func_->body->block->list.push_back(stmt_expr::make(loc, std::move(lvalue))); } - else if (lvalue == node::expr_decrement) + else if (lvalue->is()) { - func_->body->block->list.push_back(stmt{ make_stmt_assign(loc, std::move(lvalue)) }); + func_->body->block->list.push_back(stmt_expr::make(loc, std::move(lvalue))); } else { - auto rvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - loc = rvalue.loc(); - auto exp = expr{ make_expr_assign_equal(loc, std::move(lvalue), std::move(rvalue)) }; - func_->body->block->list.push_back(stmt{ make_stmt_assign(loc, std::move(exp)) }); + auto rvalue = node::as(std::move(stack_.top())); stack_.pop(); + loc = rvalue->loc(); + auto exp = expr_assign::make(loc, std::move(lvalue), std::move(rvalue), expr_assign::op::eq); + func_->body->block->list.push_back(stmt_expr::make(loc, std::move(exp))); } break; } case opcode::OP_SetAnimFieldVariableField: { - auto rvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - loc = rvalue.loc(); - auto obj = expr{ make_expr_anim(loc) }; - auto field = make_expr_identifier(loc, inst.data[0]); - auto lvalue = expr{ make_expr_field(loc, std::move(obj), std::move(field)) }; - auto exp = expr{ make_expr_assign_equal(loc, std::move(lvalue), std::move(rvalue)) }; - func_->body->block->list.push_back(stmt{ make_stmt_assign(loc, std::move(exp)) }); + auto rvalue = node::as(std::move(stack_.top())); stack_.pop(); + loc = rvalue->loc(); + auto obj = expr_anim::make(loc); + auto field = expr_identifier::make(loc, inst.data[0]); + auto lvalue = expr_field::make(loc, std::move(obj), std::move(field)); + auto exp = expr_assign::make(loc, std::move(lvalue), std::move(rvalue), expr_assign::op::eq); + func_->body->block->list.push_back(stmt_expr::make(loc, std::move(exp))); break; } case opcode::OP_SetSelfFieldVariableField: { - auto rvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - loc = rvalue.loc(); - auto obj = expr{ make_expr_self(loc) }; - auto field = make_expr_identifier(loc, inst.data[0]); - auto lvalue = expr{ make_expr_field(loc, std::move(obj), std::move(field)) }; - auto exp = expr{ make_expr_assign_equal(loc, std::move(lvalue), std::move(rvalue)) }; - func_->body->block->list.push_back(stmt{ make_stmt_assign(loc, std::move(exp)) }); + auto rvalue = node::as(std::move(stack_.top())); stack_.pop(); + loc = rvalue->loc(); + auto obj = expr_self::make(loc); + auto field = expr_identifier::make(loc, inst.data[0]); + auto lvalue = expr_field::make(loc, std::move(obj), std::move(field)); + auto exp = expr_assign::make(loc, std::move(lvalue), std::move(rvalue), expr_assign::op::eq); + func_->body->block->list.push_back(stmt_expr::make(loc, std::move(exp))); break; } case opcode::OP_SetLocalVariableFieldCached0: { - auto lvalue = expr{ make_asm_access(loc, "0") }; - auto rvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - loc = rvalue.loc(); - auto exp = expr{ make_expr_assign_equal(loc, std::move(lvalue), std::move(rvalue)) }; - func_->body->block->list.push_back(stmt{ make_stmt_assign(loc, std::move(exp)) }); + auto lvalue = expr_var_access::make(loc, "0"); + auto rvalue = node::as(std::move(stack_.top())); stack_.pop(); + loc = rvalue->loc(); + auto exp = expr_assign::make(loc, std::move(lvalue), std::move(rvalue), expr_assign::op::eq); + func_->body->block->list.push_back(stmt_expr::make(loc, std::move(exp))); break; } case opcode::OP_SetNewLocalVariableFieldCached0: { - auto lvalue = expr{ make_asm_create(loc, inst.data[0]) }; - auto rvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - loc = rvalue.loc(); + auto lvalue = expr_var_create::make(loc, inst.data[0]); + auto rvalue = node::as(std::move(stack_.top())); stack_.pop(); + loc = rvalue->loc(); if (func_->body->block->list.size() > 0) { std::vector vars; - while (func_->body->block->list.back() == node::asm_create) + while (func_->body->block->list.back()->is()) { auto& entry = func_->body->block->list.back(); - if (loc.begin.line < entry.loc().begin.line) + if (loc.begin.line < entry->loc().begin.line) { - vars.push_back(entry.as_asm_create->index); + vars.push_back(entry->as().index); func_->body->block->list.pop_back(); continue; } @@ -1357,96 +1357,96 @@ auto decompiler::decompile_instruction(instruction const& inst) -> void } std::reverse(vars.begin(), vars.end()); - lvalue.as_asm_create->vars = vars; + lvalue->vars = vars; } - auto exp = expr{ make_expr_assign_equal(loc, std::move(lvalue), std::move(rvalue)) }; - func_->body->block->list.push_back(stmt{ make_stmt_assign(loc, std::move(exp)) }); + auto exp = expr_assign::make(loc, std::move(lvalue), std::move(rvalue), expr_assign::op::eq); + func_->body->block->list.push_back(stmt_expr::make(loc, std::move(exp))); break; } case opcode::OP_SetLocalVariableFieldCached: { - auto lvalue = expr{ make_asm_access(loc, inst.data[0]) }; - auto rvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - loc = rvalue.loc(); - auto exp = expr{ make_expr_assign_equal(loc, std::move(lvalue), std::move(rvalue)) }; - func_->body->block->list.push_back(stmt{ make_stmt_assign(loc, std::move(exp)) }); + auto lvalue = expr_var_access::make(loc, inst.data[0]); + auto rvalue = node::as(std::move(stack_.top())); stack_.pop(); + loc = rvalue->loc(); + auto exp = expr_assign::make(loc, std::move(lvalue), std::move(rvalue), expr_assign::op::eq); + func_->body->block->list.push_back(stmt_expr::make(loc, std::move(exp))); break; } case opcode::OP_ClearLocalVariableFieldCached: { - func_->body->block->list.push_back(stmt{ make_asm_clear(loc, inst.data[0]) }); + func_->body->block->list.push_back(stmt_clear::make(loc, inst.data[0])); break; } case opcode::OP_ClearLocalVariableFieldCached0: { - func_->body->block->list.push_back(stmt{ make_asm_clear(loc, "0") }); + func_->body->block->list.push_back(stmt_clear::make(loc, "0")); break; } case opcode::OP_EvalLocalVariableObjectCached: { - stack_.push(make_asm_access(loc, inst.data[0])); + stack_.push(expr_var_access::make(loc, inst.data[0])); break; } case opcode::OP_BoolNot: { - auto lvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - stack_.push(make_expr_not(lvalue.loc(), std::move(lvalue))); + auto lvalue = node::as(std::move(stack_.top())); stack_.pop(); + stack_.push(expr_not::make(lvalue->loc(), std::move(lvalue))); break; } case opcode::OP_BoolComplement: { - auto lvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - stack_.push(make_expr_complement(lvalue.loc(), std::move(lvalue))); + auto lvalue = node::as(std::move(stack_.top())); stack_.pop(); + stack_.push(expr_complement::make(lvalue->loc(), std::move(lvalue))); break; } case opcode::OP_switch: { - auto test = expr{ std::move(stack_.top()) }; stack_.pop(); - func_->body->block->list.push_back(stmt{ make_asm_switch(test.loc(), std::move(test), inst.data[0]) }); + auto test = node::as(std::move(stack_.top())); stack_.pop(); + func_->body->block->list.push_back(stmt_jmp_switch::make(test->loc(), std::move(test), inst.data[0])); break; } case opcode::OP_endswitch: { - func_->body->block->list.push_back(stmt{ make_asm_endswitch(loc, inst.data) }); + func_->body->block->list.push_back(stmt_jmp_endswitch::make(loc, inst.data)); break; } case opcode::OP_jump: { - func_->body->block->list.push_back(stmt{ make_asm_jmp(loc, inst.data[0]) }); + func_->body->block->list.push_back(stmt_jmp::make(loc, inst.data[0])); if (stack_.size() != 0) tern_labels_.push_back(inst.data[0]); break; } case opcode::OP_jumpback: { - func_->body->block->list.push_back(stmt{ make_asm_jmp_back(loc, inst.data[0]) }); + func_->body->block->list.push_back(stmt_jmp_back::make(loc, inst.data[0])); break; } case opcode::OP_JumpOnTrue: { - auto lvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - loc = lvalue.loc(); - auto test = expr{ make_expr_not(loc, std::move(lvalue)) }; - func_->body->block->list.push_back(stmt{ make_asm_jmp_cond(loc, std::move(test), inst.data[0]) }); + auto lvalue = node::as(std::move(stack_.top())); stack_.pop(); + loc = lvalue->loc(); + auto test = expr_not::make(loc, std::move(lvalue)); + func_->body->block->list.push_back(stmt_jmp_cond::make(loc, std::move(test), inst.data[0])); break; } case opcode::OP_JumpOnFalse: { - auto test = expr{ std::move(stack_.top()) }; stack_.pop(); - func_->body->block->list.push_back(stmt{ make_asm_jmp_cond(test.loc(), std::move(test), inst.data[0]) }); + auto test = node::as(std::move(stack_.top())); stack_.pop(); + func_->body->block->list.push_back(stmt_jmp_cond::make(test->loc(), std::move(test), inst.data[0])); break; } case opcode::OP_JumpOnTrueExpr: { - auto test = expr{ std::move(stack_.top()) }; stack_.pop(); - stack_.push(make_asm_jmp_true(test.loc(), std::move(test), inst.data[0])); + auto test = node::as(std::move(stack_.top())); stack_.pop(); + stack_.push(stmt_jmp_true::make(test->loc(), std::move(test), inst.data[0])); expr_labels_.push_back(inst.data[0]); break; } case opcode::OP_JumpOnFalseExpr: { - auto test = expr{ std::move(stack_.top()) }; stack_.pop(); - stack_.push(make_asm_jmp_false(test.loc(), std::move(test), inst.data[0])); + auto test = node::as(std::move(stack_.top())); stack_.pop(); + stack_.push(stmt_jmp_false::make(test->loc(), std::move(test), inst.data[0])); expr_labels_.push_back(inst.data[0]); break; } @@ -1457,46 +1457,46 @@ auto decompiler::decompile_instruction(instruction const& inst) -> void for (auto i = 1; i <= count; i++) { auto name = (ctx_->props() & props::hash) ? inst.data[i] : fmt::format("var_{}", inst.data[i]); - func_->params->list.push_back(make_expr_identifier(loc, name)); + func_->params->list.push_back(expr_identifier::make(loc, name)); } break; } case opcode::OP_IsDefined: { - auto value = expr{ std::move(stack_.top()) }; stack_.pop(); - stack_.push(make_expr_isdefined(value.loc(), std::move(value))); + auto value = node::as(std::move(stack_.top())); stack_.pop(); + stack_.push(expr_isdefined::make(value->loc(), std::move(value))); break; } case opcode::OP_IsTrue: { - auto value = expr{ std::move(stack_.top()) }; stack_.pop(); - stack_.push(make_expr_istrue(value.loc(), std::move(value))); + auto value = node::as(std::move(stack_.top())); stack_.pop(); + stack_.push(expr_istrue::make(value->loc(), std::move(value))); break; } case opcode::OP_BoolNotAfterAnd: { - auto value = expr{ std::move(stack_.top()) }; stack_.pop(); - stack_.push(make_expr_not(value.loc(), std::move(value))); + auto value = node::as(std::move(stack_.top())); stack_.pop(); + stack_.push(expr_not::make(value->loc(), std::move(value))); break; } case opcode::OP_GetStatHash: { - stack_.push(make_expr_string(loc, fmt::format("stat_{}", inst.data[0]))); + stack_.push(expr_string::make(loc, fmt::format("stat_{}", inst.data[0]))); break; } case opcode::OP_GetUnkxHash: { - stack_.push(make_expr_string(loc, fmt::format("hunk_{}", inst.data[0]))); + stack_.push(expr_string::make(loc, fmt::format("hunk_{}", inst.data[0]))); break; } case opcode::OP_GetEnumHash: { - stack_.push(make_expr_string(loc, fmt::format("enum_{}", inst.data[0]))); + stack_.push(expr_string::make(loc, fmt::format("enum_{}", inst.data[0]))); break; } case opcode::OP_GetDvarHash: { - stack_.push(make_expr_string(loc, fmt::format("dvar_{}", inst.data[0]))); + stack_.push(expr_string::make(loc, fmt::format("dvar_{}", inst.data[0]))); break; } case opcode::OP_waittillmatch2: @@ -1520,19 +1520,19 @@ auto decompiler::decompile_expressions(instruction const& inst) -> void { if (exp == itr->second) { - auto rvalue = expr{ std::move(stack_.top()) }; stack_.pop(); + auto rvalue = node::as(std::move(stack_.top())); stack_.pop(); auto jump = std::move(stack_.top()); stack_.pop(); auto loc = jump->loc(); - if (jump->kind() == node::asm_jmp_true) + if (jump->kind() == node::stmt_jmp_true) { - auto lvalue = std::move(reinterpret_cast(jump.get())->test); - stack_.push(make_expr_or(loc, std::move(lvalue), std::move(rvalue))); + auto lvalue = std::move(reinterpret_cast(jump.get())->test); + stack_.push(expr_binary::make(loc, std::move(lvalue), std::move(rvalue), expr_binary::op::bool_or)); } - else if (jump->kind() == node::asm_jmp_false) + else if (jump->kind() == node::stmt_jmp_false) { - auto lvalue = std::move(reinterpret_cast(jump.get())->test); - stack_.push(make_expr_and(loc, std::move(lvalue), std::move(rvalue))); + auto lvalue = std::move(reinterpret_cast(jump.get())->test); + stack_.push(expr_binary::make(loc, std::move(lvalue), std::move(rvalue), expr_binary::op::bool_and)); } else { @@ -1545,17 +1545,17 @@ auto decompiler::decompile_expressions(instruction const& inst) -> void { if (tern == itr->second) { - auto rvalue = expr{ std::move(stack_.top()) }; stack_.pop(); - auto lvalue = expr{ std::move(stack_.top()) }; stack_.pop(); + auto rvalue = node::as(std::move(stack_.top())); stack_.pop(); + auto lvalue = node::as(std::move(stack_.top())); stack_.pop(); func_->body->block->list.pop_back(); auto stm = std::move(func_->body->block->list.back()); func_->body->block->list.pop_back(); - if (stm == node::asm_jmp_cond) + if (stm->is()) { - auto loc = stm.as_cond->loc(); - stack_.push(make_expr_ternary(loc, std::move(stm.as_cond->test), std::move(lvalue), std::move(rvalue))); + auto loc = stm->as().loc(); + stack_.push(expr_ternary::make(loc, std::move(stm->as().test), std::move(lvalue), std::move(rvalue))); } else { @@ -1581,12 +1581,12 @@ auto decompiler::decompile_loops(stmt_list& stm) -> void for (auto i = static_cast(stm.list.size() - 1); i >= 0; i--) { - if (stm.list.at(i) == node::asm_jmp_back) + if (stm.list.at(i)->is()) { - auto break_loc = last_location_index(stm, i) ? locs_.end : stm.list.at(i + 1).label(); - auto start = find_location_index(stm, stm.list.at(i).as_jump_back->value); + auto break_loc = last_location_index(stm, i) ? locs_.end : stm.list.at(i + 1)->label(); + auto start = find_location_index(stm, stm.list.at(i)->as().value); - if (i > 0 && stm.list.at(i - 1) == node::asm_jmp_cond) + if (i > 0 && stm.list.at(i - 1)->is()) { if (i - 1 == static_cast(start)) // condition belongs to empty loop { @@ -1594,7 +1594,7 @@ auto decompiler::decompile_loops(stmt_list& stm) -> void i = static_cast(stm.list.size()); continue; } - else if (static_cast(i) < find_location_index(stm, stm.list.at(i - 1).as_cond->value)) + else if (static_cast(i) < find_location_index(stm, stm.list.at(i - 1)->as().value)) { decompile_dowhile(stm, i - 1, i); i = static_cast(stm.list.size()); @@ -1606,11 +1606,11 @@ auto decompiler::decompile_loops(stmt_list& stm) -> void { decompile_inf(stm, start, i); } - else if (stm.list.at(start) != node::asm_jmp_cond) // no condition + else if (!stm.list.at(start)->is()) // no condition { decompile_inf(stm, start, i); } - else if (stm.list.at(start).as_cond->value != break_loc) // condition belong to other stmt + else if (stm.list.at(start)->as().value != break_loc) // condition belong to other stmt { decompile_inf(stm, start, i); } @@ -1628,9 +1628,9 @@ auto decompiler::decompile_switches(stmt_list& stm) -> void { for (auto i = 0u; i < stm.list.size(); i++) { - if (stm.list[i] == node::asm_switch) + if (stm.list[i]->is()) { - auto end = find_location_index(stm, stm.list[i].as_asm_switch->value); + auto end = find_location_index(stm, stm.list[i]->as().value); decompile_switch(stm, i, end); } } @@ -1642,33 +1642,33 @@ auto decompiler::decompile_ifelses(stmt_list& stm) -> void { auto const& entry = stm.list.at(i); - if (entry == node::asm_jmp_cond) + if (entry->is()) { - auto j = find_location_index(stm, entry.as_cond->value) - 1; + auto j = find_location_index(stm, entry->as().value) - 1; auto last_loc = locs_.end; - if (stm.list.at(j) == node::asm_jmp) + if (stm.list.at(j)->is()) { // if scope is a loop check break, continue - if (stm.list.at(j).as_jump->value == locs_.cnt) + if (stm.list.at(j)->as().value == locs_.cnt) { // check for if/else or if/continue - if (j - i > 1 && stm.list.at(j - 1) == node::stmt_return) + if (j - i > 1 && stm.list.at(j - 1)->is()) { // scope ends with a return, so jump belows to if/else decompile_ifelse(stm, i, j); } - else if (j - i > 1 && stm.list.at(j - 1) == node::asm_jmp) + else if (j - i > 1 && stm.list.at(j - 1)->is()) { - if (stm.list.at(j - 1).as_jump->value == locs_.brk) + if (stm.list.at(j - 1)->as().value == locs_.brk) { // scope ends with a break, so jump belows to if/else decompile_ifelse(stm, i, j); } - else if (stm.list.at(j - 1).as_jump->value == locs_.cnt) + else if (stm.list.at(j - 1)->as().value == locs_.cnt) { // if { break/return } else { continue } at loop scope end - if (j - i > 2 && (stm.list.at(j - 2) == node::asm_jmp || stm.list.at(j - 2) == node::stmt_return)) + if (j - i > 2 && (stm.list.at(j - 2)->is() || stm.list.at(j - 2)->is())) { decompile_if(stm, i, j); } @@ -1689,13 +1689,13 @@ auto decompiler::decompile_ifelses(stmt_list& stm) -> void decompile_if(stm, i, j); } } - else if (stm.list.at(j).as_jump->value == locs_.brk) + else if (stm.list.at(j)->as().value == locs_.brk) { decompile_if(stm, i, j); } - else if (stm.list.at(j).as_jump->value == entry.as_cond->value) + else if (stm.list.at(j)->as().value == entry->as().value) { - if (find_location_reference(stm, i + 1, j, entry.as_cond->value)) + if (find_location_reference(stm, i + 1, j, entry->as().value)) { // if scope, have a empty else inside at end decompile_if(stm, i, j); @@ -1710,11 +1710,11 @@ auto decompiler::decompile_ifelses(stmt_list& stm) -> void decompile_ifelse(stm, i, j); } } - else if (stm.list.at(j) == node::stmt_return && stm.list.at(j).as_return->value == node::null) + else if (stm.list.at(j)->is() && stm.list.at(j)->as().value->is()) { - if(entry.as_cond->value != locs_.end) + if(entry->as().value != locs_.end) { - auto ref = stm.list.at(j + 1).label(); + auto ref = stm.list.at(j + 1)->label(); if (find_location_reference(stm, i + 1, j, ref)) { @@ -1732,11 +1732,11 @@ auto decompiler::decompile_ifelses(stmt_list& stm) -> void { decompile_if(stm, i, j); // only one explicit return } - else if (stm.list.back() != node::stmt_return) + else if (!stm.list.back()->is()) { decompile_if(stm, i, j); // scope end is not a last return } - else if (locs_.last && stm.list.back() != node::stmt_return) + else if (locs_.last && !stm.list.back()->is()) { decompile_if(stm, i, j); // inside a last scope but is not and inner last } @@ -1765,20 +1765,20 @@ auto decompiler::decompile_aborts(stmt_list& stm) -> void { for (auto i = 0u; i < stm.list.size(); i++) { - if (stm.list[i] == node::asm_jmp) + if (stm.list[i]->is()) { - auto const loc = stm.list[i].loc(); - auto const jmp = stm.list[i].as_jump->value; + auto const loc = stm.list[i]->loc(); + auto const jmp = stm.list[i]->as().value; if (jmp == locs_.brk) { stm.list.erase(stm.list.begin() + i); - stm.list.insert(stm.list.begin() + i, stmt{ make_stmt_break(loc) }); + stm.list.insert(stm.list.begin() + i, stmt_break::make(loc)); } else if (jmp == locs_.cnt) { stm.list.erase(stm.list.begin() + i); - stm.list.insert(stm.list.begin() + i, stmt{ make_stmt_continue(loc) }); + stm.list.insert(stm.list.begin() + i, stmt_continue::make(loc)); } else { @@ -1792,34 +1792,34 @@ auto decompiler::decompile_tuples(stmt_list& stm) -> void { for (auto i = 1u; i < stm.list.size(); i++) { - if (stm.list.at(i) == node::asm_clear) + if (stm.list.at(i)->is()) { auto j = i - 1; auto found = false, done = false; - while (j >= 0 && stm.list.at(j) == node::stmt_assign) + while (j >= 0 && stm.list.at(j)->is()) { - auto const& exp = stm.list.at(j).as_assign->value; + auto const& exp = stm.list.at(j)->as().value; - if (exp != node::expr_assign_equal) + if (!exp->is()) break; if (!done) { - if (exp.as_assign_equal->rvalue != node::expr_array) + if (!exp->as().rvalue->is()) break; - if (exp.as_assign_equal->rvalue.as_array->key != node::expr_integer) + if (!exp->as().rvalue->as().key->is()) break; - if (exp.as_assign_equal->rvalue.as_array->key.as_integer->value == "0") + if (exp->as().rvalue->as().key->as().value == "0") done = true; j--; } else { - if (exp.as_assign_equal->lvalue == node::asm_create || exp.as_assign_equal->lvalue == node::asm_access) + if (exp->as().lvalue->is() || exp->as().lvalue->is()) found = true; break; @@ -1829,13 +1829,13 @@ auto decompiler::decompile_tuples(stmt_list& stm) -> void if (found) { auto& entry = stm.list.at(j); // temp = expr; - auto tuple = make_expr_tuple(entry.loc()); - tuple->temp = std::move(entry.as_assign->value.as_assign_equal->lvalue); + auto tuple = expr_tuple::make(entry->loc()); + tuple->temp = std::move(entry->as().value->as().lvalue); j++; while (j < i) { - tuple->list.push_back(std::move(stm.list.at(j).as_assign->value.as_assign_equal->lvalue)); + tuple->list.push_back(std::move(stm.list.at(j)->as().value->as().lvalue)); stm.list.erase(stm.list.begin() + j); i--; } @@ -1843,7 +1843,7 @@ auto decompiler::decompile_tuples(stmt_list& stm) -> void stm.list.erase(stm.list.begin() + j); // clear temp array i--; - entry.as_assign->value.as_assign_equal->lvalue = expr{ std::move(tuple) }; + entry->as().value->as().lvalue = std::move(tuple); } } } @@ -1853,14 +1853,14 @@ auto decompiler::decompile_if(stmt_list& stm, usize begin, usize end) -> void { auto save = locs_; locs_.last = false; - locs_.end = stm.list[begin].as_cond->value; + locs_.end = stm.list[begin]->as().value; - auto loc = stm.list[begin].loc(); - auto test = std::move(stm.list[begin].as_cond->test); + auto loc = stm.list[begin]->loc(); + auto test = std::move(stm.list[begin]->as().test); stm.list.erase(stm.list.begin() + begin); - auto body = make_stmt_list(loc); + auto body = stmt_list::make(loc); for (auto i = begin; i < end; i++) { @@ -1870,22 +1870,22 @@ auto decompiler::decompile_if(stmt_list& stm, usize begin, usize end) -> void decompile_statements(*body); locs_ = save; - stm.list.insert(stm.list.begin() + begin, stmt{ make_stmt_if(loc, std::move(test), stmt{ make_stmt_comp(loc, std::move(body)) }) }); + stm.list.insert(stm.list.begin() + begin, stmt_if::make(loc, std::move(test), stmt_comp::make(loc, std::move(body)))); } auto decompiler::decompile_ifelse(stmt_list& stm, usize begin, usize end) -> void { auto save = locs_; locs_.last = false; - locs_.end = stm.list[end].label(); + locs_.end = stm.list[end]->label(); - auto loc = stm.list[begin].loc(); - auto test = std::move(stm.list[begin].as_cond->test); + auto loc = stm.list[begin]->loc(); + auto test = std::move(stm.list[begin]->as().test); stm.list.erase(stm.list.begin() + begin); end--; - auto body_if = make_stmt_list(loc); + auto body_if = stmt_list::make(loc); for (auto i = begin; i < end; i++) { @@ -1896,7 +1896,7 @@ auto decompiler::decompile_ifelse(stmt_list& stm, usize begin, usize end) -> voi decompile_statements(*body_if); locs_ = save; - auto end_loc = stm.list[begin].as_jump->value; + auto end_loc = stm.list[begin]->as().value; stm.list.erase(stm.list.begin() + begin); @@ -1906,7 +1906,7 @@ auto decompiler::decompile_ifelse(stmt_list& stm, usize begin, usize end) -> voi locs_.last = false; locs_.end = end_loc; - auto body_else = make_stmt_list(loc); + auto body_else = stmt_list::make(loc); for (auto i = begin; i < end; i++) { @@ -1916,22 +1916,22 @@ auto decompiler::decompile_ifelse(stmt_list& stm, usize begin, usize end) -> voi decompile_statements(*body_else); locs_ = save; - stm.list.insert(stm.list.begin() + begin, stmt{ make_stmt_ifelse(loc, std::move(test), stmt{ make_stmt_comp(loc, std::move(body_if)) }, stmt{ make_stmt_comp(loc, std::move(body_else)) }) }); + stm.list.insert(stm.list.begin() + begin, stmt_ifelse::make(loc, std::move(test), stmt_comp::make(loc, std::move(body_if)), stmt_comp::make(loc, std::move(body_else)))); } auto decompiler::decompile_ifelse_end(stmt_list& stm, usize begin, usize end) -> void { auto save = locs_; locs_.last = true; - locs_.end = stm.list[find_location_index(stm, stm.list[begin].as_cond->value) - 1].label(); + locs_.end = stm.list[find_location_index(stm, stm.list[begin]->as().value) - 1]->label(); - auto loc = stm.list[begin].loc(); - auto test = std::move(stm.list[begin].as_cond->test); + auto loc = stm.list[begin]->loc(); + auto test = std::move(stm.list[begin]->as().test); stm.list.erase(stm.list.begin() + begin); end--; - auto body_if = make_stmt_list(loc); + auto body_if = stmt_list::make(loc); for (auto i = begin; i < end; i++) { @@ -1946,16 +1946,16 @@ auto decompiler::decompile_ifelse_end(stmt_list& stm, usize begin, usize end) -> if (begin == stm.list.size()) { - stm.list.insert(stm.list.begin() + begin, stmt{ make_stmt_if(loc, std::move(test), stmt{ make_stmt_comp(loc, std::move(body_if)) }) }); + stm.list.insert(stm.list.begin() + begin, stmt_if::make(loc, std::move(test), stmt_comp::make(loc, std::move(body_if)))); } else { end = stm.list.size() - 1; save = locs_; locs_.last = true; - locs_.end = stm.list[end].label(); + locs_.end = stm.list[end]->label(); - auto body_else = make_stmt_list(loc); + auto body_else = stmt_list::make(loc); for (auto i = begin; i < end; i++) { @@ -1967,7 +1967,7 @@ auto decompiler::decompile_ifelse_end(stmt_list& stm, usize begin, usize end) -> decompile_statements(*body_else); locs_ = save; - stm.list.insert(stm.list.begin() + begin, stmt{ make_stmt_ifelse(loc, std::move(test), stmt{ make_stmt_comp(loc, std::move(body_if)) }, stmt{ make_stmt_comp(loc, std::move(body_else)) }) }); + stm.list.insert(stm.list.begin() + begin, stmt_ifelse::make(loc, std::move(test), stmt_comp::make(loc, std::move(body_if)), stmt_comp::make(loc, std::move(body_else)))); } } @@ -1975,15 +1975,15 @@ auto decompiler::decompile_inf(stmt_list& stm, usize begin, usize end) -> void { auto save = locs_; locs_.last = false; - locs_.brk = last_location_index(stm, end) ? locs_.end : stm.list[end + 1].label(); - locs_.end = stm.list[end].label(); - locs_.cnt = stm.list[end].label(); + locs_.brk = last_location_index(stm, end) ? locs_.end : stm.list[end + 1]->label(); + locs_.end = stm.list[end]->label(); + locs_.cnt = stm.list[end]->label(); - auto loc = stm.list[begin].loc(); + auto loc = stm.list[begin]->loc(); stm.list.erase(stm.list.begin() + end); - auto body = make_stmt_list(loc); + auto body = stmt_list::make(loc); for (auto i = begin; i < end; i++) { @@ -1993,24 +1993,24 @@ auto decompiler::decompile_inf(stmt_list& stm, usize begin, usize end) -> void decompile_statements(*body); locs_ = save; - stm.list.insert(stm.list.begin() + begin, stmt{ make_stmt_for(loc, stmt{ make_node(loc) }, expr{ make_node(loc) }, stmt{ make_node(loc) }, stmt{ make_stmt_comp(loc, std::move(body)) }) }); + stm.list.insert(stm.list.begin() + begin, stmt_for::make(loc, stmt_empty::make(loc), expr_empty::make(loc), stmt_empty::make(loc), stmt_comp::make(loc, std::move(body)))); } auto decompiler::decompile_loop(stmt_list& stm, usize start, usize end) -> void { auto const& last = stm.list.at(end - 1); - if (last == node::stmt_assign) + if (last->is()) { - if (last.as_assign->value == node::expr_assign_equal) + if (last->as().value->is()) { - auto& val = last.as_assign->value.as_assign_equal->rvalue; + auto& val = last->as().value->as().rvalue; - if (val == node::expr_call && val.as_call->value == node::expr_function) + if (val->is() && val->as().value->is()) { - if (utils::string::to_lower(val.as_call->value.as_function->name->value) == "getnextarraykey") + if (utils::string::to_lower(val->as().value->as().name->value) == "getnextarraykey") { - auto ref = stm.list.at(start).label(); + auto ref = stm.list.at(start)->label(); if (!find_location_reference(stm, 0, start, ref)) { @@ -2021,10 +2021,10 @@ auto decompiler::decompile_loop(stmt_list& stm, usize start, usize end) -> void } } - if (start > 0) // while at func start + if (start > 0 && last->as().value->is_assign()) // while at func start { auto index = 1; - while (stm.list.at(start - index) == node::asm_create) + while (stm.list.at(start - index)->is()) { if (start - index > 0) index++; @@ -2032,10 +2032,10 @@ auto decompiler::decompile_loop(stmt_list& stm, usize start, usize end) -> void break; } - if (stm.list.at(start - index) == node::stmt_assign) + if (stm.list.at(start - index)->is() && stm.list.at(start - index)->as().value->is_assign()) { - auto ref = stm.list.at(end).label(); - auto ref2 = stm.list.at(start - index + 1).label(); + auto ref = stm.list.at(end)->label(); + auto ref2 = stm.list.at(start - index + 1)->label(); if (find_location_reference(stm, start, end, ref)) { @@ -2065,18 +2065,18 @@ auto decompiler::decompile_while(stmt_list& stm, usize begin, usize end) -> void { auto save = locs_; locs_.last = false; - locs_.end = stm.list[end].label(); - locs_.cnt = stm.list[end].label(); - locs_.brk = stm.list[begin].as_cond->value; + locs_.end = stm.list[end]->label(); + locs_.cnt = stm.list[end]->label(); + locs_.brk = stm.list[begin]->as().value; - auto loc = stm.list[begin].loc(); - auto test = std::move(stm.list[begin].as_cond->test); + auto loc = stm.list[begin]->loc(); + auto test = std::move(stm.list[begin]->as().test); end--; stm.list.erase(stm.list.begin() + begin); stm.list.erase(stm.list.begin() + end); - auto body = make_stmt_list(loc); + auto body = stmt_list::make(loc); for (auto i = begin; i < end; i++) { @@ -2086,26 +2086,26 @@ auto decompiler::decompile_while(stmt_list& stm, usize begin, usize end) -> void decompile_statements(*body); locs_ = save; - stm.list.insert(stm.list.begin() + begin, stmt{ make_stmt_while(loc, std::move(test), stmt{ make_stmt_comp(loc, std::move(body)) }) }); + stm.list.insert(stm.list.begin() + begin, stmt_while::make(loc, std::move(test), stmt_comp::make(loc, std::move(body)))); } auto decompiler::decompile_dowhile(stmt_list& stm, usize begin, usize end) -> void { auto save = locs_; locs_.last = false; - locs_.end = stm.list[begin].label(); - locs_.cnt = stm.list[begin].label(); - locs_.brk = stm.list[begin].as_cond->value; + locs_.end = stm.list[begin]->label(); + locs_.cnt = stm.list[begin]->label(); + locs_.brk = stm.list[begin]->as().value; - auto test = std::move(stm.list[begin].as_cond->test); - begin = find_location_index(stm, stm.list[end].as_jump_back->value); - auto loc = stm.list[begin].loc(); + auto test = std::move(stm.list[begin]->as().test); + begin = find_location_index(stm, stm.list[end]->as().value); + auto loc = stm.list[begin]->loc(); end--; stm.list.erase(stm.list.begin() + end); stm.list.erase(stm.list.begin() + end); - auto body = make_stmt_list(loc); + auto body = stmt_list::make(loc); for (auto i = begin; i < end; i++) { @@ -2115,39 +2115,39 @@ auto decompiler::decompile_dowhile(stmt_list& stm, usize begin, usize end) -> vo decompile_statements(*body); locs_ = save; - stm.list.insert(stm.list.begin() + begin, stmt{ make_stmt_dowhile(loc, std::move(test), stmt{ make_stmt_comp(loc, std::move(body)) }) }); + stm.list.insert(stm.list.begin() + begin, stmt_dowhile::make(loc, std::move(test), stmt_comp::make(loc, std::move(body)))); } auto decompiler::decompile_for(stmt_list& stm, usize begin, usize end) -> void { auto save = locs_; locs_.last = false; - locs_.end = stm.list[end - 1].label(); - locs_.cnt = stm.list[end - 1].label(); - locs_.brk = stm.list[begin].as_cond->value; + locs_.end = stm.list[end - 1]->label(); + locs_.cnt = stm.list[end - 1]->label(); + locs_.brk = stm.list[begin]->as().value; - for (begin -= 1; stm.list[begin] == node::asm_create; begin--); + for (begin -= 1; stm.list[begin]->is(); begin--); - auto loc = stm.list[begin].loc(); - auto init = make_stmt_list(loc); + auto loc = stm.list[begin]->loc(); + auto init = stmt_list::make(loc); - while (stm.list[begin] != node::asm_jmp_cond) + while (!stm.list[begin]->is()) { init->list.push_back(std::move(stm.list[begin])); stm.list.erase(stm.list.begin() + begin); } - auto test = std::move(stm.list[begin].as_cond->test); + auto test = std::move(stm.list[begin]->as().test); stm.list.erase(stm.list.begin() + begin); end -= 2 + init->list.size(); - auto iter = make_stmt_list(loc); + auto iter = stmt_list::make(loc); iter->list.push_back(std::move(stm.list[end])); stm.list.erase(stm.list.begin() + end); stm.list.erase(stm.list.begin() + end); - auto body = make_stmt_list(loc); + auto body = stmt_list::make(loc); for (auto i = begin; i < end; i++) { @@ -2157,22 +2157,22 @@ auto decompiler::decompile_for(stmt_list& stm, usize begin, usize end) -> void decompile_statements(*body); locs_ = save; - stm.list.insert(stm.list.begin() + begin, stmt{ make_stmt_for(loc, stmt { std::move(init) }, std::move(test), stmt { std::move(iter) }, stmt{ make_stmt_comp(loc, std::move(body)) }) }); + stm.list.insert(stm.list.begin() + begin, stmt_for::make(loc, std::move(init), std::move(test), std::move(iter), stmt_comp::make(loc, std::move(body)))); } auto decompiler::decompile_foreach(stmt_list& stm, usize begin, usize end) -> void { auto save = locs_; locs_.last = false; - locs_.end = stm.list[end - 1].label(); - locs_.cnt = stm.list[end - 1].label(); - locs_.brk = stm.list[begin].as_cond->value; + locs_.end = stm.list[end - 1]->label(); + locs_.cnt = stm.list[end - 1]->label(); + locs_.brk = stm.list[begin]->as().value; - for (begin -= 1; stm.list[begin] == node::asm_create; begin--); + for (begin -= 1; stm.list[begin]->is(); begin--); auto use_index = false; - if ((ctx_->props() & props::foreach) && stm.list[begin] == node::stmt_assign && stm.list[begin].as_assign->value.as_assign->rvalue == node::expr_undefined) + if ((ctx_->props() & props::foreach) && stm.list[begin]->is() && stm.list[begin]->as().value->as().rvalue->is()) { use_index = true; begin--; @@ -2180,25 +2180,25 @@ auto decompiler::decompile_foreach(stmt_list& stm, usize begin, usize end) -> vo begin--; - auto loc = stm.list[begin].loc(); + auto loc = stm.list[begin]->loc(); - auto container = std::move(stm.list[begin].as_assign->value.as_assign->rvalue); - auto array = std::move(stm.list[begin].as_assign->value.as_assign->lvalue); + auto container = std::move(stm.list[begin]->as().value->as().rvalue); + auto array = std::move(stm.list[begin]->as().value->as().lvalue); stm.list.erase(stm.list.begin() + begin); - auto key = std::move(stm.list[begin].as_assign->value.as_assign->lvalue); + auto key = std::move(stm.list[begin]->as().value->as().lvalue); stm.list.erase(stm.list.begin() + begin); - auto index = (use_index) ? std::move(stm.list[begin].as_assign->value.as_assign->lvalue): expr{ make_node() }; + auto index = (use_index) ? std::move(stm.list[begin]->as().value->as().lvalue) : expr_empty::make(location{}); if (use_index) { stm.list.erase(stm.list.begin() + begin); } - auto init = make_stmt_list(loc); + auto init = stmt_list::make(loc); - while (stm.list[begin] != node::asm_jmp_cond) + while (!stm.list[begin]->is()) { init->list.push_back(std::move(stm.list[begin])); stm.list.erase(stm.list.begin() + begin); @@ -2206,7 +2206,7 @@ auto decompiler::decompile_foreach(stmt_list& stm, usize begin, usize end) -> vo stm.list.erase(stm.list.begin() + begin); - auto value = std::move(stm.list[begin].as_assign->value.as_assign->lvalue); + auto value = std::move(stm.list[begin]->as().value->as().lvalue); stm.list.erase(stm.list.begin() + begin); if (use_index) @@ -2220,18 +2220,18 @@ auto decompiler::decompile_foreach(stmt_list& stm, usize begin, usize end) -> vo auto use_key = true; - if (stm.list.size() > end && stm.list[end] == node::asm_clear) + if (stm.list.size() > end && stm.list[end]->is()) { stm.list.erase(stm.list.begin() + end); } - if (stm.list.size() > end && stm.list[end] == node::asm_clear) + if (stm.list.size() > end && stm.list[end]->is()) { stm.list.erase(stm.list.begin() + end); use_key = false; } - auto body = make_stmt_list(loc); + auto body = stmt_list::make(loc); for (auto i = begin; i < end; i++) { @@ -2241,13 +2241,13 @@ auto decompiler::decompile_foreach(stmt_list& stm, usize begin, usize end) -> vo decompile_statements(*body); locs_ = save; - body->list.insert(body->list.begin(), stmt{ std::move(init) }); - stm.list.insert(stm.list.begin() + begin, stmt{ make_stmt_foreach(loc, std::move(container), std::move(value), std::move(index), std::move(array), std::move(key), stmt{ make_stmt_comp(loc, std::move(body)) }, (ctx_->props() & props::foreach) ? use_index : use_key) }); + body->list.insert(body->list.begin(), std::move(init)); + stm.list.insert(stm.list.begin() + begin, stmt_foreach::make(loc, std::move(container), std::move(value), std::move(index), std::move(array), std::move(key), stmt_comp::make(loc, std::move(body)), (ctx_->props() & props::foreach) ? use_index : use_key)); } auto decompiler::decompile_switch(stmt_list& stm, usize begin, usize end) -> void { - auto const& data = stm.list[end].as_asm_endswitch->data; + auto const& data = stm.list[end]->as().data; auto const count = std::stoul(data[0]); if (count) @@ -2263,19 +2263,19 @@ auto decompiler::decompile_switch(stmt_list& stm, usize begin, usize end) -> voi { type = static_cast(std::stoul(data[index + 1])); auto j = find_location_index(stm, data[index + 3]); - auto loc = stm.list[j].loc(); - auto exp = (type == switch_type::integer) ? expr{ make_expr_integer(loc, data[index + 2]) } : expr{ make_expr_string(loc, data[index + 2]) }; - while (stm.list[j] == node::stmt_case) j++; - stm.list.insert(stm.list.begin() + j, stmt{ make_stmt_case(loc, std::move(exp), make_stmt_list(loc)) }); + auto loc = stm.list[j]->loc(); + auto exp = (type == switch_type::integer) ? expr::ptr{ expr_integer::make(loc, data[index + 2]) } : expr::ptr{ expr_string::make(loc, data[index + 2]) }; + while (stm.list[j]->is()) j++; + stm.list.insert(stm.list.begin() + j, stmt_case::make(loc, std::move(exp), stmt_list::make(loc))); index += 4; } else { auto j = find_location_index(stm, data[index + 2]); - auto loc = stm.list[j].loc(); - auto exp = (type == switch_type::integer) ? expr{ make_expr_integer(loc, data[index + 1]) } : expr{ make_expr_string(loc, data[index + 1]) }; - while (stm.list[j] == node::stmt_case) j++; - stm.list.insert(stm.list.begin() + j, stmt{ make_stmt_case(loc, std::move(exp), make_stmt_list(loc)) }); + auto loc = stm.list[j]->loc(); + auto exp = (type == switch_type::integer) ? expr::ptr{ expr_integer::make(loc, data[index + 1]) } : expr::ptr{ expr_string::make(loc, data[index + 1]) }; + while (stm.list[j]->is()) j++; + stm.list.insert(stm.list.begin() + j, stmt_case::make(loc, std::move(exp), stmt_list::make(loc))); index += 3; } @@ -2283,9 +2283,9 @@ auto decompiler::decompile_switch(stmt_list& stm, usize begin, usize end) -> voi else if (data[index] == "default") { auto j = find_location_index(stm, data[index + 1]); - auto loc = stm.list[j].loc(); - while (stm.list[j] == node::stmt_case) j++; - stm.list.insert(stm.list.begin() + j, stmt{ make_stmt_default(loc, make_stmt_list(loc)) }); + auto loc = stm.list[j]->loc(); + while (stm.list[j]->is()) j++; + stm.list.insert(stm.list.begin() + j, stmt_default::make(loc, stmt_list::make(loc))); index += 2; } else @@ -2299,17 +2299,17 @@ auto decompiler::decompile_switch(stmt_list& stm, usize begin, usize end) -> voi auto save = locs_; locs_.last = false; - locs_.brk = last_location_index(stm, end) ? locs_.end : stm.list[end + 1].label(); - locs_.end = stm.list[begin].as_asm_switch->value; + locs_.brk = last_location_index(stm, end) ? locs_.end : stm.list[end + 1]->label(); + locs_.end = stm.list[begin]->as().value; - auto loc = stm.list[begin].loc(); - auto test = std::move(stm.list[begin].as_asm_switch->test); + auto loc = stm.list[begin]->loc(); + auto test = std::move(stm.list[begin]->as().test); end--; stm.list.erase(stm.list.begin() + begin); stm.list.erase(stm.list.begin() + end); - auto body = make_stmt_list(loc); + auto body = stmt_list::make(loc); for (auto i = begin; i < end; i++) { @@ -2320,13 +2320,13 @@ auto decompiler::decompile_switch(stmt_list& stm, usize begin, usize end) -> voi decompile_statements(*body); locs_ = save; - auto temp = stmt{ make_node() }; + auto temp = stmt::ptr{ stmt_empty::make(location{}) }; for (auto i = 0u; i < body->list.size(); ) { - if (body->list[i] == node::stmt_case || body->list[i] == node::stmt_default) + if (body->list[i]->is() || body->list[i]->is()) { - if (temp != node::null) + if (!temp->is()) { body->list.insert(body->list.begin() + i, std::move(temp)); i++; @@ -2337,14 +2337,14 @@ auto decompiler::decompile_switch(stmt_list& stm, usize begin, usize end) -> voi } else { - if (temp == node::stmt_case) + if (temp->is()) { - temp.as_case->body->list.push_back(std::move(body->list[i])); + temp->as().body->list.push_back(std::move(body->list[i])); body->list.erase(body->list.begin() + i); } - else if (temp == node::stmt_default) + else if (temp->is()) { - temp.as_default->body->list.push_back(std::move(body->list[i])); + temp->as().body->list.push_back(std::move(body->list[i])); body->list.erase(body->list.begin() + i); } else @@ -2354,12 +2354,12 @@ auto decompiler::decompile_switch(stmt_list& stm, usize begin, usize end) -> voi } } - if (temp != node::null) + if (!temp->is()) { body->list.push_back(std::move(temp)); } - stm.list.insert(stm.list.begin() + begin, stmt{ make_stmt_switch(loc, std::move(test), make_stmt_comp(loc, std::move(body))) }); + stm.list.insert(stm.list.begin() + begin, stmt_switch::make(loc, std::move(test), stmt_comp::make(loc, std::move(body)))); } auto decompiler::find_location_reference(stmt_list const& stm, usize begin, usize end, std::string const& loc) -> bool @@ -2368,11 +2368,11 @@ auto decompiler::find_location_reference(stmt_list const& stm, usize begin, usiz { auto const& entry = stm.list.at(i); - if (entry == node::asm_jmp_cond && entry.as_cond->value == loc) + if (entry->is() && entry->as().value == loc) { return true; } - else if (entry == node::asm_jmp && entry.as_jump->value == loc) + else if (entry->is() && entry->as().value == loc) { return true; } @@ -2390,7 +2390,7 @@ auto decompiler::find_location_index(stmt_list const& stm, std::string const& lo for (auto const& entry : stm.list) { - if (entry.label() == loc) + if (entry->label() == loc) return index; index++; @@ -2422,73 +2422,67 @@ auto decompiler::process_stmt(stmt& stm, scope& scp) -> void switch (stm.kind()) { case node::stmt_list: - process_stmt_list(*stm.as_list, scp); + process_stmt_list(stm.as(), scp); break; case node::stmt_comp: - process_stmt_comp(*stm.as_comp, scp); + process_stmt_comp(stm.as(), scp); break; case node::stmt_dev: - process_stmt_dev(*stm.as_dev, scp); + process_stmt_dev(stm.as(), scp); break; case node::stmt_expr: - process_stmt_expr(*stm.as_expr, scp); - break; - case node::stmt_call: - process_stmt_call(*stm.as_call, scp); - break; - case node::stmt_assign: - process_stmt_assign(*stm.as_assign, scp); + process_stmt_expr(stm.as(), scp); break; case node::stmt_endon: - process_stmt_endon(*stm.as_endon, scp); + process_stmt_endon(stm.as(), scp); break; case node::stmt_notify: - process_stmt_notify(*stm.as_notify, scp); + process_stmt_notify(stm.as(), scp); break; case node::stmt_wait: - process_stmt_wait(*stm.as_wait, scp); + process_stmt_wait(stm.as(), scp); break; case node::stmt_waittill: - process_stmt_waittill(*stm.as_waittill, scp); + process_stmt_waittill(stm.as(), scp); break; case node::stmt_waittillmatch: - process_stmt_waittillmatch(*stm.as_waittillmatch, scp); + process_stmt_waittillmatch(stm.as(), scp); break; case node::stmt_if: - process_stmt_if(*stm.as_if, scp); + process_stmt_if(stm.as(), scp); break; case node::stmt_ifelse: - process_stmt_ifelse(*stm.as_ifelse, scp); + process_stmt_ifelse(stm.as(), scp); break; case node::stmt_while: - process_stmt_while(*stm.as_while, scp); + process_stmt_while(stm.as(), scp); break; case node::stmt_dowhile: - process_stmt_dowhile(*stm.as_dowhile, scp); + process_stmt_dowhile(stm.as(), scp); break; case node::stmt_for: - process_stmt_for(*stm.as_for, scp); + process_stmt_for(stm.as(), scp); break; case node::stmt_foreach: - process_stmt_foreach(*stm.as_foreach, scp); + process_stmt_foreach(stm.as(), scp); break; case node::stmt_switch: - process_stmt_switch(*stm.as_switch, scp); + process_stmt_switch(stm.as(), scp); break; case node::stmt_break: - process_stmt_break(*stm.as_break, scp); + process_stmt_break(stm.as(), scp); break; case node::stmt_continue: - process_stmt_continue(*stm.as_continue, scp); + process_stmt_continue(stm.as(), scp); break; case node::stmt_return: - process_stmt_return(*stm.as_return, scp); + process_stmt_return(stm.as(), scp); break; - case node::asm_create: - process_stmt_asm_create(*stm.as_asm_create, scp); + case node::stmt_create: + process_stmt_create(stm.as(), scp); break; - case node::asm_remove: - process_stmt_asm_remove(*stm.as_asm_remove, scp); + case node::stmt_remove: + process_stmt_remove(stm.as(), scp); break; default: break; @@ -2499,12 +2493,12 @@ auto decompiler::process_stmt_list(stmt_list& stm, scope& scp) -> void { for (auto& entry : stm.list) { - process_stmt(entry, scp); + process_stmt(*entry, scp); } for (auto i = 0u; i < stm.list.size(); ) { - if (stm.list[i] == node::asm_create || stm.list[i] == node::asm_remove) + if (stm.list[i]->is() || stm.list[i]->is()) stm.list.erase(stm.list.begin() + i); else i++; @@ -2523,69 +2517,22 @@ auto decompiler::process_stmt_dev(stmt_dev& stm, scope& scp) -> void auto decompiler::process_stmt_expr(stmt_expr& stm, scope& scp) -> void { - switch (stm.value.kind()) + switch (stm.value->kind()) { case node::expr_increment: - process_expr_increment(*stm.value.as_increment, scp); + process_expr_increment(stm.value->as(), scp); break; case node::expr_decrement: - process_expr_decrement(*stm.value.as_decrement, scp); + process_expr_decrement(stm.value->as(), scp); break; - case node::expr_assign_equal: - case node::expr_assign_add: - case node::expr_assign_sub: - case node::expr_assign_mul: - case node::expr_assign_div: - case node::expr_assign_mod: - case node::expr_assign_shift_left: - case node::expr_assign_shift_right: - case node::expr_assign_bitwise_or: - case node::expr_assign_bitwise_and: - case node::expr_assign_bitwise_exor: - process_expr_assign(stm.value.as_assign, scp); + case node::expr_assign: + process_expr_assign(*reinterpret_cast(&stm.value), scp); break; - default: - break; - } -} - -auto decompiler::process_stmt_call(stmt_call& stm, scope& scp) -> void -{ - switch (stm.value.kind()) - { case node::expr_call: - process_expr_call(*stm.value.as_call, scp); + process_expr_call(stm.value->as(), scp); break; case node::expr_method: - process_expr_method(*stm.value.as_method, scp); - break; - default: - break; - } -} - -auto decompiler::process_stmt_assign(stmt_assign& stm, scope& scp) -> void -{ - switch (stm.value.kind()) - { - case node::expr_increment: - process_expr_increment(*stm.value.as_increment, scp); - break; - case node::expr_decrement: - process_expr_decrement(*stm.value.as_decrement, scp); - break; - case node::expr_assign_equal: - case node::expr_assign_add: - case node::expr_assign_sub: - case node::expr_assign_mul: - case node::expr_assign_div: - case node::expr_assign_mod: - case node::expr_assign_shift_left: - case node::expr_assign_shift_right: - case node::expr_assign_bitwise_or: - case node::expr_assign_bitwise_and: - case node::expr_assign_bitwise_exor: - process_expr_assign(stm.value.as_assign, scp); + process_expr_method(stm.value->as(), scp); break; default: break; @@ -2636,11 +2583,11 @@ auto decompiler::process_stmt_if(stmt_if& stm, scope& scp) -> void scp.transfer_dec(scp_then); - process_stmt(stm.body, *scp_then); + process_stmt(*stm.body, *scp_then); - if (stm.body.as_comp->block->list.size() == 1 && !stm.body.as_comp->block->list[0].as_node->is_special_stmt()) + if (stm.body->as().block->list.size() == 1 && !stm.body->as().block->list[0]->is_special_stmt()) { - stm.body = std::move(stm.body.as_comp->block->list.back()); + stm.body = std::move(stm.body->as().block->list.back()); } } @@ -2655,7 +2602,7 @@ auto decompiler::process_stmt_ifelse(stmt_ifelse& stm, scope& scp) -> void scp.transfer_dec(scp_then); - process_stmt(stm.stmt_if, *scp_then); + process_stmt(*stm.stmt_if, *scp_then); if (scp_then->abort <= scope::abort_return) { @@ -2667,7 +2614,7 @@ auto decompiler::process_stmt_ifelse(stmt_ifelse& stm, scope& scp) -> void scp.transfer_dec(scp_else); - process_stmt(stm.stmt_else, *scp_else); + process_stmt(*stm.stmt_else, *scp_else); if (scp_else->abort <= abort) { @@ -2682,14 +2629,14 @@ auto decompiler::process_stmt_ifelse(stmt_ifelse& stm, scope& scp) -> void scp.append(childs); - if (stm.stmt_if.as_comp->block->list.size() == 1 && !stm.stmt_if.as_comp->block->list[0].as_node->is_special_stmt()) + if (stm.stmt_if->as().block->list.size() == 1 && !stm.stmt_if->as().block->list[0]->is_special_stmt()) { - stm.stmt_if = std::move(stm.stmt_if.as_comp->block->list.back()); + stm.stmt_if = std::move(stm.stmt_if->as().block->list.back()); } - if (stm.stmt_else.as_comp->block->list.size() == 1 && !stm.stmt_else.as_comp->block->list[0].as_node->is_special_stmt_noif()) + if (stm.stmt_else->as().block->list.size() == 1 && !stm.stmt_else->as().block->list[0]->is_special_stmt_noif()) { - stm.stmt_else = std::move(stm.stmt_else.as_comp->block->list.back()); + stm.stmt_else = std::move(stm.stmt_else->as().block->list.back()); } } @@ -2701,14 +2648,14 @@ auto decompiler::process_stmt_while(stmt_while& stm, scope& scp) -> void scp.transfer_dec(scp_body); - process_stmt(stm.body, *scp_body); + process_stmt(*stm.body, *scp_body); - if (stm.test == node::null) + if (stm.test->is()) scp.append_dec(scp_body); - if (stm.body.as_comp->block->list.size() == 1 && !stm.body.as_comp->block->list[0].as_node->is_special_stmt()) + if (stm.body->as().block->list.size() == 1 && !stm.body->as().block->list[0]->is_special_stmt()) { - stm.body = std::move(stm.body.as_comp->block->list.back()); + stm.body = std::move(stm.body->as().block->list.back()); } } @@ -2720,14 +2667,14 @@ auto decompiler::process_stmt_dowhile(stmt_dowhile& stm, scope& scp) -> void scp.transfer_dec(scp_body); - process_stmt(stm.body, *scp_body); + process_stmt(*stm.body, *scp_body); - if (stm.test == node::null) + if (stm.test->is()) scp.append_dec(scp_body); - if (stm.body.as_comp->block->list.size() == 1 && !stm.body.as_comp->block->list[0].as_node->is_special_stmt()) + if (stm.body->as().block->list.size() == 1 && !stm.body->as().block->list[0]->is_special_stmt()) { - stm.body = std::move(stm.body.as_comp->block->list.back()); + stm.body = std::move(stm.body->as().block->list.back()); } } @@ -2735,32 +2682,32 @@ auto decompiler::process_stmt_for(stmt_for& stm, scope& scp) -> void { auto scp_body = make_scope(); - process_stmt(stm.init, scp); + process_stmt(*stm.init, scp); - if (stm.init == node::stmt_list && stm.init.as_list->list[0] == node::stmt_assign) + if (stm.init->is() && stm.init->as().list[0]->is()) { - stm.init = stmt{ make_stmt_expr(stm.init.loc(), std::move(stm.init.as_list->list[0].as_assign->value)) }; + stm.init = stmt_expr::make(stm.init->loc(), std::move(stm.init->as().list[0]->as().value)); } scp.transfer_dec(scp_body); process_expr(stm.test, scp); - process_stmt(stm.body, *scp_body); + process_stmt(*stm.body, *scp_body); - process_stmt(stm.iter, scp); + process_stmt(*stm.iter, scp); - if (stm.iter == node::stmt_list && stm.iter.as_list->list[0] == node::stmt_assign) + if (stm.iter->is() && stm.iter->as().list[0]->is()) { - stm.iter = stmt{ make_stmt_expr(stm.iter.loc(), std::move(stm.iter.as_list->list[0].as_assign->value)) }; + stm.iter = stmt_expr::make(stm.iter->loc(), std::move(stm.iter->as().list[0]->as().value)); } - if (stm.test == node::null) + if (stm.test->is()) scp.append_dec(scp_body); - if (stm.body.as_comp->block->list.size() == 1 && !stm.body.as_comp->block->list[0].as_node->is_special_stmt()) + if (stm.body->as().block->list.size() == 1 && !stm.body->as().block->list[0]->is_special_stmt()) { - stm.body = std::move(stm.body.as_comp->block->list.back()); + stm.body = std::move(stm.body->as().block->list.back()); } } @@ -2777,18 +2724,18 @@ auto decompiler::process_stmt_foreach(stmt_foreach& stm, scope& scp) -> void process_expr(stm.index, scp); } - process_stmt(stm.body.as_comp->block->list[0], scp); + process_stmt(*stm.body->as().block->list[0], scp); - stm.body.as_comp->block->list.erase(stm.body.as_comp->block->list.begin()); + stm.body->as().block->list.erase(stm.body->as().block->list.begin()); scp.transfer_dec(scp_body); process_expr(stm.value, *scp_body); - process_stmt(stm.body, *scp_body); + process_stmt(*stm.body, *scp_body); - if (stm.body.as_comp->block->list.size() == 1 && !stm.body.as_comp->block->list[0].as_node->is_special_stmt()) + if (stm.body->as().block->list.size() == 1 && !stm.body->as().block->list[0]->is_special_stmt()) { - stm.body = std::move(stm.body.as_comp->block->list.back()); + stm.body = std::move(stm.body->as().block->list.back()); } } @@ -2802,13 +2749,13 @@ auto decompiler::process_stmt_switch(stmt_switch& stm, scope& scp) -> void for (auto& entry : stm.body->block->list) { - if (entry == node::stmt_case) + if (entry->is()) { auto scp_case = make_scope(); scp.transfer_dec(scp_case); - process_stmt_list(*entry.as_case->body, *scp_case); + process_stmt_list(*entry->as().body, *scp_case); if (scp_case->abort == scope::abort_break) { @@ -2816,14 +2763,14 @@ auto decompiler::process_stmt_switch(stmt_switch& stm, scope& scp) -> void scopes.push_back(std::move(scp_case)); } } - else if (entry == node::stmt_default) + else if (entry->is()) { has_default = true; auto scp_case = make_scope(); scp.transfer_dec(scp_case); - process_stmt_list(*entry.as_default->body, *scp_case); + process_stmt_list(*entry->as().body, *scp_case); if (scp_case->abort == scope::abort_break) { @@ -2862,157 +2809,81 @@ auto decompiler::process_stmt_return(stmt_return& stm, scope& scp) -> void scp.abort = scope::abort_return; } - if (stm.value != node::null) + if (!stm.value->is()) { process_expr(stm.value, scp); } } -auto decompiler::process_stmt_asm_create(asm_create& stm, scope& scp) -> void +auto decompiler::process_stmt_create(stmt_create& stm, scope& scp) -> void { auto var = (ctx_->props() & props::hash) ? stm.index : fmt::format("var_{}", stm.index); scp.vars.push_back({ var, static_cast(scp.create_count), true }); scp.create_count++; } -auto decompiler::process_stmt_asm_remove(asm_remove& stm, scope& scp) -> void +auto decompiler::process_stmt_remove(stmt_remove& stm, scope& scp) -> void { scp.public_count = static_cast(scp.vars.size() - std::stoi(stm.index)); } -auto decompiler::process_expr(expr& exp, scope& scp) -> void +auto decompiler::process_expr(expr::ptr& exp, scope& scp) -> void { - switch (exp.kind()) + switch (exp->kind()) { case node::expr_ternary: - process_expr_ternary(*exp.as_ternary, scp); + process_expr_ternary(exp->as(), scp); break; - case node::expr_and: - process_expr_and(*exp.as_and, scp); - break; - case node::expr_or: - process_expr_or(*exp.as_or, scp); - break; - case node::expr_equality: - case node::expr_inequality: - case node::expr_less: - case node::expr_greater: - case node::expr_less_equal: - case node::expr_greater_equal: - case node::expr_bitwise_or: - case node::expr_bitwise_and: - case node::expr_bitwise_exor: - case node::expr_shift_left: - case node::expr_shift_right: - case node::expr_add: - case node::expr_sub: - case node::expr_mul: - case node::expr_div: - case node::expr_mod: - process_expr_binary(*exp.as_binary, scp); + case node::expr_binary: + process_expr_binary(exp->as(), scp); break; case node::expr_complement: - process_expr_complement(*exp.as_complement, scp); + process_expr_complement(exp->as(), scp); break; case node::expr_not: - process_expr_not(*exp.as_not, scp); + process_expr_not(exp->as(), scp); break; case node::expr_call: - process_expr_call(*exp.as_call, scp); + process_expr_call(exp->as(), scp); break; case node::expr_method: - process_expr_method(*exp.as_method, scp); + process_expr_method(exp->as(), scp); break; case node::expr_isdefined: - process_expr(exp.as_isdefined->value, scp); + process_expr(exp->as().value, scp); break; case node::expr_istrue: - process_expr(exp.as_istrue->value, scp); + process_expr(exp->as().value, scp); break; case node::expr_add_array: - process_expr_add_array(*exp.as_add_array, scp); + process_expr_add_array(exp->as(), scp); break; case node::expr_size: - process_expr_size(*exp.as_size, scp); + process_expr_size(exp->as(), scp); break; case node::expr_tuple: - process_expr_tuple(*exp.as_tuple, scp); + process_expr_tuple(exp->as(), scp); break; case node::expr_array: - process_expr_array(*exp.as_array, scp); + process_expr_array(exp->as(), scp); break; case node::expr_field: - process_expr_field(*exp.as_field, scp); + process_expr_field(exp->as(), scp); break; case node::expr_vector: - process_expr_vector(*exp.as_vector, scp); + process_expr_vector(exp->as(), scp); break; - case node::asm_create: - process_expr_asm_create(exp, scp); + case node::expr_var_create: + process_expr_var_create(exp, scp); break; - case node::asm_access: - process_expr_asm_access(exp, scp); + case node::expr_var_access: + process_expr_var_access(exp, scp); break; default: break; } } -auto decompiler::process_expr_assign(expr_assign::ptr& exp, scope& scp) -> void -{ - process_expr(exp->rvalue, scp); - process_expr(exp->lvalue, scp); - - if (exp->kind() == node::expr_assign_equal) - { - switch (exp->rvalue.kind()) - { - case node::expr_bitwise_or: - if (exp->lvalue == exp->rvalue.as_bitwise_or->lvalue) - exp = make_expr_assign_bitwise_or(exp->loc(), std::move(exp->lvalue), std::move(exp->rvalue.as_bitwise_or->rvalue)); - break; - case node::expr_bitwise_and: - if (exp->lvalue == exp->rvalue.as_bitwise_and->lvalue) - exp = make_expr_assign_bitwise_and(exp->loc(), std::move(exp->lvalue), std::move(exp->rvalue.as_bitwise_and->rvalue)); - break; - case node::expr_bitwise_exor: - if (exp->lvalue == exp->rvalue.as_bitwise_exor->lvalue) - exp = make_expr_assign_bitwise_exor(exp->loc(), std::move(exp->lvalue), std::move(exp->rvalue.as_bitwise_exor->rvalue)); - break; - case node::expr_shift_left: - if (exp->lvalue == exp->rvalue.as_shift_left->lvalue) - exp = make_expr_assign_shift_left(exp->loc(), std::move(exp->lvalue), std::move(exp->rvalue.as_shift_left->rvalue)); - break; - case node::expr_shift_right: - if (exp->lvalue == exp->rvalue.as_shift_right->lvalue) - exp = make_expr_assign_shift_right(exp->loc(), std::move(exp->lvalue), std::move(exp->rvalue.as_shift_right->rvalue)); - break; - case node::expr_add: - if (exp->lvalue == exp->rvalue.as_add->lvalue) - exp = make_expr_assign_add(exp->loc(), std::move(exp->lvalue), std::move(exp->rvalue.as_add->rvalue)); - break; - case node::expr_sub: - if (exp->lvalue == exp->rvalue.as_sub->lvalue) - exp = make_expr_assign_sub(exp->loc(), std::move(exp->lvalue), std::move(exp->rvalue.as_sub->rvalue)); - break; - case node::expr_mul: - if (exp->lvalue == exp->rvalue.as_mul->lvalue) - exp = make_expr_assign_mul(exp->loc(), std::move(exp->lvalue), std::move(exp->rvalue.as_mul->rvalue)); - break; - case node::expr_div: - if (exp->lvalue == exp->rvalue.as_div->lvalue) - exp = make_expr_assign_div(exp->loc(), std::move(exp->lvalue), std::move(exp->rvalue.as_div->rvalue)); - break; - case node::expr_mod: - if (exp->lvalue == exp->rvalue.as_mod->lvalue) - exp = make_expr_assign_mod(exp->loc(), std::move(exp->lvalue), std::move(exp->rvalue.as_mod->rvalue)); - break; - default: - break; - } - } -} - auto decompiler::process_expr_increment(expr_increment& exp, scope& scp) -> void { process_expr(exp.lvalue, scp); @@ -3023,6 +2894,61 @@ auto decompiler::process_expr_decrement(expr_decrement& exp, scope& scp) -> void process_expr(exp.lvalue, scp); } +auto decompiler::process_expr_assign(expr_assign::ptr& exp, scope& scp) -> void +{ + process_expr(exp->rvalue, scp); + process_expr(exp->lvalue, scp); + + if (exp->oper != expr_assign::op::eq) + return; + + if (exp->rvalue->kind() != node::expr_binary) + return; + + auto& rval = exp->rvalue->as(); + + if (exp->lvalue != rval.lvalue) + return; + + switch (rval.oper) + { + case expr_binary::op::add: + exp->oper = expr_assign::op::add; + break; + case expr_binary::op::sub: + exp->oper = expr_assign::op::sub; + break; + case expr_binary::op::mul: + exp->oper = expr_assign::op::mul; + break; + case expr_binary::op::div: + exp->oper = expr_assign::op::div; + break; + case expr_binary::op::mod: + exp->oper = expr_assign::op::mod; + break; + case expr_binary::op::shl: + exp->oper = expr_assign::op::shl; + break; + case expr_binary::op::shr: + exp->oper = expr_assign::op::shr; + break; + case expr_binary::op::bwor: + exp->oper = expr_assign::op::bwor; + break; + case expr_binary::op::bwand: + exp->oper = expr_assign::op::bwand; + break; + case expr_binary::op::bwexor: + exp->oper = expr_assign::op::bwexor; + break; + default: + return; + } + + exp->rvalue = std::move(rval.rvalue); +} + auto decompiler::process_expr_ternary(expr_ternary& exp, scope& scp) -> void { process_expr(exp.test, scp); @@ -3035,54 +2961,28 @@ auto decompiler::process_expr_binary(expr_binary& exp, scope& scp) -> void process_expr(exp.lvalue, scp); process_expr(exp.rvalue, scp); - auto prec = exp.lvalue.as_node->precedence(); + auto prec = exp.lvalue->precedence(); if (prec && prec < exp.precedence()) { - exp.lvalue = expr{ make_expr_paren(exp.loc(), std::move(exp.lvalue)) }; + exp.lvalue = expr_paren::make(exp.loc(), std::move(exp.lvalue)); } - prec = exp.rvalue.as_node->precedence(); + prec = exp.rvalue->precedence(); - if ((prec && prec < exp.precedence()) || (prec == exp.precedence() && exp.kind() == exp.rvalue.as_node->kind())) + if ((prec && prec < exp.precedence()) || (prec == exp.precedence() && exp.kind() == exp.rvalue->kind())) { - exp.rvalue = expr{ make_expr_paren(exp.loc(), std::move(exp.rvalue)) }; + exp.rvalue = expr_paren::make(exp.loc(), std::move(exp.rvalue)); } } -auto decompiler::process_expr_and(expr_and& exp, scope& scp) -> void -{ - process_expr(exp.lvalue, scp); - process_expr(exp.rvalue, scp); - - auto prec = exp.lvalue.as_node->precedence(); - - if (prec && prec < exp.precedence()) - { - exp.lvalue = expr{ make_expr_paren(exp.loc(), std::move(exp.lvalue)) }; - } - - prec = exp.rvalue.as_node->precedence(); - - if ((prec && prec < exp.precedence()) || (prec == exp.precedence() && exp.kind() == exp.rvalue.kind())) - { - exp.rvalue = expr{ make_expr_paren(exp.loc(), std::move(exp.rvalue)) }; - } -} - -auto decompiler::process_expr_or(expr_or& exp, scope& scp) -> void -{ - process_expr(exp.lvalue, scp); - process_expr(exp.rvalue, scp); -} - auto decompiler::process_expr_complement(expr_complement& exp, scope& scp) -> void { process_expr(exp.rvalue, scp); - if (exp.rvalue.as_node->is_binary()) + if (exp.rvalue->is()) { - exp.rvalue = expr{ make_expr_paren(exp.loc(), std::move(exp.rvalue)) }; + exp.rvalue = expr_paren::make(exp.loc(), std::move(exp.rvalue)); } } @@ -3090,21 +2990,21 @@ auto decompiler::process_expr_not(expr_not& exp, scope& scp) -> void { process_expr(exp.rvalue, scp); - if (exp.rvalue.as_node->is_binary()) + if (exp.rvalue->is()) { - exp.rvalue = expr{ make_expr_paren(exp.loc(), std::move(exp.rvalue)) }; + exp.rvalue = expr_paren::make(exp.loc(), std::move(exp.rvalue)); } } auto decompiler::process_expr_call(expr_call& exp, scope& scp) -> void { - switch (exp.value.kind()) + switch (exp.value->kind()) { case node::expr_pointer: - process_expr_call_pointer(*exp.value.as_pointer, scp); + process_expr_call_pointer(exp.value->as(), scp); break; case node::expr_function: - process_expr_call_function(*exp.value.as_function, scp); + process_expr_call_function(exp.value->as(), scp); break; default: break; @@ -3113,13 +3013,13 @@ auto decompiler::process_expr_call(expr_call& exp, scope& scp) -> void auto decompiler::process_expr_method(expr_method& exp, scope& scp) -> void { - switch (exp.value.kind()) + switch (exp.value->kind()) { case node::expr_pointer: - process_expr_method_pointer(*exp.value.as_pointer, exp.obj, scp); + process_expr_method_pointer(exp.value->as(), exp.obj, scp); break; case node::expr_function: - process_expr_method_function(*exp.value.as_function, exp.obj, scp); + process_expr_method_function(exp.value->as(), exp.obj, scp); break; default: break; @@ -3137,14 +3037,14 @@ auto decompiler::process_expr_call_function(expr_function& exp, scope& scp) -> v process_expr_arguments(*exp.args, scp); } -auto decompiler::process_expr_method_pointer(expr_pointer& exp, expr& obj, scope& scp) -> void +auto decompiler::process_expr_method_pointer(expr_pointer& exp, expr::ptr& obj, scope& scp) -> void { process_expr_arguments(*exp.args, scp); process_expr(obj, scp); process_expr(exp.func, scp); } -auto decompiler::process_expr_method_function(expr_function& exp, expr& obj, scope& scp) -> void +auto decompiler::process_expr_method_function(expr_function& exp, expr::ptr& obj, scope& scp) -> void { process_expr_arguments(*exp.args, scp); process_expr(obj, scp); @@ -3199,25 +3099,25 @@ auto decompiler::process_expr_vector(expr_vector& exp, scope& scp) -> void process_expr(exp.x, scp); } -auto decompiler::process_expr_asm_create(expr& exp, scope& scp) -> void +auto decompiler::process_expr_var_create(expr::ptr& exp, scope& scp) -> void { - for (auto const& entry : exp.as_asm_create->vars) + for (auto const& entry : exp->as().vars) { auto var = (ctx_->props() & props::hash) ? entry : fmt::format("var_{}", entry); scp.vars.push_back({ var, static_cast(scp.create_count), true }); scp.create_count++; } - auto var = (ctx_->props() & props::hash) ? exp.as_asm_create->index : fmt::format("var_{}", exp.as_asm_create->index); + auto var = (ctx_->props() & props::hash) ? exp->as().index : fmt::format("var_{}", exp->as().index); scp.vars.push_back({ var, static_cast(scp.create_count), true }); scp.create_count++; - exp = expr{ make_expr_identifier(exp.loc(), var) }; + exp = expr_identifier::make(exp->loc(), var); } -auto decompiler::process_expr_asm_access(expr& exp, scope& scp) -> void +auto decompiler::process_expr_var_access(expr::ptr& exp, scope& scp) -> void { - auto const index = std::stoul(exp.as_asm_access->index); + auto const index = std::stoul(exp->as().index); if (scp.vars.size() <= index) { @@ -3225,7 +3125,7 @@ auto decompiler::process_expr_asm_access(expr& exp, scope& scp) -> void } else { - exp = expr{ make_expr_identifier(exp.loc(), scp.vars[scp.vars.size() - 1 - index].name) }; + exp = expr_identifier::make(exp->loc(), scp.vars[scp.vars.size() - 1 - index].name); } } diff --git a/src/gsc/parser.cpp b/src/gsc/parser.cpp index b92a9e78..9f29c884 100644 --- a/src/gsc/parser.cpp +++ b/src/gsc/parser.cpp @@ -220,11 +220,11 @@ namespace xsk { namespace gsc { { case symbol_kind::S_expr_function: // expr_function case symbol_kind::S_expr_pointer: // expr_pointer - value.YY_MOVE_OR_COPY< call > (YY_MOVE (that.value)); + value.YY_MOVE_OR_COPY< call::ptr > (YY_MOVE (that.value)); break; case symbol_kind::S_declaration: // declaration - value.YY_MOVE_OR_COPY< decl > (YY_MOVE (that.value)); + value.YY_MOVE_OR_COPY< decl::ptr > (YY_MOVE (that.value)); break; case symbol_kind::S_decl_constant: // decl_constant @@ -241,16 +241,16 @@ namespace xsk { namespace gsc { case symbol_kind::S_expr: // expr case symbol_kind::S_expr_or_empty: // expr_or_empty - case symbol_kind::S_expr_assign: // expr_assign case symbol_kind::S_expr_increment: // expr_increment case symbol_kind::S_expr_decrement: // expr_decrement + case symbol_kind::S_expr_assign: // expr_assign case symbol_kind::S_expr_ternary: // expr_ternary case symbol_kind::S_expr_binary: // expr_binary case symbol_kind::S_expr_primitive: // expr_primitive case symbol_kind::S_expr_tuple: // expr_tuple case symbol_kind::S_expr_tuple_types: // expr_tuple_types case symbol_kind::S_expr_object: // expr_object - value.YY_MOVE_OR_COPY< expr > (YY_MOVE (that.value)); + value.YY_MOVE_OR_COPY< expr::ptr > (YY_MOVE (that.value)); break; case symbol_kind::S_expr_add_array: // expr_add_array @@ -410,7 +410,7 @@ namespace xsk { namespace gsc { case symbol_kind::S_stmt: // stmt case symbol_kind::S_stmt_or_dev: // stmt_or_dev - value.YY_MOVE_OR_COPY< stmt > (YY_MOVE (that.value)); + value.YY_MOVE_OR_COPY< stmt::ptr > (YY_MOVE (that.value)); break; case symbol_kind::S_stmt_assert: // stmt_assert @@ -425,10 +425,6 @@ namespace xsk { namespace gsc { value.YY_MOVE_OR_COPY< stmt_assertmsg::ptr > (YY_MOVE (that.value)); break; - case symbol_kind::S_stmt_assign: // stmt_assign - value.YY_MOVE_OR_COPY< stmt_assign::ptr > (YY_MOVE (that.value)); - break; - case symbol_kind::S_stmt_break: // stmt_break value.YY_MOVE_OR_COPY< stmt_break::ptr > (YY_MOVE (that.value)); break; @@ -437,10 +433,6 @@ namespace xsk { namespace gsc { value.YY_MOVE_OR_COPY< stmt_breakpoint::ptr > (YY_MOVE (that.value)); break; - case symbol_kind::S_stmt_call: // stmt_call - value.YY_MOVE_OR_COPY< stmt_call::ptr > (YY_MOVE (that.value)); - break; - case symbol_kind::S_stmt_case: // stmt_case value.YY_MOVE_OR_COPY< stmt_case::ptr > (YY_MOVE (that.value)); break; @@ -470,6 +462,8 @@ namespace xsk { namespace gsc { break; case symbol_kind::S_stmt_expr: // stmt_expr + case symbol_kind::S_stmt_call: // stmt_call + case symbol_kind::S_stmt_assign: // stmt_assign value.YY_MOVE_OR_COPY< stmt_expr::ptr > (YY_MOVE (that.value)); break; @@ -555,11 +549,11 @@ namespace xsk { namespace gsc { { case symbol_kind::S_expr_function: // expr_function case symbol_kind::S_expr_pointer: // expr_pointer - value.move< call > (YY_MOVE (that.value)); + value.move< call::ptr > (YY_MOVE (that.value)); break; case symbol_kind::S_declaration: // declaration - value.move< decl > (YY_MOVE (that.value)); + value.move< decl::ptr > (YY_MOVE (that.value)); break; case symbol_kind::S_decl_constant: // decl_constant @@ -576,16 +570,16 @@ namespace xsk { namespace gsc { case symbol_kind::S_expr: // expr case symbol_kind::S_expr_or_empty: // expr_or_empty - case symbol_kind::S_expr_assign: // expr_assign case symbol_kind::S_expr_increment: // expr_increment case symbol_kind::S_expr_decrement: // expr_decrement + case symbol_kind::S_expr_assign: // expr_assign case symbol_kind::S_expr_ternary: // expr_ternary case symbol_kind::S_expr_binary: // expr_binary case symbol_kind::S_expr_primitive: // expr_primitive case symbol_kind::S_expr_tuple: // expr_tuple case symbol_kind::S_expr_tuple_types: // expr_tuple_types case symbol_kind::S_expr_object: // expr_object - value.move< expr > (YY_MOVE (that.value)); + value.move< expr::ptr > (YY_MOVE (that.value)); break; case symbol_kind::S_expr_add_array: // expr_add_array @@ -745,7 +739,7 @@ namespace xsk { namespace gsc { case symbol_kind::S_stmt: // stmt case symbol_kind::S_stmt_or_dev: // stmt_or_dev - value.move< stmt > (YY_MOVE (that.value)); + value.move< stmt::ptr > (YY_MOVE (that.value)); break; case symbol_kind::S_stmt_assert: // stmt_assert @@ -760,10 +754,6 @@ namespace xsk { namespace gsc { value.move< stmt_assertmsg::ptr > (YY_MOVE (that.value)); break; - case symbol_kind::S_stmt_assign: // stmt_assign - value.move< stmt_assign::ptr > (YY_MOVE (that.value)); - break; - case symbol_kind::S_stmt_break: // stmt_break value.move< stmt_break::ptr > (YY_MOVE (that.value)); break; @@ -772,10 +762,6 @@ namespace xsk { namespace gsc { value.move< stmt_breakpoint::ptr > (YY_MOVE (that.value)); break; - case symbol_kind::S_stmt_call: // stmt_call - value.move< stmt_call::ptr > (YY_MOVE (that.value)); - break; - case symbol_kind::S_stmt_case: // stmt_case value.move< stmt_case::ptr > (YY_MOVE (that.value)); break; @@ -805,6 +791,8 @@ namespace xsk { namespace gsc { break; case symbol_kind::S_stmt_expr: // stmt_expr + case symbol_kind::S_stmt_call: // stmt_call + case symbol_kind::S_stmt_assign: // stmt_assign value.move< stmt_expr::ptr > (YY_MOVE (that.value)); break; @@ -890,11 +878,11 @@ namespace xsk { namespace gsc { { case symbol_kind::S_expr_function: // expr_function case symbol_kind::S_expr_pointer: // expr_pointer - value.copy< call > (that.value); + value.copy< call::ptr > (that.value); break; case symbol_kind::S_declaration: // declaration - value.copy< decl > (that.value); + value.copy< decl::ptr > (that.value); break; case symbol_kind::S_decl_constant: // decl_constant @@ -911,16 +899,16 @@ namespace xsk { namespace gsc { case symbol_kind::S_expr: // expr case symbol_kind::S_expr_or_empty: // expr_or_empty - case symbol_kind::S_expr_assign: // expr_assign case symbol_kind::S_expr_increment: // expr_increment case symbol_kind::S_expr_decrement: // expr_decrement + case symbol_kind::S_expr_assign: // expr_assign case symbol_kind::S_expr_ternary: // expr_ternary case symbol_kind::S_expr_binary: // expr_binary case symbol_kind::S_expr_primitive: // expr_primitive case symbol_kind::S_expr_tuple: // expr_tuple case symbol_kind::S_expr_tuple_types: // expr_tuple_types case symbol_kind::S_expr_object: // expr_object - value.copy< expr > (that.value); + value.copy< expr::ptr > (that.value); break; case symbol_kind::S_expr_add_array: // expr_add_array @@ -1080,7 +1068,7 @@ namespace xsk { namespace gsc { case symbol_kind::S_stmt: // stmt case symbol_kind::S_stmt_or_dev: // stmt_or_dev - value.copy< stmt > (that.value); + value.copy< stmt::ptr > (that.value); break; case symbol_kind::S_stmt_assert: // stmt_assert @@ -1095,10 +1083,6 @@ namespace xsk { namespace gsc { value.copy< stmt_assertmsg::ptr > (that.value); break; - case symbol_kind::S_stmt_assign: // stmt_assign - value.copy< stmt_assign::ptr > (that.value); - break; - case symbol_kind::S_stmt_break: // stmt_break value.copy< stmt_break::ptr > (that.value); break; @@ -1107,10 +1091,6 @@ namespace xsk { namespace gsc { value.copy< stmt_breakpoint::ptr > (that.value); break; - case symbol_kind::S_stmt_call: // stmt_call - value.copy< stmt_call::ptr > (that.value); - break; - case symbol_kind::S_stmt_case: // stmt_case value.copy< stmt_case::ptr > (that.value); break; @@ -1140,6 +1120,8 @@ namespace xsk { namespace gsc { break; case symbol_kind::S_stmt_expr: // stmt_expr + case symbol_kind::S_stmt_call: // stmt_call + case symbol_kind::S_stmt_assign: // stmt_assign value.copy< stmt_expr::ptr > (that.value); break; @@ -1224,11 +1206,11 @@ namespace xsk { namespace gsc { { case symbol_kind::S_expr_function: // expr_function case symbol_kind::S_expr_pointer: // expr_pointer - value.move< call > (that.value); + value.move< call::ptr > (that.value); break; case symbol_kind::S_declaration: // declaration - value.move< decl > (that.value); + value.move< decl::ptr > (that.value); break; case symbol_kind::S_decl_constant: // decl_constant @@ -1245,16 +1227,16 @@ namespace xsk { namespace gsc { case symbol_kind::S_expr: // expr case symbol_kind::S_expr_or_empty: // expr_or_empty - case symbol_kind::S_expr_assign: // expr_assign case symbol_kind::S_expr_increment: // expr_increment case symbol_kind::S_expr_decrement: // expr_decrement + case symbol_kind::S_expr_assign: // expr_assign case symbol_kind::S_expr_ternary: // expr_ternary case symbol_kind::S_expr_binary: // expr_binary case symbol_kind::S_expr_primitive: // expr_primitive case symbol_kind::S_expr_tuple: // expr_tuple case symbol_kind::S_expr_tuple_types: // expr_tuple_types case symbol_kind::S_expr_object: // expr_object - value.move< expr > (that.value); + value.move< expr::ptr > (that.value); break; case symbol_kind::S_expr_add_array: // expr_add_array @@ -1414,7 +1396,7 @@ namespace xsk { namespace gsc { case symbol_kind::S_stmt: // stmt case symbol_kind::S_stmt_or_dev: // stmt_or_dev - value.move< stmt > (that.value); + value.move< stmt::ptr > (that.value); break; case symbol_kind::S_stmt_assert: // stmt_assert @@ -1429,10 +1411,6 @@ namespace xsk { namespace gsc { value.move< stmt_assertmsg::ptr > (that.value); break; - case symbol_kind::S_stmt_assign: // stmt_assign - value.move< stmt_assign::ptr > (that.value); - break; - case symbol_kind::S_stmt_break: // stmt_break value.move< stmt_break::ptr > (that.value); break; @@ -1441,10 +1419,6 @@ namespace xsk { namespace gsc { value.move< stmt_breakpoint::ptr > (that.value); break; - case symbol_kind::S_stmt_call: // stmt_call - value.move< stmt_call::ptr > (that.value); - break; - case symbol_kind::S_stmt_case: // stmt_case value.move< stmt_case::ptr > (that.value); break; @@ -1474,6 +1448,8 @@ namespace xsk { namespace gsc { break; case symbol_kind::S_stmt_expr: // stmt_expr + case symbol_kind::S_stmt_call: // stmt_call + case symbol_kind::S_stmt_assign: // stmt_assign value.move< stmt_expr::ptr > (that.value); break; @@ -1813,11 +1789,11 @@ namespace xsk { namespace gsc { { case symbol_kind::S_expr_function: // expr_function case symbol_kind::S_expr_pointer: // expr_pointer - yylhs.value.emplace< call > (); + yylhs.value.emplace< call::ptr > (); break; case symbol_kind::S_declaration: // declaration - yylhs.value.emplace< decl > (); + yylhs.value.emplace< decl::ptr > (); break; case symbol_kind::S_decl_constant: // decl_constant @@ -1834,16 +1810,16 @@ namespace xsk { namespace gsc { case symbol_kind::S_expr: // expr case symbol_kind::S_expr_or_empty: // expr_or_empty - case symbol_kind::S_expr_assign: // expr_assign case symbol_kind::S_expr_increment: // expr_increment case symbol_kind::S_expr_decrement: // expr_decrement + case symbol_kind::S_expr_assign: // expr_assign case symbol_kind::S_expr_ternary: // expr_ternary case symbol_kind::S_expr_binary: // expr_binary case symbol_kind::S_expr_primitive: // expr_primitive case symbol_kind::S_expr_tuple: // expr_tuple case symbol_kind::S_expr_tuple_types: // expr_tuple_types case symbol_kind::S_expr_object: // expr_object - yylhs.value.emplace< expr > (); + yylhs.value.emplace< expr::ptr > (); break; case symbol_kind::S_expr_add_array: // expr_add_array @@ -2003,7 +1979,7 @@ namespace xsk { namespace gsc { case symbol_kind::S_stmt: // stmt case symbol_kind::S_stmt_or_dev: // stmt_or_dev - yylhs.value.emplace< stmt > (); + yylhs.value.emplace< stmt::ptr > (); break; case symbol_kind::S_stmt_assert: // stmt_assert @@ -2018,10 +1994,6 @@ namespace xsk { namespace gsc { yylhs.value.emplace< stmt_assertmsg::ptr > (); break; - case symbol_kind::S_stmt_assign: // stmt_assign - yylhs.value.emplace< stmt_assign::ptr > (); - break; - case symbol_kind::S_stmt_break: // stmt_break yylhs.value.emplace< stmt_break::ptr > (); break; @@ -2030,10 +2002,6 @@ namespace xsk { namespace gsc { yylhs.value.emplace< stmt_breakpoint::ptr > (); break; - case symbol_kind::S_stmt_call: // stmt_call - yylhs.value.emplace< stmt_call::ptr > (); - break; - case symbol_kind::S_stmt_case: // stmt_case yylhs.value.emplace< stmt_case::ptr > (); break; @@ -2063,6 +2031,8 @@ namespace xsk { namespace gsc { break; case symbol_kind::S_stmt_expr: // stmt_expr + case symbol_kind::S_stmt_call: // stmt_call + case symbol_kind::S_stmt_assign: // stmt_assign yylhs.value.emplace< stmt_expr::ptr > (); break; @@ -2154,1507 +2124,1509 @@ namespace xsk { namespace gsc { case 2: // root: program #line 275 "parser.ypp" { ast = std::move(yystack_[0].value.as < program::ptr > ()); } -#line 2161 "parser.cpp" +#line 2131 "parser.cpp" break; case 3: // root: %empty #line 276 "parser.ypp" - { ast = make_program(yylhs.location); } -#line 2167 "parser.cpp" + { ast = program::make(yylhs.location); } +#line 2137 "parser.cpp" break; case 4: // program: program ";" #line 281 "parser.ypp" { yylhs.value.as < program::ptr > () = std::move(yystack_[1].value.as < program::ptr > ()); } -#line 2173 "parser.cpp" +#line 2143 "parser.cpp" break; case 5: // program: program inline #line 283 "parser.ypp" { yylhs.value.as < program::ptr > () = std::move(yystack_[1].value.as < program::ptr > ()); } -#line 2179 "parser.cpp" +#line 2149 "parser.cpp" break; case 6: // program: program include #line 285 "parser.ypp" { yylhs.value.as < program::ptr > () = std::move(yystack_[1].value.as < program::ptr > ()); yylhs.value.as < program::ptr > ()->includes.push_back(std::move(yystack_[0].value.as < include::ptr > ())); } -#line 2185 "parser.cpp" +#line 2155 "parser.cpp" break; case 7: // program: program declaration #line 287 "parser.ypp" - { yylhs.value.as < program::ptr > () = std::move(yystack_[1].value.as < program::ptr > ()); yylhs.value.as < program::ptr > ()->declarations.push_back(std::move(yystack_[0].value.as < decl > ())); } -#line 2191 "parser.cpp" + { yylhs.value.as < program::ptr > () = std::move(yystack_[1].value.as < program::ptr > ()); yylhs.value.as < program::ptr > ()->declarations.push_back(std::move(yystack_[0].value.as < decl::ptr > ())); } +#line 2161 "parser.cpp" break; case 8: // program: ";" #line 289 "parser.ypp" - { yylhs.value.as < program::ptr > () = make_program(yylhs.location); } -#line 2197 "parser.cpp" + { yylhs.value.as < program::ptr > () = program::make(yylhs.location); } +#line 2167 "parser.cpp" break; case 9: // program: inline #line 291 "parser.ypp" - { yylhs.value.as < program::ptr > () = make_program(yylhs.location); } -#line 2203 "parser.cpp" + { yylhs.value.as < program::ptr > () = program::make(yylhs.location); } +#line 2173 "parser.cpp" break; case 10: // program: include #line 293 "parser.ypp" - { yylhs.value.as < program::ptr > () = make_program(yylhs.location); yylhs.value.as < program::ptr > ()->includes.push_back(std::move(yystack_[0].value.as < include::ptr > ())); } -#line 2209 "parser.cpp" + { yylhs.value.as < program::ptr > () = program::make(yylhs.location); yylhs.value.as < program::ptr > ()->includes.push_back(std::move(yystack_[0].value.as < include::ptr > ())); } +#line 2179 "parser.cpp" break; case 11: // program: declaration #line 295 "parser.ypp" - { yylhs.value.as < program::ptr > () = make_program(yylhs.location); yylhs.value.as < program::ptr > ()->declarations.push_back(std::move(yystack_[0].value.as < decl > ())); } -#line 2215 "parser.cpp" + { yylhs.value.as < program::ptr > () = program::make(yylhs.location); yylhs.value.as < program::ptr > ()->declarations.push_back(std::move(yystack_[0].value.as < decl::ptr > ())); } +#line 2185 "parser.cpp" break; case 12: // inline: "#inline" expr_path ";" #line 299 "parser.ypp" { ppr.push_header(yystack_[1].value.as < expr_path::ptr > ()->value); } -#line 2221 "parser.cpp" +#line 2191 "parser.cpp" break; case 13: // include: "#include" expr_path ";" #line 304 "parser.ypp" - { yylhs.value.as < include::ptr > () = make_include(yylhs.location, std::move(yystack_[1].value.as < expr_path::ptr > ())); } -#line 2227 "parser.cpp" + { yylhs.value.as < include::ptr > () = include::make(yylhs.location, std::move(yystack_[1].value.as < expr_path::ptr > ())); } +#line 2197 "parser.cpp" break; case 14: // declaration: "/#" #line 308 "parser.ypp" - { yylhs.value.as < decl > ().as_dev_begin = make_decl_dev_begin(yylhs.location); } -#line 2233 "parser.cpp" + { yylhs.value.as < decl::ptr > () = decl_dev_begin::make(yylhs.location); } +#line 2203 "parser.cpp" break; case 15: // declaration: "#/" #line 309 "parser.ypp" - { yylhs.value.as < decl > ().as_dev_end = make_decl_dev_end(yylhs.location); } -#line 2239 "parser.cpp" + { yylhs.value.as < decl::ptr > () = decl_dev_end::make(yylhs.location); } +#line 2209 "parser.cpp" break; case 16: // declaration: decl_usingtree #line 310 "parser.ypp" - { yylhs.value.as < decl > ().as_usingtree = std::move(yystack_[0].value.as < decl_usingtree::ptr > ()); } -#line 2245 "parser.cpp" + { yylhs.value.as < decl::ptr > () = std::move(yystack_[0].value.as < decl_usingtree::ptr > ()); } +#line 2215 "parser.cpp" break; case 17: // declaration: decl_constant #line 311 "parser.ypp" - { yylhs.value.as < decl > ().as_constant = std::move(yystack_[0].value.as < decl_constant::ptr > ()); } -#line 2251 "parser.cpp" + { yylhs.value.as < decl::ptr > () = std::move(yystack_[0].value.as < decl_constant::ptr > ()); } +#line 2221 "parser.cpp" break; case 18: // declaration: decl_function #line 312 "parser.ypp" - { yylhs.value.as < decl > ().as_function = std::move(yystack_[0].value.as < decl_function::ptr > ()); } -#line 2257 "parser.cpp" + { yylhs.value.as < decl::ptr > () = std::move(yystack_[0].value.as < decl_function::ptr > ()); } +#line 2227 "parser.cpp" break; case 19: // decl_usingtree: "#using_animtree" "(" expr_string ")" ";" #line 317 "parser.ypp" - { ppr.ban_header(yylhs.location); yylhs.value.as < decl_usingtree::ptr > () = make_decl_usingtree(yylhs.location, std::move(yystack_[2].value.as < expr_string::ptr > ())); } -#line 2263 "parser.cpp" + { ppr.ban_header(yylhs.location); yylhs.value.as < decl_usingtree::ptr > () = decl_usingtree::make(yylhs.location, std::move(yystack_[2].value.as < expr_string::ptr > ())); } +#line 2233 "parser.cpp" break; case 20: // decl_constant: expr_identifier "=" expr ";" #line 322 "parser.ypp" { - ppr.ban_header(yylhs.location); yylhs.value.as < decl_constant::ptr > () = make_decl_constant(yylhs.location, std::move(yystack_[3].value.as < expr_identifier::ptr > ()), std::move(yystack_[1].value.as < expr > ())); + ppr.ban_header(yylhs.location); yylhs.value.as < decl_constant::ptr > () = decl_constant::make(yylhs.location, std::move(yystack_[3].value.as < expr_identifier::ptr > ()), std::move(yystack_[1].value.as < expr::ptr > ())); printf("%s" , fmt::format("{}: constants deprecated, use #define instead\n", yylhs.location.print()).data()); } -#line 2272 "parser.cpp" +#line 2242 "parser.cpp" break; case 21: // decl_function: expr_identifier "(" expr_parameters ")" stmt_comp #line 330 "parser.ypp" - { ppr.ban_header(yylhs.location); yylhs.value.as < decl_function::ptr > () = make_decl_function(yylhs.location, std::move(yystack_[4].value.as < expr_identifier::ptr > ()), std::move(yystack_[2].value.as < expr_parameters::ptr > ()), std::move(yystack_[0].value.as < stmt_comp::ptr > ())); } -#line 2278 "parser.cpp" + { ppr.ban_header(yylhs.location); yylhs.value.as < decl_function::ptr > () = decl_function::make(yylhs.location, std::move(yystack_[4].value.as < expr_identifier::ptr > ()), std::move(yystack_[2].value.as < expr_parameters::ptr > ()), std::move(yystack_[0].value.as < stmt_comp::ptr > ())); } +#line 2248 "parser.cpp" break; case 22: // stmt: stmt_comp #line 334 "parser.ypp" - { yylhs.value.as < stmt > ().as_comp = std::move(yystack_[0].value.as < stmt_comp::ptr > ()); } -#line 2284 "parser.cpp" + { yylhs.value.as < stmt::ptr > () = std::move(yystack_[0].value.as < stmt_comp::ptr > ()); } +#line 2254 "parser.cpp" break; case 23: // stmt: stmt_call #line 335 "parser.ypp" - { yylhs.value.as < stmt > ().as_call = std::move(yystack_[0].value.as < stmt_call::ptr > ()); } -#line 2290 "parser.cpp" + { yylhs.value.as < stmt::ptr > () = std::move(yystack_[0].value.as < stmt_expr::ptr > ()); } +#line 2260 "parser.cpp" break; case 24: // stmt: stmt_assign #line 336 "parser.ypp" - { yylhs.value.as < stmt > ().as_assign = std::move(yystack_[0].value.as < stmt_assign::ptr > ()); } -#line 2296 "parser.cpp" + { yylhs.value.as < stmt::ptr > () = std::move(yystack_[0].value.as < stmt_expr::ptr > ()); } +#line 2266 "parser.cpp" break; case 25: // stmt: stmt_endon #line 337 "parser.ypp" - { yylhs.value.as < stmt > ().as_endon = std::move(yystack_[0].value.as < stmt_endon::ptr > ()); } -#line 2302 "parser.cpp" + { yylhs.value.as < stmt::ptr > () = std::move(yystack_[0].value.as < stmt_endon::ptr > ()); } +#line 2272 "parser.cpp" break; case 26: // stmt: stmt_notify #line 338 "parser.ypp" - { yylhs.value.as < stmt > ().as_notify = std::move(yystack_[0].value.as < stmt_notify::ptr > ()); } -#line 2308 "parser.cpp" + { yylhs.value.as < stmt::ptr > () = std::move(yystack_[0].value.as < stmt_notify::ptr > ()); } +#line 2278 "parser.cpp" break; case 27: // stmt: stmt_wait #line 339 "parser.ypp" - { yylhs.value.as < stmt > ().as_wait = std::move(yystack_[0].value.as < stmt_wait::ptr > ()); } -#line 2314 "parser.cpp" + { yylhs.value.as < stmt::ptr > () = std::move(yystack_[0].value.as < stmt_wait::ptr > ()); } +#line 2284 "parser.cpp" break; case 28: // stmt: stmt_waittill #line 340 "parser.ypp" - { yylhs.value.as < stmt > ().as_waittill = std::move(yystack_[0].value.as < stmt_waittill::ptr > ()); } -#line 2320 "parser.cpp" + { yylhs.value.as < stmt::ptr > () = std::move(yystack_[0].value.as < stmt_waittill::ptr > ()); } +#line 2290 "parser.cpp" break; case 29: // stmt: stmt_waittillmatch #line 341 "parser.ypp" - { yylhs.value.as < stmt > ().as_waittillmatch = std::move(yystack_[0].value.as < stmt_waittillmatch::ptr > ()); } -#line 2326 "parser.cpp" + { yylhs.value.as < stmt::ptr > () = std::move(yystack_[0].value.as < stmt_waittillmatch::ptr > ()); } +#line 2296 "parser.cpp" break; case 30: // stmt: stmt_waittillframeend #line 342 "parser.ypp" - { yylhs.value.as < stmt > ().as_waittillframeend = std::move(yystack_[0].value.as < stmt_waittillframeend::ptr > ()); } -#line 2332 "parser.cpp" + { yylhs.value.as < stmt::ptr > () = std::move(yystack_[0].value.as < stmt_waittillframeend::ptr > ()); } +#line 2302 "parser.cpp" break; case 31: // stmt: stmt_waitframe #line 343 "parser.ypp" - { yylhs.value.as < stmt > ().as_waitframe = std::move(yystack_[0].value.as < stmt_waitframe::ptr > ()); } -#line 2338 "parser.cpp" + { yylhs.value.as < stmt::ptr > () = std::move(yystack_[0].value.as < stmt_waitframe::ptr > ()); } +#line 2308 "parser.cpp" break; case 32: // stmt: stmt_if #line 344 "parser.ypp" - { yylhs.value.as < stmt > ().as_if = std::move(yystack_[0].value.as < stmt_if::ptr > ()); } -#line 2344 "parser.cpp" + { yylhs.value.as < stmt::ptr > () = std::move(yystack_[0].value.as < stmt_if::ptr > ()); } +#line 2314 "parser.cpp" break; case 33: // stmt: stmt_ifelse #line 345 "parser.ypp" - { yylhs.value.as < stmt > ().as_ifelse = std::move(yystack_[0].value.as < stmt_ifelse::ptr > ()); } -#line 2350 "parser.cpp" + { yylhs.value.as < stmt::ptr > () = std::move(yystack_[0].value.as < stmt_ifelse::ptr > ()); } +#line 2320 "parser.cpp" break; case 34: // stmt: stmt_while #line 346 "parser.ypp" - { yylhs.value.as < stmt > ().as_while = std::move(yystack_[0].value.as < stmt_while::ptr > ()); } -#line 2356 "parser.cpp" + { yylhs.value.as < stmt::ptr > () = std::move(yystack_[0].value.as < stmt_while::ptr > ()); } +#line 2326 "parser.cpp" break; case 35: // stmt: stmt_dowhile #line 347 "parser.ypp" - { yylhs.value.as < stmt > ().as_dowhile = std::move(yystack_[0].value.as < stmt_dowhile::ptr > ()); } -#line 2362 "parser.cpp" + { yylhs.value.as < stmt::ptr > () = std::move(yystack_[0].value.as < stmt_dowhile::ptr > ()); } +#line 2332 "parser.cpp" break; case 36: // stmt: stmt_for #line 348 "parser.ypp" - { yylhs.value.as < stmt > ().as_for = std::move(yystack_[0].value.as < stmt_for::ptr > ()); } -#line 2368 "parser.cpp" + { yylhs.value.as < stmt::ptr > () = std::move(yystack_[0].value.as < stmt_for::ptr > ()); } +#line 2338 "parser.cpp" break; case 37: // stmt: stmt_foreach #line 349 "parser.ypp" - { yylhs.value.as < stmt > ().as_foreach = std::move(yystack_[0].value.as < stmt_foreach::ptr > ()); } -#line 2374 "parser.cpp" + { yylhs.value.as < stmt::ptr > () = std::move(yystack_[0].value.as < stmt_foreach::ptr > ()); } +#line 2344 "parser.cpp" break; case 38: // stmt: stmt_switch #line 350 "parser.ypp" - { yylhs.value.as < stmt > ().as_switch = std::move(yystack_[0].value.as < stmt_switch::ptr > ()); } -#line 2380 "parser.cpp" + { yylhs.value.as < stmt::ptr > () = std::move(yystack_[0].value.as < stmt_switch::ptr > ()); } +#line 2350 "parser.cpp" break; case 39: // stmt: stmt_case #line 351 "parser.ypp" - { yylhs.value.as < stmt > ().as_case = std::move(yystack_[0].value.as < stmt_case::ptr > ()); } -#line 2386 "parser.cpp" + { yylhs.value.as < stmt::ptr > () = std::move(yystack_[0].value.as < stmt_case::ptr > ()); } +#line 2356 "parser.cpp" break; case 40: // stmt: stmt_default #line 352 "parser.ypp" - { yylhs.value.as < stmt > ().as_default = std::move(yystack_[0].value.as < stmt_default::ptr > ()); } -#line 2392 "parser.cpp" + { yylhs.value.as < stmt::ptr > () = std::move(yystack_[0].value.as < stmt_default::ptr > ()); } +#line 2362 "parser.cpp" break; case 41: // stmt: stmt_break #line 353 "parser.ypp" - { yylhs.value.as < stmt > ().as_break = std::move(yystack_[0].value.as < stmt_break::ptr > ()); } -#line 2398 "parser.cpp" + { yylhs.value.as < stmt::ptr > () = std::move(yystack_[0].value.as < stmt_break::ptr > ()); } +#line 2368 "parser.cpp" break; case 42: // stmt: stmt_continue #line 354 "parser.ypp" - { yylhs.value.as < stmt > ().as_continue = std::move(yystack_[0].value.as < stmt_continue::ptr > ()); } -#line 2404 "parser.cpp" + { yylhs.value.as < stmt::ptr > () = std::move(yystack_[0].value.as < stmt_continue::ptr > ()); } +#line 2374 "parser.cpp" break; case 43: // stmt: stmt_return #line 355 "parser.ypp" - { yylhs.value.as < stmt > ().as_return = std::move(yystack_[0].value.as < stmt_return::ptr > ()); } -#line 2410 "parser.cpp" + { yylhs.value.as < stmt::ptr > () = std::move(yystack_[0].value.as < stmt_return::ptr > ()); } +#line 2380 "parser.cpp" break; case 44: // stmt: stmt_breakpoint #line 356 "parser.ypp" - { yylhs.value.as < stmt > ().as_breakpoint = std::move(yystack_[0].value.as < stmt_breakpoint::ptr > ()); } -#line 2416 "parser.cpp" + { yylhs.value.as < stmt::ptr > () = std::move(yystack_[0].value.as < stmt_breakpoint::ptr > ()); } +#line 2386 "parser.cpp" break; case 45: // stmt: stmt_prof_begin #line 357 "parser.ypp" - { yylhs.value.as < stmt > ().as_prof_begin = std::move(yystack_[0].value.as < stmt_prof_begin::ptr > ()); } -#line 2422 "parser.cpp" + { yylhs.value.as < stmt::ptr > () = std::move(yystack_[0].value.as < stmt_prof_begin::ptr > ()); } +#line 2392 "parser.cpp" break; case 46: // stmt: stmt_prof_end #line 358 "parser.ypp" - { yylhs.value.as < stmt > ().as_prof_end = std::move(yystack_[0].value.as < stmt_prof_end::ptr > ()); } -#line 2428 "parser.cpp" + { yylhs.value.as < stmt::ptr > () = std::move(yystack_[0].value.as < stmt_prof_end::ptr > ()); } +#line 2398 "parser.cpp" break; case 47: // stmt: stmt_assert #line 359 "parser.ypp" - { yylhs.value.as < stmt > ().as_assert = std::move(yystack_[0].value.as < stmt_assert::ptr > ()); } -#line 2434 "parser.cpp" + { yylhs.value.as < stmt::ptr > () = std::move(yystack_[0].value.as < stmt_assert::ptr > ()); } +#line 2404 "parser.cpp" break; case 48: // stmt: stmt_assertex #line 360 "parser.ypp" - { yylhs.value.as < stmt > ().as_assertex = std::move(yystack_[0].value.as < stmt_assertex::ptr > ()); } -#line 2440 "parser.cpp" + { yylhs.value.as < stmt::ptr > () = std::move(yystack_[0].value.as < stmt_assertex::ptr > ()); } +#line 2410 "parser.cpp" break; case 49: // stmt: stmt_assertmsg #line 361 "parser.ypp" - { yylhs.value.as < stmt > ().as_assertmsg = std::move(yystack_[0].value.as < stmt_assertmsg::ptr > ()); } -#line 2446 "parser.cpp" + { yylhs.value.as < stmt::ptr > () = std::move(yystack_[0].value.as < stmt_assertmsg::ptr > ()); } +#line 2416 "parser.cpp" break; case 50: // stmt_or_dev: stmt #line 365 "parser.ypp" - { yylhs.value.as < stmt > () = std::move(yystack_[0].value.as < stmt > ()); } -#line 2452 "parser.cpp" + { yylhs.value.as < stmt::ptr > () = std::move(yystack_[0].value.as < stmt::ptr > ()); } +#line 2422 "parser.cpp" break; case 51: // stmt_or_dev: stmt_dev #line 366 "parser.ypp" - { yylhs.value.as < stmt > ().as_dev = std::move(yystack_[0].value.as < stmt_dev::ptr > ()); } -#line 2458 "parser.cpp" + { yylhs.value.as < stmt::ptr > () = std::move(yystack_[0].value.as < stmt_dev::ptr > ()); } +#line 2428 "parser.cpp" break; case 52: // stmt_list: stmt_list stmt #line 371 "parser.ypp" - { yylhs.value.as < stmt_list::ptr > () = std::move(yystack_[1].value.as < stmt_list::ptr > ()); yylhs.value.as < stmt_list::ptr > ()->list.push_back(std::move(yystack_[0].value.as < stmt > ())); } -#line 2464 "parser.cpp" + { yylhs.value.as < stmt_list::ptr > () = std::move(yystack_[1].value.as < stmt_list::ptr > ()); yylhs.value.as < stmt_list::ptr > ()->list.push_back(std::move(yystack_[0].value.as < stmt::ptr > ())); } +#line 2434 "parser.cpp" break; case 53: // stmt_list: stmt #line 373 "parser.ypp" - { yylhs.value.as < stmt_list::ptr > () = make_stmt_list(yylhs.location); yylhs.value.as < stmt_list::ptr > ()->list.push_back(std::move(yystack_[0].value.as < stmt > ())); } -#line 2470 "parser.cpp" + { yylhs.value.as < stmt_list::ptr > () = stmt_list::make(yylhs.location); yylhs.value.as < stmt_list::ptr > ()->list.push_back(std::move(yystack_[0].value.as < stmt::ptr > ())); } +#line 2440 "parser.cpp" break; case 54: // stmt_list: stmt_list ";" #line 375 "parser.ypp" { yylhs.value.as < stmt_list::ptr > () = std::move(yystack_[1].value.as < stmt_list::ptr > ()); } -#line 2476 "parser.cpp" +#line 2446 "parser.cpp" break; case 55: // stmt_list: ";" #line 377 "parser.ypp" - { yylhs.value.as < stmt_list::ptr > () = make_stmt_list(yylhs.location); } -#line 2482 "parser.cpp" + { yylhs.value.as < stmt_list::ptr > () = stmt_list::make(yylhs.location); } +#line 2452 "parser.cpp" break; case 56: // stmt_or_dev_list: stmt_or_dev_list stmt_or_dev #line 382 "parser.ypp" - { yylhs.value.as < stmt_list::ptr > () = std::move(yystack_[1].value.as < stmt_list::ptr > ()); yylhs.value.as < stmt_list::ptr > ()->list.push_back(std::move(yystack_[0].value.as < stmt > ())); } -#line 2488 "parser.cpp" + { yylhs.value.as < stmt_list::ptr > () = std::move(yystack_[1].value.as < stmt_list::ptr > ()); yylhs.value.as < stmt_list::ptr > ()->list.push_back(std::move(yystack_[0].value.as < stmt::ptr > ())); } +#line 2458 "parser.cpp" break; case 57: // stmt_or_dev_list: stmt_or_dev #line 384 "parser.ypp" - { yylhs.value.as < stmt_list::ptr > () = make_stmt_list(yylhs.location); yylhs.value.as < stmt_list::ptr > ()->list.push_back(std::move(yystack_[0].value.as < stmt > ())); } -#line 2494 "parser.cpp" + { yylhs.value.as < stmt_list::ptr > () = stmt_list::make(yylhs.location); yylhs.value.as < stmt_list::ptr > ()->list.push_back(std::move(yystack_[0].value.as < stmt::ptr > ())); } +#line 2464 "parser.cpp" break; case 58: // stmt_or_dev_list: stmt_or_dev_list ";" #line 386 "parser.ypp" { yylhs.value.as < stmt_list::ptr > () = std::move(yystack_[1].value.as < stmt_list::ptr > ()); } -#line 2500 "parser.cpp" +#line 2470 "parser.cpp" break; case 59: // stmt_or_dev_list: ";" #line 388 "parser.ypp" - { yylhs.value.as < stmt_list::ptr > () = make_stmt_list(yylhs.location); } -#line 2506 "parser.cpp" + { yylhs.value.as < stmt_list::ptr > () = stmt_list::make(yylhs.location); } +#line 2476 "parser.cpp" break; case 60: // stmt_dev: "/#" stmt_list "#/" #line 392 "parser.ypp" - { yylhs.value.as < stmt_dev::ptr > () = make_stmt_dev(yylhs.location, std::move(yystack_[1].value.as < stmt_list::ptr > ())); } -#line 2512 "parser.cpp" + { yylhs.value.as < stmt_dev::ptr > () = stmt_dev::make(yylhs.location, std::move(yystack_[1].value.as < stmt_list::ptr > ())); } +#line 2482 "parser.cpp" break; case 61: // stmt_dev: "/#" "#/" #line 393 "parser.ypp" - { yylhs.value.as < stmt_dev::ptr > () = make_stmt_dev(yylhs.location, make_stmt_list(yylhs.location)); } -#line 2518 "parser.cpp" + { yylhs.value.as < stmt_dev::ptr > () = stmt_dev::make(yylhs.location, stmt_list::make(yylhs.location)); } +#line 2488 "parser.cpp" break; case 62: // stmt_comp: "{" stmt_or_dev_list "}" #line 397 "parser.ypp" - { yylhs.value.as < stmt_comp::ptr > () = make_stmt_comp(yylhs.location, std::move(yystack_[1].value.as < stmt_list::ptr > ())); } -#line 2524 "parser.cpp" + { yylhs.value.as < stmt_comp::ptr > () = stmt_comp::make(yylhs.location, std::move(yystack_[1].value.as < stmt_list::ptr > ())); } +#line 2494 "parser.cpp" break; case 63: // stmt_comp: "{" "}" #line 398 "parser.ypp" - { yylhs.value.as < stmt_comp::ptr > () = make_stmt_comp(yylhs.location, make_stmt_list(yylhs.location)); } -#line 2530 "parser.cpp" + { yylhs.value.as < stmt_comp::ptr > () = stmt_comp::make(yylhs.location, stmt_list::make(yylhs.location)); } +#line 2500 "parser.cpp" break; case 64: // stmt_expr: expr_assign #line 403 "parser.ypp" - { yylhs.value.as < stmt_expr::ptr > () = make_stmt_expr(yylhs.location, std::move(yystack_[0].value.as < expr > ())); } -#line 2536 "parser.cpp" + { yylhs.value.as < stmt_expr::ptr > () = stmt_expr::make(yylhs.location, std::move(yystack_[0].value.as < expr::ptr > ())); } +#line 2506 "parser.cpp" break; case 65: // stmt_expr: expr_increment #line 405 "parser.ypp" - { yylhs.value.as < stmt_expr::ptr > () = make_stmt_expr(yylhs.location, std::move(yystack_[0].value.as < expr > ())); } -#line 2542 "parser.cpp" + { yylhs.value.as < stmt_expr::ptr > () = stmt_expr::make(yylhs.location, std::move(yystack_[0].value.as < expr::ptr > ())); } +#line 2512 "parser.cpp" break; case 66: // stmt_expr: expr_decrement #line 407 "parser.ypp" - { yylhs.value.as < stmt_expr::ptr > () = make_stmt_expr(yylhs.location, std::move(yystack_[0].value.as < expr > ())); } -#line 2548 "parser.cpp" + { yylhs.value.as < stmt_expr::ptr > () = stmt_expr::make(yylhs.location, std::move(yystack_[0].value.as < expr::ptr > ())); } +#line 2518 "parser.cpp" break; case 67: // stmt_expr: %empty #line 409 "parser.ypp" - { yylhs.value.as < stmt_expr::ptr > () = make_stmt_expr(yylhs.location, make_node(yylhs.location)); } -#line 2554 "parser.cpp" + { yylhs.value.as < stmt_expr::ptr > () = stmt_expr::make(yylhs.location, expr_empty::make(yylhs.location)); } +#line 2524 "parser.cpp" break; case 68: // stmt_call: expr_call ";" #line 414 "parser.ypp" - { yylhs.value.as < stmt_call::ptr > () = make_stmt_call(yylhs.location, expr{ std::move(yystack_[1].value.as < expr_call::ptr > ()) }); } -#line 2560 "parser.cpp" + { yylhs.value.as < stmt_expr::ptr > () = stmt_expr::make(yylhs.location, std::move(yystack_[1].value.as < expr_call::ptr > ())); } +#line 2530 "parser.cpp" break; case 69: // stmt_call: expr_method ";" #line 416 "parser.ypp" - { yylhs.value.as < stmt_call::ptr > () = make_stmt_call(yylhs.location, expr{ std::move(yystack_[1].value.as < expr_method::ptr > ()) }); } -#line 2566 "parser.cpp" + { yylhs.value.as < stmt_expr::ptr > () = stmt_expr::make(yylhs.location, std::move(yystack_[1].value.as < expr_method::ptr > ())); } +#line 2536 "parser.cpp" break; case 70: // stmt_assign: expr_assign ";" #line 421 "parser.ypp" - { yylhs.value.as < stmt_assign::ptr > () = make_stmt_assign(yylhs.location, std::move(yystack_[1].value.as < expr > ())); } -#line 2572 "parser.cpp" + { yylhs.value.as < stmt_expr::ptr > () = stmt_expr::make(yylhs.location, std::move(yystack_[1].value.as < expr::ptr > ())); } +#line 2542 "parser.cpp" break; case 71: // stmt_assign: expr_increment ";" #line 423 "parser.ypp" - { yylhs.value.as < stmt_assign::ptr > () = make_stmt_assign(yylhs.location, std::move(yystack_[1].value.as < expr > ())); } -#line 2578 "parser.cpp" + { yylhs.value.as < stmt_expr::ptr > () = stmt_expr::make(yylhs.location, std::move(yystack_[1].value.as < expr::ptr > ())); } +#line 2548 "parser.cpp" break; case 72: // stmt_assign: expr_decrement ";" #line 425 "parser.ypp" - { yylhs.value.as < stmt_assign::ptr > () = make_stmt_assign(yylhs.location, std::move(yystack_[1].value.as < expr > ())); } -#line 2584 "parser.cpp" + { yylhs.value.as < stmt_expr::ptr > () = stmt_expr::make(yylhs.location, std::move(yystack_[1].value.as < expr::ptr > ())); } +#line 2554 "parser.cpp" break; case 73: // stmt_endon: expr_object "endon" "(" expr ")" ";" #line 430 "parser.ypp" - { yylhs.value.as < stmt_endon::ptr > () = make_stmt_endon(yylhs.location, std::move(yystack_[5].value.as < expr > ()), std::move(yystack_[2].value.as < expr > ())); } -#line 2590 "parser.cpp" + { yylhs.value.as < stmt_endon::ptr > () = stmt_endon::make(yylhs.location, std::move(yystack_[5].value.as < expr::ptr > ()), std::move(yystack_[2].value.as < expr::ptr > ())); } +#line 2560 "parser.cpp" break; case 74: // stmt_notify: expr_object "notify" "(" expr "," expr_arguments_no_empty ")" ";" #line 435 "parser.ypp" - { yylhs.value.as < stmt_notify::ptr > () = make_stmt_notify(yylhs.location, std::move(yystack_[7].value.as < expr > ()), std::move(yystack_[4].value.as < expr > ()), std::move(yystack_[2].value.as < expr_arguments::ptr > ())); } -#line 2596 "parser.cpp" + { yylhs.value.as < stmt_notify::ptr > () = stmt_notify::make(yylhs.location, std::move(yystack_[7].value.as < expr::ptr > ()), std::move(yystack_[4].value.as < expr::ptr > ()), std::move(yystack_[2].value.as < expr_arguments::ptr > ())); } +#line 2566 "parser.cpp" break; case 75: // stmt_notify: expr_object "notify" "(" expr ")" ";" #line 437 "parser.ypp" - { yylhs.value.as < stmt_notify::ptr > () = make_stmt_notify(yylhs.location, std::move(yystack_[5].value.as < expr > ()), std::move(yystack_[2].value.as < expr > ()), make_expr_arguments(yylhs.location)); } -#line 2602 "parser.cpp" + { yylhs.value.as < stmt_notify::ptr > () = stmt_notify::make(yylhs.location, std::move(yystack_[5].value.as < expr::ptr > ()), std::move(yystack_[2].value.as < expr::ptr > ()), expr_arguments::make(yylhs.location)); } +#line 2572 "parser.cpp" break; case 76: // stmt_wait: "wait" expr ";" #line 442 "parser.ypp" - { yylhs.value.as < stmt_wait::ptr > () = make_stmt_wait(yylhs.location, std::move(yystack_[1].value.as < expr > ())); } -#line 2608 "parser.cpp" + { yylhs.value.as < stmt_wait::ptr > () = stmt_wait::make(yylhs.location, std::move(yystack_[1].value.as < expr::ptr > ())); } +#line 2578 "parser.cpp" break; case 77: // stmt_waittill: expr_object "waittill" "(" expr "," expr_arguments_no_empty ")" ";" #line 447 "parser.ypp" - { yylhs.value.as < stmt_waittill::ptr > () = make_stmt_waittill(yylhs.location, std::move(yystack_[7].value.as < expr > ()), std::move(yystack_[4].value.as < expr > ()), std::move(yystack_[2].value.as < expr_arguments::ptr > ())); } -#line 2614 "parser.cpp" + { yylhs.value.as < stmt_waittill::ptr > () = stmt_waittill::make(yylhs.location, std::move(yystack_[7].value.as < expr::ptr > ()), std::move(yystack_[4].value.as < expr::ptr > ()), std::move(yystack_[2].value.as < expr_arguments::ptr > ())); } +#line 2584 "parser.cpp" break; case 78: // stmt_waittill: expr_object "waittill" "(" expr ")" ";" #line 449 "parser.ypp" - { yylhs.value.as < stmt_waittill::ptr > () = make_stmt_waittill(yylhs.location, std::move(yystack_[5].value.as < expr > ()), std::move(yystack_[2].value.as < expr > ()), make_expr_arguments(yylhs.location)); } -#line 2620 "parser.cpp" + { yylhs.value.as < stmt_waittill::ptr > () = stmt_waittill::make(yylhs.location, std::move(yystack_[5].value.as < expr::ptr > ()), std::move(yystack_[2].value.as < expr::ptr > ()), expr_arguments::make(yylhs.location)); } +#line 2590 "parser.cpp" break; case 79: // stmt_waittillmatch: expr_object "waittillmatch" "(" expr "," expr_arguments_no_empty ")" ";" #line 454 "parser.ypp" - { yylhs.value.as < stmt_waittillmatch::ptr > () = make_stmt_waittillmatch(yylhs.location, std::move(yystack_[7].value.as < expr > ()), std::move(yystack_[4].value.as < expr > ()), std::move(yystack_[2].value.as < expr_arguments::ptr > ())); } -#line 2626 "parser.cpp" + { yylhs.value.as < stmt_waittillmatch::ptr > () = stmt_waittillmatch::make(yylhs.location, std::move(yystack_[7].value.as < expr::ptr > ()), std::move(yystack_[4].value.as < expr::ptr > ()), std::move(yystack_[2].value.as < expr_arguments::ptr > ())); } +#line 2596 "parser.cpp" break; case 80: // stmt_waittillmatch: expr_object "waittillmatch" "(" expr ")" ";" #line 456 "parser.ypp" - { yylhs.value.as < stmt_waittillmatch::ptr > () = make_stmt_waittillmatch(yylhs.location, std::move(yystack_[5].value.as < expr > ()), std::move(yystack_[2].value.as < expr > ()), make_expr_arguments(yylhs.location)); } -#line 2632 "parser.cpp" + { yylhs.value.as < stmt_waittillmatch::ptr > () = stmt_waittillmatch::make(yylhs.location, std::move(yystack_[5].value.as < expr::ptr > ()), std::move(yystack_[2].value.as < expr::ptr > ()), expr_arguments::make(yylhs.location)); } +#line 2602 "parser.cpp" break; case 81: // stmt_waittillframeend: "waittillframeend" ";" #line 461 "parser.ypp" - { yylhs.value.as < stmt_waittillframeend::ptr > () = make_stmt_waittillframeend(yylhs.location); } -#line 2638 "parser.cpp" + { yylhs.value.as < stmt_waittillframeend::ptr > () = stmt_waittillframeend::make(yylhs.location); } +#line 2608 "parser.cpp" break; case 82: // stmt_waitframe: "waitframe" ";" #line 466 "parser.ypp" - { yylhs.value.as < stmt_waitframe::ptr > () = make_stmt_waitframe(yylhs.location); } -#line 2644 "parser.cpp" + { yylhs.value.as < stmt_waitframe::ptr > () = stmt_waitframe::make(yylhs.location); } +#line 2614 "parser.cpp" break; case 83: // stmt_waitframe: "waitframe" "(" ")" ";" #line 468 "parser.ypp" - { yylhs.value.as < stmt_waitframe::ptr > () = make_stmt_waitframe(yylhs.location); } -#line 2650 "parser.cpp" + { yylhs.value.as < stmt_waitframe::ptr > () = stmt_waitframe::make(yylhs.location); } +#line 2620 "parser.cpp" break; case 84: // stmt_if: "if" "(" expr ")" stmt #line 473 "parser.ypp" - { yylhs.value.as < stmt_if::ptr > () = make_stmt_if(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < stmt > ())); } -#line 2656 "parser.cpp" + { yylhs.value.as < stmt_if::ptr > () = stmt_if::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < stmt::ptr > ())); } +#line 2626 "parser.cpp" break; case 85: // stmt_ifelse: "if" "(" expr ")" stmt "else" stmt #line 478 "parser.ypp" - { yylhs.value.as < stmt_ifelse::ptr > () = make_stmt_ifelse(yylhs.location, std::move(yystack_[4].value.as < expr > ()), std::move(yystack_[2].value.as < stmt > ()), std::move(yystack_[0].value.as < stmt > ())); } -#line 2662 "parser.cpp" + { yylhs.value.as < stmt_ifelse::ptr > () = stmt_ifelse::make(yylhs.location, std::move(yystack_[4].value.as < expr::ptr > ()), std::move(yystack_[2].value.as < stmt::ptr > ()), std::move(yystack_[0].value.as < stmt::ptr > ())); } +#line 2632 "parser.cpp" break; case 86: // stmt_while: "while" "(" expr ")" stmt #line 483 "parser.ypp" - { yylhs.value.as < stmt_while::ptr > () = make_stmt_while(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < stmt > ())); } -#line 2668 "parser.cpp" + { yylhs.value.as < stmt_while::ptr > () = stmt_while::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < stmt::ptr > ())); } +#line 2638 "parser.cpp" break; case 87: // stmt_dowhile: "do" stmt "while" "(" expr ")" ";" #line 488 "parser.ypp" - { yylhs.value.as < stmt_dowhile::ptr > () = make_stmt_dowhile(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[5].value.as < stmt > ())); } -#line 2674 "parser.cpp" + { yylhs.value.as < stmt_dowhile::ptr > () = stmt_dowhile::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[5].value.as < stmt::ptr > ())); } +#line 2644 "parser.cpp" break; case 88: // stmt_for: "for" "(" stmt_expr ";" expr_or_empty ";" stmt_expr ")" stmt #line 493 "parser.ypp" - { yylhs.value.as < stmt_for::ptr > () = make_stmt_for(yylhs.location, stmt{ std::move(yystack_[6].value.as < stmt_expr::ptr > ()) }, std::move(yystack_[4].value.as < expr > ()), stmt{ std::move(yystack_[2].value.as < stmt_expr::ptr > ()) }, std::move(yystack_[0].value.as < stmt > ())); } -#line 2680 "parser.cpp" + { yylhs.value.as < stmt_for::ptr > () = stmt_for::make(yylhs.location, std::move(yystack_[6].value.as < stmt_expr::ptr > ()), std::move(yystack_[4].value.as < expr::ptr > ()), std::move(yystack_[2].value.as < stmt_expr::ptr > ()), std::move(yystack_[0].value.as < stmt::ptr > ())); } +#line 2650 "parser.cpp" break; case 89: // stmt_foreach: "foreach" "(" expr_identifier "in" expr ")" stmt #line 498 "parser.ypp" { - auto array = expr{ make_expr_identifier(yylhs.location, fmt::format("_temp_{}", ++index)) }; - auto key = expr{ make_expr_identifier(yylhs.location, fmt::format("_temp_{}", ++index)) }; - yylhs.value.as < stmt_foreach::ptr > () = make_stmt_foreach(yylhs.location, std::move(yystack_[2].value.as < expr > ()), expr{ std::move(yystack_[4].value.as < expr_identifier::ptr > ()) }, expr{ make_node(yylhs.location) }, std::move(array), std::move(key), std::move(yystack_[0].value.as < stmt > ()), false); } -#line 2689 "parser.cpp" + auto array = expr_identifier::make(yylhs.location, fmt::format("_temp_{}", ++index)); + auto key = expr_identifier::make(yylhs.location, fmt::format("_temp_{}", ++index)); + yylhs.value.as < stmt_foreach::ptr > () = stmt_foreach::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[4].value.as < expr_identifier::ptr > ()), expr_empty::make(yylhs.location), std::move(array), std::move(key), std::move(yystack_[0].value.as < stmt::ptr > ()), false); + } +#line 2660 "parser.cpp" break; case 90: // stmt_foreach: "foreach" "(" expr_identifier "," expr_identifier "in" expr ")" stmt -#line 503 "parser.ypp" +#line 504 "parser.ypp" { - auto array = expr{ make_expr_identifier(yylhs.location, fmt::format("_temp_{}", ++index)) }; - auto key = (ctx_->props() & props::foreach) ? expr{ make_expr_identifier(yylhs.location, fmt::format("_temp_{}", ++index)) } : expr{ std::move(yystack_[6].value.as < expr_identifier::ptr > ()) }; - yylhs.value.as < stmt_foreach::ptr > () = make_stmt_foreach(yylhs.location, std::move(yystack_[2].value.as < expr > ()), expr{ std::move(yystack_[4].value.as < expr_identifier::ptr > ()) }, (ctx_->props() & props::foreach) ? expr{ std::move(yystack_[6].value.as < expr_identifier::ptr > ()) } : expr{ make_node(yylhs.location) }, std::move(array), std::move(key), std::move(yystack_[0].value.as < stmt > ()), true); + auto array = expr_identifier::make(yylhs.location, fmt::format("_temp_{}", ++index)); + expr::ptr key = (ctx_->props() & props::foreach) ? expr_identifier::make(yylhs.location, fmt::format("_temp_{}", ++index)) : std::move(yystack_[6].value.as < expr_identifier::ptr > ()); + yylhs.value.as < stmt_foreach::ptr > () = stmt_foreach::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[4].value.as < expr_identifier::ptr > ()), (ctx_->props() & props::foreach) ? std::move(yystack_[6].value.as < expr_identifier::ptr > ()) : (expr::ptr)expr_empty::make(yylhs.location), std::move(array), std::move(key), std::move(yystack_[0].value.as < stmt::ptr > ()), true); } -#line 2699 "parser.cpp" +#line 2670 "parser.cpp" break; case 91: // stmt_switch: "switch" "(" expr ")" stmt_comp -#line 512 "parser.ypp" - { yylhs.value.as < stmt_switch::ptr > () = make_stmt_switch(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < stmt_comp::ptr > ())); +#line 513 "parser.ypp" + { yylhs.value.as < stmt_switch::ptr > () = stmt_switch::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < stmt_comp::ptr > ())); parse_switch(*yylhs.value.as < stmt_switch::ptr > ()); } -#line 2707 "parser.cpp" +#line 2678 "parser.cpp" break; case 92: // stmt_case: "case" expr_integer ":" -#line 519 "parser.ypp" - { yylhs.value.as < stmt_case::ptr > () = make_stmt_case(yylhs.location, expr{ std::move(yystack_[1].value.as < expr_integer::ptr > ()) }, make_stmt_list(yylhs.location)); } -#line 2713 "parser.cpp" +#line 520 "parser.ypp" + { yylhs.value.as < stmt_case::ptr > () = stmt_case::make(yylhs.location, std::move(yystack_[1].value.as < expr_integer::ptr > ()), stmt_list::make(yylhs.location)); } +#line 2684 "parser.cpp" break; case 93: // stmt_case: "case" expr_string ":" -#line 521 "parser.ypp" - { yylhs.value.as < stmt_case::ptr > () = make_stmt_case(yylhs.location, expr{ std::move(yystack_[1].value.as < expr_string::ptr > ()) }, make_stmt_list(yylhs.location)); } -#line 2719 "parser.cpp" +#line 522 "parser.ypp" + { yylhs.value.as < stmt_case::ptr > () = stmt_case::make(yylhs.location, std::move(yystack_[1].value.as < expr_string::ptr > ()), stmt_list::make(yylhs.location)); } +#line 2690 "parser.cpp" break; case 94: // stmt_default: "default" ":" -#line 526 "parser.ypp" - { yylhs.value.as < stmt_default::ptr > () = make_stmt_default(yylhs.location, make_stmt_list(yylhs.location)); } -#line 2725 "parser.cpp" +#line 527 "parser.ypp" + { yylhs.value.as < stmt_default::ptr > () = stmt_default::make(yylhs.location, stmt_list::make(yylhs.location)); } +#line 2696 "parser.cpp" break; case 95: // stmt_break: "break" ";" -#line 531 "parser.ypp" - { yylhs.value.as < stmt_break::ptr > () = make_stmt_break(yylhs.location); } -#line 2731 "parser.cpp" +#line 532 "parser.ypp" + { yylhs.value.as < stmt_break::ptr > () = stmt_break::make(yylhs.location); } +#line 2702 "parser.cpp" break; case 96: // stmt_continue: "continue" ";" -#line 536 "parser.ypp" - { yylhs.value.as < stmt_continue::ptr > () = make_stmt_continue(yylhs.location); } -#line 2737 "parser.cpp" +#line 537 "parser.ypp" + { yylhs.value.as < stmt_continue::ptr > () = stmt_continue::make(yylhs.location); } +#line 2708 "parser.cpp" break; case 97: // stmt_return: "return" expr ";" -#line 541 "parser.ypp" - { yylhs.value.as < stmt_return::ptr > () = make_stmt_return(yylhs.location, std::move(yystack_[1].value.as < expr > ())); } -#line 2743 "parser.cpp" +#line 542 "parser.ypp" + { yylhs.value.as < stmt_return::ptr > () = stmt_return::make(yylhs.location, std::move(yystack_[1].value.as < expr::ptr > ())); } +#line 2714 "parser.cpp" break; case 98: // stmt_return: "return" ";" -#line 543 "parser.ypp" - { yylhs.value.as < stmt_return::ptr > () = make_stmt_return(yylhs.location, make_node(yylhs.location)); } -#line 2749 "parser.cpp" +#line 544 "parser.ypp" + { yylhs.value.as < stmt_return::ptr > () = stmt_return::make(yylhs.location, expr_empty::make(yylhs.location)); } +#line 2720 "parser.cpp" break; case 99: // stmt_breakpoint: "breakpoint" ";" -#line 548 "parser.ypp" - { yylhs.value.as < stmt_breakpoint::ptr > () = make_stmt_breakpoint(yylhs.location); } -#line 2755 "parser.cpp" +#line 549 "parser.ypp" + { yylhs.value.as < stmt_breakpoint::ptr > () = stmt_breakpoint::make(yylhs.location); } +#line 2726 "parser.cpp" break; case 100: // stmt_prof_begin: "prof_begin" "(" expr_arguments ")" ";" -#line 553 "parser.ypp" - { yylhs.value.as < stmt_prof_begin::ptr > () = make_stmt_prof_begin(yylhs.location, std::move(yystack_[2].value.as < expr_arguments::ptr > ())); } -#line 2761 "parser.cpp" +#line 554 "parser.ypp" + { yylhs.value.as < stmt_prof_begin::ptr > () = stmt_prof_begin::make(yylhs.location, std::move(yystack_[2].value.as < expr_arguments::ptr > ())); } +#line 2732 "parser.cpp" break; case 101: // stmt_prof_end: "prof_end" "(" expr_arguments ")" ";" -#line 558 "parser.ypp" - { yylhs.value.as < stmt_prof_end::ptr > () = make_stmt_prof_end(yylhs.location, std::move(yystack_[2].value.as < expr_arguments::ptr > ())); } -#line 2767 "parser.cpp" +#line 559 "parser.ypp" + { yylhs.value.as < stmt_prof_end::ptr > () = stmt_prof_end::make(yylhs.location, std::move(yystack_[2].value.as < expr_arguments::ptr > ())); } +#line 2738 "parser.cpp" break; case 102: // stmt_assert: "assert" "(" expr_arguments ")" ";" -#line 563 "parser.ypp" - { yylhs.value.as < stmt_assert::ptr > () = make_stmt_assert(yylhs.location, std::move(yystack_[2].value.as < expr_arguments::ptr > ())); } -#line 2773 "parser.cpp" +#line 564 "parser.ypp" + { yylhs.value.as < stmt_assert::ptr > () = stmt_assert::make(yylhs.location, std::move(yystack_[2].value.as < expr_arguments::ptr > ())); } +#line 2744 "parser.cpp" break; case 103: // stmt_assertex: "assertex" "(" expr_arguments ")" ";" -#line 568 "parser.ypp" - { yylhs.value.as < stmt_assertex::ptr > () = make_stmt_assertex(yylhs.location, std::move(yystack_[2].value.as < expr_arguments::ptr > ())); } -#line 2779 "parser.cpp" +#line 569 "parser.ypp" + { yylhs.value.as < stmt_assertex::ptr > () = stmt_assertex::make(yylhs.location, std::move(yystack_[2].value.as < expr_arguments::ptr > ())); } +#line 2750 "parser.cpp" break; case 104: // stmt_assertmsg: "assertmsg" "(" expr_arguments ")" ";" -#line 573 "parser.ypp" - { yylhs.value.as < stmt_assertmsg::ptr > () = make_stmt_assertmsg(yylhs.location, std::move(yystack_[2].value.as < expr_arguments::ptr > ())); } -#line 2785 "parser.cpp" +#line 574 "parser.ypp" + { yylhs.value.as < stmt_assertmsg::ptr > () = stmt_assertmsg::make(yylhs.location, std::move(yystack_[2].value.as < expr_arguments::ptr > ())); } +#line 2756 "parser.cpp" break; case 105: // expr: expr_ternary -#line 577 "parser.ypp" - { yylhs.value.as < expr > () = std::move(yystack_[0].value.as < expr > ()); } -#line 2791 "parser.cpp" +#line 578 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr::ptr > ()); } +#line 2762 "parser.cpp" break; case 106: // expr: expr_binary -#line 578 "parser.ypp" - { yylhs.value.as < expr > () = std::move(yystack_[0].value.as < expr > ()); } -#line 2797 "parser.cpp" +#line 579 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr::ptr > ()); } +#line 2768 "parser.cpp" break; case 107: // expr: expr_primitive -#line 579 "parser.ypp" - { yylhs.value.as < expr > () = std::move(yystack_[0].value.as < expr > ()); } -#line 2803 "parser.cpp" +#line 580 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr::ptr > ()); } +#line 2774 "parser.cpp" break; case 108: // expr_or_empty: expr -#line 583 "parser.ypp" - { yylhs.value.as < expr > () = std::move(yystack_[0].value.as < expr > ()); } -#line 2809 "parser.cpp" +#line 584 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr::ptr > ()); } +#line 2780 "parser.cpp" break; case 109: // expr_or_empty: %empty -#line 584 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_node(yylhs.location); } -#line 2815 "parser.cpp" +#line 585 "parser.ypp" + { yylhs.value.as < expr::ptr > () = expr_empty::make(yylhs.location); } +#line 2786 "parser.cpp" break; - case 110: // expr_assign: expr_tuple "=" expr -#line 589 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_assign_equal(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < expr > ())); } -#line 2821 "parser.cpp" + case 110: // expr_increment: "++" expr_object +#line 590 "parser.ypp" + { yylhs.value.as < expr::ptr > () = expr_increment::make(yylhs.location, std::move(yystack_[0].value.as < expr::ptr > ()), true); } +#line 2792 "parser.cpp" break; - case 111: // expr_assign: expr_object "=" expr -#line 591 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_assign_equal(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < expr > ())); } -#line 2827 "parser.cpp" + case 111: // expr_increment: expr_object "++" +#line 592 "parser.ypp" + { yylhs.value.as < expr::ptr > () = expr_increment::make(yylhs.location, std::move(yystack_[1].value.as < expr::ptr > ()), false); } +#line 2798 "parser.cpp" break; - case 112: // expr_assign: expr_object "|=" expr -#line 593 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_assign_bitwise_or(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < expr > ())); } -#line 2833 "parser.cpp" - break; - - case 113: // expr_assign: expr_object "&=" expr -#line 595 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_assign_bitwise_and(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < expr > ())); } -#line 2839 "parser.cpp" - break; - - case 114: // expr_assign: expr_object "^=" expr + case 112: // expr_decrement: "--" expr_object #line 597 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_assign_bitwise_exor(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < expr > ())); } -#line 2845 "parser.cpp" + { yylhs.value.as < expr::ptr > () = expr_decrement::make(yylhs.location, std::move(yystack_[0].value.as < expr::ptr > ()), true); } +#line 2804 "parser.cpp" break; - case 115: // expr_assign: expr_object "<<=" expr + case 113: // expr_decrement: expr_object "--" #line 599 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_assign_shift_left(yylhs.location, std::move(yystack_[2].value.as < expr > ()),std::move( yystack_[0].value.as < expr > ())); } -#line 2851 "parser.cpp" + { yylhs.value.as < expr::ptr > () = expr_decrement::make(yylhs.location, std::move(yystack_[1].value.as < expr::ptr > ()), false); } +#line 2810 "parser.cpp" break; - case 116: // expr_assign: expr_object ">>=" expr -#line 601 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_assign_shift_right(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < expr > ())); } -#line 2857 "parser.cpp" + case 114: // expr_assign: expr_tuple "=" expr +#line 604 "parser.ypp" + { yylhs.value.as < expr::ptr > () = expr_assign::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < expr::ptr > ()), expr_assign::op::eq); } +#line 2816 "parser.cpp" break; - case 117: // expr_assign: expr_object "+=" expr -#line 603 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_assign_add(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < expr > ())); } -#line 2863 "parser.cpp" + case 115: // expr_assign: expr_object "=" expr +#line 606 "parser.ypp" + { yylhs.value.as < expr::ptr > () = expr_assign::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < expr::ptr > ()), expr_assign::op::eq); } +#line 2822 "parser.cpp" break; - case 118: // expr_assign: expr_object "-=" expr -#line 605 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_assign_sub(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < expr > ())); } -#line 2869 "parser.cpp" + case 116: // expr_assign: expr_object "|=" expr +#line 608 "parser.ypp" + { yylhs.value.as < expr::ptr > () = expr_assign::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < expr::ptr > ()), expr_assign::op::bwor); } +#line 2828 "parser.cpp" break; - case 119: // expr_assign: expr_object "*=" expr -#line 607 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_assign_mul(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < expr > ())); } -#line 2875 "parser.cpp" + case 117: // expr_assign: expr_object "&=" expr +#line 610 "parser.ypp" + { yylhs.value.as < expr::ptr > () = expr_assign::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < expr::ptr > ()), expr_assign::op::bwand); } +#line 2834 "parser.cpp" break; - case 120: // expr_assign: expr_object "/=" expr -#line 609 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_assign_div(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < expr > ())); } -#line 2881 "parser.cpp" + case 118: // expr_assign: expr_object "^=" expr +#line 612 "parser.ypp" + { yylhs.value.as < expr::ptr > () = expr_assign::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < expr::ptr > ()), expr_assign::op::bwexor); } +#line 2840 "parser.cpp" break; - case 121: // expr_assign: expr_object "%=" expr -#line 611 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_assign_mod(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < expr > ())); } -#line 2887 "parser.cpp" + case 119: // expr_assign: expr_object "<<=" expr +#line 614 "parser.ypp" + { yylhs.value.as < expr::ptr > () = expr_assign::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < expr::ptr > ()), expr_assign::op::shl); } +#line 2846 "parser.cpp" break; - case 122: // expr_increment: "++" expr_object + case 120: // expr_assign: expr_object ">>=" expr #line 616 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_increment(yylhs.location, std::move(yystack_[0].value.as < expr > ()), true); } -#line 2893 "parser.cpp" + { yylhs.value.as < expr::ptr > () = expr_assign::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < expr::ptr > ()), expr_assign::op::shr); } +#line 2852 "parser.cpp" break; - case 123: // expr_increment: expr_object "++" + case 121: // expr_assign: expr_object "+=" expr #line 618 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_increment(yylhs.location, std::move(yystack_[1].value.as < expr > ()), false); } -#line 2899 "parser.cpp" + { yylhs.value.as < expr::ptr > () = expr_assign::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < expr::ptr > ()), expr_assign::op::add); } +#line 2858 "parser.cpp" break; - case 124: // expr_decrement: "--" expr_object -#line 623 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_decrement(yylhs.location, std::move(yystack_[0].value.as < expr > ()), true); } -#line 2905 "parser.cpp" + case 122: // expr_assign: expr_object "-=" expr +#line 620 "parser.ypp" + { yylhs.value.as < expr::ptr > () = expr_assign::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < expr::ptr > ()), expr_assign::op::sub); } +#line 2864 "parser.cpp" break; - case 125: // expr_decrement: expr_object "--" -#line 625 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_decrement(yylhs.location, std::move(yystack_[1].value.as < expr > ()), false); } -#line 2911 "parser.cpp" + case 123: // expr_assign: expr_object "*=" expr +#line 622 "parser.ypp" + { yylhs.value.as < expr::ptr > () = expr_assign::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < expr::ptr > ()), expr_assign::op::mul); } +#line 2870 "parser.cpp" + break; + + case 124: // expr_assign: expr_object "/=" expr +#line 624 "parser.ypp" + { yylhs.value.as < expr::ptr > () = expr_assign::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < expr::ptr > ()), expr_assign::op::div); } +#line 2876 "parser.cpp" + break; + + case 125: // expr_assign: expr_object "%=" expr +#line 626 "parser.ypp" + { yylhs.value.as < expr::ptr > () = expr_assign::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < expr::ptr > ()), expr_assign::op::mod); } +#line 2882 "parser.cpp" break; case 126: // expr_ternary: expr "?" expr ":" expr -#line 630 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_ternary(yylhs.location, std::move(yystack_[4].value.as < expr > ()), std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < expr > ())); } -#line 2917 "parser.cpp" +#line 631 "parser.ypp" + { yylhs.value.as < expr::ptr > () = expr_ternary::make(yylhs.location, std::move(yystack_[4].value.as < expr::ptr > ()), std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < expr::ptr > ())); } +#line 2888 "parser.cpp" break; case 127: // expr_binary: expr "||" expr -#line 635 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_or(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < expr > ())); } -#line 2923 "parser.cpp" +#line 636 "parser.ypp" + { yylhs.value.as < expr::ptr > () = expr_binary::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < expr::ptr > ()), expr_binary::op::bool_or); } +#line 2894 "parser.cpp" break; case 128: // expr_binary: expr "&&" expr -#line 637 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_and(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < expr > ())); } -#line 2929 "parser.cpp" +#line 638 "parser.ypp" + { yylhs.value.as < expr::ptr > () = expr_binary::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < expr::ptr > ()), expr_binary::op::bool_and); } +#line 2900 "parser.cpp" break; case 129: // expr_binary: expr "==" expr -#line 639 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_equality(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < expr > ())); } -#line 2935 "parser.cpp" +#line 640 "parser.ypp" + { yylhs.value.as < expr::ptr > () = expr_binary::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < expr::ptr > ()), expr_binary::op::eq); } +#line 2906 "parser.cpp" break; case 130: // expr_binary: expr "!=" expr -#line 641 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_inequality(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < expr > ())); } -#line 2941 "parser.cpp" +#line 642 "parser.ypp" + { yylhs.value.as < expr::ptr > () = expr_binary::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < expr::ptr > ()), expr_binary::op::ne); } +#line 2912 "parser.cpp" break; case 131: // expr_binary: expr "<=" expr -#line 643 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_less_equal(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < expr > ())); } -#line 2947 "parser.cpp" +#line 644 "parser.ypp" + { yylhs.value.as < expr::ptr > () = expr_binary::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < expr::ptr > ()), expr_binary::op::le); } +#line 2918 "parser.cpp" break; case 132: // expr_binary: expr ">=" expr -#line 645 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_greater_equal(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < expr > ())); } -#line 2953 "parser.cpp" +#line 646 "parser.ypp" + { yylhs.value.as < expr::ptr > () = expr_binary::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < expr::ptr > ()), expr_binary::op::ge); } +#line 2924 "parser.cpp" break; case 133: // expr_binary: expr "<" expr -#line 647 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_less(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < expr > ())); } -#line 2959 "parser.cpp" +#line 648 "parser.ypp" + { yylhs.value.as < expr::ptr > () = expr_binary::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < expr::ptr > ()), expr_binary::op::lt); } +#line 2930 "parser.cpp" break; case 134: // expr_binary: expr ">" expr -#line 649 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_greater(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < expr > ())); } -#line 2965 "parser.cpp" +#line 650 "parser.ypp" + { yylhs.value.as < expr::ptr > () = expr_binary::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < expr::ptr > ()), expr_binary::op::gt); } +#line 2936 "parser.cpp" break; case 135: // expr_binary: expr "|" expr -#line 651 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_bitwise_or(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < expr > ())); } -#line 2971 "parser.cpp" +#line 652 "parser.ypp" + { yylhs.value.as < expr::ptr > () = expr_binary::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < expr::ptr > ()), expr_binary::op::bwor); } +#line 2942 "parser.cpp" break; case 136: // expr_binary: expr "&" expr -#line 653 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_bitwise_and(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < expr > ())); } -#line 2977 "parser.cpp" +#line 654 "parser.ypp" + { yylhs.value.as < expr::ptr > () = expr_binary::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < expr::ptr > ()), expr_binary::op::bwand); } +#line 2948 "parser.cpp" break; case 137: // expr_binary: expr "^" expr -#line 655 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_bitwise_exor(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < expr > ())); } -#line 2983 "parser.cpp" +#line 656 "parser.ypp" + { yylhs.value.as < expr::ptr > () = expr_binary::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < expr::ptr > ()), expr_binary::op::bwexor); } +#line 2954 "parser.cpp" break; case 138: // expr_binary: expr "<<" expr -#line 657 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_shift_left(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < expr > ())); } -#line 2989 "parser.cpp" +#line 658 "parser.ypp" + { yylhs.value.as < expr::ptr > () = expr_binary::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < expr::ptr > ()), expr_binary::op::shl); } +#line 2960 "parser.cpp" break; case 139: // expr_binary: expr ">>" expr -#line 659 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_shift_right(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < expr > ())); } -#line 2995 "parser.cpp" +#line 660 "parser.ypp" + { yylhs.value.as < expr::ptr > () = expr_binary::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < expr::ptr > ()), expr_binary::op::shr); } +#line 2966 "parser.cpp" break; case 140: // expr_binary: expr "+" expr -#line 661 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_add(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < expr > ())); } -#line 3001 "parser.cpp" +#line 662 "parser.ypp" + { yylhs.value.as < expr::ptr > () = expr_binary::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < expr::ptr > ()), expr_binary::op::add); } +#line 2972 "parser.cpp" break; case 141: // expr_binary: expr "-" expr -#line 663 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_sub(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < expr > ())); } -#line 3007 "parser.cpp" +#line 664 "parser.ypp" + { yylhs.value.as < expr::ptr > () = expr_binary::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < expr::ptr > ()), expr_binary::op::sub); } +#line 2978 "parser.cpp" break; case 142: // expr_binary: expr "*" expr -#line 665 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_mul(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < expr > ())); } -#line 3013 "parser.cpp" +#line 666 "parser.ypp" + { yylhs.value.as < expr::ptr > () = expr_binary::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < expr::ptr > ()), expr_binary::op::mul); } +#line 2984 "parser.cpp" break; case 143: // expr_binary: expr "/" expr -#line 667 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_div(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < expr > ())); } -#line 3019 "parser.cpp" +#line 668 "parser.ypp" + { yylhs.value.as < expr::ptr > () = expr_binary::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < expr::ptr > ()), expr_binary::op::div); } +#line 2990 "parser.cpp" break; case 144: // expr_binary: expr "%" expr -#line 669 "parser.ypp" - { yylhs.value.as < expr > ().as_node = make_expr_mod(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < expr > ())); } -#line 3025 "parser.cpp" +#line 670 "parser.ypp" + { yylhs.value.as < expr::ptr > () = expr_binary::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < expr::ptr > ()), expr_binary::op::mod); } +#line 2996 "parser.cpp" break; case 145: // expr_primitive: expr_complement -#line 673 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_complement::ptr > ()); } -#line 3031 "parser.cpp" +#line 674 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_complement::ptr > ()); } +#line 3002 "parser.cpp" break; case 146: // expr_primitive: expr_negate -#line 674 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_negate::ptr > ()); } -#line 3037 "parser.cpp" +#line 675 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_negate::ptr > ()); } +#line 3008 "parser.cpp" break; case 147: // expr_primitive: expr_not -#line 675 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_not::ptr > ()); } -#line 3043 "parser.cpp" +#line 676 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_not::ptr > ()); } +#line 3014 "parser.cpp" break; case 148: // expr_primitive: expr_call -#line 676 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_call::ptr > ()); } -#line 3049 "parser.cpp" +#line 677 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_call::ptr > ()); } +#line 3020 "parser.cpp" break; case 149: // expr_primitive: expr_method -#line 677 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_method::ptr > ()); } -#line 3055 "parser.cpp" +#line 678 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_method::ptr > ()); } +#line 3026 "parser.cpp" break; case 150: // expr_primitive: expr_add_array -#line 678 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_add_array::ptr > ()); } -#line 3061 "parser.cpp" +#line 679 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_add_array::ptr > ()); } +#line 3032 "parser.cpp" break; case 151: // expr_primitive: expr_isdefined -#line 679 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_isdefined::ptr > ()); } -#line 3067 "parser.cpp" +#line 680 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_isdefined::ptr > ()); } +#line 3038 "parser.cpp" break; case 152: // expr_primitive: expr_istrue -#line 680 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_istrue::ptr > ()); } -#line 3073 "parser.cpp" +#line 681 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_istrue::ptr > ()); } +#line 3044 "parser.cpp" break; case 153: // expr_primitive: expr_reference -#line 681 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_reference::ptr > ()); } -#line 3079 "parser.cpp" +#line 682 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_reference::ptr > ()); } +#line 3050 "parser.cpp" break; case 154: // expr_primitive: expr_array -#line 682 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_array::ptr > ()); } -#line 3085 "parser.cpp" +#line 683 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_array::ptr > ()); } +#line 3056 "parser.cpp" break; case 155: // expr_primitive: expr_field -#line 683 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_field::ptr > ()); } -#line 3091 "parser.cpp" +#line 684 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_field::ptr > ()); } +#line 3062 "parser.cpp" break; case 156: // expr_primitive: expr_size -#line 684 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_size::ptr > ()); } -#line 3097 "parser.cpp" +#line 685 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_size::ptr > ()); } +#line 3068 "parser.cpp" break; case 157: // expr_primitive: expr_paren -#line 685 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_paren::ptr > ()); } -#line 3103 "parser.cpp" +#line 686 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_paren::ptr > ()); } +#line 3074 "parser.cpp" break; case 158: // expr_primitive: expr_thisthread -#line 686 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_thisthread::ptr > ()); } -#line 3109 "parser.cpp" +#line 687 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_thisthread::ptr > ()); } +#line 3080 "parser.cpp" break; case 159: // expr_primitive: expr_empty_array -#line 687 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_empty_array::ptr > ()); } -#line 3115 "parser.cpp" +#line 688 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_empty_array::ptr > ()); } +#line 3086 "parser.cpp" break; case 160: // expr_primitive: expr_undefined -#line 688 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_undefined::ptr > ()); } -#line 3121 "parser.cpp" +#line 689 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_undefined::ptr > ()); } +#line 3092 "parser.cpp" break; case 161: // expr_primitive: expr_game -#line 689 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_game::ptr > ()); } -#line 3127 "parser.cpp" +#line 690 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_game::ptr > ()); } +#line 3098 "parser.cpp" break; case 162: // expr_primitive: expr_self -#line 690 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_self::ptr > ()); } -#line 3133 "parser.cpp" +#line 691 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_self::ptr > ()); } +#line 3104 "parser.cpp" break; case 163: // expr_primitive: expr_anim -#line 691 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_anim::ptr > ()); } -#line 3139 "parser.cpp" +#line 692 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_anim::ptr > ()); } +#line 3110 "parser.cpp" break; case 164: // expr_primitive: expr_level -#line 692 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_level::ptr > ()); } -#line 3145 "parser.cpp" +#line 693 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_level::ptr > ()); } +#line 3116 "parser.cpp" break; case 165: // expr_primitive: expr_animation -#line 693 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_animation::ptr > ()); } -#line 3151 "parser.cpp" +#line 694 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_animation::ptr > ()); } +#line 3122 "parser.cpp" break; case 166: // expr_primitive: expr_animtree -#line 694 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_animtree::ptr > ()); } -#line 3157 "parser.cpp" +#line 695 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_animtree::ptr > ()); } +#line 3128 "parser.cpp" break; case 167: // expr_primitive: expr_identifier -#line 695 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_identifier::ptr > ()); } -#line 3163 "parser.cpp" +#line 696 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_identifier::ptr > ()); } +#line 3134 "parser.cpp" break; case 168: // expr_primitive: expr_istring -#line 696 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_istring::ptr > ()); } -#line 3169 "parser.cpp" +#line 697 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_istring::ptr > ()); } +#line 3140 "parser.cpp" break; case 169: // expr_primitive: expr_string -#line 697 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_string::ptr > ()); } -#line 3175 "parser.cpp" +#line 698 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_string::ptr > ()); } +#line 3146 "parser.cpp" break; case 170: // expr_primitive: expr_vector -#line 698 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_vector::ptr > ()); } -#line 3181 "parser.cpp" +#line 699 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_vector::ptr > ()); } +#line 3152 "parser.cpp" break; case 171: // expr_primitive: expr_float -#line 699 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_float::ptr > ()); } -#line 3187 "parser.cpp" +#line 700 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_float::ptr > ()); } +#line 3158 "parser.cpp" break; case 172: // expr_primitive: expr_integer -#line 700 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_integer::ptr > ()); } -#line 3193 "parser.cpp" +#line 701 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_integer::ptr > ()); } +#line 3164 "parser.cpp" break; case 173: // expr_primitive: expr_false -#line 701 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_false::ptr > ()); } -#line 3199 "parser.cpp" +#line 702 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_false::ptr > ()); } +#line 3170 "parser.cpp" break; case 174: // expr_primitive: expr_true -#line 702 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_true::ptr > ()); } -#line 3205 "parser.cpp" +#line 703 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_true::ptr > ()); } +#line 3176 "parser.cpp" break; case 175: // expr_complement: "~" expr -#line 707 "parser.ypp" - { yylhs.value.as < expr_complement::ptr > () = make_expr_complement(yylhs.location, std::move(yystack_[0].value.as < expr > ())); } -#line 3211 "parser.cpp" +#line 708 "parser.ypp" + { yylhs.value.as < expr_complement::ptr > () = expr_complement::make(yylhs.location, std::move(yystack_[0].value.as < expr::ptr > ())); } +#line 3182 "parser.cpp" break; case 176: // expr_negate: "-" expr_identifier -#line 712 "parser.ypp" - { yylhs.value.as < expr_negate::ptr > () = make_expr_negate(yylhs.location, expr{ std::move(yystack_[0].value.as < expr_identifier::ptr > ()) }); } -#line 3217 "parser.cpp" +#line 713 "parser.ypp" + { yylhs.value.as < expr_negate::ptr > () = expr_negate::make(yylhs.location, std::move(yystack_[0].value.as < expr_identifier::ptr > ())); } +#line 3188 "parser.cpp" break; case 177: // expr_negate: "-" expr_paren -#line 714 "parser.ypp" - { yylhs.value.as < expr_negate::ptr > () = make_expr_negate(yylhs.location, expr{ std::move(yystack_[0].value.as < expr_paren::ptr > ()) }); } -#line 3223 "parser.cpp" +#line 715 "parser.ypp" + { yylhs.value.as < expr_negate::ptr > () = expr_negate::make(yylhs.location, std::move(yystack_[0].value.as < expr_paren::ptr > ())); } +#line 3194 "parser.cpp" break; case 178: // expr_negate: "-" expr_array -#line 716 "parser.ypp" - { yylhs.value.as < expr_negate::ptr > () = make_expr_negate(yylhs.location, expr{ std::move(yystack_[0].value.as < expr_array::ptr > ()) }); } -#line 3229 "parser.cpp" +#line 717 "parser.ypp" + { yylhs.value.as < expr_negate::ptr > () = expr_negate::make(yylhs.location, std::move(yystack_[0].value.as < expr_array::ptr > ())); } +#line 3200 "parser.cpp" break; case 179: // expr_negate: "-" expr_field -#line 718 "parser.ypp" - { yylhs.value.as < expr_negate::ptr > () = make_expr_negate(yylhs.location, expr{ std::move(yystack_[0].value.as < expr_field::ptr > ()) }); } -#line 3235 "parser.cpp" +#line 719 "parser.ypp" + { yylhs.value.as < expr_negate::ptr > () = expr_negate::make(yylhs.location, std::move(yystack_[0].value.as < expr_field::ptr > ())); } +#line 3206 "parser.cpp" break; case 180: // expr_not: "!" expr -#line 723 "parser.ypp" - { yylhs.value.as < expr_not::ptr > () = make_expr_not(yylhs.location, std::move(yystack_[0].value.as < expr > ())); } -#line 3241 "parser.cpp" +#line 724 "parser.ypp" + { yylhs.value.as < expr_not::ptr > () = expr_not::make(yylhs.location, std::move(yystack_[0].value.as < expr::ptr > ())); } +#line 3212 "parser.cpp" break; case 181: // expr_call: expr_function -#line 727 "parser.ypp" - { yylhs.value.as < expr_call::ptr > () = make_expr_call(yylhs.location, std::move(yystack_[0].value.as < call > ())); } -#line 3247 "parser.cpp" +#line 728 "parser.ypp" + { yylhs.value.as < expr_call::ptr > () = expr_call::make(yylhs.location, std::move(yystack_[0].value.as < call::ptr > ())); } +#line 3218 "parser.cpp" break; case 182: // expr_call: expr_pointer -#line 728 "parser.ypp" - { yylhs.value.as < expr_call::ptr > () = make_expr_call(yylhs.location, std::move(yystack_[0].value.as < call > ())); } -#line 3253 "parser.cpp" +#line 729 "parser.ypp" + { yylhs.value.as < expr_call::ptr > () = expr_call::make(yylhs.location, std::move(yystack_[0].value.as < call::ptr > ())); } +#line 3224 "parser.cpp" break; case 183: // expr_method: expr_object expr_function -#line 731 "parser.ypp" - { yylhs.value.as < expr_method::ptr > () = make_expr_method(yylhs.location, std::move(yystack_[1].value.as < expr > ()), std::move(yystack_[0].value.as < call > ())); } -#line 3259 "parser.cpp" +#line 732 "parser.ypp" + { yylhs.value.as < expr_method::ptr > () = expr_method::make(yylhs.location, std::move(yystack_[1].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < call::ptr > ())); } +#line 3230 "parser.cpp" break; case 184: // expr_method: expr_object expr_pointer -#line 732 "parser.ypp" - { yylhs.value.as < expr_method::ptr > () = make_expr_method(yylhs.location, std::move(yystack_[1].value.as < expr > ()), std::move(yystack_[0].value.as < call > ())); } -#line 3265 "parser.cpp" +#line 733 "parser.ypp" + { yylhs.value.as < expr_method::ptr > () = expr_method::make(yylhs.location, std::move(yystack_[1].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < call::ptr > ())); } +#line 3236 "parser.cpp" break; case 185: // expr_function: expr_identifier "(" expr_arguments ")" -#line 737 "parser.ypp" - { yylhs.value.as < call > ().as_function = make_expr_function(yylhs.location, make_expr_path(yylhs.location), std::move(yystack_[3].value.as < expr_identifier::ptr > ()), std::move(yystack_[1].value.as < expr_arguments::ptr > ()), call::mode::normal); } -#line 3271 "parser.cpp" +#line 738 "parser.ypp" + { yylhs.value.as < call::ptr > () = expr_function::make(yylhs.location, expr_path::make(yylhs.location), std::move(yystack_[3].value.as < expr_identifier::ptr > ()), std::move(yystack_[1].value.as < expr_arguments::ptr > ()), call::mode::normal); } +#line 3242 "parser.cpp" break; case 186: // expr_function: expr_path "::" expr_identifier "(" expr_arguments ")" -#line 739 "parser.ypp" - { yylhs.value.as < call > ().as_function = make_expr_function(yylhs.location, std::move(yystack_[5].value.as < expr_path::ptr > ()), std::move(yystack_[3].value.as < expr_identifier::ptr > ()), std::move(yystack_[1].value.as < expr_arguments::ptr > ()), call::mode::normal); } -#line 3277 "parser.cpp" +#line 740 "parser.ypp" + { yylhs.value.as < call::ptr > () = expr_function::make(yylhs.location, std::move(yystack_[5].value.as < expr_path::ptr > ()), std::move(yystack_[3].value.as < expr_identifier::ptr > ()), std::move(yystack_[1].value.as < expr_arguments::ptr > ()), call::mode::normal); } +#line 3248 "parser.cpp" break; case 187: // expr_function: "thread" expr_identifier "(" expr_arguments ")" -#line 741 "parser.ypp" - { yylhs.value.as < call > ().as_function = make_expr_function(yylhs.location, make_expr_path(yylhs.location), std::move(yystack_[3].value.as < expr_identifier::ptr > ()), std::move(yystack_[1].value.as < expr_arguments::ptr > ()), call::mode::thread); } -#line 3283 "parser.cpp" +#line 742 "parser.ypp" + { yylhs.value.as < call::ptr > () = expr_function::make(yylhs.location, expr_path::make(yylhs.location), std::move(yystack_[3].value.as < expr_identifier::ptr > ()), std::move(yystack_[1].value.as < expr_arguments::ptr > ()), call::mode::thread); } +#line 3254 "parser.cpp" break; case 188: // expr_function: "thread" expr_path "::" expr_identifier "(" expr_arguments ")" -#line 743 "parser.ypp" - { yylhs.value.as < call > ().as_function = make_expr_function(yylhs.location, std::move(yystack_[5].value.as < expr_path::ptr > ()), std::move(yystack_[3].value.as < expr_identifier::ptr > ()), std::move(yystack_[1].value.as < expr_arguments::ptr > ()), call::mode::thread); } -#line 3289 "parser.cpp" +#line 744 "parser.ypp" + { yylhs.value.as < call::ptr > () = expr_function::make(yylhs.location, std::move(yystack_[5].value.as < expr_path::ptr > ()), std::move(yystack_[3].value.as < expr_identifier::ptr > ()), std::move(yystack_[1].value.as < expr_arguments::ptr > ()), call::mode::thread); } +#line 3260 "parser.cpp" break; case 189: // expr_function: "childthread" expr_identifier "(" expr_arguments ")" -#line 745 "parser.ypp" - { yylhs.value.as < call > ().as_function = make_expr_function(yylhs.location, make_expr_path(yylhs.location), std::move(yystack_[3].value.as < expr_identifier::ptr > ()), std::move(yystack_[1].value.as < expr_arguments::ptr > ()), call::mode::childthread); } -#line 3295 "parser.cpp" +#line 746 "parser.ypp" + { yylhs.value.as < call::ptr > () = expr_function::make(yylhs.location, expr_path::make(yylhs.location), std::move(yystack_[3].value.as < expr_identifier::ptr > ()), std::move(yystack_[1].value.as < expr_arguments::ptr > ()), call::mode::childthread); } +#line 3266 "parser.cpp" break; case 190: // expr_function: "childthread" expr_path "::" expr_identifier "(" expr_arguments ")" -#line 747 "parser.ypp" - { yylhs.value.as < call > ().as_function = make_expr_function(yylhs.location, std::move(yystack_[5].value.as < expr_path::ptr > ()), std::move(yystack_[3].value.as < expr_identifier::ptr > ()), std::move(yystack_[1].value.as < expr_arguments::ptr > ()), call::mode::childthread); } -#line 3301 "parser.cpp" +#line 748 "parser.ypp" + { yylhs.value.as < call::ptr > () = expr_function::make(yylhs.location, std::move(yystack_[5].value.as < expr_path::ptr > ()), std::move(yystack_[3].value.as < expr_identifier::ptr > ()), std::move(yystack_[1].value.as < expr_arguments::ptr > ()), call::mode::childthread); } +#line 3272 "parser.cpp" break; case 191: // expr_pointer: "[" "[" expr "]" "]" "(" expr_arguments ")" -#line 752 "parser.ypp" - { yylhs.value.as < call > ().as_pointer = make_expr_pointer(yylhs.location, std::move(yystack_[5].value.as < expr > ()), std::move(yystack_[1].value.as < expr_arguments::ptr > ()), call::mode::normal); } -#line 3307 "parser.cpp" +#line 753 "parser.ypp" + { yylhs.value.as < call::ptr > () = expr_pointer::make(yylhs.location, std::move(yystack_[5].value.as < expr::ptr > ()), std::move(yystack_[1].value.as < expr_arguments::ptr > ()), call::mode::normal); } +#line 3278 "parser.cpp" break; case 192: // expr_pointer: "thread" "[" "[" expr "]" "]" "(" expr_arguments ")" -#line 754 "parser.ypp" - { yylhs.value.as < call > ().as_pointer = make_expr_pointer(yylhs.location, std::move(yystack_[5].value.as < expr > ()), std::move(yystack_[1].value.as < expr_arguments::ptr > ()), call::mode::thread); } -#line 3313 "parser.cpp" +#line 755 "parser.ypp" + { yylhs.value.as < call::ptr > () = expr_pointer::make(yylhs.location, std::move(yystack_[5].value.as < expr::ptr > ()), std::move(yystack_[1].value.as < expr_arguments::ptr > ()), call::mode::thread); } +#line 3284 "parser.cpp" break; case 193: // expr_pointer: "childthread" "[" "[" expr "]" "]" "(" expr_arguments ")" -#line 756 "parser.ypp" - { yylhs.value.as < call > ().as_pointer = make_expr_pointer(yylhs.location, std::move(yystack_[5].value.as < expr > ()), std::move(yystack_[1].value.as < expr_arguments::ptr > ()), call::mode::childthread); } -#line 3319 "parser.cpp" +#line 757 "parser.ypp" + { yylhs.value.as < call::ptr > () = expr_pointer::make(yylhs.location, std::move(yystack_[5].value.as < expr::ptr > ()), std::move(yystack_[1].value.as < expr_arguments::ptr > ()), call::mode::childthread); } +#line 3290 "parser.cpp" break; case 194: // expr_pointer: "call" "[" "[" expr "]" "]" "(" expr_arguments ")" -#line 758 "parser.ypp" - { yylhs.value.as < call > ().as_pointer = make_expr_pointer(yylhs.location, std::move(yystack_[5].value.as < expr > ()), std::move(yystack_[1].value.as < expr_arguments::ptr > ()), call::mode::builtin); } -#line 3325 "parser.cpp" +#line 759 "parser.ypp" + { yylhs.value.as < call::ptr > () = expr_pointer::make(yylhs.location, std::move(yystack_[5].value.as < expr::ptr > ()), std::move(yystack_[1].value.as < expr_arguments::ptr > ()), call::mode::builtin); } +#line 3296 "parser.cpp" break; case 195: // expr_add_array: "[" expr_arguments_no_empty "]" -#line 763 "parser.ypp" - { yylhs.value.as < expr_add_array::ptr > () = make_expr_add_array(yylhs.location, std::move(yystack_[1].value.as < expr_arguments::ptr > ())); } -#line 3331 "parser.cpp" +#line 764 "parser.ypp" + { yylhs.value.as < expr_add_array::ptr > () = expr_add_array::make(yylhs.location, std::move(yystack_[1].value.as < expr_arguments::ptr > ())); } +#line 3302 "parser.cpp" break; case 196: // expr_parameters: expr_parameters "," expr_identifier -#line 768 "parser.ypp" +#line 769 "parser.ypp" { yylhs.value.as < expr_parameters::ptr > () = std::move(yystack_[2].value.as < expr_parameters::ptr > ()); yylhs.value.as < expr_parameters::ptr > ()->list.push_back(std::move(yystack_[0].value.as < expr_identifier::ptr > ())); } -#line 3337 "parser.cpp" +#line 3308 "parser.cpp" break; case 197: // expr_parameters: expr_identifier -#line 770 "parser.ypp" - { yylhs.value.as < expr_parameters::ptr > () = make_expr_parameters(yylhs.location); yylhs.value.as < expr_parameters::ptr > ()->list.push_back(std::move(yystack_[0].value.as < expr_identifier::ptr > ())); } -#line 3343 "parser.cpp" +#line 771 "parser.ypp" + { yylhs.value.as < expr_parameters::ptr > () = expr_parameters::make(yylhs.location); yylhs.value.as < expr_parameters::ptr > ()->list.push_back(std::move(yystack_[0].value.as < expr_identifier::ptr > ())); } +#line 3314 "parser.cpp" break; case 198: // expr_parameters: %empty -#line 772 "parser.ypp" - { yylhs.value.as < expr_parameters::ptr > () = make_expr_parameters(yylhs.location); } -#line 3349 "parser.cpp" +#line 773 "parser.ypp" + { yylhs.value.as < expr_parameters::ptr > () = expr_parameters::make(yylhs.location); } +#line 3320 "parser.cpp" break; case 199: // expr_arguments: expr_arguments_no_empty -#line 777 "parser.ypp" +#line 778 "parser.ypp" { yylhs.value.as < expr_arguments::ptr > () = std::move(yystack_[0].value.as < expr_arguments::ptr > ()); } -#line 3355 "parser.cpp" +#line 3326 "parser.cpp" break; case 200: // expr_arguments: %empty -#line 779 "parser.ypp" - { yylhs.value.as < expr_arguments::ptr > () = make_expr_arguments(yylhs.location); } -#line 3361 "parser.cpp" +#line 780 "parser.ypp" + { yylhs.value.as < expr_arguments::ptr > () = expr_arguments::make(yylhs.location); } +#line 3332 "parser.cpp" break; case 201: // expr_arguments_no_empty: expr_arguments "," expr -#line 784 "parser.ypp" - { yylhs.value.as < expr_arguments::ptr > () = std::move(yystack_[2].value.as < expr_arguments::ptr > ()); yylhs.value.as < expr_arguments::ptr > ()->list.push_back(std::move(yystack_[0].value.as < expr > ())); } -#line 3367 "parser.cpp" +#line 785 "parser.ypp" + { yylhs.value.as < expr_arguments::ptr > () = std::move(yystack_[2].value.as < expr_arguments::ptr > ()); yylhs.value.as < expr_arguments::ptr > ()->list.push_back(std::move(yystack_[0].value.as < expr::ptr > ())); } +#line 3338 "parser.cpp" break; case 202: // expr_arguments_no_empty: expr -#line 786 "parser.ypp" - { yylhs.value.as < expr_arguments::ptr > () = make_expr_arguments(yylhs.location); yylhs.value.as < expr_arguments::ptr > ()->list.push_back(std::move(yystack_[0].value.as < expr > ())); } -#line 3373 "parser.cpp" +#line 787 "parser.ypp" + { yylhs.value.as < expr_arguments::ptr > () = expr_arguments::make(yylhs.location); yylhs.value.as < expr_arguments::ptr > ()->list.push_back(std::move(yystack_[0].value.as < expr::ptr > ())); } +#line 3344 "parser.cpp" break; case 203: // expr_isdefined: "isdefined" "(" expr ")" -#line 791 "parser.ypp" - { yylhs.value.as < expr_isdefined::ptr > () = make_expr_isdefined(yylhs.location, std::move(yystack_[1].value.as < expr > ())); } -#line 3379 "parser.cpp" +#line 792 "parser.ypp" + { yylhs.value.as < expr_isdefined::ptr > () = expr_isdefined::make(yylhs.location, std::move(yystack_[1].value.as < expr::ptr > ())); } +#line 3350 "parser.cpp" break; case 204: // expr_istrue: "istrue" "(" expr ")" -#line 796 "parser.ypp" - { yylhs.value.as < expr_istrue::ptr > () = make_expr_istrue(yylhs.location, std::move(yystack_[1].value.as < expr > ())); } -#line 3385 "parser.cpp" +#line 797 "parser.ypp" + { yylhs.value.as < expr_istrue::ptr > () = expr_istrue::make(yylhs.location, std::move(yystack_[1].value.as < expr::ptr > ())); } +#line 3356 "parser.cpp" break; case 205: // expr_reference: "::" expr_identifier -#line 801 "parser.ypp" - { yylhs.value.as < expr_reference::ptr > () = make_expr_reference(yylhs.location, make_expr_path(yylhs.location), std::move(yystack_[0].value.as < expr_identifier::ptr > ())); } -#line 3391 "parser.cpp" +#line 802 "parser.ypp" + { yylhs.value.as < expr_reference::ptr > () = expr_reference::make(yylhs.location, expr_path::make(yylhs.location), std::move(yystack_[0].value.as < expr_identifier::ptr > ())); } +#line 3362 "parser.cpp" break; case 206: // expr_reference: expr_path "::" expr_identifier -#line 803 "parser.ypp" - { yylhs.value.as < expr_reference::ptr > () = make_expr_reference(yylhs.location, std::move(yystack_[2].value.as < expr_path::ptr > ()), std::move(yystack_[0].value.as < expr_identifier::ptr > ())); } -#line 3397 "parser.cpp" +#line 804 "parser.ypp" + { yylhs.value.as < expr_reference::ptr > () = expr_reference::make(yylhs.location, std::move(yystack_[2].value.as < expr_path::ptr > ()), std::move(yystack_[0].value.as < expr_identifier::ptr > ())); } +#line 3368 "parser.cpp" break; case 207: // expr_tuple: "[" expr_tuple_arguments "]" -#line 808 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[1].value.as < expr_tuple::ptr > ()); - yylhs.value.as < expr > ().as_tuple->temp = expr{ std::make_unique(yylhs.value.as < expr > ().loc(), fmt::format("_temp_{}", ++index)) }; +#line 809 "parser.ypp" + { + yylhs.value.as < expr::ptr > () = std::move(yystack_[1].value.as < expr_tuple::ptr > ()); + yylhs.value.as < expr::ptr > ()->as().temp = expr_identifier::make(yylhs.value.as < expr::ptr > ()->loc(), fmt::format("_temp_{}", ++index)); } -#line 3405 "parser.cpp" +#line 3377 "parser.cpp" break; case 208: // expr_tuple_arguments: expr_tuple_arguments "," expr_tuple_types -#line 815 "parser.ypp" - { yylhs.value.as < expr_tuple::ptr > () = std::move(yystack_[2].value.as < expr_tuple::ptr > ()); yylhs.value.as < expr_tuple::ptr > ()->list.push_back(std::move(yystack_[0].value.as < expr > ())); } -#line 3411 "parser.cpp" +#line 817 "parser.ypp" + { yylhs.value.as < expr_tuple::ptr > () = std::move(yystack_[2].value.as < expr_tuple::ptr > ()); yylhs.value.as < expr_tuple::ptr > ()->list.push_back(std::move(yystack_[0].value.as < expr::ptr > ())); } +#line 3383 "parser.cpp" break; case 209: // expr_tuple_arguments: expr_tuple_types -#line 817 "parser.ypp" - { yylhs.value.as < expr_tuple::ptr > () = make_expr_tuple(yylhs.location); yylhs.value.as < expr_tuple::ptr > ()->list.push_back(std::move(yystack_[0].value.as < expr > ())); } -#line 3417 "parser.cpp" +#line 819 "parser.ypp" + { yylhs.value.as < expr_tuple::ptr > () = expr_tuple::make(yylhs.location); yylhs.value.as < expr_tuple::ptr > ()->list.push_back(std::move(yystack_[0].value.as < expr::ptr > ())); } +#line 3389 "parser.cpp" break; case 210: // expr_tuple_types: expr_array -#line 821 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_array::ptr > ()); } -#line 3423 "parser.cpp" +#line 823 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_array::ptr > ()); } +#line 3395 "parser.cpp" break; case 211: // expr_tuple_types: expr_field -#line 822 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_field::ptr > ()); } -#line 3429 "parser.cpp" +#line 824 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_field::ptr > ()); } +#line 3401 "parser.cpp" break; case 212: // expr_tuple_types: expr_identifier -#line 823 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_identifier::ptr > ()); } -#line 3435 "parser.cpp" +#line 825 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_identifier::ptr > ()); } +#line 3407 "parser.cpp" break; case 213: // expr_array: expr_object "[" expr "]" -#line 828 "parser.ypp" - { yylhs.value.as < expr_array::ptr > () = make_expr_array(yylhs.location, std::move(yystack_[3].value.as < expr > ()), std::move(yystack_[1].value.as < expr > ())); } -#line 3441 "parser.cpp" +#line 830 "parser.ypp" + { yylhs.value.as < expr_array::ptr > () = expr_array::make(yylhs.location, std::move(yystack_[3].value.as < expr::ptr > ()), std::move(yystack_[1].value.as < expr::ptr > ())); } +#line 3413 "parser.cpp" break; case 214: // expr_field: expr_object "." expr_identifier_nosize -#line 833 "parser.ypp" - { yylhs.value.as < expr_field::ptr > () = make_expr_field(yylhs.location, std::move(yystack_[2].value.as < expr > ()), std::move(yystack_[0].value.as < expr_identifier::ptr > ())); } -#line 3447 "parser.cpp" +#line 835 "parser.ypp" + { yylhs.value.as < expr_field::ptr > () = expr_field::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ()), std::move(yystack_[0].value.as < expr_identifier::ptr > ())); } +#line 3419 "parser.cpp" break; case 215: // expr_size: expr_object "." "size" -#line 838 "parser.ypp" - { yylhs.value.as < expr_size::ptr > () = make_expr_size(yylhs.location, std::move(yystack_[2].value.as < expr > ())); } -#line 3453 "parser.cpp" +#line 840 "parser.ypp" + { yylhs.value.as < expr_size::ptr > () = expr_size::make(yylhs.location, std::move(yystack_[2].value.as < expr::ptr > ())); } +#line 3425 "parser.cpp" break; case 216: // expr_paren: "(" expr ")" -#line 843 "parser.ypp" - { yylhs.value.as < expr_paren::ptr > () = make_expr_paren(yylhs.location, std::move(yystack_[1].value.as < expr > ())); } -#line 3459 "parser.cpp" +#line 845 "parser.ypp" + { yylhs.value.as < expr_paren::ptr > () = expr_paren::make(yylhs.location, std::move(yystack_[1].value.as < expr::ptr > ())); } +#line 3431 "parser.cpp" break; case 217: // expr_object: expr_call -#line 847 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_call::ptr > ()); } -#line 3465 "parser.cpp" +#line 849 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_call::ptr > ()); } +#line 3437 "parser.cpp" break; case 218: // expr_object: expr_method -#line 848 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_method::ptr > ()); } -#line 3471 "parser.cpp" +#line 850 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_method::ptr > ()); } +#line 3443 "parser.cpp" break; case 219: // expr_object: expr_array -#line 849 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_array::ptr > ()); } -#line 3477 "parser.cpp" +#line 851 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_array::ptr > ()); } +#line 3449 "parser.cpp" break; case 220: // expr_object: expr_field -#line 850 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_field::ptr > ()); } -#line 3483 "parser.cpp" +#line 852 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_field::ptr > ()); } +#line 3455 "parser.cpp" break; case 221: // expr_object: expr_game -#line 851 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_game::ptr > ()); } -#line 3489 "parser.cpp" +#line 853 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_game::ptr > ()); } +#line 3461 "parser.cpp" break; case 222: // expr_object: expr_self -#line 852 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_self::ptr > ()); } -#line 3495 "parser.cpp" +#line 854 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_self::ptr > ()); } +#line 3467 "parser.cpp" break; case 223: // expr_object: expr_anim -#line 853 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_anim::ptr > ()); } -#line 3501 "parser.cpp" +#line 855 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_anim::ptr > ()); } +#line 3473 "parser.cpp" break; case 224: // expr_object: expr_level -#line 854 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_level::ptr > ()); } -#line 3507 "parser.cpp" +#line 856 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_level::ptr > ()); } +#line 3479 "parser.cpp" break; case 225: // expr_object: expr_identifier -#line 855 "parser.ypp" - { yylhs.value.as < expr > ().as_node = std::move(yystack_[0].value.as < expr_identifier::ptr > ()); } -#line 3513 "parser.cpp" +#line 857 "parser.ypp" + { yylhs.value.as < expr::ptr > () = std::move(yystack_[0].value.as < expr_identifier::ptr > ()); } +#line 3485 "parser.cpp" break; case 226: // expr_thisthread: "thisthread" -#line 860 "parser.ypp" - { yylhs.value.as < expr_thisthread::ptr > () = make_expr_thisthread(yylhs.location); } -#line 3519 "parser.cpp" +#line 862 "parser.ypp" + { yylhs.value.as < expr_thisthread::ptr > () = expr_thisthread::make(yylhs.location); } +#line 3491 "parser.cpp" break; case 227: // expr_empty_array: "[" "]" -#line 865 "parser.ypp" - { yylhs.value.as < expr_empty_array::ptr > () = make_expr_empty_array(yylhs.location); } -#line 3525 "parser.cpp" +#line 867 "parser.ypp" + { yylhs.value.as < expr_empty_array::ptr > () = expr_empty_array::make(yylhs.location); } +#line 3497 "parser.cpp" break; case 228: // expr_undefined: "undefined" -#line 870 "parser.ypp" - { yylhs.value.as < expr_undefined::ptr > () = make_expr_undefined(yylhs.location); } -#line 3531 "parser.cpp" +#line 872 "parser.ypp" + { yylhs.value.as < expr_undefined::ptr > () = expr_undefined::make(yylhs.location); } +#line 3503 "parser.cpp" break; case 229: // expr_game: "game" -#line 875 "parser.ypp" - { yylhs.value.as < expr_game::ptr > () = make_expr_game(yylhs.location); } -#line 3537 "parser.cpp" +#line 877 "parser.ypp" + { yylhs.value.as < expr_game::ptr > () = expr_game::make(yylhs.location); } +#line 3509 "parser.cpp" break; case 230: // expr_self: "self" -#line 880 "parser.ypp" - { yylhs.value.as < expr_self::ptr > () = make_expr_self(yylhs.location); } -#line 3543 "parser.cpp" +#line 882 "parser.ypp" + { yylhs.value.as < expr_self::ptr > () = expr_self::make(yylhs.location); } +#line 3515 "parser.cpp" break; case 231: // expr_anim: "anim" -#line 885 "parser.ypp" - { yylhs.value.as < expr_anim::ptr > () = make_expr_anim(yylhs.location); } -#line 3549 "parser.cpp" +#line 887 "parser.ypp" + { yylhs.value.as < expr_anim::ptr > () = expr_anim::make(yylhs.location); } +#line 3521 "parser.cpp" break; case 232: // expr_level: "level" -#line 890 "parser.ypp" - { yylhs.value.as < expr_level::ptr > () = make_expr_level(yylhs.location); } -#line 3555 "parser.cpp" +#line 892 "parser.ypp" + { yylhs.value.as < expr_level::ptr > () = expr_level::make(yylhs.location); } +#line 3527 "parser.cpp" break; case 233: // expr_animation: "%" "identifier" -#line 895 "parser.ypp" - { yylhs.value.as < expr_animation::ptr > () = make_expr_animation(yylhs.location, yystack_[0].value.as < std::string > ()); } -#line 3561 "parser.cpp" +#line 897 "parser.ypp" + { yylhs.value.as < expr_animation::ptr > () = expr_animation::make(yylhs.location, yystack_[0].value.as < std::string > ()); } +#line 3533 "parser.cpp" break; case 234: // expr_animtree: "#animtree" -#line 900 "parser.ypp" - { yylhs.value.as < expr_animtree::ptr > () = make_expr_animtree(yylhs.location); } -#line 3567 "parser.cpp" +#line 902 "parser.ypp" + { yylhs.value.as < expr_animtree::ptr > () = expr_animtree::make(yylhs.location); } +#line 3539 "parser.cpp" break; case 235: // expr_identifier_nosize: "identifier" -#line 905 "parser.ypp" - { yylhs.value.as < expr_identifier::ptr > () = make_expr_identifier(yylhs.location, yystack_[0].value.as < std::string > ()); } -#line 3573 "parser.cpp" +#line 907 "parser.ypp" + { yylhs.value.as < expr_identifier::ptr > () = expr_identifier::make(yylhs.location, yystack_[0].value.as < std::string > ()); } +#line 3545 "parser.cpp" break; case 236: // expr_identifier: "identifier" -#line 910 "parser.ypp" - { yylhs.value.as < expr_identifier::ptr > () = make_expr_identifier(yylhs.location, yystack_[0].value.as < std::string > ()); } -#line 3579 "parser.cpp" +#line 912 "parser.ypp" + { yylhs.value.as < expr_identifier::ptr > () = expr_identifier::make(yylhs.location, yystack_[0].value.as < std::string > ()); } +#line 3551 "parser.cpp" break; case 237: // expr_identifier: "size" -#line 912 "parser.ypp" - { yylhs.value.as < expr_identifier::ptr > () = make_expr_identifier(yylhs.location, "size"); } -#line 3585 "parser.cpp" +#line 914 "parser.ypp" + { yylhs.value.as < expr_identifier::ptr > () = expr_identifier::make(yylhs.location, "size"); } +#line 3557 "parser.cpp" break; case 238: // expr_path: "path" "/" "identifier" -#line 917 "parser.ypp" - { yylhs.value.as < expr_path::ptr > () = make_expr_path(yylhs.location, yystack_[2].value.as < std::string > () + "/" + yystack_[0].value.as < std::string > ()); } -#line 3591 "parser.cpp" +#line 919 "parser.ypp" + { yylhs.value.as < expr_path::ptr > () = expr_path::make(yylhs.location, yystack_[2].value.as < std::string > () + "/" + yystack_[0].value.as < std::string > ()); } +#line 3563 "parser.cpp" break; case 239: // expr_path: "identifier" -#line 919 "parser.ypp" - { yylhs.value.as < expr_path::ptr > () = make_expr_path(yylhs.location, yystack_[0].value.as < std::string > ()); } -#line 3597 "parser.cpp" +#line 921 "parser.ypp" + { yylhs.value.as < expr_path::ptr > () = expr_path::make(yylhs.location, yystack_[0].value.as < std::string > ()); } +#line 3569 "parser.cpp" break; case 240: // expr_path: "path" -#line 921 "parser.ypp" - { yylhs.value.as < expr_path::ptr > () = make_expr_path(yylhs.location, yystack_[0].value.as < std::string > ()); } -#line 3603 "parser.cpp" +#line 923 "parser.ypp" + { yylhs.value.as < expr_path::ptr > () = expr_path::make(yylhs.location, yystack_[0].value.as < std::string > ()); } +#line 3575 "parser.cpp" break; case 241: // expr_istring: "localized string" -#line 926 "parser.ypp" - { yylhs.value.as < expr_istring::ptr > () = make_expr_istring(yylhs.location, yystack_[0].value.as < std::string > ()); } -#line 3609 "parser.cpp" +#line 928 "parser.ypp" + { yylhs.value.as < expr_istring::ptr > () = expr_istring::make(yylhs.location, yystack_[0].value.as < std::string > ()); } +#line 3581 "parser.cpp" break; case 242: // expr_string: "string literal" -#line 931 "parser.ypp" - { yylhs.value.as < expr_string::ptr > () = make_expr_string(yylhs.location, yystack_[0].value.as < std::string > ()); } -#line 3615 "parser.cpp" +#line 933 "parser.ypp" + { yylhs.value.as < expr_string::ptr > () = expr_string::make(yylhs.location, yystack_[0].value.as < std::string > ()); } +#line 3587 "parser.cpp" break; case 243: // expr_vector: "(" expr "," expr "," expr ")" -#line 936 "parser.ypp" - { yylhs.value.as < expr_vector::ptr > () = make_expr_vector(yylhs.location, std::move(yystack_[5].value.as < expr > ()), std::move(yystack_[3].value.as < expr > ()), std::move(yystack_[1].value.as < expr > ())); } -#line 3621 "parser.cpp" +#line 938 "parser.ypp" + { yylhs.value.as < expr_vector::ptr > () = expr_vector::make(yylhs.location, std::move(yystack_[5].value.as < expr::ptr > ()), std::move(yystack_[3].value.as < expr::ptr > ()), std::move(yystack_[1].value.as < expr::ptr > ())); } +#line 3593 "parser.cpp" break; case 244: // expr_float: "-" "float" -#line 941 "parser.ypp" - { yylhs.value.as < expr_float::ptr > () = make_expr_float(yylhs.location, "-" + yystack_[0].value.as < std::string > ()); } -#line 3627 "parser.cpp" +#line 943 "parser.ypp" + { yylhs.value.as < expr_float::ptr > () = expr_float::make(yylhs.location, "-" + yystack_[0].value.as < std::string > ()); } +#line 3599 "parser.cpp" break; case 245: // expr_float: "float" -#line 943 "parser.ypp" - { yylhs.value.as < expr_float::ptr > () = make_expr_float(yylhs.location, yystack_[0].value.as < std::string > ()); } -#line 3633 "parser.cpp" +#line 945 "parser.ypp" + { yylhs.value.as < expr_float::ptr > () = expr_float::make(yylhs.location, yystack_[0].value.as < std::string > ()); } +#line 3605 "parser.cpp" break; case 246: // expr_integer: "-" "integer" -#line 948 "parser.ypp" - { yylhs.value.as < expr_integer::ptr > () = make_expr_integer(yylhs.location, "-" + yystack_[0].value.as < std::string > ()); } -#line 3639 "parser.cpp" +#line 950 "parser.ypp" + { yylhs.value.as < expr_integer::ptr > () = expr_integer::make(yylhs.location, "-" + yystack_[0].value.as < std::string > ()); } +#line 3611 "parser.cpp" break; case 247: // expr_integer: "integer" -#line 950 "parser.ypp" - { yylhs.value.as < expr_integer::ptr > () = make_expr_integer(yylhs.location, yystack_[0].value.as < std::string > ()); } -#line 3645 "parser.cpp" +#line 952 "parser.ypp" + { yylhs.value.as < expr_integer::ptr > () = expr_integer::make(yylhs.location, yystack_[0].value.as < std::string > ()); } +#line 3617 "parser.cpp" break; case 248: // expr_false: "false" -#line 955 "parser.ypp" - { yylhs.value.as < expr_false::ptr > () = make_expr_false(yylhs.location); } -#line 3651 "parser.cpp" +#line 957 "parser.ypp" + { yylhs.value.as < expr_false::ptr > () = expr_false::make(yylhs.location); } +#line 3623 "parser.cpp" break; case 249: // expr_true: "true" -#line 960 "parser.ypp" - { yylhs.value.as < expr_true::ptr > () = make_expr_true(yylhs.location); } -#line 3657 "parser.cpp" +#line 962 "parser.ypp" + { yylhs.value.as < expr_true::ptr > () = expr_true::make(yylhs.location); } +#line 3629 "parser.cpp" break; -#line 3661 "parser.cpp" +#line 3633 "parser.cpp" default: break; @@ -3862,7 +3834,7 @@ namespace xsk { namespace gsc { "stmt_case", "stmt_default", "stmt_break", "stmt_continue", "stmt_return", "stmt_breakpoint", "stmt_prof_begin", "stmt_prof_end", "stmt_assert", "stmt_assertex", "stmt_assertmsg", "expr", - "expr_or_empty", "expr_assign", "expr_increment", "expr_decrement", + "expr_or_empty", "expr_increment", "expr_decrement", "expr_assign", "expr_ternary", "expr_binary", "expr_primitive", "expr_complement", "expr_negate", "expr_not", "expr_call", "expr_method", "expr_function", "expr_pointer", "expr_add_array", "expr_parameters", "expr_arguments", @@ -4238,15 +4210,15 @@ namespace xsk { namespace gsc { 61, 55, 53, 0, 0, 81, 0, 82, 0, 0, 0, 67, 0, 0, 0, 0, 0, 94, 95, 96, 98, 0, 99, 200, 200, 200, 200, 200, 0, 0, - 209, 219, 220, 225, 122, 124, 62, 58, 56, 70, - 71, 72, 68, 69, 0, 0, 0, 0, 0, 123, - 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 209, 219, 220, 225, 110, 112, 62, 58, 56, 71, + 72, 70, 68, 69, 0, 0, 0, 0, 0, 111, + 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 187, 200, 0, 189, 200, 0, 0, 0, 126, 0, 60, 54, 52, 76, 0, 0, 0, - 0, 0, 64, 65, 66, 0, 0, 0, 93, 92, - 97, 0, 0, 0, 0, 0, 207, 0, 110, 0, - 0, 0, 0, 111, 117, 118, 119, 120, 121, 112, - 113, 114, 116, 115, 0, 0, 0, 0, 0, 0, + 0, 0, 65, 66, 64, 0, 0, 0, 93, 92, + 97, 0, 0, 0, 0, 0, 207, 0, 114, 0, + 0, 0, 0, 115, 121, 122, 123, 124, 125, 116, + 117, 118, 120, 119, 0, 0, 0, 0, 0, 0, 200, 186, 83, 0, 0, 0, 109, 0, 0, 0, 0, 0, 0, 0, 0, 208, 0, 0, 0, 0, 200, 188, 200, 190, 200, 243, 0, 84, 0, 86, @@ -4850,8 +4822,8 @@ namespace xsk { namespace gsc { 135, 136, 137, 137, 138, 139, 140, 141, 142, 143, 143, 144, 145, 145, 146, 147, 148, 149, 149, 150, 151, 152, 153, 154, 155, 156, 156, 156, 157, 157, - 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, - 158, 158, 159, 159, 160, 160, 161, 162, 162, 162, + 158, 158, 159, 159, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 161, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, @@ -4880,8 +4852,8 @@ namespace xsk { namespace gsc { 6, 2, 2, 4, 5, 7, 5, 7, 9, 7, 9, 5, 3, 3, 2, 2, 2, 3, 2, 2, 5, 5, 5, 5, 5, 1, 1, 1, 1, 0, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 2, 2, 2, 2, 5, 3, 3, 3, + 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -4912,22 +4884,22 @@ namespace xsk { namespace gsc { 392, 393, 397, 398, 402, 404, 406, 409, 413, 415, 420, 422, 424, 429, 434, 436, 441, 446, 448, 453, 455, 460, 465, 467, 472, 477, 482, 487, 492, 497, - 502, 511, 518, 520, 525, 530, 535, 540, 542, 547, - 552, 557, 562, 567, 572, 577, 578, 579, 583, 584, - 588, 590, 592, 594, 596, 598, 600, 602, 604, 606, - 608, 610, 615, 617, 622, 624, 629, 634, 636, 638, - 640, 642, 644, 646, 648, 650, 652, 654, 656, 658, - 660, 662, 664, 666, 668, 673, 674, 675, 676, 677, - 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, - 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, - 698, 699, 700, 701, 702, 706, 711, 713, 715, 717, - 722, 727, 728, 731, 732, 736, 738, 740, 742, 744, - 746, 751, 753, 755, 757, 762, 767, 769, 772, 776, - 779, 783, 785, 790, 795, 800, 802, 807, 814, 816, - 821, 822, 823, 827, 832, 837, 842, 847, 848, 849, - 850, 851, 852, 853, 854, 855, 859, 864, 869, 874, - 879, 884, 889, 894, 899, 904, 909, 911, 916, 918, - 920, 925, 930, 935, 940, 942, 947, 949, 954, 959 + 503, 512, 519, 521, 526, 531, 536, 541, 543, 548, + 553, 558, 563, 568, 573, 578, 579, 580, 584, 585, + 589, 591, 596, 598, 603, 605, 607, 609, 611, 613, + 615, 617, 619, 621, 623, 625, 630, 635, 637, 639, + 641, 643, 645, 647, 649, 651, 653, 655, 657, 659, + 661, 663, 665, 667, 669, 674, 675, 676, 677, 678, + 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, + 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, + 699, 700, 701, 702, 703, 707, 712, 714, 716, 718, + 723, 728, 729, 732, 733, 737, 739, 741, 743, 745, + 747, 752, 754, 756, 758, 763, 768, 770, 773, 777, + 780, 784, 786, 791, 796, 801, 803, 808, 816, 818, + 823, 824, 825, 829, 834, 839, 844, 849, 850, 851, + 852, 853, 854, 855, 856, 857, 861, 866, 871, 876, + 881, 886, 891, 896, 901, 906, 911, 913, 918, 920, + 922, 927, 932, 937, 942, 944, 949, 951, 956, 961 }; void @@ -4960,9 +4932,9 @@ namespace xsk { namespace gsc { #line 13 "parser.ypp" } } // xsk::gsc -#line 4967 "parser.cpp" +#line 4939 "parser.cpp" -#line 963 "parser.ypp" +#line 965 "parser.ypp" namespace xsk::gsc @@ -4975,8 +4947,8 @@ void parser::error(location const& loc, std::string const& msg) auto parse_switch(stmt_switch& stm) -> void { - auto body = make_stmt_list(stm.body->block->loc()); - auto current_case = stmt{ nullptr }; + auto body = stmt_list::make(stm.body->block->loc()); + auto curr = stmt::ptr{ nullptr }; auto num = stm.body->block->list.size(); @@ -4984,41 +4956,41 @@ auto parse_switch(stmt_switch& stm) -> void { auto& entry = stm.body->block->list[0]; - if (entry == node::stmt_case || entry == node::stmt_default) + if (entry->is() || entry->is()) { - if (current_case.as_node != nullptr) + if (curr != nullptr) { - body->list.push_back(std::move(current_case)); + body->list.push_back(std::move(curr)); } - current_case = std::move(stm.body->block->list[0]); + curr = std::move(stm.body->block->list[0]); stm.body->block->list.erase(stm.body->block->list.begin()); } else { - if (current_case.as_node != nullptr) + if (curr != nullptr) { - if (current_case == node::stmt_case) + if (curr->is()) { - current_case.as_case->body->list.push_back(std::move(entry)); + curr->as().body->list.push_back(std::move(entry)); stm.body->block->list.erase(stm.body->block->list.begin()); } else { - current_case.as_default->body->list.push_back(std::move(entry)); + curr->as().body->list.push_back(std::move(entry)); stm.body->block->list.erase(stm.body->block->list.begin()); } } else { - throw comp_error(entry.loc(), "missing case statement"); + throw comp_error(entry->loc(), "missing case statement"); } } } - if (current_case.as_node != nullptr) + if (curr != nullptr) { - body->list.push_back(std::move(current_case)); + body->list.push_back(std::move(curr)); } stm.body->block = std::move(body); diff --git a/src/gsc/source.cpp b/src/gsc/source.cpp index 2212b55f..3da76d47 100644 --- a/src/gsc/source.cpp +++ b/src/gsc/source.cpp @@ -290,7 +290,7 @@ auto source::dump_program(program const& data) -> void for (auto const& dec : data.declarations) { fmt::format_to(std::back_inserter(buf_), "\n"); - dump_decl(dec); + dump_decl(*dec); } } @@ -306,19 +306,22 @@ auto source::dump_decl(decl const& dec) -> void switch (dec.kind()) { case node::decl_dev_begin: - dump_decl_dev_begin(*dec.as_dev_begin); + dump_decl_dev_begin(dec.as()); break; case node::decl_dev_end: - dump_decl_dev_end(*dec.as_dev_end); + dump_decl_dev_end(dec.as()); break; case node::decl_usingtree: - dump_decl_usingtree(*dec.as_usingtree); + dump_decl_usingtree(dec.as()); break; case node::decl_constant: - dump_decl_constant(*dec.as_constant); + dump_decl_constant(dec.as()); break; case node::decl_function: - dump_decl_function(*dec.as_function); + dump_decl_function(dec.as()); + break; + case node::decl_empty: + dump_decl_empty(dec.as()); break; default: break; @@ -346,7 +349,7 @@ auto source::dump_decl_constant(decl_constant const& dec) -> void { dump_expr_identifier(*dec.name); fmt::format_to(std::back_inserter(buf_), " = "); - dump_expr(dec.value); + dump_expr(*dec.value); fmt::format_to(std::back_inserter(buf_), ";\n"); } @@ -361,135 +364,136 @@ auto source::dump_decl_function(decl_function const& dec) -> void fmt::format_to(std::back_inserter(buf_), "\n"); } +auto source::dump_decl_empty(decl_empty const&) -> void +{ + fmt::format_to(std::back_inserter(buf_), ";"); +} + auto source::dump_stmt(stmt const& stm) -> void { switch (stm.kind()) { case node::stmt_list: - dump_stmt_list(*stm.as_list); + dump_stmt_list(stm.as()); break; case node::stmt_comp: - dump_stmt_comp(*stm.as_comp); + dump_stmt_comp(stm.as()); break; case node::stmt_dev: - dump_stmt_dev(*stm.as_dev); + dump_stmt_dev(stm.as()); break; case node::stmt_expr: - dump_stmt_expr(*stm.as_expr); - break; - case node::stmt_call: - dump_stmt_call(*stm.as_call); - break; - case node::stmt_assign: - dump_stmt_assign(*stm.as_assign); + dump_stmt_expr(stm.as()); break; case node::stmt_endon: - dump_stmt_endon(*stm.as_endon); + dump_stmt_endon(stm.as()); break; case node::stmt_notify: - dump_stmt_notify(*stm.as_notify); + dump_stmt_notify(stm.as()); break; case node::stmt_wait: - dump_stmt_wait(*stm.as_wait); + dump_stmt_wait(stm.as()); break; case node::stmt_waittill: - dump_stmt_waittill(*stm.as_waittill); + dump_stmt_waittill(stm.as()); break; case node::stmt_waittillmatch: - dump_stmt_waittillmatch(*stm.as_waittillmatch); + dump_stmt_waittillmatch(stm.as()); break; case node::stmt_waittillframeend: - dump_stmt_waittillframeend(*stm.as_waittillframeend); + dump_stmt_waittillframeend(stm.as()); break; case node::stmt_waitframe: - dump_stmt_waitframe(*stm.as_waitframe); + dump_stmt_waitframe(stm.as()); break; case node::stmt_if: - dump_stmt_if(*stm.as_if); + dump_stmt_if(stm.as()); break; case node::stmt_ifelse: - dump_stmt_ifelse(*stm.as_ifelse); + dump_stmt_ifelse(stm.as()); break; case node::stmt_while: - dump_stmt_while(*stm.as_while); + dump_stmt_while(stm.as()); break; case node::stmt_dowhile: - dump_stmt_dowhile(*stm.as_dowhile); + dump_stmt_dowhile(stm.as()); break; case node::stmt_for: - dump_stmt_for(*stm.as_for); + dump_stmt_for(stm.as()); break; case node::stmt_foreach: - dump_stmt_foreach(*stm.as_foreach); + dump_stmt_foreach(stm.as()); break; case node::stmt_switch: - dump_stmt_switch(*stm.as_switch); + dump_stmt_switch(stm.as()); break; case node::stmt_case: - dump_stmt_case(*stm.as_case); + dump_stmt_case(stm.as()); break; case node::stmt_default: - dump_stmt_default(*stm.as_default); + dump_stmt_default(stm.as()); break; case node::stmt_break: - dump_stmt_break(*stm.as_break); + dump_stmt_break(stm.as()); break; case node::stmt_continue: - dump_stmt_continue(*stm.as_continue); + dump_stmt_continue(stm.as()); break; case node::stmt_return: - dump_stmt_return(*stm.as_return); + dump_stmt_return(stm.as()); break; case node::stmt_breakpoint: - dump_stmt_breakpoint(*stm.as_breakpoint); + dump_stmt_breakpoint(stm.as()); break; case node::stmt_prof_begin: - dump_stmt_prof_begin(*stm.as_prof_begin); + dump_stmt_prof_begin(stm.as()); break; case node::stmt_prof_end: - dump_stmt_prof_end(*stm.as_prof_end); + dump_stmt_prof_end(stm.as()); break; case node::stmt_assert: - dump_stmt_assert(*stm.as_assert); + dump_stmt_assert(stm.as()); break; case node::stmt_assertex: - dump_stmt_assertex(*stm.as_assertex); + dump_stmt_assertex(stm.as()); break; case node::stmt_assertmsg: - dump_stmt_assertmsg(*stm.as_assertmsg); + dump_stmt_assertmsg(stm.as()); break; - case node::asm_jmp: - dump_asm_jmp(*stm.as_jump); + case node::stmt_create: + dump_stmt_create(stm.as()); break; - case node::asm_jmp_back: - dump_asm_jmp_back(*stm.as_jump_back); + case node::stmt_remove: + dump_stmt_remove(stm.as()); break; - case node::asm_jmp_cond: - dump_asm_jmp_cond(*stm.as_cond); + case node::stmt_clear: + dump_stmt_clear(stm.as()); break; - case node::asm_switch: - dump_asm_switch(*stm.as_asm_switch); + case node::stmt_jmp: + dump_stmt_jmp(stm.as()); break; - case node::asm_endswitch: - dump_asm_endswitch(*stm.as_asm_endswitch); + case node::stmt_jmp_back: + dump_stmt_jmp_back(stm.as()); break; - case node::asm_create: - dump_asm_create(*stm.as_asm_create); + case node::stmt_jmp_cond: + dump_stmt_jmp_cond(stm.as()); break; - case node::asm_access: - dump_asm_access(*stm.as_asm_access); + case node::stmt_jmp_switch: + dump_stmt_jmp_switch(stm.as()); break; - case node::asm_remove: - dump_asm_remove(*stm.as_asm_remove); - break; - case node::asm_clear: - dump_asm_clear(*stm.as_asm_clear); + case node::stmt_jmp_endswitch: + dump_stmt_jmp_endswitch(stm.as()); break; default: break; } } +auto source::dump_stmt_empty(stmt_empty const&) -> void +{ + fmt::format_to(std::back_inserter(buf_), ";"); +} + auto source::dump_stmt_list(stmt_list const& stm) -> void { auto last_special = false; @@ -497,23 +501,23 @@ auto source::dump_stmt_list(stmt_list const& stm) -> void for (auto const& entry : stm.list) { - if ((&entry != &stm.list.front() && entry.as_node->is_special_stmt()) || last_special) + if ((&entry != &stm.list.front() && entry->is_special_stmt()) || last_special) fmt::format_to(std::back_inserter(buf_), "\n"); - if (entry == node::stmt_dev) + if (entry->is()) { - dump_stmt(entry); + dump_stmt(*entry); } else { fmt::format_to(std::back_inserter(buf_), "{: >{}}", "", indent_); - dump_stmt(entry); + dump_stmt(*entry); } if (&entry != &stm.list.back()) fmt::format_to(std::back_inserter(buf_), "\n"); - if (entry.as_node->is_special_stmt()) + if (entry->is_special_stmt()) last_special = true; else last_special = false; @@ -538,34 +542,44 @@ auto source::dump_stmt_dev(stmt_dev const& stm) -> void auto source::dump_stmt_expr(stmt_expr const& stm) -> void { - dump_expr(stm.value); -} + switch (stm.value->kind()) + { + case node::expr_increment: + dump_expr_increment(stm.value->as()); + break; + case node::expr_decrement: + dump_expr_decrement(stm.value->as()); + break; + case node::expr_assign: + dump_expr_assign(stm.value->as()); + break; + case node::expr_call: + dump_expr_call(stm.value->as()); + break; + case node::expr_method: + dump_expr_method(stm.value->as()); + break; + case node::expr_empty: + default: + break; + } -auto source::dump_stmt_call(stmt_call const& stm) -> void -{ - dump_expr(stm.value); - fmt::format_to(std::back_inserter(buf_), ";"); -} - -auto source::dump_stmt_assign(stmt_assign const& stm) -> void -{ - dump_expr(stm.value); fmt::format_to(std::back_inserter(buf_), ";"); } auto source::dump_stmt_endon(stmt_endon const& stm) -> void { - dump_expr(stm.obj); + dump_expr(*stm.obj); fmt::format_to(std::back_inserter(buf_), " endon( "); - dump_expr(stm.event); + dump_expr(*stm.event); fmt::format_to(std::back_inserter(buf_), " );"); } auto source::dump_stmt_notify(stmt_notify const& stm) -> void { - dump_expr(stm.obj); + dump_expr(*stm.obj); fmt::format_to(std::back_inserter(buf_), " notify( "); - dump_expr(stm.event); + dump_expr(*stm.event); if (stm.args->list.size() > 0) { @@ -582,31 +596,31 @@ auto source::dump_stmt_notify(stmt_notify const& stm) -> void auto source::dump_stmt_wait(stmt_wait const& stm) -> void { - if (stm.time == node::expr_float || stm.time == node::expr_integer) + if (stm.time->is() || stm.time->is()) { fmt::format_to(std::back_inserter(buf_), "wait "); - dump_expr(stm.time); + dump_expr(*stm.time); fmt::format_to(std::back_inserter(buf_), ";"); } - else if (stm.time == node::expr_paren) + else if (stm.time->is()) { fmt::format_to(std::back_inserter(buf_), "wait"); - dump_expr(stm.time); + dump_expr(*stm.time); fmt::format_to(std::back_inserter(buf_), ";"); } else { fmt::format_to(std::back_inserter(buf_), "wait( "); - dump_expr(stm.time); + dump_expr(*stm.time); fmt::format_to(std::back_inserter(buf_), " );"); } } auto source::dump_stmt_waittill(stmt_waittill const& stm) -> void { - dump_expr(stm.obj); + dump_expr(*stm.obj); fmt::format_to(std::back_inserter(buf_), " waittill( "); - dump_expr(stm.event); + dump_expr(*stm.event); if (stm.args->list.size() > 0) { @@ -623,9 +637,9 @@ auto source::dump_stmt_waittill(stmt_waittill const& stm) -> void auto source::dump_stmt_waittillmatch(stmt_waittillmatch const& stm) -> void { - dump_expr(stm.obj); + dump_expr(*stm.obj); fmt::format_to(std::back_inserter(buf_), " waittillmatch( "); - dump_expr(stm.event); + dump_expr(*stm.event); if (stm.args->list.size() > 0) { @@ -653,18 +667,18 @@ auto source::dump_stmt_waitframe(stmt_waitframe const&) -> void auto source::dump_stmt_if(stmt_if const& stm) -> void { fmt::format_to(std::back_inserter(buf_), "if ( "); - dump_expr(stm.test); + dump_expr(*stm.test); fmt::format_to(std::back_inserter(buf_), " )\n"); - if (stm.body == node::stmt_comp) + if (stm.body->is()) { - dump_stmt(stm.body); + dump_stmt(*stm.body); } else { indent_ += 4; fmt::format_to(std::back_inserter(buf_), "{: >{}}", "", indent_); - dump_stmt(stm.body); + dump_stmt(*stm.body); indent_ -= 4; } } @@ -672,40 +686,40 @@ auto source::dump_stmt_if(stmt_if const& stm) -> void auto source::dump_stmt_ifelse(stmt_ifelse const& stm) -> void { fmt::format_to(std::back_inserter(buf_), "if ( "); - dump_expr(stm.test); + dump_expr(*stm.test); fmt::format_to(std::back_inserter(buf_), " )\n"); - if (stm.stmt_if == node::stmt_comp) + if (stm.stmt_if->is()) { - dump_stmt(stm.stmt_if); + dump_stmt(*stm.stmt_if); } else { indent_ += 4; fmt::format_to(std::back_inserter(buf_), "{: >{}}", "", indent_); - dump_stmt(stm.stmt_if); + dump_stmt(*stm.stmt_if); indent_ -= 4; } fmt::format_to(std::back_inserter(buf_), "\n{: >{}}else", "", indent_); - if (stm.stmt_else == node::stmt_comp) + if (stm.stmt_else->is()) { fmt::format_to(std::back_inserter(buf_), "\n"); - dump_stmt(stm.stmt_else); + dump_stmt(*stm.stmt_else); } else { - if (stm.stmt_else == node::stmt_if || stm.stmt_else == node::stmt_ifelse) + if (stm.stmt_else->is() || stm.stmt_else ->is()) { fmt::format_to(std::back_inserter(buf_), " "); - dump_stmt(stm.stmt_else); + dump_stmt(*stm.stmt_else); } else { indent_ += 4; fmt::format_to(std::back_inserter(buf_), "\n{: >{}}", "", indent_); - dump_stmt(stm.stmt_else); + dump_stmt(*stm.stmt_else); indent_ -= 4; } } @@ -713,26 +727,26 @@ auto source::dump_stmt_ifelse(stmt_ifelse const& stm) -> void auto source::dump_stmt_while(stmt_while const& stm) -> void { - if (stm.test == node::null) + if (stm.test->is()) { fmt::format_to(std::back_inserter(buf_), "while ( true )\n"); } else { fmt::format_to(std::back_inserter(buf_), "while ( "); - dump_expr(stm.test); + dump_expr(*stm.test); fmt::format_to(std::back_inserter(buf_), " )\n"); } - if (stm.body == node::stmt_comp) + if (stm.body->is()) { - dump_stmt(stm.body); + dump_stmt(*stm.body); } else { indent_ += 4; fmt::format_to(std::back_inserter(buf_), "{: >{}}", "", indent_); - dump_stmt(stm.body); + dump_stmt(*stm.body); indent_ -= 4; } } @@ -741,56 +755,58 @@ auto source::dump_stmt_dowhile(stmt_dowhile const& stm) -> void { fmt::format_to(std::back_inserter(buf_), "do\n"); - if (stm.body == node::stmt_comp) + if (stm.body->is()) { - dump_stmt(stm.body); + dump_stmt(*stm.body); } else { indent_ += 4; fmt::format_to(std::back_inserter(buf_), "{: >{}}", "", indent_); - dump_stmt(stm.body); + dump_stmt(*stm.body); indent_ -= 4; } - if (stm.test == node::null) + if (stm.test->is()) { fmt::format_to(std::back_inserter(buf_), "\n{: >{}}while ( true )", "", indent_); } else { fmt::format_to(std::back_inserter(buf_), "\n{: >{}}while (", "", indent_); - dump_expr(stm.test); + dump_expr(*stm.test); fmt::format_to(std::back_inserter(buf_), " );"); } } auto source::dump_stmt_for(stmt_for const& stm) -> void { - if (stm.test == node::null) + if (stm.test->is()) { fmt::format_to(std::back_inserter(buf_), "for (;;)\n"); } else { fmt::format_to(std::back_inserter(buf_), "for ( "); - dump_stmt(stm.init); + dump_stmt(*stm.init); + buf_.pop_back(); fmt::format_to(std::back_inserter(buf_), "; "); - dump_expr(stm.test); + dump_expr(*stm.test); fmt::format_to(std::back_inserter(buf_), "; "); - dump_stmt(stm.iter); + dump_stmt(*stm.iter); + buf_.pop_back(); fmt::format_to(std::back_inserter(buf_), " )\n"); } - if (stm.body == node::stmt_comp) + if (stm.body->is()) { - dump_stmt(stm.body); + dump_stmt(*stm.body); } else { indent_ += 4; fmt::format_to(std::back_inserter(buf_), "{: >{}}", "", indent_); - dump_stmt(stm.body); + dump_stmt(*stm.body); indent_ -= 4; } } @@ -801,24 +817,24 @@ auto source::dump_stmt_foreach(stmt_foreach const& stm) -> void if (stm.use_key) { - dump_expr((ctx_->props() & props::foreach) ? stm.index : stm.key); + dump_expr((ctx_->props() & props::foreach) ? *stm.index : *stm.key); fmt::format_to(std::back_inserter(buf_), ", "); } - dump_expr(stm.value); + dump_expr(*stm.value); fmt::format_to(std::back_inserter(buf_), " in "); - dump_expr(stm.container); + dump_expr(*stm.container); fmt::format_to(std::back_inserter(buf_), " )\n"); - if (stm.body == node::stmt_comp) + if (stm.body->is()) { - dump_stmt(stm.body); + dump_stmt(*stm.body); } else { indent_ += 4; fmt::format_to(std::back_inserter(buf_), "{: >{}}", "", indent_); - dump_stmt(stm.body); + dump_stmt(*stm.body); indent_ -= 4; } } @@ -826,7 +842,7 @@ auto source::dump_stmt_foreach(stmt_foreach const& stm) -> void auto source::dump_stmt_switch(stmt_switch const& stm) -> void { fmt::format_to(std::back_inserter(buf_), "switch ( "); - dump_expr(stm.test); + dump_expr(*stm.test); fmt::format_to(std::back_inserter(buf_), " )\n"); dump_stmt_comp(*stm.body); } @@ -834,7 +850,7 @@ auto source::dump_stmt_switch(stmt_switch const& stm) -> void auto source::dump_stmt_case(stmt_case const& stm) -> void { fmt::format_to(std::back_inserter(buf_), "case "); - dump_expr(stm.value); + dump_expr(*stm.value); fmt::format_to(std::back_inserter(buf_), ":"); if (stm.body != nullptr && stm.body->list.size() > 0) @@ -867,14 +883,14 @@ auto source::dump_stmt_continue(stmt_continue const&) -> void auto source::dump_stmt_return(stmt_return const& stm) -> void { - if (stm.value == node::null) + if (stm.value->is()) { fmt::format_to(std::back_inserter(buf_), "return;"); } else { fmt::format_to(std::back_inserter(buf_), "return "); - dump_expr(stm.value); + dump_expr(*stm.value); fmt::format_to(std::back_inserter(buf_), ";"); } } @@ -919,213 +935,179 @@ auto source::dump_stmt_assertmsg(stmt_assertmsg const& stm) -> void fmt::format_to(std::back_inserter(buf_), ");"); } +auto source::dump_stmt_create(stmt_create const& stm) -> void +{ + fmt::format_to(std::back_inserter(buf_), "__asm_var_create( {} )", stm.index); +} + +auto source::dump_stmt_remove(stmt_remove const& stm) -> void +{ + fmt::format_to(std::back_inserter(buf_), "__asm_var_remove( {} )", stm.index); +} + +auto source::dump_stmt_clear(stmt_clear const& stm) -> void +{ + fmt::format_to(std::back_inserter(buf_), "__asm_var_clear( {} )", stm.index); +} + +auto source::dump_stmt_jmp(stmt_jmp const& stm) -> void +{ + fmt::format_to(std::back_inserter(buf_), "__asm_jmp( {} )", stm.value); +} + +auto source::dump_stmt_jmp_back(stmt_jmp_back const& stm) -> void +{ + fmt::format_to(std::back_inserter(buf_), "__asm_jmp_back( {} )", stm.value); +} + +auto source::dump_stmt_jmp_cond(stmt_jmp_cond const& stm) -> void +{ + fmt::format_to(std::back_inserter(buf_), "__asm_jmp_cond( {} )", stm.value); +} + +auto source::dump_stmt_jmp_true(stmt_jmp_true const& stm) -> void +{ + fmt::format_to(std::back_inserter(buf_), "__asm_jmp_expr_true( {} )", stm.value); +} + +auto source::dump_stmt_jmp_false(stmt_jmp_false const& stm) -> void +{ + fmt::format_to(std::back_inserter(buf_), "__asm_jmp_expr_false( {} )", stm.value); +} + +auto source::dump_stmt_jmp_switch(stmt_jmp_switch const& stm) -> void +{ + fmt::format_to(std::back_inserter(buf_), "__asm_switch( {} )", stm.value); +} + +auto source::dump_stmt_jmp_endswitch(stmt_jmp_endswitch const&) -> void +{ + fmt::format_to(std::back_inserter(buf_), "__asm_endswitch()"); +} + auto source::dump_expr(expr const& exp) -> void { - switch (exp.as_node->kind()) + switch (exp.kind()) { - case node::expr_increment: - dump_expr_increment(*exp.as_increment); - break; - case node::expr_decrement: - dump_expr_decrement(*exp.as_decrement); - break; - case node::expr_assign_equal: - dump_expr_assign_equal(*exp.as_assign_equal); - break; - case node::expr_assign_add: - dump_expr_assign_add(*exp.as_assign_add); - break; - case node::expr_assign_sub: - dump_expr_assign_sub(*exp.as_assign_sub); - break; - case node::expr_assign_mul: - dump_expr_assign_mul(*exp.as_assign_mul); - break; - case node::expr_assign_div: - dump_expr_assign_div(*exp.as_assign_div); - break; - case node::expr_assign_mod: - dump_expr_assign_mod(*exp.as_assign_mod); - break; - case node::expr_assign_shift_left: - dump_expr_assign_shift_left(*exp.as_assign_shift_left); - break; - case node::expr_assign_shift_right: - dump_expr_assign_shift_right(*exp.as_assign_shift_right); - break; - case node::expr_assign_bitwise_or: - dump_expr_assign_bitwise_or(*exp.as_assign_bw_or); - break; - case node::expr_assign_bitwise_and: - dump_expr_assign_bitwise_and(*exp.as_assign_bw_and); - break; - case node::expr_assign_bitwise_exor: - dump_expr_assign_bitwise_exor(*exp.as_assign_bw_exor); - break; case node::expr_ternary: - dump_expr_ternary(*exp.as_ternary); + dump_expr_ternary(exp.as()); break; - case node::expr_and: - dump_expr_and(*exp.as_and); - break; - case node::expr_or: - dump_expr_or(*exp.as_or); - break; - case node::expr_equality: - dump_expr_equality(*exp.as_equality); - break; - case node::expr_inequality: - dump_expr_inequality(*exp.as_inequality); - break; - case node::expr_less_equal: - dump_expr_less_equal(*exp.as_less_equal); - break; - case node::expr_greater_equal: - dump_expr_greater_equal(*exp.as_greater_equal); - break; - case node::expr_less: - dump_expr_less(*exp.as_less); - break; - case node::expr_greater: - dump_expr_greater(*exp.as_greater); - break; - case node::expr_add: - dump_expr_add(*exp.as_add); - break; - case node::expr_sub: - dump_expr_sub(*exp.as_sub); - break; - case node::expr_mul: - dump_expr_mul(*exp.as_mul); - break; - case node::expr_div: - dump_expr_div(*exp.as_div); - break; - case node::expr_mod: - dump_expr_mod(*exp.as_mod); - break; - case node::expr_shift_left: - dump_expr_shift_left(*exp.as_shift_left); - break; - case node::expr_shift_right: - dump_expr_shift_right(*exp.as_shift_right); - break; - case node::expr_bitwise_or: - dump_expr_bitwise_or(*exp.as_bitwise_or); - break; - case node::expr_bitwise_and: - dump_expr_bitwise_and(*exp.as_bitwise_and); - break; - case node::expr_bitwise_exor: - dump_expr_bitwise_exor(*exp.as_bitwise_exor); + case node::expr_binary: + dump_expr_binary(exp.as()); break; case node::expr_complement: - dump_expr_complement(*exp.as_complement); + dump_expr_complement(exp.as()); break; case node::expr_negate: - dump_expr_negate(*exp.as_negate); + dump_expr_negate(exp.as()); break; case node::expr_not: - dump_expr_not(*exp.as_not); + dump_expr_not(exp.as()); break; case node::expr_call: - dump_expr_call(*exp.as_call); + dump_expr_call(exp.as()); break; case node::expr_method: - dump_expr_method(*exp.as_method); + dump_expr_method(exp.as()); break; case node::expr_function: - dump_expr_function(*exp.as_function); + dump_expr_function(exp.as()); break; case node::expr_pointer: - dump_expr_pointer(*exp.as_pointer); + dump_expr_pointer(exp.as()); break; case node::expr_add_array: - dump_expr_add_array(*exp.as_add_array); + dump_expr_add_array(exp.as()); break; case node::expr_parameters: - dump_expr_parameters(*exp.as_parameters); + dump_expr_parameters(exp.as()); break; case node::expr_arguments: - dump_expr_arguments(*exp.as_arguments); + dump_expr_arguments(exp.as()); break; case node::expr_isdefined: - dump_expr_isdefined(*exp.as_isdefined); + dump_expr_isdefined(exp.as()); break; case node::expr_istrue: - dump_expr_istrue(*exp.as_istrue); + dump_expr_istrue(exp.as()); break; case node::expr_reference: - dump_expr_reference(*exp.as_reference); + dump_expr_reference(exp.as()); break; case node::expr_tuple: - dump_expr_tuple(*exp.as_tuple); + dump_expr_tuple(exp.as()); break; case node::expr_array: - dump_expr_array(*exp.as_array); + dump_expr_array(exp.as()); break; case node::expr_field: - dump_expr_field(*exp.as_field); + dump_expr_field(exp.as()); break; case node::expr_size: - dump_expr_size(*exp.as_size); + dump_expr_size(exp.as()); break; case node::expr_paren: - dump_expr_paren(*exp.as_paren); + dump_expr_paren(exp.as()); break; case node::expr_thisthread: - dump_expr_thisthread(*exp.as_thisthread); + dump_expr_thisthread(exp.as()); break; case node::expr_empty_array: - dump_expr_empty_array(*exp.as_empty_array); + dump_expr_empty_array(exp.as()); break; case node::expr_undefined: - dump_expr_undefined(*exp.as_undefined); + dump_expr_undefined(exp.as()); break; case node::expr_game: - dump_expr_game(*exp.as_game); + dump_expr_game(exp.as()); break; case node::expr_self: - dump_expr_self(*exp.as_self); + dump_expr_self(exp.as()); break; case node::expr_anim: - dump_expr_anim(*exp.as_anim); + dump_expr_anim(exp.as()); break; case node::expr_level: - dump_expr_level(*exp.as_level); + dump_expr_level(exp.as()); break; case node::expr_animation: - dump_expr_animation(*exp.as_animation); + dump_expr_animation(exp.as()); break; case node::expr_animtree: - dump_expr_animtree(*exp.as_animtree); + dump_expr_animtree(exp.as()); break; case node::expr_identifier: - dump_expr_identifier(*exp.as_identifier); + dump_expr_identifier(exp.as()); break; case node::expr_path: - dump_expr_path(*exp.as_path); + dump_expr_path(exp.as()); break; case node::expr_istring: - dump_expr_istring(*exp.as_istring); + dump_expr_istring(exp.as()); break; case node::expr_string: - dump_expr_string(*exp.as_string); + dump_expr_string(exp.as()); break; case node::expr_vector: - dump_expr_vector(*exp.as_vector); + dump_expr_vector(exp.as()); break; case node::expr_float: - dump_expr_float(*exp.as_float); + dump_expr_float(exp.as()); break; case node::expr_integer: - dump_expr_integer(*exp.as_integer); + dump_expr_integer(exp.as()); break; case node::expr_false: - dump_expr_false(*exp.as_false); + dump_expr_false(exp.as()); break; case node::expr_true: - dump_expr_true(*exp.as_true); + dump_expr_true(exp.as()); + break; + case node::expr_var_create: + dump_expr_var_create(exp.as()); + break; + case node::expr_var_access: + dump_expr_var_access(exp.as()); break; default: break; @@ -1137,11 +1119,11 @@ auto source::dump_expr_increment(expr_increment const& exp) -> void if (exp.prefix) { fmt::format_to(std::back_inserter(buf_), "++"); - dump_expr(exp.lvalue); + dump_expr(*exp.lvalue); } else { - dump_expr(exp.lvalue); + dump_expr(*exp.lvalue); fmt::format_to(std::back_inserter(buf_), "++"); } } @@ -1151,266 +1133,172 @@ auto source::dump_expr_decrement(expr_decrement const& exp) -> void if (exp.prefix) { fmt::format_to(std::back_inserter(buf_), "--"); - dump_expr(exp.lvalue); + dump_expr(*exp.lvalue); } else { - dump_expr(exp.lvalue); + dump_expr(*exp.lvalue); fmt::format_to(std::back_inserter(buf_), "--"); } } -auto source::dump_expr_assign_equal(expr_assign_equal const& exp) -> void +auto source::dump_expr_assign(expr_assign const& exp) -> void { - dump_expr(exp.lvalue); - fmt::format_to(std::back_inserter(buf_), " = "); - dump_expr(exp.rvalue); -} + dump_expr(*exp.lvalue); -auto source::dump_expr_assign_add(expr_assign_add const& exp) -> void -{ - dump_expr(exp.lvalue); - fmt::format_to(std::back_inserter(buf_), " += "); - dump_expr(exp.rvalue); -} + switch (exp.oper) + { + case expr_assign::op::eq: + fmt::format_to(std::back_inserter(buf_), " = "); + break; + case expr_assign::op::add: + fmt::format_to(std::back_inserter(buf_), " += "); + break; + case expr_assign::op::sub: + fmt::format_to(std::back_inserter(buf_), " -= "); + break; + case expr_assign::op::mul: + fmt::format_to(std::back_inserter(buf_), " *= "); + break; + case expr_assign::op::div: + fmt::format_to(std::back_inserter(buf_), " /= "); + break; + case expr_assign::op::mod: + fmt::format_to(std::back_inserter(buf_), " %= "); + break; + case expr_assign::op::shl: + fmt::format_to(std::back_inserter(buf_), " <<= "); + break; + case expr_assign::op::shr: + fmt::format_to(std::back_inserter(buf_), " >>= "); + break; + case expr_assign::op::bwor: + fmt::format_to(std::back_inserter(buf_), " |= "); + break; + case expr_assign::op::bwand: + fmt::format_to(std::back_inserter(buf_), " &= "); + break; + case expr_assign::op::bwexor: + fmt::format_to(std::back_inserter(buf_), " ^= "); + break; + } -auto source::dump_expr_assign_sub(expr_assign_sub const& exp) -> void -{ - dump_expr(exp.lvalue); - fmt::format_to(std::back_inserter(buf_), " -= "); - dump_expr(exp.rvalue); -} - -auto source::dump_expr_assign_mul(expr_assign_mul const& exp) -> void -{ - dump_expr(exp.lvalue); - fmt::format_to(std::back_inserter(buf_), " *= "); - dump_expr(exp.rvalue); -} - -auto source::dump_expr_assign_div(expr_assign_div const& exp) -> void -{ - dump_expr(exp.lvalue); - fmt::format_to(std::back_inserter(buf_), " /= "); - dump_expr(exp.rvalue); -} - -auto source::dump_expr_assign_mod(expr_assign_mod const& exp) -> void -{ - dump_expr(exp.lvalue); - fmt::format_to(std::back_inserter(buf_), " %= "); - dump_expr(exp.rvalue); -} - -auto source::dump_expr_assign_shift_left(expr_assign_shift_left const& exp) -> void -{ - dump_expr(exp.lvalue); - fmt::format_to(std::back_inserter(buf_), " <<= "); - dump_expr(exp.rvalue); -} - -auto source::dump_expr_assign_shift_right(expr_assign_shift_right const& exp) -> void -{ - dump_expr(exp.lvalue); - fmt::format_to(std::back_inserter(buf_), " >>= "); - dump_expr(exp.rvalue); -} - -auto source::dump_expr_assign_bitwise_or(expr_assign_bitwise_or const& exp) -> void -{ - dump_expr(exp.lvalue); - fmt::format_to(std::back_inserter(buf_), " |= "); - dump_expr(exp.rvalue); -} - -auto source::dump_expr_assign_bitwise_and(expr_assign_bitwise_and const& exp) -> void -{ - dump_expr(exp.lvalue); - fmt::format_to(std::back_inserter(buf_), " &= "); - dump_expr(exp.rvalue); -} - -auto source::dump_expr_assign_bitwise_exor(expr_assign_bitwise_exor const& exp) -> void -{ - dump_expr(exp.lvalue); - fmt::format_to(std::back_inserter(buf_), " ^= "); - dump_expr(exp.rvalue); + dump_expr(*exp.rvalue); } auto source::dump_expr_ternary(expr_ternary const& exp) -> void { - dump_expr(exp.test); + dump_expr(*exp.test); fmt::format_to(std::back_inserter(buf_), " ? "); - dump_expr(exp.true_expr); + dump_expr(*exp.true_expr); fmt::format_to(std::back_inserter(buf_), " : "); - dump_expr(exp.false_expr); + dump_expr(*exp.false_expr); } -auto source::dump_expr_or(expr_or const& exp) -> void +auto source::dump_expr_binary(expr_binary const& exp) -> void { - dump_expr(exp.lvalue); - fmt::format_to(std::back_inserter(buf_), " || "); - dump_expr(exp.rvalue); -} + dump_expr(*exp.lvalue); -auto source::dump_expr_and(expr_and const& exp) -> void -{ - dump_expr(exp.lvalue); - fmt::format_to(std::back_inserter(buf_), " && "); - dump_expr(exp.rvalue); -} + switch (exp.oper) + { + case expr_binary::op::bool_or: + fmt::format_to(std::back_inserter(buf_), " || "); + break; + case expr_binary::op::bool_and: + fmt::format_to(std::back_inserter(buf_), " && "); + break; + case expr_binary::op::eq: + fmt::format_to(std::back_inserter(buf_), " == "); + break; + case expr_binary::op::ne: + fmt::format_to(std::back_inserter(buf_), " != "); + break; + case expr_binary::op::le: + fmt::format_to(std::back_inserter(buf_), " <= "); + break; + case expr_binary::op::ge: + fmt::format_to(std::back_inserter(buf_), " >= "); + break; + case expr_binary::op::lt: + fmt::format_to(std::back_inserter(buf_), " < "); + break; + case expr_binary::op::gt: + fmt::format_to(std::back_inserter(buf_), " > "); + break; + case expr_binary::op::add: + fmt::format_to(std::back_inserter(buf_), " + "); + break; + case expr_binary::op::sub: + fmt::format_to(std::back_inserter(buf_), " - "); + break; + case expr_binary::op::mul: + fmt::format_to(std::back_inserter(buf_), " * "); + break; + case expr_binary::op::div: + fmt::format_to(std::back_inserter(buf_), " / "); + break; + case expr_binary::op::mod: + fmt::format_to(std::back_inserter(buf_), " % "); + break; + case expr_binary::op::shl: + fmt::format_to(std::back_inserter(buf_), " << "); + break; + case expr_binary::op::shr: + fmt::format_to(std::back_inserter(buf_), " >> "); + break; + case expr_binary::op::bwor: + fmt::format_to(std::back_inserter(buf_), " | "); + break; + case expr_binary::op::bwand: + fmt::format_to(std::back_inserter(buf_), " & "); + break; + case expr_binary::op::bwexor: + fmt::format_to(std::back_inserter(buf_), " ^ "); + break; + } -auto source::dump_expr_equality(expr_equality const& exp) -> void -{ - dump_expr(exp.lvalue); - fmt::format_to(std::back_inserter(buf_), " == "); - dump_expr(exp.rvalue); -} - -auto source::dump_expr_inequality(expr_inequality const& exp) -> void -{ - dump_expr(exp.lvalue); - fmt::format_to(std::back_inserter(buf_), " != "); - dump_expr(exp.rvalue); -} - -auto source::dump_expr_less_equal(expr_less_equal const& exp) -> void -{ - dump_expr(exp.lvalue); - fmt::format_to(std::back_inserter(buf_), " <= "); - dump_expr(exp.rvalue); -} - -auto source::dump_expr_greater_equal(expr_greater_equal const& exp) -> void -{ - dump_expr(exp.lvalue); - fmt::format_to(std::back_inserter(buf_), " >= "); - dump_expr(exp.rvalue); -} - -auto source::dump_expr_less(expr_less const& exp) -> void -{ - dump_expr(exp.lvalue); - fmt::format_to(std::back_inserter(buf_), " < "); - dump_expr(exp.rvalue); -} - -auto source::dump_expr_greater(expr_greater const& exp) -> void -{ - dump_expr(exp.lvalue); - fmt::format_to(std::back_inserter(buf_), " > "); - dump_expr(exp.rvalue); -} - -auto source::dump_expr_add(expr_add const& exp) -> void -{ - dump_expr(exp.lvalue); - fmt::format_to(std::back_inserter(buf_), " + "); - dump_expr(exp.rvalue); -} - -auto source::dump_expr_sub(expr_sub const& exp) -> void -{ - dump_expr(exp.lvalue); - fmt::format_to(std::back_inserter(buf_), " - "); - dump_expr(exp.rvalue); -} - -auto source::dump_expr_mul(expr_mul const& exp) -> void -{ - dump_expr(exp.lvalue); - fmt::format_to(std::back_inserter(buf_), " * "); - dump_expr(exp.rvalue); -} - -auto source::dump_expr_div(expr_div const& exp) -> void -{ - dump_expr(exp.lvalue); - fmt::format_to(std::back_inserter(buf_), " / "); - dump_expr(exp.rvalue); -} - -auto source::dump_expr_mod(expr_mod const& exp) -> void -{ - dump_expr(exp.lvalue); - fmt::format_to(std::back_inserter(buf_), " % "); - dump_expr(exp.rvalue); -} - -auto source::dump_expr_shift_left(expr_shift_left const& exp) -> void -{ - dump_expr(exp.lvalue); - fmt::format_to(std::back_inserter(buf_), " << "); - dump_expr(exp.rvalue); -} - -auto source::dump_expr_shift_right(expr_shift_right const& exp) -> void -{ - dump_expr(exp.lvalue); - fmt::format_to(std::back_inserter(buf_), " >> "); - dump_expr(exp.rvalue); -} - -auto source::dump_expr_bitwise_or(expr_bitwise_or const& exp) -> void -{ - dump_expr(exp.lvalue); - fmt::format_to(std::back_inserter(buf_), " | "); - dump_expr(exp.rvalue); -} - -auto source::dump_expr_bitwise_and(expr_bitwise_and const& exp) -> void -{ - dump_expr(exp.lvalue); - fmt::format_to(std::back_inserter(buf_), " & "); - dump_expr(exp.rvalue); -} - -auto source::dump_expr_bitwise_exor(expr_bitwise_exor const& exp) -> void -{ - dump_expr(exp.lvalue); - fmt::format_to(std::back_inserter(buf_), " ^ "); - dump_expr(exp.rvalue); + dump_expr(*exp.rvalue); } auto source::dump_expr_not(expr_not const& exp) -> void { fmt::format_to(std::back_inserter(buf_), "!"); - dump_expr(exp.rvalue); + dump_expr(*exp.rvalue); } auto source::dump_expr_negate(expr_negate const& exp) -> void { fmt::format_to(std::back_inserter(buf_), "-"); - dump_expr(exp.rvalue); + dump_expr(*exp.rvalue); } auto source::dump_expr_complement(expr_complement const& exp) -> void { fmt::format_to(std::back_inserter(buf_), "~"); - dump_expr(exp.rvalue); + dump_expr(*exp.rvalue); } auto source::dump_expr_call(expr_call const& exp) -> void { - dump_call(exp.value); + dump_call(*exp.value); } auto source::dump_expr_method(expr_method const& exp) -> void { - dump_expr(exp.obj); + dump_expr(*exp.obj); fmt::format_to(std::back_inserter(buf_), " "); - dump_call(exp.value); + dump_call(*exp.value); } auto source::dump_call(call const& exp) -> void { - switch (exp.as_node->kind()) + switch (exp.kind()) { case node::expr_function: - dump_expr_function(*exp.as_function); + dump_expr_function(exp.as()); break; case node::expr_pointer: - dump_expr_pointer(*exp.as_pointer); + dump_expr_pointer(exp.as()); break; default: break; @@ -1446,7 +1334,7 @@ auto source::dump_expr_pointer(expr_pointer const& exp) -> void fmt::format_to(std::back_inserter(buf_), "childthread "); fmt::format_to(std::back_inserter(buf_), "[[ "); - dump_expr(exp.func); + dump_expr(*exp.func); fmt::format_to(std::back_inserter(buf_), " ]]("); dump_expr_arguments(*exp.args); fmt::format_to(std::back_inserter(buf_), ")"); @@ -1478,7 +1366,7 @@ auto source::dump_expr_arguments(expr_arguments const& exp) -> void for (auto const& entry : exp.list) { fmt::format_to(std::back_inserter(buf_), " "); - dump_expr(entry); + dump_expr(*entry); if (&entry != &exp.list.back()) fmt::format_to(std::back_inserter(buf_), ","); @@ -1490,14 +1378,14 @@ auto source::dump_expr_arguments(expr_arguments const& exp) -> void auto source::dump_expr_isdefined(expr_isdefined const& exp) -> void { fmt::format_to(std::back_inserter(buf_), "isdefined( "); - dump_expr(exp.value); + dump_expr(*exp.value); fmt::format_to(std::back_inserter(buf_), " )"); } auto source::dump_expr_istrue(expr_istrue const& exp) -> void { fmt::format_to(std::back_inserter(buf_), "istrue( "); - dump_expr(exp.value); + dump_expr(*exp.value); fmt::format_to(std::back_inserter(buf_), " )"); } @@ -1514,7 +1402,7 @@ auto source::dump_expr_tuple(expr_tuple const& exp) -> void for (auto const& entry : exp.list) { - dump_expr(entry); + dump_expr(*entry); if (&entry != &exp.list.back()) fmt::format_to(std::back_inserter(buf_), ", "); @@ -1525,29 +1413,29 @@ auto source::dump_expr_tuple(expr_tuple const& exp) -> void auto source::dump_expr_array(expr_array const& exp) -> void { - dump_expr(exp.obj); + dump_expr(*exp.obj); fmt::format_to(std::back_inserter(buf_), "["); - dump_expr(exp.key); + dump_expr(*exp.key); fmt::format_to(std::back_inserter(buf_), "]"); } auto source::dump_expr_field(expr_field const& exp) -> void { - dump_expr(exp.obj); + dump_expr(*exp.obj); fmt::format_to(std::back_inserter(buf_), "."); dump_expr_identifier(*exp.field); } auto source::dump_expr_size(expr_size const& exp) -> void { - dump_expr(exp.obj); + dump_expr(*exp.obj); fmt::format_to(std::back_inserter(buf_), ".size"); } auto source::dump_expr_paren(expr_paren const& exp) -> void { fmt::format_to(std::back_inserter(buf_), "( "); - dump_expr(exp.value); + dump_expr(*exp.value); fmt::format_to(std::back_inserter(buf_), " )"); } @@ -1619,11 +1507,11 @@ auto source::dump_expr_string(expr_string const& exp) -> void auto source::dump_expr_vector(expr_vector const& exp) -> void { fmt::format_to(std::back_inserter(buf_), "( "); - dump_expr(exp.x); + dump_expr(*exp.x); fmt::format_to(std::back_inserter(buf_), ", "); - dump_expr(exp.y); + dump_expr(*exp.y); fmt::format_to(std::back_inserter(buf_), ", "); - dump_expr(exp.z); + dump_expr(*exp.z); fmt::format_to(std::back_inserter(buf_), " )"); } @@ -1647,69 +1535,14 @@ auto source::dump_expr_true(expr_true const&) -> void fmt::format_to(std::back_inserter(buf_), "true"); } -auto source::dump_asm_jmp(asm_jmp const& exp) -> void -{ - fmt::format_to(std::back_inserter(buf_), "__asm_jmp( {} )", exp.value); -} - -auto source::dump_asm_jmp_back(asm_jmp_back const& exp) -> void -{ - fmt::format_to(std::back_inserter(buf_), "__asm_jmp_back( {} )", exp.value); -} - -auto source::dump_asm_jmp_cond(asm_jmp_cond const& exp) -> void -{ - fmt::format_to(std::back_inserter(buf_), "__asm_jmp_cond( {} )", exp.value); -} - -auto source::dump_asm_jmp_true(asm_jmp_true const& exp) -> void -{ - fmt::format_to(std::back_inserter(buf_), "__asm_jmp_expr_true( {} )", exp.value); -} - -auto source::dump_asm_jmp_false(asm_jmp_false const& exp) -> void -{ - fmt::format_to(std::back_inserter(buf_), "__asm_jmp_expr_false( {} )", exp.value); -} - -auto source::dump_asm_switch(asm_switch const& exp) -> void -{ - fmt::format_to(std::back_inserter(buf_), "__asm_switch( {} )", exp.value); -} - -auto source::dump_asm_endswitch(asm_endswitch const&) -> void -{ - fmt::format_to(std::back_inserter(buf_), "__asm_endswitch()"); -} - -auto source::dump_asm_prescriptcall(asm_prescriptcall const&) -> void -{ - fmt::format_to(std::back_inserter(buf_), "__asm_prescriptcall()"); -} - -auto source::dump_asm_voidcodepos(asm_voidcodepos const&) -> void -{ - fmt::format_to(std::back_inserter(buf_), "__asm_voidcodepos()"); -} - -auto source::dump_asm_create(asm_create const& exp) -> void +auto source::dump_expr_var_create(expr_var_create const& exp) -> void { fmt::format_to(std::back_inserter(buf_), "__asm_var_create( {} )", exp.index); } -auto source::dump_asm_access(asm_access const& exp) -> void +auto source::dump_expr_var_access(expr_var_access const& exp) -> void { fmt::format_to(std::back_inserter(buf_), "__asm_var_access( {} )", exp.index); } -auto source::dump_asm_remove(asm_remove const& exp) -> void -{ - fmt::format_to(std::back_inserter(buf_), "__asm_var_remove( {} )", exp.index); -} - -auto source::dump_asm_clear(asm_clear const& exp) -> void -{ - fmt::format_to(std::back_inserter(buf_), "__asm_var_clear( {} )", exp.index); -} - } // namespace xsk::gsc