feature(parser): deprecate constants & add asserts (#52)

This commit is contained in:
Xenxo Espasandín 2023-02-01 16:39:46 +01:00 committed by GitHub
parent d73793833e
commit df8f74bbce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 2532 additions and 1972 deletions

View File

@ -80,6 +80,9 @@ namespace xsk::gsc
%token BREAKPOINT "breakpoint"
%token PROFBEGIN "prof_begin"
%token PROFEND "prof_end"
%token ASSERT "assert"
%token ASSERTEX "assertex"
%token ASSERTMSG "assertmsg"
%token THREAD "thread"
%token CHILDTHREAD "childthread"
%token THISTHREAD "thisthread"
@ -151,6 +154,7 @@ namespace xsk::gsc
%type <include::ptr> include
%type <decl> declaration
%type <decl_usingtree::ptr> decl_usingtree
%type <decl_constant::ptr> decl_constant
%type <decl_function::ptr> decl_function
%type <stmt> stmt
%type <stmt> stmt_or_dev
@ -183,6 +187,9 @@ namespace xsk::gsc
%type <stmt_breakpoint::ptr> stmt_breakpoint
%type <stmt_prof_begin::ptr> stmt_prof_begin
%type <stmt_prof_end::ptr> stmt_prof_end
%type <stmt_assert::ptr> stmt_assert
%type <stmt_assertex::ptr> stmt_assertex
%type <stmt_assertmsg::ptr> stmt_assertmsg
%type <expr> expr
%type <expr> expr_or_empty
%type <expr> expr_assign
@ -296,6 +303,7 @@ 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); }
;
@ -304,6 +312,14 @@ decl_usingtree
{ ppr.ban_header(@$); $$ = make_decl_usingtree(@$, std::move($3)); }
;
decl_constant
: expr_identifier ASSIGN expr SEMICOLON
{
ppr.ban_header(@$); $$ = make_decl_constant(@$, 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)); }
@ -335,6 +351,9 @@ stmt
| 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_or_dev
@ -534,6 +553,21 @@ stmt_prof_end
{ $$ = make_stmt_prof_end(@$, std::move($3)); }
;
stmt_assert
: ASSERT LPAREN expr_arguments RPAREN SEMICOLON
{ $$ = make_stmt_assert(@$, std::move($3)); }
;
stmt_assertex
: ASSERTEX LPAREN expr_arguments RPAREN SEMICOLON
{ $$ = make_stmt_assertex(@$, std::move($3)); }
;
stmt_assertmsg
: ASSERTMSG LPAREN expr_arguments RPAREN SEMICOLON
{ $$ = make_stmt_assertmsg(@$, std::move($3)); }
;
expr
: expr_ternary { $$ = std::move($1); }
| expr_binary { $$ = std::move($1); }
@ -1126,6 +1160,9 @@ std::unordered_map<token::kind, parser::token::token_kind_type> const tok_to_par
{ token::BREAKPOINT, parser::token::BREAKPOINT },
{ token::PROFBEGIN, parser::token::PROFBEGIN },
{ token::PROFEND, parser::token::PROFEND },
{ token::ASSERT, parser::token::ASSERT },
{ token::ASSERTEX, parser::token::ASSERTEX },
{ token::ASSERTMSG, parser::token::ASSERTMSG },
{ token::THREAD, parser::token::THREAD },
{ token::CHILDTHREAD, parser::token::CHILDTHREAD },
{ token::THISTHREAD, parser::token::THISTHREAD },
@ -1169,6 +1206,9 @@ std::unordered_map<std::string_view, parser::token::token_kind_type> const keywo
{ "breakpoint", parser::token::BREAKPOINT },
{ "prof_begin", parser::token::PROFBEGIN },
{ "prof_end", parser::token::PROFEND },
{ "assert", parser::token::ASSERT },
{ "assertex", parser::token::ASSERTEX },
{ "assertmsg", parser::token::ASSERTMSG },
{ "thread", parser::token::THREAD },
{ "childthread", parser::token::CHILDTHREAD },
{ "thisthread", parser::token::THISTHREAD },

View File

