gsc-tool/gen/arc/parser.ypp
2024-01-05 16:33:16 +01:00

1352 lines
48 KiB
Plaintext

/* 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 {ARC}
%define api.namespace {xsk::arc}
%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::context const* ctx_ }
%lex-param { xsk::arc::preprocessor& ppr }
%parse-param { xsk::arc::context const* ctx_ }
%parse-param { xsk::arc::preprocessor& ppr }
%parse-param { xsk::arc::program::ptr& ast }
%parse-param { std::uint32_t index }
%code requires
{
#ifdef _MSC_VER
#pragma warning(disable:4065)
#pragma warning(disable:4127)
#endif
#include "context.hpp"
namespace xsk::arc { class preprocessor; }
}
%code top
{
#include "xsk/stdinc.hpp"
#include "xsk/arc/parser.hpp"
#include "xsk/arc/preprocessor.hpp"
using namespace xsk::arc;
namespace xsk::arc
{
auto ARClex(context const* ctx_, preprocessor& ppr) -> parser::symbol_type;
auto parse_switch(stmt_switch& stm) -> void;
}
}
%token HASH "#"
%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 WAITREALTIME "waitrealtime"
%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 DOUBLEDOT ".."
%token ELLIPSIS "..."
%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 <std::string> PATH "path"
%token <std::string> IDENTIFIER "identifier"
%token <std::string> STRING "string literal"
%token <std::string> ISTRING "localized string"
%token <std::string> HASHSTR "hash string"
%token <std::string> FLOAT "float"
%token <std::string> INTEGER "integer"
%type <program::ptr> program
%type <include::ptr> include
%type <decl::ptr> declaration
%type <decl_usingtree::ptr> decl_usingtree
%type <decl_function::ptr> decl_function
%type <stmt::ptr> stmt
%type <stmt::ptr> stmt_or_dev
%type <stmt_list::ptr> stmt_list
%type <stmt_list::ptr> stmt_or_dev_list
%type <stmt_dev::ptr> stmt_dev
%type <stmt_comp::ptr> stmt_comp
%type <stmt_expr::ptr> stmt_expr
%type <stmt_expr::ptr> stmt_call
%type <stmt_expr::ptr> stmt_const
%type <stmt_expr::ptr> stmt_assign
%type <stmt_endon::ptr> stmt_endon
%type <stmt_notify::ptr> stmt_notify
%type <stmt_wait::ptr> stmt_wait
%type <stmt_waitrealtime::ptr> stmt_waitrealtime
%type <stmt_waittill::ptr> stmt_waittill
%type <stmt_waittillmatch::ptr> stmt_waittillmatch
%type <stmt_waittillframeend::ptr> stmt_waittillframeend
%type <stmt_if::ptr> stmt_if
%type <stmt_ifelse::ptr> stmt_ifelse
%type <stmt_while::ptr> stmt_while
%type <stmt_dowhile::ptr> stmt_dowhile
%type <stmt_for::ptr> stmt_for
%type <stmt_foreach::ptr> stmt_foreach
%type <stmt_switch::ptr> stmt_switch
%type <stmt_case::ptr> stmt_case
%type <stmt_default::ptr> stmt_default
%type <stmt_break::ptr> stmt_break
%type <stmt_continue::ptr> stmt_continue
%type <stmt_return::ptr> stmt_return
%type <stmt_prof_begin::ptr> stmt_prof_begin
%type <stmt_prof_end::ptr> stmt_prof_end
%type <expr::ptr> expr
%type <expr::ptr> expr_or_empty
%type <expr::ptr> expr_increment
%type <expr::ptr> expr_decrement
%type <expr::ptr> expr_assign
%type <expr::ptr> expr_ternary
%type <expr::ptr> expr_binary
%type <expr::ptr> expr_primitive
%type <expr_complement::ptr> expr_complement
%type <expr_negate::ptr> expr_negate
%type <expr_not::ptr> expr_not
%type <expr_call::ptr> expr_call
%type <expr_method::ptr> expr_method
%type <call::ptr> expr_function
%type <call::ptr> expr_pointer
%type <expr_parameters::ptr> expr_parameters
%type <expr::ptr> expr_parameters_default
%type <expr_arguments::ptr> expr_arguments
%type <expr_arguments::ptr> expr_arguments_no_empty
%type <expr_getnextarraykey::ptr> expr_getnextarraykey
%type <expr_getfirstarraykey::ptr> expr_getfirstarraykey
%type <expr_getdvarcoloralpha::ptr> expr_getdvarcoloralpha
%type <expr_getdvarcolorblue::ptr> expr_getdvarcolorblue
%type <expr_getdvarcolorgreen::ptr> expr_getdvarcolorgreen
%type <expr_getdvarcolorred::ptr> expr_getdvarcolorred
%type <expr_getdvarvector::ptr> expr_getdvarvector
%type <expr_getdvarfloat::ptr> expr_getdvarfloat
%type <expr_getdvarint::ptr> expr_getdvarint
%type <expr_getdvar::ptr> expr_getdvar
%type <expr_gettime::ptr> expr_gettime
%type <expr_abs::ptr> expr_abs
%type <expr_vectortoangles::ptr> expr_vectortoangles
%type <expr_angleclamp180::ptr> expr_angleclamp180
%type <expr_anglestoforward::ptr> expr_anglestoforward
%type <expr_anglestoright::ptr> expr_anglestoright
%type <expr_anglestoup::ptr> expr_anglestoup
%type <expr_vectorscale::ptr> expr_vectorscale
%type <expr_isdefined::ptr> expr_isdefined
%type <expr_reference::ptr> expr_reference
%type <expr_array::ptr> expr_array
%type <expr_field::ptr> expr_field
%type <expr_size::ptr> expr_size
%type <expr_paren::ptr> expr_paren
%type <expr::ptr> expr_object
%type <expr_empty_array::ptr> expr_empty_array
%type <expr_undefined::ptr> expr_undefined
%type <expr_game::ptr> expr_game
%type <expr_self::ptr> expr_self
%type <expr_anim::ptr> expr_anim
%type <expr_level::ptr> expr_level
%type <expr_animation::ptr> expr_animation
%type <expr_animtree::ptr> expr_animtree
%type <expr_identifier::ptr> expr_identifier_nosize
%type <expr_identifier::ptr> expr_identifier
%type <expr_path::ptr> expr_path
%type <expr_istring::ptr> expr_istring
%type <expr_string::ptr> expr_string
%type <expr_vector::ptr> expr_vector
%type <expr_hash::ptr> expr_hash
%type <expr_float::ptr> expr_float
%type <expr_integer::ptr> expr_integer
%type <expr_false::ptr> expr_false
%type <expr_true::ptr> 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 = program::make(@$); }
;
program
: program SEMICOLON
{ $$ = std::move($1); }
| 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)); }
| SEMICOLON
{ $$ = program::make(@$); }
| inline
{ $$ = program::make(@$); }
| include
{ $$ = program::make(@$); $$->includes.push_back(std::move($1)); }
| declaration
{ $$ = program::make(@$); $$->declarations.push_back(std::move($1)); }
;
inline
: INLINE expr_path SEMICOLON { ppr.push_header($2->value); }
;
include
: INCLUDE expr_path SEMICOLON
{ $$ = include::make(@$, std::move($2)); }
;
declaration
: DEVBEGIN { $$ = decl_dev_begin::make(@$); }
| DEVEND { $$ = decl_dev_end::make(@$); }
| decl_usingtree { $$ = std::move($1); }
| decl_function { $$ = std::move($1); }
;
decl_usingtree
: USINGTREE LPAREN expr_string RPAREN SEMICOLON
{ ppr.ban_header(@$); $$ = decl_usingtree::make(@$, std::move($3)); }
;
decl_function
: expr_identifier LPAREN expr_parameters RPAREN stmt_comp
{ ppr.ban_header(@$); $$ = decl_function::make(@$, expr_identifier::make(@$, ""), std::move($1), std::move($3), std::move($5), export_flags::export_none); }
| AUTOEXEC expr_identifier LPAREN expr_parameters RPAREN stmt_comp
{ ppr.ban_header(@$); $$ = decl_function::make(@$, expr_identifier::make(@$, ""), std::move($2), std::move($4), std::move($6), export_flags::export_autoexec); }
| CODECALL expr_identifier LPAREN expr_parameters RPAREN stmt_comp
{ ppr.ban_header(@$); $$ = decl_function::make(@$, expr_identifier::make(@$, ""), std::move($2), std::move($4), std::move($6), export_flags::export_codecall); }
| PRIVATE expr_identifier LPAREN expr_parameters RPAREN stmt_comp
{ ppr.ban_header(@$); $$ = decl_function::make(@$, expr_identifier::make(@$, ""), std::move($2), std::move($4), std::move($6), export_flags::export_private2); }
;
stmt
: stmt_comp { $$ = std::move($1); }
| stmt_call { $$ = std::move($1); }
| stmt_const { $$ = std::move($1); }
| stmt_assign { $$ = std::move($1); }
| stmt_endon { $$ = std::move($1); }
| stmt_notify { $$ = std::move($1); }
| stmt_wait { $$ = std::move($1); }
| stmt_waitrealtime { $$ = std::move($1); }
| stmt_waittill { $$ = std::move($1); }
| stmt_waittillmatch { $$ = std::move($1); }
| stmt_waittillframeend { $$ = 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_prof_begin { $$ = std::move($1); }
| stmt_prof_end { $$ = std::move($1); }
;
stmt_or_dev
: stmt { $$ = std::move($1); }
| stmt_dev { $$ = std::move($1); }
;
stmt_list
: stmt_list stmt
{ $$ = std::move($1); $$->list.push_back(std::move($2)); }
| stmt
{ $$ = stmt_list::make(@$); $$->list.push_back(std::move($1)); }
| stmt_list SEMICOLON
{ $$ = std::move($1); }
| SEMICOLON
{ $$ = 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
{ $$ = stmt_list::make(@$); $$->list.push_back(std::move($1)); }
| stmt_or_dev_list SEMICOLON
{ $$ = std::move($1); }
| SEMICOLON
{ $$ = stmt_list::make(@$); }
;
stmt_dev
: 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 { $$ = stmt_comp::make(@$, std::move($2)); }
| LBRACE RBRACE { $$ = stmt_comp::make(@$, stmt_list::make(@$)); }
;
stmt_expr
: expr_assign
{ $$ = stmt_expr::make(@$, std::move($1)); }
| expr_increment
{ $$ = stmt_expr::make(@$, std::move($1)); }
| expr_decrement
{ $$ = stmt_expr::make(@$, std::move($1)); }
|
{ $$ = stmt_expr::make(@$, expr_empty::make(@$)); }
;
stmt_call
: expr_call SEMICOLON
{ $$ = stmt_expr::make(@$, std::move($1)); }
| expr_method SEMICOLON
{ $$ = stmt_expr::make(@$, std::move($1)); }
;
stmt_const
: CONST expr_identifier ASSIGN expr SEMICOLON
{ $$ = stmt_expr::make(@$, expr_const::make(@$, std::move($2), std::move($4))); }
;
stmt_assign
: expr_assign SEMICOLON
{ $$ = stmt_expr::make(@$, std::move($1)); }
| expr_increment SEMICOLON
{ $$ = stmt_expr::make(@$, std::move($1)); }
| expr_decrement SEMICOLON
{ $$ = stmt_expr::make(@$, std::move($1)); }
;
stmt_endon
: expr_object ENDON LPAREN expr RPAREN SEMICOLON
{ $$ = stmt_endon::make(@$, std::move($1), std::move($4)); }
;
stmt_notify
: expr_object NOTIFY LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON
{ $$ = stmt_notify::make(@$, std::move($1), std::move($4), std::move($6)); }
| expr_object NOTIFY LPAREN expr RPAREN SEMICOLON
{ $$ = stmt_notify::make(@$, std::move($1), std::move($4), expr_arguments::make(@$)); }
;
stmt_wait
: WAIT expr SEMICOLON
{ $$ = stmt_wait::make(@$, std::move($2)); }
;
stmt_waitrealtime
: WAITREALTIME expr SEMICOLON
{ $$ = stmt_waitrealtime::make(@$, std::move($2)); }
;
stmt_waittill
: expr_object WAITTILL LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON
{ $$ = stmt_waittill::make(@$, std::move($1), std::move($4), std::move($6)); }
| expr_object WAITTILL LPAREN expr RPAREN SEMICOLON
{ $$ = 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
{ $$ = stmt_waittillmatch::make(@$, std::move($1), std::move($4), std::move($6)); }
| expr_object WAITTILLMATCH LPAREN expr RPAREN SEMICOLON
{ $$ = stmt_waittillmatch::make(@$, std::move($1), std::move($4), expr_arguments::make(@$)); }
;
stmt_waittillframeend
: WAITTILLFRAMEEND SEMICOLON
{ $$ = stmt_waittillframeend::make(@$); }
;
stmt_if
: IF LPAREN expr RPAREN stmt %prec THEN
{ $$ = stmt_if::make(@$, std::move($3), std::move($5)); }
;
stmt_ifelse
: IF LPAREN expr RPAREN stmt ELSE stmt
{ $$ = stmt_ifelse::make(@$, std::move($3), std::move($5), std::move($7)); }
;
stmt_while
: WHILE LPAREN expr RPAREN stmt
{ $$ = stmt_while::make(@$, std::move($3), std::move($5)); }
;
stmt_dowhile
: DO stmt WHILE LPAREN expr RPAREN SEMICOLON
{ $$ = stmt_dowhile::make(@$, std::move($5), std::move($2)); }
;
stmt_for
: FOR LPAREN stmt_expr SEMICOLON expr_or_empty SEMICOLON stmt_expr RPAREN stmt
{ $$ = 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_identifier::make(@$, fmt::format("_a{}", ++index));
auto key = expr_identifier::make(@$, fmt::format("_k{}", ++index));
$$ = stmt_foreach::make(@$, std::move($5), std::move($3), std::move(array), std::move(key), std::move($7), false);
}
| FOREACH LPAREN expr_identifier COMMA expr_identifier IN expr RPAREN stmt
{
auto array = expr_identifier::make(@$, fmt::format("_a{}", ++index));
$$ = stmt_foreach::make(@$, std::move($7), std::move($5), std::move(array), std::move($3), std::move($9), true);
}
;
stmt_switch
: SWITCH LPAREN expr RPAREN stmt_comp
{ $$ = stmt_switch::make(@$, std::move($3), std::move($5));
parse_switch(*$$);
}
;
stmt_case
: CASE expr_integer COLON
{ $$ = stmt_case::make(@$, std::move($2), stmt_list::make(@$)); }
| CASE expr_string COLON
{ $$ = stmt_case::make(@$, std::move($2), stmt_list::make(@$)); }
;
stmt_default
: DEFAULT COLON
{ $$ = stmt_default::make(@$, stmt_list::make(@$)); }
;
stmt_break
: BREAK SEMICOLON
{ $$ = stmt_break::make(@$); }
;
stmt_continue
: CONTINUE SEMICOLON
{ $$ = stmt_continue::make(@$); }
;
stmt_return
: RETURN expr SEMICOLON
{ $$ = stmt_return::make(@$, std::move($2)); }
| RETURN SEMICOLON
{ $$ = stmt_return::make(@$, expr_empty::make(@$)); }
;
stmt_prof_begin
: PROFBEGIN LPAREN expr_arguments RPAREN SEMICOLON
{ $$ = stmt_prof_begin::make(@$, std::move($3)); }
;
stmt_prof_end
: PROFEND LPAREN expr_arguments RPAREN SEMICOLON
{ $$ = stmt_prof_end::make(@$, 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); }
| { $$ = expr_empty::make(@$); }
;
expr_increment
: INCREMENT expr_object %prec PREINC
{ $$ = expr_increment::make(@$, std::move($2), true); }
| expr_object INCREMENT %prec POSTINC
{ $$ = expr_increment::make(@$, std::move($1), false); }
;
expr_decrement
: DECREMENT expr_object %prec PREDEC
{ $$ = expr_decrement::make(@$, std::move($2), true); }
| expr_object DECREMENT %prec POSTDEC
{ $$ = expr_decrement::make(@$, std::move($1), false); }
;
expr_assign
: 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
{ $$ = expr_ternary::make(@$, std::move($1), std::move($3), std::move($5)); }
;
expr_binary
: expr OR expr
{ $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::bool_or); }
| expr AND expr
{ $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::bool_and); }
| expr EQUALITY expr
{ $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::eq); }
| expr INEQUALITY expr
{ $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::ne); }
| expr LESS_EQUAL expr
{ $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::le); }
| expr GREATER_EQUAL expr
{ $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::ge); }
| expr LESS expr
{ $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::lt); }
| expr GREATER expr
{ $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::gt); }
| expr BITWISE_OR expr
{ $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::bwor); }
| expr BITWISE_AND expr
{ $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::bwand); }
| expr BITWISE_EXOR expr
{ $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::bwexor); }
| expr LSHIFT expr
{ $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::shl); }
| expr RSHIFT expr
{ $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::shr); }
| expr ADD expr
{ $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::add); }
| expr SUB expr
{ $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::sub); }
| expr MUL expr
{ $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::mul); }
| expr DIV expr
{ $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::div); }
| expr MOD expr
{ $$ = expr_binary::make(@$, std::move($1), std::move($3), expr_binary::op::mod); }
;
expr_primitive
: 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_getnextarraykey { $$ = std::move($1); }
| expr_getfirstarraykey { $$ = std::move($1); }
| expr_getdvarcoloralpha { $$ = std::move($1); }
| expr_getdvarcolorblue { $$ = std::move($1); }
| expr_getdvarcolorgreen { $$ = std::move($1); }
| expr_getdvarcolorred { $$ = std::move($1); }
| expr_getdvarvector { $$ = std::move($1); }
| expr_getdvarfloat { $$ = std::move($1); }
| expr_getdvarint { $$ = std::move($1); }
| expr_getdvar { $$ = std::move($1); }
| expr_gettime { $$ = std::move($1); }
| expr_abs { $$ = std::move($1); }
| expr_vectortoangles { $$ = std::move($1); }
| expr_angleclamp180 { $$ = std::move($1); }
| expr_anglestoforward { $$ = std::move($1); }
| expr_anglestoright { $$ = std::move($1); }
| expr_anglestoup { $$ = std::move($1); }
| expr_vectorscale { $$ = std::move($1); }
| expr_isdefined { $$ = 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_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_hash { $$ = 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
{ $$ = expr_complement::make(@$, std::move($2)); }
;
expr_negate
: SUB expr_identifier %prec NEG
{ $$ = expr_negate::make(@$, std::move($2)); }
| SUB expr_paren %prec NEG
{ $$ = expr_negate::make(@$, std::move($2)); }
| SUB expr_array %prec NEG
{ $$ = expr_negate::make(@$, std::move($2)); }
| SUB expr_field %prec NEG
{ $$ = expr_negate::make(@$, std::move($2)); }
;
expr_not
: NOT expr
{ $$ = expr_not::make(@$, std::move($2)); }
;
expr_call
: expr_function { $$ = expr_call::make(@$, std::move($1)); }
| expr_pointer { $$ = expr_call::make(@$, std::move($1)); }
;
expr_method
: expr_object expr_function
{
if ($1->loc().begin.line != $2->loc().begin.line)
error($2->loc(), "missing ';' ?");
$$ = expr_method::make(@$, std::move($1), std::move($2));
}
| expr_object expr_pointer
{
if ($1->loc().begin.line != $2->loc().begin.line)
error($2->loc(), "missing ';' ?");
$$ = expr_method::make(@$, std::move($1), std::move($2));
}
;
expr_function
: expr_identifier LPAREN expr_arguments RPAREN
{ $$ = expr_function::make(@$, expr_path::make(@$), std::move($1), std::move($3), call::mode::normal); }
| expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN
{ $$ = expr_function::make(@$, std::move($1), std::move($3), std::move($5), call::mode::normal); }
| THREAD expr_identifier LPAREN expr_arguments RPAREN
{ $$ = 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
{ $$ = expr_function::make(@$, std::move($2), std::move($4), std::move($6), call::mode::thread); }
;
expr_pointer
: LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
{ $$ = expr_pointer::make(@$, std::move($3), std::move($7), call::mode::normal); }
| THREAD LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
{ $$ = expr_pointer::make(@$, std::move($4), std::move($8), 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(std::move($3)); }
| expr_parameters_default
{ $$ = expr_parameters::make(@$); $$->list.push_back(std::move($1)); }
| expr_identifier
{ $$ = expr_parameters::make(@$); $$->list.push_back(std::move($1)); }
|
{ $$ = expr_parameters::make(@$); }
;
expr_parameters_default
: expr_identifier ASSIGN expr
{ $$ = expr_assign::make(@$, std::move($1), std::move($3), expr_assign::op::eq); }
;
expr_arguments
: expr_arguments_no_empty
{ $$ = std::move($1); }
|
{ $$ = expr_arguments::make(@$); }
;
expr_arguments_no_empty
: expr_arguments COMMA expr
{ $$ = std::move($1); $$->list.push_back(std::move($3)); }
| expr
{ $$ = expr_arguments::make(@$); $$->list.push_back(std::move($1)); }
;
expr_getnextarraykey
: GETNEXTARRAYKEY LPAREN expr COMMA expr RPAREN
{ $$ = expr_getnextarraykey::make(@$, std::move($3), std::move($5)); }
;
expr_getfirstarraykey
: GETFIRSTARRAYKEY LPAREN expr RPAREN
{ $$ = expr_getfirstarraykey::make(@$, std::move($3)); }
;
expr_getdvarcoloralpha
: GETDVARCOLORALPHA LPAREN expr RPAREN
{ $$ = expr_getdvarcoloralpha::make(@$, std::move($3)); }
;
expr_getdvarcolorblue
: GETDVARCOLORBLUE LPAREN expr RPAREN
{ $$ = expr_getdvarcolorblue::make(@$, std::move($3)); }
;
expr_getdvarcolorgreen
: GETDVARCOLORGREEN LPAREN expr RPAREN
{ $$ = expr_getdvarcolorgreen::make(@$, std::move($3)); }
;
expr_getdvarcolorred
: GETDVARCOLORRED LPAREN expr RPAREN
{ $$ = expr_getdvarcolorred::make(@$, std::move($3)); }
;
expr_getdvarvector
: GETDVARVECTOR LPAREN expr RPAREN
{ $$ = expr_getdvarvector::make(@$, std::move($3)); }
;
expr_getdvarfloat
: GETDVARFLOAT LPAREN expr RPAREN
{ $$ = expr_getdvarfloat::make(@$, std::move($3)); }
;
expr_getdvarint
: GETDVARINT LPAREN expr RPAREN
{ $$ = expr_getdvarint::make(@$, std::move($3)); }
;
expr_getdvar
: GETDVAR LPAREN expr RPAREN
{ $$ = expr_getdvar::make(@$, std::move($3)); }
;
expr_gettime
: GETTIME LPAREN RPAREN
{ $$ = expr_gettime::make(@$); }
;
expr_abs
: ABS LPAREN expr RPAREN
{ $$ = expr_abs::make(@$, std::move($3)); }
;
expr_vectortoangles
: VECTORTOANGLES LPAREN expr RPAREN
{ $$ = expr_vectortoangles::make(@$, std::move($3)); }
;
expr_angleclamp180
: ANGLECLAMP180 LPAREN expr RPAREN
{ $$ = expr_angleclamp180::make(@$, std::move($3)); }
;
expr_anglestoforward
: ANGLESTOFORWARD LPAREN expr RPAREN
{ $$ = expr_anglestoforward::make(@$, std::move($3)); }
;
expr_anglestoright
: ANGLESTORIGHT LPAREN expr RPAREN
{ $$ = expr_anglestoright::make(@$, std::move($3)); }
;
expr_anglestoup
: ANGLESTOUP LPAREN expr RPAREN
{ $$ = expr_anglestoup::make(@$, std::move($3)); }
;
expr_vectorscale
: VECTORSCALE LPAREN expr COMMA expr RPAREN
{ $$ = expr_vectorscale::make(@$, std::move($3), std::move($5)); }
;
expr_isdefined
: ISDEFINED LPAREN expr RPAREN
{ $$ = expr_isdefined::make(@$, std::move($3)); }
;
expr_reference
: DOUBLECOLON expr_identifier
{ $$ = expr_reference::make(@$, expr_path::make(@$), std::move($2)); }
| expr_path DOUBLECOLON expr_identifier
{ $$ = expr_reference::make(@$, std::move($1), std::move($3)); }
;
expr_array
: expr_object LBRACKET expr RBRACKET
{ $$ = expr_array::make(@$, std::move($1), std::move($3)); }
| expr_getdvarvector LBRACKET expr RBRACKET
{ $$ = expr_array::make(@$, std::move($1), std::move($3)); }
| expr_vectortoangles LBRACKET expr RBRACKET
{ $$ = expr_array::make(@$, std::move($1), std::move($3)); }
| expr_angleclamp180 LBRACKET expr RBRACKET
{ $$ = expr_array::make(@$, std::move($1), std::move($3)); }
| expr_anglestoforward LBRACKET expr RBRACKET
{ $$ = expr_array::make(@$, std::move($1), std::move($3)); }
| expr_anglestoright LBRACKET expr RBRACKET
{ $$ = expr_array::make(@$, std::move($1), std::move($3)); }
| expr_anglestoup LBRACKET expr RBRACKET
{ $$ = expr_array::make(@$, std::move($1), std::move($3)); }
| expr_vectorscale LBRACKET expr RBRACKET
{ $$ = expr_array::make(@$, std::move($1), std::move($3)); }
;
expr_field
: expr_object DOT expr_identifier_nosize
{ $$ = expr_field::make(@$, std::move($1), std::move($3)); }
;
expr_size
: expr_object DOT SIZE %prec SIZEOF
{ $$ = expr_size::make(@$, std::move($1)); }
| expr_string DOT SIZE %prec SIZEOF
{ $$ = expr_size::make(@$, std::move($1)); }
;
expr_paren
: LPAREN expr RPAREN
{ $$ = expr_paren::make(@$, std::move($2)); }
;
expr_object
: 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_empty_array
: LBRACKET RBRACKET
{ $$ = expr_empty_array::make(@$); };
;
expr_undefined
: UNDEFINED
{ $$ = expr_undefined::make(@$); };
;
expr_game
: GAME
{ $$ = expr_game::make(@$); };
;
expr_self
: SELF
{ $$ = expr_self::make(@$); };
;
expr_anim
: ANIM
{ $$ = expr_anim::make(@$); };
;
expr_level
: LEVEL
{ $$ = expr_level::make(@$); };
;
expr_animation
: MOD IDENTIFIER %prec ANIMREF
{ $$ = expr_animation::make(@$, $2); };
;
expr_animtree
: ANIMTREE
{ $$ = expr_animtree::make(@$); };
;
expr_identifier_nosize
: IDENTIFIER
{ $$ = expr_identifier::make(@$, $1); };
;
expr_identifier
: IDENTIFIER
{ $$ = expr_identifier::make(@$, $1); };
| SIZE
{ $$ = expr_identifier::make(@$, "size"); };
;
expr_path
: IDENTIFIER
{ $$ = expr_path::make(@$, $1); };
| PATH
{ $$ = expr_path::make(@$, $1); };
;
expr_istring
: ISTRING
{ $$ = expr_istring::make(@$, $1); };
;
expr_string
: STRING
{ $$ = expr_string::make(@$, $1); };
;
expr_vector
: LPAREN expr COMMA expr COMMA expr RPAREN
{ $$ = expr_vector::make(@$, std::move($2), std::move($4), std::move($6)); };
;
expr_hash
: HASHSTR
{ $$ = expr_hash::make(@$, $1); };
;
expr_float
: SUB FLOAT %prec NEG
{ $$ = expr_float::make(@$, "-" + $2); };
| FLOAT
{ $$ = expr_float::make(@$, $1); };
;
expr_integer
: SUB INTEGER %prec NEG
{ $$ = expr_integer::make(@$, "-" + $2); };
| INTEGER
{ $$ = expr_integer::make(@$, $1); };
;
expr_false
: FALSE
{ $$ = expr_false::make(@$); };
;
expr_true
: TRUE
{ $$ = expr_true::make(@$); };
;
%%
namespace xsk::arc
{
void parser::error(location const& loc, std::string const& msg)
{
throw comp_error(loc, msg);
}
auto parse_switch(stmt_switch& stm) -> void
{
auto body = stmt_list::make(stm.body->block->loc());
auto curr = stmt::ptr{ nullptr };
auto num = stm.body->block->list.size();
for (auto i = 0u; i < num; i++)
{
auto& entry = stm.body->block->list[0];
if (entry->is<stmt_case>() || entry->is<stmt_default>())
{
if (curr != nullptr)
{
body->list.push_back(std::move(curr));
}
curr = std::move(stm.body->block->list[0]);
stm.body->block->list.erase(stm.body->block->list.begin());
}
else
{
if (curr != nullptr)
{
if (curr->is<stmt_case>())
{
curr->as<stmt_case>().body->list.push_back(std::move(entry));
stm.body->block->list.erase(stm.body->block->list.begin());
}
else
{
curr->as<stmt_default>().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");
}
}
}
if (curr != nullptr)
{
body->list.push_back(std::move(curr));
}
stm.body->block = std::move(body);
}
extern std::unordered_map<token::kind, parser::token::token_kind_type> const tok_to_parser;
extern std::unordered_map<std::string_view, parser::token::token_kind_type> const keyword_map;
auto map_token(context const* ctx_, token& tok) -> parser::symbol_type
{
if (tok.type == token::NAME)
{
tok.data = ctx_->make_token(tok.data);
auto const it = keyword_map.find(tok.data);
if (it != keyword_map.end())
{
return parser::symbol_type(it->second, tok.pos);
}
return parser::symbol_type(parser::token::IDENTIFIER, std::move(tok.data), tok.pos);
}
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);
if (it != tok_to_parser.end())
{
return parser::symbol_type(it->second, std::move(tok.data), tok.pos);
}
}
else
{
auto it = tok_to_parser.find(tok.type);
if (it != tok_to_parser.end())
{
return parser::symbol_type(it->second, tok.pos);
}
}
throw error(fmt::format("unmapped token! {}", (u8)tok.type));
}
auto ARClex(context const* ctx_, preprocessor& ppr) -> parser::symbol_type
{
auto tok = ppr.process();
return map_token(ctx_, tok);
}
std::unordered_map<token::kind, parser::token::token_kind_type> const tok_to_parser
{{
{ token::NAME, parser::token::IDENTIFIER },
{ token::PATH, parser::token::PATH },
{ token::STRING, parser::token::STRING },
{ token::ISTRING, parser::token::ISTRING },
{ token::HASHSTR, parser::token::HASHSTR },
{ token::INT, parser::token::INTEGER },
{ token::FLT, parser::token::FLOAT },
{ token::PLUS, parser::token::ADD },
{ token::MINUS, parser::token::SUB },
{ token::STAR, parser::token::MUL },
{ token::DIV, parser::token::DIV },
{ token::MOD, parser::token::MOD },
{ token::BITOR, parser::token::BITWISE_OR },
{ token::BITAND, parser::token::BITWISE_AND },
{ token::BITEXOR, parser::token::BITWISE_EXOR },
{ token::ASSIGN, parser::token::ASSIGN },
{ token::PLUSEQ, parser::token::ASSIGN_ADD },
{ token::MINUSEQ, parser::token::ASSIGN_SUB },
{ token::STAREQ, parser::token::ASSIGN_MUL },
{ token::DIVEQ, parser::token::ASSIGN_DIV },
{ token::MODEQ, parser::token::ASSIGN_MOD },
{ token::BITOREQ, parser::token::ASSIGN_BW_OR },
{ token::BITANDEQ, parser::token::ASSIGN_BW_AND },
{ token::BITEXOREQ, parser::token::ASSIGN_BW_EXOR },
{ token::SHLEQ, parser::token::ASSIGN_LSHIFT },
{ token::SHREQ, parser::token::ASSIGN_RSHIFT },
{ token::TILDE, parser::token::COMPLEMENT },
{ token::BANG, parser::token::NOT },
{ token::GT, parser::token::GREATER },
{ token::LT, parser::token::LESS },
{ token::GE, parser::token::GREATER_EQUAL },
{ token::LE, parser::token::LESS_EQUAL },
{ token::NE, parser::token::INEQUALITY },
{ token::EQ, parser::token::EQUALITY },
{ token::OR, parser::token::OR },
{ token::AND, parser::token::AND },
{ token::SHL, parser::token::LSHIFT },
{ token::SHR, parser::token::RSHIFT },
{ token::INC, parser::token::INCREMENT },
{ token::DEC, parser::token::DECREMENT },
{ token::QMARK, parser::token::QMARK },
{ token::DOT, parser::token::DOT },
{ token::DOUBLEDOT, parser::token::DOUBLEDOT },
{ token::ELLIPSIS, parser::token::ELLIPSIS },
{ token::COMMA, parser::token::COMMA },
{ token::COLON, parser::token::COLON },
{ token::SEMICOLON, parser::token::SEMICOLON },
{ token::DOUBLECOLON, parser::token::DOUBLECOLON },
{ token::LBRACKET, parser::token::LBRACKET },
{ token::RBRACKET, parser::token::RBRACKET },
{ token::LBRACE, parser::token::LBRACE },
{ token::RBRACE, parser::token::RBRACE },
{ token::LPAREN, parser::token::LPAREN },
{ token::RPAREN, parser::token::RPAREN },
{ token::DEVBEGIN, parser::token::DEVBEGIN },
{ token::DEVEND, parser::token::DEVEND },
{ token::INLINE, parser::token::INLINE },
{ token::INCLUDE, parser::token::INCLUDE },
{ token::USINGTREE, parser::token::USINGTREE },
{ token::ANIMTREE, parser::token::ANIMTREE },
{ token::AUTOEXEC, parser::token::AUTOEXEC },
{ token::CODECALL, parser::token::CODECALL },
{ token::PRIVATE, parser::token::PRIVATE },
{ token::ENDON, parser::token::ENDON },
{ token::NOTIFY, parser::token::NOTIFY },
{ token::WAIT, parser::token::WAIT },
{ token::WAITREALTIME, parser::token::WAITREALTIME },
{ token::WAITTILL, parser::token::WAITTILL },
{ token::WAITTILLMATCH, parser::token::WAITTILLMATCH },
{ token::WAITTILLFRAMEEND, parser::token::WAITTILLFRAMEEND },
{ token::IF, parser::token::IF },
{ token::ELSE, parser::token::ELSE },
{ token::DO, parser::token::DO },
{ token::WHILE, parser::token::WHILE },
{ token::FOR, parser::token::FOR },
{ token::FOREACH, parser::token::FOREACH },
{ token::IN, parser::token::IN },
{ token::SWITCH, parser::token::SWITCH },
{ token::CASE, parser::token::CASE },
{ token::DEFAULT, parser::token::DEFAULT },
{ token::BREAK, parser::token::BREAK },
{ token::CONTINUE, parser::token::CONTINUE },
{ token::RETURN, parser::token::RETURN },
{ token::PROFBEGIN, parser::token::PROFBEGIN },
{ token::PROFEND, parser::token::PROFEND },
{ token::THREAD, parser::token::THREAD },
{ token::TRUE, parser::token::TRUE },
{ token::FALSE, parser::token::FALSE },
{ token::UNDEFINED, parser::token::UNDEFINED },
{ token::SIZE, parser::token::SIZE },
{ token::GAME, parser::token::GAME },
{ token::SELF, parser::token::SELF },
{ token::ANIM, parser::token::ANIM },
{ token::LEVEL, parser::token::LEVEL },
{ token::CONST, parser::token::CONST },
{ token::ISDEFINED, parser::token::ISDEFINED },
{ token::VECTORSCALE, parser::token::VECTORSCALE },
{ token::ANGLESTOUP, parser::token::ANGLESTOUP },
{ token::ANGLESTORIGHT, parser::token::ANGLESTORIGHT },
{ token::ANGLESTOFORWARD, parser::token::ANGLESTOFORWARD },
{ token::ANGLECLAMP180, parser::token::ANGLECLAMP180 },
{ token::VECTORTOANGLES, parser::token::VECTORTOANGLES },
{ token::ABS, parser::token::ABS },
{ token::GETTIME, parser::token::GETTIME },
{ token::GETDVAR, parser::token::GETDVAR },
{ token::GETDVARINT, parser::token::GETDVARINT },
{ token::GETDVARFLOAT, parser::token::GETDVARFLOAT },
{ token::GETDVARVECTOR, parser::token::GETDVARVECTOR },
{ token::GETDVARCOLORRED, parser::token::GETDVARCOLORRED },
{ token::GETDVARCOLORGREEN, parser::token::GETDVARCOLORGREEN },
{ token::GETDVARCOLORBLUE, parser::token::GETDVARCOLORBLUE },
{ token::GETDVARCOLORALPHA, parser::token::GETDVARCOLORALPHA },
{ token::GETFIRSTARRAYKEY, parser::token::GETFIRSTARRAYKEY },
{ token::GETNEXTARRAYKEY, parser::token::GETNEXTARRAYKEY },
{ token::EOS, parser::token::ARCEOF },
{ token::HASH, parser::token::HASH }
}};
std::unordered_map<std::string_view, parser::token::token_kind_type> const keyword_map
{{
{ "autoexec", parser::token::AUTOEXEC },
{ "codecall", parser::token::CODECALL },
{ "private", parser::token::PRIVATE },
{ "endon", parser::token::ENDON },
{ "notify", parser::token::NOTIFY },
{ "wait", parser::token::WAIT },
{ "waitrealtime", parser::token::WAITREALTIME},
{ "waittill", parser::token::WAITTILL },
{ "waittillmatch", parser::token::WAITTILLMATCH },
{ "waittillframeend", parser::token::WAITTILLFRAMEEND },
{ "if", parser::token::IF },
{ "else", parser::token::ELSE },
{ "do", parser::token::DO },
{ "while", parser::token::WHILE },
{ "for", parser::token::FOR },
{ "foreach", parser::token::FOREACH },
{ "in", parser::token::IN },
{ "switch", parser::token::SWITCH },
{ "case", parser::token::CASE },
{ "default", parser::token::DEFAULT },
{ "break", parser::token::BREAK },
{ "continue", parser::token::CONTINUE },
{ "return", parser::token::RETURN },
{ "prof_begin", parser::token::PROFBEGIN },
{ "prof_end", parser::token::PROFEND },
{ "thread", parser::token::THREAD },
{ "true", parser::token::TRUE },
{ "false", parser::token::FALSE },
{ "undefined", parser::token::UNDEFINED },
{ "size", parser::token::SIZE },
{ "game", parser::token::GAME },
{ "self", parser::token::SELF },
{ "anim", parser::token::ANIM },
{ "level", parser::token::LEVEL },
{ "const", parser::token::CONST },
{ "isdefined", parser::token::ISDEFINED },
{ "vectorscale", parser::token::VECTORSCALE },
{ "anglestoup", parser::token::ANGLESTOUP },
{ "anglestoright", parser::token::ANGLESTORIGHT },
{ "anglestoforward", parser::token::ANGLESTOFORWARD },
{ "angleclamp180", parser::token::ANGLECLAMP180 },
{ "vectortoangles", parser::token::VECTORTOANGLES },
{ "abs", parser::token::ABS },
{ "gettime", parser::token::GETTIME },
{ "getdvar", parser::token::GETDVAR },
{ "getdvarint", parser::token::GETDVARINT },
{ "getdvarfloat", parser::token::GETDVARFLOAT },
{ "getdvarvector", parser::token::GETDVARVECTOR },
{ "getdvarcolorred", parser::token::GETDVARCOLORRED },
{ "getdvarcolorgreen", parser::token::GETDVARCOLORGREEN },
{ "getdvarcolorblue", parser::token::GETDVARCOLORBLUE },
{ "getdvarcoloralpha", parser::token::GETDVARCOLORALPHA },
{ "getfirstarraykey", parser::token::GETFIRSTARRAYKEY },
{ "getnextarraykey", parser::token::GETNEXTARRAYKEY },
}};
} // namespace xsk::arc