diff --git a/gen/arc/parser.ypp b/gen/arc/parser.ypp index 37ef8d7e..303db383 100644 --- a/gen/arc/parser.ypp +++ b/gen/arc/parser.ypp @@ -1121,7 +1121,7 @@ auto map_token(context const* ctx_, token& tok) -> parser::symbol_type return parser::symbol_type(parser::token::IDENTIFIER, std::move(tok.data), tok.pos); } - else if (tok.type == token::PATH ||tok.type == token::STRING ||tok.type == token::ISTRING || tok.type == token::INT ||tok.type == token::FLT) + else if (tok.type == token::PATH ||tok.type == token::HASHSTR ||tok.type == token::STRING ||tok.type == token::ISTRING || tok.type == token::INT ||tok.type == token::FLT) { auto it = tok_to_parser.find(tok.type); diff --git a/gen/t6/Makefile b/gen/t6/Makefile deleted file mode 100644 index e8ddb37b..00000000 --- a/gen/t6/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -generate: t6 - -clean: - rm -rf ./parser.hpp - rm -rf ./parser.cpp - -t6: parser.ypp - bison parser.ypp -Wcounterexamples - mv parser.hpp ../../include/xsk/t6/ - mv parser.cpp ../../src/t6/ diff --git a/gen/t6/parser.ypp b/gen/t6/parser.ypp deleted file mode 100644 index 788ee17c..00000000 --- a/gen/t6/parser.ypp +++ /dev/null @@ -1,1027 +0,0 @@ -/* Copyright 2023 xensik. All rights reserved. -// -// Use of this source code is governed by a GNU GPLv3 license -// that can be found in the LICENSE file. -*/ - -%require "3.7" -%skeleton "lalr1.cc" -%language "c++" -%output "parser.cpp" -%defines "parser.hpp" -%define api.prefix {T6} -%define api.namespace {xsk::arc::t6} -%define api.location.type {xsk::arc::location} -%define api.value.type variant -%define api.token.constructor -%define api.token.raw -%define parse.assert -%define parse.trace -%define parse.error detailed -%define parse.lac full -%locations -%lex-param { xsk::arc::t6::lexer& lexer } -%parse-param { xsk::arc::t6::lexer& lexer } -%parse-param { xsk::arc::ast::program::ptr& ast } - -%code requires -{ -#ifdef _MSC_VER -#pragma warning(disable:4065) -#pragma warning(disable:4127) -#endif -#include "t6.hpp" -namespace xsk::arc::t6 { class lexer; } -} - -%code top -{ -#include "xsk/stdinc.hpp" -#include "xsk/t6/parser.hpp" -#include "xsk/t6/lexer.hpp" -using namespace xsk::arc; -xsk::arc::t6::parser::symbol_type T6lex(xsk::arc::t6::lexer& lexer); -} - -%token SH_DEFINE "#define" -%token SH_UNDEF "#undef" -%token SH_IFDEF "#ifdef" -%token SH_IFNDEF "#ifndef" -%token SH_IF "#if" -%token SH_ELIF "#elif" -%token SH_ELSE "#else" -%token SH_ENDIF "#endif" -%token DEVBEGIN "/#" -%token DEVEND "#/" -%token INLINE "#inline" -%token INCLUDE "#include" -%token USINGTREE "#using_animtree" -%token ANIMTREE "#animtree" -%token AUTOEXEC "autoexec" -%token CODECALL "codecall" -%token PRIVATE "private" -%token ENDON "endon" -%token NOTIFY "notify" -%token WAIT "wait" -%token WAITTILL "waittill" -%token WAITTILLMATCH "waittillmatch" -%token WAITTILLFRAMEEND "waittillframeend" -%token IF "if" -%token ELSE "else" -%token DO "do" -%token WHILE "while" -%token FOR "for" -%token FOREACH "foreach" -%token IN "in" -%token SWITCH "switch" -%token CASE "case" -%token DEFAULT "default" -%token BREAK "break" -%token CONTINUE "continue" -%token RETURN "return" -%token PROFBEGIN "prof_begin" -%token PROFEND "prof_end" -%token THREAD "thread" -%token TRUE "true" -%token FALSE "false" -%token UNDEFINED "undefined" -%token SIZE "size" -%token GAME "game" -%token SELF "self" -%token ANIM "anim" -%token LEVEL "level" -%token CONST "const" -%token GETNEXTARRAYKEY "getnextarraykey" -%token GETFIRSTARRAYKEY "getfirstarraykey" -%token GETDVARCOLORALPHA "getdvarcoloralpha" -%token GETDVARCOLORBLUE "getdvarcolorblue" -%token GETDVARCOLORGREEN "getdvarcolorgreen" -%token GETDVARCOLORRED "getdvarcolorred" -%token GETDVARVECTOR "getdvarvector" -%token GETDVARFLOAT "getdvarfloat" -%token GETDVARINT "getdvarint" -%token GETDVAR "getdvar" -%token GETTIME "gettime" -%token ABS "abs" -%token VECTORTOANGLES "vectortoangles" -%token ANGLECLAMP180 "angleclamp180" -%token ANGLESTOFORWARD "anglestoforward" -%token ANGLESTORIGHT "anglestoright" -%token ANGLESTOUP "anglestoup" -%token VECTORSCALE "vectorscale" -%token ISDEFINED "isdefined" -%token LPAREN "(" -%token RPAREN ")" -%token LBRACE "{" -%token RBRACE "}" -%token LBRACKET "[" -%token RBRACKET "]" -%token COMMA "," -%token DOT "." -%token DOUBLECOLON "::" -%token COLON ":" -%token SEMICOLON ";" -%token QMARK "?" -%token INCREMENT "++" -%token DECREMENT "--" -%token LSHIFT "<<" -%token RSHIFT ">>" -%token OR "||" -%token AND "&&" -%token EQUALITY "==" -%token INEQUALITY "!=" -%token LESS_EQUAL "<=" -%token GREATER_EQUAL ">=" -%token LESS "<" -%token GREATER ">" -%token NOT "!" -%token COMPLEMENT "~" -%token ASSIGN "=" -%token ASSIGN_ADD "+=" -%token ASSIGN_SUB "-=" -%token ASSIGN_MUL "*=" -%token ASSIGN_DIV "/=" -%token ASSIGN_MOD "%=" -%token ASSIGN_BW_OR "|=" -%token ASSIGN_BW_AND "&=" -%token ASSIGN_BW_EXOR "^=" -%token ASSIGN_RSHIFT ">>=" -%token ASSIGN_LSHIFT "<<=" -%token BITWISE_OR "|" -%token BITWISE_AND "&" -%token BITWISE_EXOR "^" -%token ADD "+" -%token SUB "-" -%token MUL "*" -%token DIV "/" -%token MOD "%" -%token PATH "path" -%token IDENTIFIER "identifier" -%token STRING "string literal" -%token ISTRING "localized string" -%token HASH "hash" -%token FLOAT "float" -%token INTEGER "integer" - -%type program -%type include -%type declaration -%type decl_usingtree -%type decl_thread -%type stmt -%type stmt_or_dev -%type stmt_list -%type stmt_or_dev_list -%type stmt_dev -%type stmt_block -%type stmt_expr -%type stmt_call -%type stmt_const -%type stmt_assign -%type stmt_endon -%type stmt_notify -%type stmt_wait -%type stmt_waittill -%type stmt_waittillmatch -%type stmt_waittillframeend -%type stmt_if -%type stmt_ifelse -%type stmt_while -%type stmt_dowhile -%type stmt_for -%type stmt_foreach -%type stmt_switch -%type stmt_case -%type stmt_default -%type stmt_break -%type stmt_continue -%type stmt_return -%type stmt_prof_begin -%type stmt_prof_end -%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_complement -%type expr_negate -%type expr_not -%type expr_call -%type expr_method -%type expr_function -%type expr_pointer -%type expr_parameters -%type expr_parameters_default -%type expr_arguments -%type expr_arguments_no_empty -%type expr_getnextarraykey -%type expr_getfirstarraykey -%type expr_getdvarcoloralpha -%type expr_getdvarcolorblue -%type expr_getdvarcolorgreen -%type expr_getdvarcolorred -%type expr_getdvarvector -%type expr_getdvarfloat -%type expr_getdvarint -%type expr_getdvar -%type expr_gettime -%type expr_abs -%type expr_vectortoangles -%type expr_angleclamp180 -%type expr_anglestoforward -%type expr_anglestoright -%type expr_anglestoup -%type expr_vectorscale -%type expr_isdefined -%type expr_reference -%type expr_array -%type expr_field -%type expr_size -%type expr_paren -%type expr_object -%type expr_empty_array -%type expr_undefined -%type expr_game -%type expr_self -%type expr_anim -%type expr_level -%type expr_animation -%type expr_animtree -%type expr_identifier_nosize -%type expr_identifier -%type expr_path -%type expr_istring -%type expr_string -%type expr_vector -%type expr_hash -%type expr_float -%type expr_integer -%type expr_false -%type expr_true - -%nonassoc SIZEOF -%nonassoc RBRACKET -%nonassoc THEN -%nonassoc ELSE -%nonassoc INCREMENT DECREMENT - -%precedence TERN -%right QMARK -%left OR -%left AND -%left BITWISE_OR -%left BITWISE_EXOR -%left BITWISE_AND -%left EQUALITY INEQUALITY -%left LESS GREATER LESS_EQUAL GREATER_EQUAL -%left LSHIFT RSHIFT -%left ADD SUB -%left MUL DIV MOD -%right NOT COMPLEMENT - -%precedence NEG -%precedence ANIMREF -%precedence PREINC PREDEC -%precedence POSTINC POSTDEC - -%start root - -%% - -root - : program { ast = std::move($1); } - | { ast = std::make_unique(@$); } - ; - -program - : program inline - { $$ = std::move($1); } - | program include - { $$ = std::move($1); $$->includes.push_back(std::move($2)); } - | program declaration - { $$ = std::move($1); $$->declarations.push_back(std::move($2)); } - | inline - { $$ = std::make_unique(@$); } - | include - { $$ = std::make_unique(@$); $$->includes.push_back(std::move($1)); } - | declaration - { $$ = std::make_unique(@$); $$->declarations.push_back(std::move($1)); } - ; - -inline - : INLINE expr_path SEMICOLON { lexer.push_header($2->value); } - ; - -include - : INCLUDE expr_path SEMICOLON - { $$ = std::make_unique(@$, std::move($2)); } - ; - -declaration - : DEVBEGIN { $$.as_dev_begin = std::make_unique(@$); } - | DEVEND { $$.as_dev_end = std::make_unique(@$); } - | decl_usingtree { $$.as_usingtree = std::move($1); } - | decl_thread { $$.as_thread = std::move($1); } - ; - -decl_usingtree - : USINGTREE LPAREN expr_string RPAREN SEMICOLON - { lexer.ban_header(@$); $$ = std::make_unique(@$, std::move($3)); } - ; - -decl_thread - : expr_identifier LPAREN expr_parameters RPAREN stmt_block - { lexer.ban_header(@$); $$ = std::make_unique(@$, std::move($1), std::move($3), std::move($5), export_flags::export_none); } - | AUTOEXEC expr_identifier LPAREN expr_parameters RPAREN stmt_block - { lexer.ban_header(@$); $$ = std::make_unique(@$, std::move($2), std::move($4), std::move($6), export_flags::export_autoexec); } - | CODECALL expr_identifier LPAREN expr_parameters RPAREN stmt_block - { lexer.ban_header(@$); $$ = std::make_unique(@$, std::move($2), std::move($4), std::move($6), export_flags::export_codecall); } - | PRIVATE expr_identifier LPAREN expr_parameters RPAREN stmt_block - { lexer.ban_header(@$); $$ = std::make_unique(@$, std::move($2), std::move($4), std::move($6), export_flags::export_private2); } - ; - -stmt - : stmt_block { $$.as_list = std::move($1); } - | stmt_call { $$.as_call = std::move($1); } - | stmt_const { $$.as_const = 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_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_prof_begin { $$.as_prof_begin = std::move($1); } - | stmt_prof_end { $$.as_prof_end = std::move($1); } - ; - -stmt_or_dev - : stmt { $$ = std::move($1); } - | stmt_dev { $$.as_dev = std::move($1); } - ; - -stmt_list - : stmt_list stmt - { $$ = std::move($1); $$->list.push_back(std::move($2)); } - | stmt - { $$ = std::make_unique(@$); $$->list.push_back(std::move($1)); } - ; - -stmt_or_dev_list - : stmt_or_dev_list stmt_or_dev - { $$ = std::move($1); $$->list.push_back(std::move($2)); } - | stmt_or_dev - { $$ = std::make_unique(@$); $$->list.push_back(std::move($1)); } - ; - -stmt_dev - : DEVBEGIN stmt_list DEVEND { $$ = std::make_unique(@$, std::move($2)); } - | DEVBEGIN DEVEND { $$ = std::make_unique(@$, std::make_unique(@$)); } - ; - -stmt_block - : LBRACE stmt_or_dev_list RBRACE { $$ = std::move($2); } - | LBRACE RBRACE { $$ = std::make_unique(@$); } - ; - -stmt_expr - : expr_assign - { $$ = std::make_unique(@$, std::move($1)); } - | expr_increment - { $$ = std::make_unique(@$, std::move($1)); } - | expr_decrement - { $$ = std::make_unique(@$, std::move($1)); } - | - { $$ = std::make_unique(@$, std::make_unique(@$)); } - ; - -stmt_call - : expr_call SEMICOLON - { $$ = std::make_unique(@$, ast::expr(std::move($1))); } - | expr_method SEMICOLON - { $$ = std::make_unique(@$, ast::expr(std::move($1))); } - ; - -stmt_const - : CONST expr_identifier ASSIGN expr SEMICOLON - { $$ = std::make_unique(@$, std::move($2), std::move($4)); } - ; - -stmt_assign - : expr_assign SEMICOLON - { $$ = std::make_unique(@$, std::move($1)); } - | expr_increment SEMICOLON - { $$ = std::make_unique(@$, std::move($1)); } - | expr_decrement SEMICOLON - { $$ = std::make_unique(@$, std::move($1)); } - ; - -stmt_endon - : expr_object ENDON LPAREN expr RPAREN SEMICOLON - { $$ = std::make_unique(@$, std::move($1), std::move($4)); } - ; - -stmt_notify - : expr_object NOTIFY LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON - { $$ = std::make_unique(@$, std::move($1), std::move($4), std::move($6)); } - | expr_object NOTIFY LPAREN expr RPAREN SEMICOLON - { $$ = std::make_unique(@$, std::move($1), std::move($4), std::make_unique(@$)); } - ; - -stmt_wait - : WAIT expr SEMICOLON - { $$ = std::make_unique(@$, std::move($2)); } - ; - -stmt_waittill - : expr_object WAITTILL LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON - { $$ = std::make_unique(@$, std::move($1), std::move($4), std::move($6)); } - | expr_object WAITTILL LPAREN expr RPAREN SEMICOLON - { $$ = std::make_unique(@$, std::move($1), std::move($4), std::make_unique(@$)); } - ; - -stmt_waittillmatch - : expr_object WAITTILLMATCH LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON - { $$ = std::make_unique(@$, std::move($1), std::move($4), std::move($6)); } - | expr_object WAITTILLMATCH LPAREN expr RPAREN SEMICOLON - { $$ = std::make_unique(@$, std::move($1), std::move($4), std::make_unique(@$)); } - ; - -stmt_waittillframeend - : WAITTILLFRAMEEND SEMICOLON - { $$ = std::make_unique(@$); } - ; - -stmt_if - : IF LPAREN expr RPAREN stmt %prec THEN - { $$ = std::make_unique(@$, std::move($3), std::move($5)); } - ; - -stmt_ifelse - : IF LPAREN expr RPAREN stmt ELSE stmt - { $$ = std::make_unique(@$, std::move($3), std::move($5), std::move($7)); } - ; - -stmt_while - : WHILE LPAREN expr RPAREN stmt - { $$ = std::make_unique(@$, std::move($3), std::move($5)); } - ; - -stmt_dowhile - : DO stmt WHILE LPAREN expr RPAREN SEMICOLON - { $$ = std::make_unique(@$, std::move($5), std::move($2)); } - ; - -stmt_for - : FOR LPAREN stmt_expr SEMICOLON expr_or_empty SEMICOLON stmt_expr RPAREN stmt - { $$ = std::make_unique(@$, ast::stmt(std::move($3)), std::move($5), ast::stmt(std::move($7)), std::move($9)); } - ; - -stmt_foreach - : FOREACH LPAREN expr_identifier IN expr RPAREN stmt - { $$ = std::make_unique(@$, ast::expr(std::move($3)), std::move($5), std::move($7)); } - | FOREACH LPAREN expr_identifier COMMA expr_identifier IN expr RPAREN stmt - { $$ = std::make_unique(@$, ast::expr(std::move($3)), ast::expr(std::move($5)), std::move($7), std::move($9)); } - ; - -stmt_switch - : SWITCH LPAREN expr RPAREN stmt_block - { $$ = std::make_unique(@$, std::move($3), std::move($5)); } - ; - -stmt_case - : CASE expr_integer COLON - { $$ = std::make_unique(@$, ast::expr(std::move($2)), std::make_unique(@$)); } - | CASE expr_string COLON - { $$ = std::make_unique(@$, ast::expr(std::move($2)), std::make_unique(@$)); } - ; - -stmt_default - : DEFAULT COLON - { $$ = std::make_unique(@$, std::make_unique(@$)); } - ; - -stmt_break - : BREAK SEMICOLON - { $$ = std::make_unique(@$); } - ; - -stmt_continue - : CONTINUE SEMICOLON - { $$ = std::make_unique(@$); } - ; - -stmt_return - : RETURN expr SEMICOLON - { $$ = std::make_unique(@$, std::move($2)); } - | RETURN SEMICOLON - { $$ = std::make_unique(@$, std::make_unique(@$)); } - ; - -stmt_prof_begin - : PROFBEGIN LPAREN expr_arguments RPAREN SEMICOLON - { $$ = std::make_unique(@$, std::move($3)); } - ; - -stmt_prof_end - : PROFEND LPAREN expr_arguments RPAREN SEMICOLON - { $$ = std::make_unique(@$, std::move($3)); } - ; - -expr - : expr_ternary { $$ = std::move($1); } - | expr_binary { $$ = std::move($1); } - | expr_primitive { $$ = std::move($1); } - ; - -expr_or_empty - : expr { $$ = std::move($1); } - | { $$.as_node = std::make_unique(@$); } - ; - -expr_assign - : expr_object ASSIGN expr - { $$.as_node = std::make_unique(@$, std::move($1), std::move($3)); } - | expr_object ASSIGN_BW_OR expr - { $$.as_node = std::make_unique(@$, std::move($1), std::move($3)); } - | expr_object ASSIGN_BW_AND expr - { $$.as_node = std::make_unique(@$, std::move($1), std::move($3)); } - | expr_object ASSIGN_BW_EXOR expr - { $$.as_node = std::make_unique(@$, std::move($1), std::move($3)); } - | expr_object ASSIGN_LSHIFT expr - { $$.as_node = std::make_unique(@$, std::move($1),std::move( $3)); } - | expr_object ASSIGN_RSHIFT expr - { $$.as_node = std::make_unique(@$, std::move($1), std::move($3)); } - | expr_object ASSIGN_ADD expr - { $$.as_node = std::make_unique(@$, std::move($1), std::move($3)); } - | expr_object ASSIGN_SUB expr - { $$.as_node = std::make_unique(@$, std::move($1), std::move($3)); } - | expr_object ASSIGN_MUL expr - { $$.as_node = std::make_unique(@$, std::move($1), std::move($3)); } - | expr_object ASSIGN_DIV expr - { $$.as_node = std::make_unique(@$, std::move($1), std::move($3)); } - | expr_object ASSIGN_MOD expr - { $$.as_node = std::make_unique(@$, std::move($1), std::move($3)); } - ; - -expr_increment - : INCREMENT expr_object %prec PREINC - { $$.as_node = std::make_unique(@$, std::move($2), true); } - | expr_object INCREMENT %prec POSTINC - { $$.as_node = std::make_unique(@$, std::move($1), false); } - ; - -expr_decrement - : DECREMENT expr_object %prec PREDEC - { $$.as_node = std::make_unique(@$, std::move($2), true); } - | expr_object DECREMENT %prec POSTDEC - { $$.as_node = std::make_unique(@$, std::move($1), false); } - ; - -expr_ternary - : expr QMARK expr COLON expr %prec TERN - { $$.as_node = std::make_unique(@$, std::move($1), std::move($3), std::move($5)); } - ; - -expr_binary - : expr OR expr - { $$.as_node = std::make_unique(@$, std::move($1), std::move($3)); } - | expr AND expr - { $$.as_node = std::make_unique(@$, std::move($1), std::move($3)); } - | expr EQUALITY expr - { $$.as_node = std::make_unique(@$, std::move($1), std::move($3)); } - | expr INEQUALITY expr - { $$.as_node = std::make_unique(@$, std::move($1), std::move($3)); } - | expr LESS_EQUAL expr - { $$.as_node = std::make_unique(@$, std::move($1), std::move($3)); } - | expr GREATER_EQUAL expr - { $$.as_node = std::make_unique(@$, std::move($1), std::move($3)); } - | expr LESS expr - { $$.as_node = std::make_unique(@$, std::move($1), std::move($3)); } - | expr GREATER expr - { $$.as_node = std::make_unique(@$, std::move($1), std::move($3)); } - | expr BITWISE_OR expr - { $$.as_node = std::make_unique(@$, std::move($1), std::move($3)); } - | expr BITWISE_AND expr - { $$.as_node = std::make_unique(@$, std::move($1), std::move($3)); } - | expr BITWISE_EXOR expr - { $$.as_node = std::make_unique(@$, std::move($1), std::move($3)); } - | expr LSHIFT expr - { $$.as_node = std::make_unique(@$, std::move($1), std::move($3)); } - | expr RSHIFT expr - { $$.as_node = std::make_unique(@$, std::move($1), std::move($3)); } - | expr ADD expr - { $$.as_node = std::make_unique(@$, std::move($1), std::move($3)); } - | expr SUB expr - { $$.as_node = std::make_unique(@$, std::move($1), std::move($3)); } - | expr MUL expr - { $$.as_node = std::make_unique(@$, std::move($1), std::move($3)); } - | expr DIV expr - { $$.as_node = std::make_unique(@$, std::move($1), std::move($3)); } - | expr MOD expr - { $$.as_node = std::make_unique(@$, std::move($1), std::move($3)); } - ; - -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_getnextarraykey { $$.as_node = std::move($1); } - | expr_getfirstarraykey { $$.as_node = std::move($1); } - | expr_getdvarcoloralpha { $$.as_node = std::move($1); } - | expr_getdvarcolorblue { $$.as_node = std::move($1); } - | expr_getdvarcolorgreen { $$.as_node = std::move($1); } - | expr_getdvarcolorred { $$.as_node = std::move($1); } - | expr_getdvarvector { $$.as_node = std::move($1); } - | expr_getdvarfloat { $$.as_node = std::move($1); } - | expr_getdvarint { $$.as_node = std::move($1); } - | expr_getdvar { $$.as_node = std::move($1); } - | expr_gettime { $$.as_node = std::move($1); } - | expr_abs { $$.as_node = std::move($1); } - | expr_vectortoangles { $$.as_node = std::move($1); } - | expr_angleclamp180 { $$.as_node = std::move($1); } - | expr_anglestoforward { $$.as_node = std::move($1); } - | expr_anglestoright { $$.as_node = std::move($1); } - | expr_anglestoup { $$.as_node = std::move($1); } - | expr_vectorscale { $$.as_node = std::move($1); } - | expr_isdefined { $$.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_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_hash { $$.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 - : COMPLEMENT expr - { $$ = std::make_unique(@$, std::move($2)); } - ; - -expr_negate - : SUB expr_identifier %prec NEG - { $$ = std::make_unique(@$, ast::expr(std::move($2))); } - | SUB expr_paren %prec NEG - { $$ = std::make_unique(@$, ast::expr(std::move($2))); } - | SUB expr_array %prec NEG - { $$ = std::make_unique(@$, ast::expr(std::move($2))); } - | SUB expr_field %prec NEG - { $$ = std::make_unique(@$, ast::expr(std::move($2))); } - ; - -expr_not - : NOT expr - { $$ = std::make_unique(@$, std::move($2)); } - ; - -expr_call - : expr_function { $$ = std::make_unique(@$, std::move($1)); } - | expr_pointer { $$ = std::make_unique(@$, std::move($1)); } - ; -expr_method - : expr_object expr_function { $$ = std::make_unique(@$, std::move($1), std::move($2)); } - | expr_object expr_pointer { $$ = std::make_unique(@$, std::move($1), std::move($2)); } - ; - -expr_function - : expr_identifier LPAREN expr_arguments RPAREN - { $$.as_function = std::make_unique(@$, std::make_unique(@$), std::move($1), std::move($3), ast::call::mode::normal); } - | expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN - { $$.as_function = std::make_unique(@$, std::move($1), std::move($3), std::move($5), ast::call::mode::normal); } - | THREAD expr_identifier LPAREN expr_arguments RPAREN - { $$.as_function = std::make_unique(@$, std::make_unique(@$), std::move($2), std::move($4), ast::call::mode::thread); } - | THREAD expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN - { $$.as_function = std::make_unique(@$, std::move($2), std::move($4), std::move($6), ast::call::mode::thread); } - ; - -expr_pointer - : LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN - { $$.as_pointer = std::make_unique(@$, std::move($3), std::move($7), ast::call::mode::normal); } - | THREAD LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN - { $$.as_pointer = std::make_unique(@$, std::move($4), std::move($8), ast::call::mode::thread); } - ; - -expr_parameters - : expr_parameters COMMA expr_parameters_default - { $$ = std::move($1); $$->list.push_back(std::move($3)); } - | expr_parameters COMMA expr_identifier - { $$ = std::move($1); $$->list.push_back(ast::expr(std::move($3))); } - | expr_parameters_default - { $$ = std::make_unique(@$); $$->list.push_back(std::move($1)); } - | expr_identifier - { $$ = std::make_unique(@$); $$->list.push_back(ast::expr(std::move($1))); } - | - { $$ = std::make_unique(@$); } - ; - -expr_parameters_default - : expr_identifier ASSIGN expr - { $$.as_node = std::make_unique(@$, ast::expr(std::move($1)), std::move($3)); } - ; - -expr_arguments - : expr_arguments_no_empty - { $$ = std::move($1); } - | - { $$ = std::make_unique(@$); } - ; - -expr_arguments_no_empty - : expr_arguments COMMA expr - { $$ = std::move($1); $$->list.push_back(std::move($3)); } - | expr - { $$ = std::make_unique(@$); $$->list.push_back(std::move($1)); } - ; - -expr_getnextarraykey - : GETNEXTARRAYKEY LPAREN expr COMMA expr RPAREN - { $$ = std::make_unique(@$, std::move($3), std::move($5)); } - ; - -expr_getfirstarraykey - : GETFIRSTARRAYKEY LPAREN expr RPAREN - { $$ = std::make_unique(@$, std::move($3)); } - ; - -expr_getdvarcoloralpha - : GETDVARCOLORALPHA LPAREN expr RPAREN - { $$ = std::make_unique(@$, std::move($3)); } - ; - -expr_getdvarcolorblue - : GETDVARCOLORBLUE LPAREN expr RPAREN - { $$ = std::make_unique(@$, std::move($3)); } - ; - -expr_getdvarcolorgreen - : GETDVARCOLORGREEN LPAREN expr RPAREN - { $$ = std::make_unique(@$, std::move($3)); } - ; - -expr_getdvarcolorred - : GETDVARCOLORRED LPAREN expr RPAREN - { $$ = std::make_unique(@$, std::move($3)); } - ; - -expr_getdvarvector - : GETDVARVECTOR LPAREN expr RPAREN - { $$ = std::make_unique(@$, std::move($3)); } - ; - -expr_getdvarfloat - : GETDVARFLOAT LPAREN expr RPAREN - { $$ = std::make_unique(@$, std::move($3)); } - ; - -expr_getdvarint - : GETDVARINT LPAREN expr RPAREN - { $$ = std::make_unique(@$, std::move($3)); } - ; - -expr_getdvar - : GETDVAR LPAREN expr RPAREN - { $$ = std::make_unique(@$, std::move($3)); } - ; - -expr_gettime - : GETTIME LPAREN RPAREN - { $$ = std::make_unique(@$); } - ; - -expr_abs - : ABS LPAREN expr RPAREN - { $$ = std::make_unique(@$, std::move($3)); } - ; - -expr_vectortoangles - : VECTORTOANGLES LPAREN expr RPAREN - { $$ = std::make_unique(@$, std::move($3)); } - ; - -expr_angleclamp180 - : ANGLECLAMP180 LPAREN expr RPAREN - { $$ = std::make_unique(@$, std::move($3)); } - ; - -expr_anglestoforward - : ANGLESTOFORWARD LPAREN expr RPAREN - { $$ = std::make_unique(@$, std::move($3)); } - ; - -expr_anglestoright - : ANGLESTORIGHT LPAREN expr RPAREN - { $$ = std::make_unique(@$, std::move($3)); } - ; - -expr_anglestoup - : ANGLESTOUP LPAREN expr RPAREN - { $$ = std::make_unique(@$, std::move($3)); } - ; - -expr_vectorscale - : VECTORSCALE LPAREN expr COMMA expr RPAREN - { $$ = std::make_unique(@$, std::move($3), std::move($5)); } - ; - -expr_isdefined - : ISDEFINED LPAREN expr RPAREN - { $$ = std::make_unique(@$, std::move($3)); } - ; - -expr_reference - : DOUBLECOLON expr_identifier - { $$ = std::make_unique(@$, std::make_unique(@$), std::move($2)); } - | expr_path DOUBLECOLON expr_identifier - { $$ = std::make_unique(@$, std::move($1), std::move($3)); } - ; - -expr_array - : expr_object LBRACKET expr RBRACKET - { $$ = std::make_unique(@$, std::move($1), std::move($3)); } - | expr_getdvarvector LBRACKET expr RBRACKET - { $$ = std::make_unique(@$, ast::expr(std::move($1)), std::move($3)); } - | expr_vectortoangles LBRACKET expr RBRACKET - { $$ = std::make_unique(@$, ast::expr(std::move($1)), std::move($3)); } - | expr_angleclamp180 LBRACKET expr RBRACKET - { $$ = std::make_unique(@$, ast::expr(std::move($1)), std::move($3)); } - | expr_anglestoforward LBRACKET expr RBRACKET - { $$ = std::make_unique(@$, ast::expr(std::move($1)), std::move($3)); } - | expr_anglestoright LBRACKET expr RBRACKET - { $$ = std::make_unique(@$, ast::expr(std::move($1)), std::move($3)); } - | expr_anglestoup LBRACKET expr RBRACKET - { $$ = std::make_unique(@$, ast::expr(std::move($1)), std::move($3)); } - | expr_vectorscale LBRACKET expr RBRACKET - { $$ = std::make_unique(@$, ast::expr(std::move($1)), std::move($3)); } - ; - -expr_field - : expr_object DOT expr_identifier_nosize - { $$ = std::make_unique(@$, std::move($1), std::move($3)); } - ; - -expr_size - : expr_object DOT SIZE %prec SIZEOF - { $$ = std::make_unique(@$, std::move($1)); } - ; - -expr_paren - : LPAREN expr RPAREN - { $$ = std::make_unique(@$, 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_empty_array - : LBRACKET RBRACKET - { $$ = std::make_unique(@$); }; - ; - -expr_undefined - : UNDEFINED - { $$ = std::make_unique(@$); }; - ; - -expr_game - : GAME - { $$ = std::make_unique(@$); }; - ; - -expr_self - : SELF - { $$ = std::make_unique(@$); }; - ; - -expr_anim - : ANIM - { $$ = std::make_unique(@$); }; - ; - -expr_level - : LEVEL - { $$ = std::make_unique(@$); }; - ; - -expr_animation - : MOD IDENTIFIER %prec ANIMREF - { $$ = std::make_unique(@$, $2); }; - ; - -expr_animtree - : ANIMTREE - { $$ = std::make_unique(@$); }; - ; - -expr_identifier_nosize - : IDENTIFIER - { $$ = std::make_unique(@$, $1); }; - ; - -expr_identifier - : IDENTIFIER - { $$ = std::make_unique(@$, $1); }; - | SIZE - { $$ = std::make_unique(@$, "size"); }; - ; - -expr_path - : PATH DIV IDENTIFIER - { $$ = std::make_unique(@$, $1 + "/" + $3); }; - | IDENTIFIER - { $$ = std::make_unique(@$, $1); }; - | PATH - { $$ = std::make_unique(@$, $1); }; - ; - -expr_istring - : ISTRING - { $$ = std::make_unique(@$, $1); }; - ; - -expr_string - : STRING - { $$ = std::make_unique(@$, $1); }; - ; - -expr_vector - : LPAREN expr COMMA expr COMMA expr RPAREN - { $$ = std::make_unique(@$, std::move($2), std::move($4), std::move($6)); }; - ; - -expr_hash - : HASH - { $$ = std::make_unique(@$, $1); }; - ; - -expr_float - : SUB FLOAT %prec NEG - { $$ = std::make_unique(@$, "-" + $2); }; - | FLOAT - { $$ = std::make_unique(@$, $1); }; - ; - -expr_integer - : SUB INTEGER %prec NEG - { $$ = std::make_unique(@$, "-" + $2); }; - | INTEGER - { $$ = std::make_unique(@$, $1); }; - ; - -expr_false - : FALSE - { $$ = std::make_unique(@$); }; - ; - -expr_true - : TRUE - { $$ = std::make_unique(@$); }; - ; - -%% - -void xsk::arc::t6::parser::error(const xsk::arc::location& loc, const std::string& msg) -{ - throw xsk::arc::comp_error(loc, msg); -} diff --git a/include/xsk/arc/preprocessor.hpp b/include/xsk/arc/preprocessor.hpp index f743f5a4..ccce3621 100644 --- a/include/xsk/arc/preprocessor.hpp +++ b/include/xsk/arc/preprocessor.hpp @@ -59,6 +59,7 @@ private: auto read_directive_usingtree(token& hash, token& name) -> void; auto read_hashtoken(token& hash) -> void; auto read_hashtoken_animtree(token& hash, token& name) -> void; + auto read_hashtoken_hashstr(token& hash, token& name) -> void; auto expand(token& tok, define& def) -> void; auto expand_params(token& tok, define& def) -> std::vector>; auto expect(token& tok, token::kind expected, spacing space = spacing::none) -> void; diff --git a/src/arc/assembler.cpp b/src/arc/assembler.cpp index 4a803dbd..43a9aa69 100644 --- a/src/arc/assembler.cpp +++ b/src/arc/assembler.cpp @@ -395,7 +395,7 @@ auto assembler::assemble_instruction(instruction const& inst) -> void break; case opcode::OP_GetHash: script_.align(4); - script_.write(static_cast(std::stoul(inst.data[0], 0, 16))); + script_.write(ctx_->hash_id(inst.data[0])); break; case opcode::OP_SafeCreateLocalVariables: assemble_localvars(inst); @@ -483,7 +483,7 @@ auto assembler::assemble_switch(instruction const& inst) -> void auto assembler::assemble_end_switch(instruction const& inst) -> void { const auto count = std::stoul(inst.data[0]); - const auto numerical = inst.data.back() == "i"; + const auto type = static_cast(std::stoul(inst.data.back())); script_.align(4); script_.write(count); @@ -492,7 +492,7 @@ auto assembler::assemble_end_switch(instruction const& inst) -> void { if (inst.data[1 + (3 * i)] == "case") { - if (numerical /*&& utils::string::is_number(inst->data[1 + (3 * i) + 1])*/) + if (type == switch_type::integer) { script_.write((std::stoi(inst.data[1 + (3 * i) + 1]) & 0xFFFFFF) + 0x800000); } @@ -515,7 +515,7 @@ auto assembler::assemble_end_switch(instruction const& inst) -> void } else { - throw asm_error("invalid switch case '" + inst.data[1 + (3 * i)] + "'!"); + throw asm_error(fmt::format("invalid switch case {}", inst.data[1 + (3 * i)])); } } } @@ -586,13 +586,13 @@ auto assembler::process_instruction(instruction const& inst) -> void case opcode::OP_EndSwitch: { const auto count = std::stoul(inst.data[0]); - const auto numerical = inst.data.back() == "i"; + const auto type = static_cast(std::stoul(inst.data.back())); for (auto i = 0u; i < count; i++) { if (inst.data[1 + (3 * i)] == "case") { - if (!numerical /*|| !utils::string::is_number(inst->data[1 + (3 * i) + 1])*/) + if (type == switch_type::string) { process_string(inst.data[1 + (3 * i) + 1]); } @@ -809,13 +809,13 @@ auto assembler::align_instruction(instruction& inst) -> void script_.seek(4); const auto count = std::stoul(inst.data[0]); - const auto numerical = inst.data.back() == "i"; + const auto type = static_cast(std::stoul(inst.data.back())); for (auto i = 0u; i < count; i++) { if (inst.data[1 + (3 * i)] == "case") { - if (!numerical /*|| !utils::string::is_number(inst.data[1 + (3 * i) + 1])*/) + if (type == switch_type::string) { add_stringref(inst.data[1 + (3 * i) + 1], string_type::literal, script_.pos() + 2); } @@ -842,7 +842,7 @@ auto assembler::resolve_label(std::string const& name) -> i32 } } - throw asm_error("couldn't resolve label address of '" + name + "'!"); + throw asm_error(fmt::format("couldn't resolve label address of {}", name)); } auto assembler::resolve_string(std::string const& name) -> u16 @@ -854,7 +854,7 @@ auto assembler::resolve_string(std::string const& name) -> u16 return itr->second; } - throw asm_error("couldn't resolve string assembly address of '" + name + "'!"); + throw asm_error(fmt::format("couldn't resolve string address of {}", name)); } void assembler::add_stringref(std::string const& str, string_type type, u32 ref) diff --git a/src/arc/parser.cpp b/src/arc/parser.cpp index b06d5632..b0a83e7a 100644 --- a/src/arc/parser.cpp +++ b/src/arc/parser.cpp @@ -5546,7 +5546,7 @@ auto map_token(context const* ctx_, token& tok) -> parser::symbol_type return parser::symbol_type(parser::token::IDENTIFIER, std::move(tok.data), tok.pos); } - else if (tok.type == token::PATH ||tok.type == token::STRING ||tok.type == token::ISTRING || tok.type == token::INT ||tok.type == token::FLT) + else if (tok.type == token::PATH ||tok.type == token::HASHSTR ||tok.type == token::STRING ||tok.type == token::ISTRING || tok.type == token::INT ||tok.type == token::FLT) { auto it = tok_to_parser.find(tok.type); diff --git a/src/arc/preprocessor.cpp b/src/arc/preprocessor.cpp index 8250f7cb..d8f94800 100644 --- a/src/arc/preprocessor.cpp +++ b/src/arc/preprocessor.cpp @@ -709,8 +709,10 @@ auto preprocessor::read_hashtoken(token& tok) -> void return read_hashtoken_animtree(tok, next); } } - - // TODO: iw9 hash literals #d"src_game" + else if (next.type == token::STRING) + { + return read_hashtoken_hashstr(tok, next); + } // if nothing match return '#' tokens_.push_front(std::move(next)); @@ -732,6 +734,21 @@ auto preprocessor::read_hashtoken_animtree(token& hash, token& name) -> void } } +auto preprocessor::read_hashtoken_hashstr(token& hash, token& name) -> void +{ + if (name.space == spacing::none) + { + name.pos.begin = hash.pos.begin; + tokens_.push_front(token{ token::HASHSTR, spacing::none, name.pos, name.data }); + } + else + { + // if '# ""' return 2 tokens + tokens_.push_front(std::move(name)); + tokens_.push_front(token{ token::HASH, hash.space, hash.pos }); + } +} + auto preprocessor::expand(token& tok, define& def) -> void { if (def.type == define::PLAIN)