feat: add if, else, return, break, continue and compounds stat
This commit is contained in:
parent
ec2d29ef18
commit
7a98dfa825
@ -78,5 +78,6 @@ namespace ppc::comp::tree::ast {
|
|||||||
|
|
||||||
parser_func_t parse_glob, parse_nmsp, parse_identifier, parse_type, parse_exp, parse_stat_exp;
|
parser_func_t parse_glob, parse_nmsp, parse_identifier, parse_type, parse_exp, parse_stat_exp;
|
||||||
parser_func_t parse_func, parse_field, parse_export;
|
parser_func_t parse_func, parse_field, parse_export;
|
||||||
|
parser_func_t parse_if, parse_while, parse_return, parse_break, parse_continue, parse_stat_comp;
|
||||||
parser_func_t parse_exp_var, parse_exp_str_lit, parse_exp_int_lit, parse_exp_float_lit;
|
parser_func_t parse_exp_var, parse_exp_str_lit, parse_exp_int_lit, parse_exp_float_lit;
|
||||||
}
|
}
|
@ -17,6 +17,12 @@ ast_ctx_t::ast_ctx_t(msg_stack_t &messages, std::vector<token_t> &tokens): messa
|
|||||||
.add_last("$_string", parse_exp_str_lit);
|
.add_last("$_string", parse_exp_str_lit);
|
||||||
// .add_last("$_float", parse_exp_float_lit)
|
// .add_last("$_float", parse_exp_float_lit)
|
||||||
group("$_stat")
|
group("$_stat")
|
||||||
|
.add_named("$_while", parse_while, { "while" })
|
||||||
|
.add_named("$_if", parse_if, { "if" })
|
||||||
|
.add_named("$_return", parse_return, { "return" })
|
||||||
|
.add_named("$_break", parse_break, { "break" })
|
||||||
|
.add_named("$_continue", parse_continue, { "continue" })
|
||||||
|
.add_last("$_comp", parse_stat_comp)
|
||||||
.add_last("$_exp", parse_stat_exp);
|
.add_last("$_exp", parse_stat_exp);
|
||||||
group("$_def")
|
group("$_def")
|
||||||
.add_last("$_func", parse_func)
|
.add_last("$_func", parse_func)
|
||||||
|
98
src/compiler/treeifier/ast/parsers/stat.cc
Normal file
98
src/compiler/treeifier/ast/parsers/stat.cc
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
#include "compiler/treeifier/ast/helper.hh"
|
||||||
|
|
||||||
|
bool ast::parse_if(ast_ctx_t &ctx, size_t &res_i, map_t &out) {
|
||||||
|
tree_helper_t h(ctx, res_i);
|
||||||
|
|
||||||
|
h.throw_ended();
|
||||||
|
if (!h.curr("Expected open parens after if keyword.").is_operator(operator_t::PAREN_OPEN)) {
|
||||||
|
throw message_t::error("Expected open parens after if keyword.", h.loc(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
h.advance("Expected an expression.");
|
||||||
|
h.force_parse(parse_exp, "Expected an expression.", out["condition"].map({}));
|
||||||
|
|
||||||
|
if (!h.curr("Expected closed parens.").is_operator(operator_t::PAREN_CLOSE)) {
|
||||||
|
throw message_t::error("Expected closed parens.", h.loc(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
h.advance("Expected a statement.");
|
||||||
|
h.force_parse(ctx.group("$_stat"), "Expected a statement.", out["if"].map({}));
|
||||||
|
|
||||||
|
if (h.ended() || !h.curr().is_identifier("else")) return h.submit(false);
|
||||||
|
|
||||||
|
h.advance("Expected a statement.");
|
||||||
|
h.force_parse(ctx.group("$_stat"), "Expected a statement.", out["else"].map({}));
|
||||||
|
|
||||||
|
return h.submit(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ast::parse_while(ast_ctx_t &ctx, size_t &res_i, map_t &out) {
|
||||||
|
tree_helper_t h(ctx, res_i);
|
||||||
|
|
||||||
|
h.throw_ended();
|
||||||
|
if (!h.curr("Expected open parens after while keyword.").is_operator(operator_t::PAREN_OPEN)) {
|
||||||
|
throw message_t::error("Expected open parens after while keyword.", h.loc(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
h.advance("Expected an expression.");
|
||||||
|
h.force_parse(parse_exp, "Expected an expression.", out["condition"].map({}));
|
||||||
|
|
||||||
|
if (!h.curr("Expected closed parens.").is_operator(operator_t::PAREN_CLOSE)) {
|
||||||
|
throw message_t::error("Expected closed parens.", h.loc(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
h.advance("Expected a statement.");
|
||||||
|
h.force_parse(ctx.group("$_stat"), "Expected a statement.", out["while"].map({}));
|
||||||
|
|
||||||
|
return h.submit(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ast::parse_return(ast_ctx_t &ctx, size_t &res_i, map_t &out) {
|
||||||
|
tree_helper_t h(ctx, res_i);
|
||||||
|
|
||||||
|
h.advance("Expected an expression.");
|
||||||
|
h.force_parse(parse_exp, "Expected an expression.", out["condition"].map({}));
|
||||||
|
|
||||||
|
if (!h.curr("Expected a semicolon.").is_operator(operator_t::SEMICOLON)) {
|
||||||
|
throw message_t::error("Expected a semicolon.", h.loc(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
return h.submit(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ast::parse_break(ast_ctx_t &ctx, size_t &res_i, map_t &out) {
|
||||||
|
tree_helper_t h(ctx, res_i);
|
||||||
|
|
||||||
|
if (!h.curr("Expected a semicolon.").is_operator(operator_t::SEMICOLON)) {
|
||||||
|
throw message_t::error("Expected a semicolon.", h.loc(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
return h.submit(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ast::parse_continue(ast_ctx_t &ctx, size_t &res_i, map_t &out) {
|
||||||
|
tree_helper_t h(ctx, res_i);
|
||||||
|
|
||||||
|
if (!h.curr("Expected a semicolon.").is_operator(operator_t::SEMICOLON)) {
|
||||||
|
throw message_t::error("Expected a semicolon.", h.loc(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
return h.submit(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ast::parse_stat_comp(ast_ctx_t &ctx, size_t &res_i, map_t &out) {
|
||||||
|
tree_helper_t h(ctx, res_i);
|
||||||
|
|
||||||
|
if (h.ended()) return false;
|
||||||
|
if (!h.curr().is_operator(operator_t::BRACE_OPEN)) return false;
|
||||||
|
h.advance("Expected a statement or a closing brace.");
|
||||||
|
|
||||||
|
auto &content = out["content"].array({});
|
||||||
|
|
||||||
|
while (!h.curr().is_operator(operator_t::BRACE_CLOSE)) {
|
||||||
|
h.throw_ended("Expected a statement or a closing brace.");
|
||||||
|
h.push_parse(ctx.group("$_stat"), content);
|
||||||
|
}
|
||||||
|
|
||||||
|
return h.submit(true);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user