@ -30,6 +30,7 @@ auto compiler::emit_program(program const& prog) -> void
{
assembly_ = make_assembly();
localfuncs_.clear();
constants_.clear();
developer_thread_ = false;
animload_ = false;
animname_ = {};
@ -87,6 +88,9 @@ auto compiler::emit_decl(decl const& dec) -> void
case node::decl_usingtree:
emit_decl_usingtree(*dec.as_usingtree);
break;
case node::decl_constant:
emit_decl_constant(*dec.as_constant);
break;
case node::decl_function:
emit_decl_function(*dec.as_function);
break;
@ -104,6 +108,16 @@ auto compiler::emit_decl_usingtree(decl_usingtree const& animtree) -> void
animload_ = false;
}
auto compiler::emit_decl_constant(decl_constant const& constant) -> void
{
auto const it = constants_.find(constant.name->value);
if (it != constants_.end())
throw comp_error(constant.loc(), fmt::format("duplicated constant '{}'", constant.name->value));
constants_.insert({ constant.name->value, &constant.value });
}
auto compiler::emit_decl_function(decl_function const& func) -> void
{
label_idx_ = 0;
@ -218,6 +232,15 @@ auto compiler::emit_stmt(stmt const& stm, scope& scp, bool last) -> void
case node::stmt_prof_end:
emit_stmt_prof_end(*stm.as_prof_end, scp);
break;
case node::stmt_assert:
emit_stmt_assert(*stm.as_assert, scp);
break;
case node::stmt_assertex:
emit_stmt_assertex(*stm.as_assertex, scp);
break;
case node::stmt_assertmsg:
emit_stmt_assertmsg(*stm.as_assertmsg, scp);
break;
default:
throw comp_error(stm.loc(), "unknown statement");
}
@ -939,6 +962,21 @@ auto compiler::emit_stmt_prof_end(stmt_prof_end const&, scope&) -> void
// TODO:
}
auto compiler::emit_stmt_assert(stmt_assert const&, scope&) -> void
{
// TODO:
}
auto compiler::emit_stmt_assertex(stmt_assertex const&, scope&) -> void
{
// TODO:
}
auto compiler::emit_stmt_assertmsg(stmt_assertmsg const&, scope&) -> void
{
// TODO:
}
auto compiler::emit_expr(expr const& exp, scope& scp) -> void
{
switch (exp.kind())
@ -1378,12 +1416,6 @@ auto compiler::emit_expr_call_pointer(expr_pointer const& exp, scope& scp, bool
auto compiler::emit_expr_call_function(expr_function const& exp, scope& scp, bool is_stmt) -> void
{
if (is_stmt && ctx_->build() == build::prod)
{
auto const& name = exp.name->value;
if (name == "assert" || name == "assertex" || name == "assertmsg") return;
}
auto path = std::string{};
auto type = resolve_function_type(exp, path);
@ -1869,6 +1901,13 @@ auto compiler::emit_expr_field_ref(expr_field const& exp, scope& scp, bool set)
auto compiler::emit_expr_local_ref(expr_identifier const& exp, scope& scp, bool set) -> void
{
auto const it = constants_.find(exp.value);
if (it != constants_.end())
{
throw comp_error(exp.loc(), fmt::format("variable name already defined as constant '{}'", exp.value));
}
if (set)
{
if (!variable_initialized(exp, scp))
@ -1976,6 +2015,15 @@ auto compiler::emit_expr_field(expr_field const& exp, scope& scp) -> void
auto compiler::emit_expr_local(expr_identifier const& exp, scope& scp) -> void
{
auto const it = constants_.find(exp.value);
if (it != constants_.end())
{
// should only allow: string, loc string, number, vector
emit_expr(*it->second, scp);
return;
}
auto index = variable_access(exp, scp);
switch (index)
@ -2333,6 +2381,9 @@ auto compiler::process_stmt(stmt const& stm, scope& scp) -> void
case node::stmt_breakpoint:
case node::stmt_prof_begin:
case node::stmt_prof_end:
case node::stmt_assert:
case node::stmt_assertex:
case node::stmt_assertmsg:
break;
default:
throw comp_error(stm.loc(), "unknown statement");

View File

@ -17,6 +17,7 @@ class compiler
function::ptr function_;
std::vector<std::string> stackframe_;
std::vector<std::string> localfuncs_;
std::unordered_map<std::string, expr const*> constants_;
std::unordered_map<node*, scope::ptr> scopes_;
std::vector<scope*> break_blks_;
std::vector<scope*> continue_blks_;
@ -37,6 +38,7 @@ private:
auto emit_program(program const& prog) -> void;
auto emit_decl(decl const& dec) -> void;
auto emit_decl_usingtree(decl_usingtree const& animtree) -> void;
auto emit_decl_constant(decl_constant const& constant) -> void;
auto emit_decl_function(decl_function const& func) -> void;
auto emit_stmt(stmt const& stm, scope& scp, bool last) -> void;
auto emit_stmt_list(stmt_list const& stm, scope& scp, bool last) -> void;
@ -67,6 +69,9 @@ private:
auto emit_stmt_breakpoint(stmt_breakpoint const& stm, scope& scp) -> void;
auto emit_stmt_prof_begin(stmt_prof_begin const& stm, scope& scp) -> void;
auto emit_stmt_prof_end(stmt_prof_end const& stm, scope& scp) -> void;
auto emit_stmt_assert(stmt_assert const& stm, scope& scp) -> void;
auto emit_stmt_assertex(stmt_assertex const& stm, scope& scp) -> void;
auto emit_stmt_assertmsg(stmt_assertmsg const& stm, scope& scp) -> void;
auto emit_expr(expr const& exp, scope& scp) -> void;
auto emit_expr_assign(expr_assign const& exp, scope& scp) -> void;
auto emit_expr_clear(expr const& exp, scope& scp) -> void;

View File

@ -530,10 +530,26 @@ stmt_prof_end::stmt_prof_end(location const& loc, expr_arguments::ptr args) : no
{
}
stmt_assert::stmt_assert(location const& loc, expr_arguments::ptr args) : node{ type::stmt_assert, loc }, args{ std::move(args) }
{
}
stmt_assertex::stmt_assertex(location const& loc, expr_arguments::ptr args) : node{ type::stmt_assertex, loc }, args{ std::move(args) }
{
}
stmt_assertmsg::stmt_assertmsg(location const& loc, expr_arguments::ptr args) : node{ type::stmt_assertmsg, loc }, args{ std::move(args) }
{
}
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_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_usingtree::decl_usingtree(location const& loc, expr_string::ptr name) : node{ type::decl_usingtree, loc }, name{ std::move(name) }
{
}
@ -985,6 +1001,9 @@ stmt::~stmt()
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;
@ -1047,6 +1066,7 @@ decl::~decl()
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;
}

View File

@ -111,7 +111,11 @@ struct node
stmt_breakpoint,
stmt_prof_begin,
stmt_prof_end,
stmt_assert,
stmt_assertex,
stmt_assertmsg,
decl_function,
decl_constant,
decl_usingtree,
decl_dev_begin,
decl_dev_end,
@ -256,7 +260,11 @@ 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;
@ -419,6 +427,9 @@ union stmt
std::unique_ptr<stmt_breakpoint> as_breakpoint;
std::unique_ptr<stmt_prof_begin> as_prof_begin;
std::unique_ptr<stmt_prof_end> as_prof_end;
std::unique_ptr<stmt_assert> as_assert;
std::unique_ptr<stmt_assertex> as_assertex;
std::unique_ptr<stmt_assertmsg> as_assertmsg;
std::unique_ptr<asm_jmp_cond> as_cond;
std::unique_ptr<asm_jmp> as_jump;
std::unique_ptr<asm_jmp_back> as_jump_back;
@ -448,6 +459,7 @@ union decl
std::unique_ptr<decl_dev_begin> as_dev_begin;
std::unique_ptr<decl_dev_end> as_dev_end;
std::unique_ptr<decl_usingtree> as_usingtree;
std::unique_ptr<decl_constant> as_constant;
std::unique_ptr<decl_function> as_function;
decl();
@ -1323,6 +1335,33 @@ struct stmt_prof_end : public node
stmt_prof_end(location const& loc, expr_arguments::ptr args);
};
struct stmt_assert : public node
{
using ptr = std::unique_ptr<stmt_assert>;
expr_arguments::ptr args;
stmt_assert(location const& loc, expr_arguments::ptr args);
};
struct stmt_assertex : public node
{
using ptr = std::unique_ptr<stmt_assertex>;
expr_arguments::ptr args;
stmt_assertex(location const& loc, expr_arguments::ptr args);
};
struct stmt_assertmsg : public node
{
using ptr = std::unique_ptr<stmt_assertmsg>;
expr_arguments::ptr args;
stmt_assertmsg(location const& loc, expr_arguments::ptr args);
};
struct decl_function : public node
{
using ptr = std::unique_ptr<decl_function>;
@ -1334,6 +1373,16 @@ struct decl_function : public node
decl_function(location const& loc, expr_identifier::ptr name, expr_parameters::ptr params, stmt_comp::ptr body);
};
struct decl_constant : public node
{
using ptr = std::unique_ptr<decl_constant>;
expr_identifier::ptr name;
expr value;
decl_constant(location const& loc, expr_identifier::ptr name, expr value);
};
struct decl_usingtree : public node
{
using ptr = std::unique_ptr<decl_usingtree>;
@ -1599,7 +1648,11 @@ 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)

View File

@ -22,8 +22,8 @@ struct token
DEVBEGIN, DEVEND, INLINE, INCLUDE, USINGTREE, ANIMTREE, ENDON, NOTIFY, WAIT,
WAITTILL, WAITTILLMATCH, WAITTILLFRAMEEND, WAITFRAME, IF, ELSE, DO, WHILE,
FOR, FOREACH, IN, SWITCH, CASE, DEFAULT, BREAK, CONTINUE, RETURN, BREAKPOINT,
PROFBEGIN, PROFEND, THREAD, CHILDTHREAD, THISTHREAD, CALL, TRUE, FALSE, UNDEFINED,
SIZE, GAME, SELF, ANIM, LEVEL, ISDEFINED, ISTRUE,
PROFBEGIN, PROFEND, ASSERT, ASSERTEX, ASSERTMSG, THREAD, CHILDTHREAD, THISTHREAD,
CALL, TRUE, FALSE, UNDEFINED, SIZE, GAME, SELF, ANIM, LEVEL, ISDEFINED, ISTRUE,
HASH, NEWLINE, EOS, DEFINED, MACROBEGIN, MACROEND,
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -314,6 +314,9 @@ auto source::dump_decl(decl const& dec) -> void
case node::decl_usingtree:
dump_decl_usingtree(*dec.as_usingtree);
break;
case node::decl_constant:
dump_decl_constant(*dec.as_constant);
break;
case node::decl_function:
dump_decl_function(*dec.as_function);
break;
@ -339,6 +342,14 @@ auto source::dump_decl_usingtree(decl_usingtree const& dec) -> void
fmt::format_to(std::back_inserter(buf_), ");\n");
}
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);
fmt::format_to(std::back_inserter(buf_), ";\n");
}
auto source::dump_decl_function(decl_function const& dec) -> void
{
indent_ = 0;
@ -438,6 +449,15 @@ auto source::dump_stmt(stmt const& stm) -> void
case node::stmt_prof_end:
dump_stmt_prof_end(*stm.as_prof_end);
break;
case node::stmt_assert:
dump_stmt_assert(*stm.as_assert);
break;
case node::stmt_assertex:
dump_stmt_assertex(*stm.as_assertex);
break;
case node::stmt_assertmsg:
dump_stmt_assertmsg(*stm.as_assertmsg);
break;
case node::asm_jmp:
dump_asm_jmp(*stm.as_jump);
break;
@ -868,14 +888,35 @@ auto source::dump_stmt_prof_begin(stmt_prof_begin const& stm) -> void
{
fmt::format_to(std::back_inserter(buf_), "prof_begin(");
dump_expr_arguments(*stm.args);
fmt::format_to(std::back_inserter(buf_), ")");
fmt::format_to(std::back_inserter(buf_), ");");
}
auto source::dump_stmt_prof_end(stmt_prof_end const& stm) -> void
{
fmt::format_to(std::back_inserter(buf_), "prof_end(");
dump_expr_arguments(*stm.args);
fmt::format_to(std::back_inserter(buf_), ")");
fmt::format_to(std::back_inserter(buf_), ");");
}
auto source::dump_stmt_assert(stmt_assert const& stm) -> void
{
fmt::format_to(std::back_inserter(buf_), "assert(");
dump_expr_arguments(*stm.args);
fmt::format_to(std::back_inserter(buf_), ");");
}
auto source::dump_stmt_assertex(stmt_assertex const& stm) -> void
{
fmt::format_to(std::back_inserter(buf_), "assertex(");
dump_expr_arguments(*stm.args);
fmt::format_to(std::back_inserter(buf_), ");");
}
auto source::dump_stmt_assertmsg(stmt_assertmsg const& stm) -> void
{
fmt::format_to(std::back_inserter(buf_), "assertmsg(");
dump_expr_arguments(*stm.args);
fmt::format_to(std::back_inserter(buf_), ");");
}
auto source::dump_expr(expr const& exp) -> void

View File

@ -37,6 +37,7 @@ private:
auto dump_decl_dev_begin(decl_dev_begin const& dec) -> void;
auto dump_decl_dev_end(decl_dev_end const& dec) -> void;
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_stmt(stmt const& stm) -> void;
auto dump_stmt_list(stmt_list const& stm) -> void;
@ -67,6 +68,9 @@ private:
auto dump_stmt_breakpoint(stmt_breakpoint const& stm) -> void;
auto dump_stmt_prof_begin(stmt_prof_begin const& stm) -> void;
auto dump_stmt_prof_end(stmt_prof_end const& stm) -> void;
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_expr(expr const& exp) -> void;
auto dump_expr_increment(expr_increment const& exp) -> void;
auto dump_expr_decrement(expr_decrement const& exp) -> void;