diff options
author | Himbeer <himbeer@disroot.org> | 2024-10-07 13:32:07 +0200 |
---|---|---|
committer | Himbeer <himbeer@disroot.org> | 2024-10-07 13:32:07 +0200 |
commit | 991d4095ba596c55ef4d043a496d5cf63fd667d1 (patch) | |
tree | 81b8cbb600c8c57c00b7df01fa9cea5563de23ee /src/parse.c | |
parent | 5ba544c4e016de3d61a296ceeaf7c4a143f3c118 (diff) |
Implement expression-based language redesign
This is the implementation of commit
ce68792c848caee2f184e7a6392d9f1e958da1a1.
Diffstat (limited to 'src/parse.c')
-rw-r--r-- | src/parse.c | 94 |
1 files changed, 53 insertions, 41 deletions
diff --git a/src/parse.c b/src/parse.c index ee115d8..c5ced09 100644 --- a/src/parse.c +++ b/src/parse.c @@ -12,6 +12,9 @@ static bool parse_disjunction_e(struct lexer *lexer, static bool parse_array(struct lexer *lexer, struct type *out); static bool parse_type(struct lexer *lexer, struct type *out); static bool parse_block(struct lexer *lexer, struct ast_block *out); +static bool parse_control_e(struct lexer *lexer, struct control_e *out); +static bool parse_location(struct lexer *lexer, struct location_e *out); +static bool parse_assignment_e(struct lexer *lexer, struct assign_e *out); static noreturn void error(struct location loc, const char *fmt, ...) @@ -188,14 +191,13 @@ parse_literal_e(struct lexer *lexer, struct literal_e *out) // Invariant: Only called from parse_primary_e with path already consumed. static bool -parse_call_e(struct lexer *lexer, struct call_e *out, struct path path) +parse_call_e(struct lexer *lexer, struct call_e *out, struct location_e *loc) { if (!match(lexer, T_LPAREN)) { return false; } - out->path = must_malloc(sizeof(struct path)); - *out->path = path; + out->loc = loc; out->args = must_calloc(1, sizeof(struct disjunction_e)); out->argsz = 1; @@ -219,8 +221,32 @@ parse_call_e(struct lexer *lexer, struct call_e *out, struct path path) } static bool +parse_named_e(struct lexer *lexer, struct named_e *out) +{ + if (!parse_location(lexer, &out->loc)) { + return false; + } + + if (parse_assignment_e(lexer, &out->nmd.assign)) { + out->kind = NMD_ASSIGN; + return true; + } + if (parse_call_e(lexer, &out->nmd.call, &out->loc)) { + out->kind = NMD_CALL; + return true; + } + + out->kind = NMD_LOCATION; + return true; +} + +static bool parse_primary_e(struct lexer *lexer, struct primary_e *out) { + if (parse_control_e(lexer, &out->prim.ctl)) { + out->kind = PRM_CONTROL; + return true; + } out->prim.grp = must_malloc(sizeof(struct disjunction_e)); if (parse_grouping_e(lexer, out->prim.grp)) { out->kind = PRM_GROUPING; @@ -231,14 +257,12 @@ parse_primary_e(struct lexer *lexer, struct primary_e *out) out->kind = PRM_LITERAL; return true; } - out->prim.path = must_malloc(sizeof(struct path)); - if (parse_path(lexer, out->prim.path)) { - out->kind = PRM_PATH; - if (parse_call_e(lexer, &out->prim.call, *out->prim.path)) { - out->kind = PRM_CALL; - } + if (parse_named_e(lexer, &out->prim.nmd)) { + out->kind = PRM_NAMED; return true; } + + return false; } static bool @@ -1178,7 +1202,8 @@ parse_declaration(struct lexer *lexer, struct ast_declaration *out) error(lex_loc(lexer), "syntax error: expected '='"); } - if (!parse_expr(lexer, &out->value)) { + out->value = must_malloc(sizeof(struct ast_expr)); + if (!parse_expr(lexer, out->value)) { error(lex_loc(lexer), "syntax error: expected expression"); } @@ -1235,11 +1260,11 @@ parse_loc_postfix(struct lexer *lexer, struct loc_postfix *out) } static bool -parse_location(struct lexer *lexer, struct ast_location *out) +parse_location(struct lexer *lexer, struct location_e *out) { - struct token name; - if (lex(lexer, &name) != T_NAME) { - unlex(lexer, &name); + out->path = must_malloc(sizeof(struct path)); + if (!parse_path(lexer, out->path)) { + free(out->path); return false; } @@ -1261,7 +1286,7 @@ parse_location(struct lexer *lexer, struct ast_location *out) } static bool -parse_assignment(struct lexer *lexer, struct ast_assign *out) +parse_assignment_e(struct lexer *lexer, struct assign_e *out) { if (!parse_location(lexer, &out->dst)) { return false; @@ -1271,7 +1296,8 @@ parse_assignment(struct lexer *lexer, struct ast_assign *out) error(lex_loc(lexer), "syntax error: expected '='"); } - if (!parse_expr(lexer, &out->value)) { + out->value = must_malloc(sizeof(struct ast_expr)); + if (!parse_expr(lexer, out->value)) { error(lex_loc(lexer), "syntax error: expected expression"); } @@ -1292,12 +1318,12 @@ parse_defer(struct lexer *lexer, struct call_e *out) return false; } - struct path path; - if (!parse_path(lexer, &path)) { + struct location_e *loc = must_malloc(sizeof(struct location_e)); + if (!parse_location(lexer, loc)) { error(lex_loc(lexer), "syntax error: expected path"); } - if (!parse_call_e(lexer, out, path)) { + if (!parse_call_e(lexer, out, loc)) { error(lex_loc(lexer), "syntax error: expected call"); } @@ -1335,33 +1361,21 @@ parse_statement(struct lexer *lexer, struct ast_statement *out) } return true; } - if (parse_assignment(lexer, &out->stmt.assign)) { - out->action = STM_ASSIGN; - if (!match(lexer, T_SEMICOLON)) { - error(lex_loc(lexer), "syntax error: expected semicolon"); - } - return true; - } - if (parse_call(lexer, &out->stmt.call)) { - out->action = STM_CALL; - if (!match(lexer, T_SEMICOLON)) { - error(lex_loc(lexer), "syntax error: expected semicolon"); - } - return true; - } - if (parse_defer(lexer, &out->stmt.call)) { + out->stmt.call = must_malloc(sizeof(struct call_e)); + if (parse_defer(lexer, out->stmt.call)) { out->action = STM_DEFER; if (!match(lexer, T_SEMICOLON)) { error(lex_loc(lexer), "syntax error: expected semicolon"); } return true; } + free(out->stmt.call); return false; } static bool -parse_control(struct lexer *lexer, struct ast_control *out) +parse_control_e(struct lexer *lexer, struct control_e *out) { /* TODO */ return false; @@ -1378,10 +1392,6 @@ parse_command(struct lexer *lexer, struct ast_cmd *out) out->kind = CMD_STATEMENT; return true; } - if (parse_control(lexer, &out->cmd.ctl)) { - out->kind = CMD_CONTROL; - return true; - } return false; } @@ -1476,9 +1486,11 @@ parse_function(struct lexer *lexer, struct ast_func *out) error(lex_loc(lexer), "syntax error: expected ')'"); } - bool nonvoid = parse_type(lexer, &out->ret); + out->ret = must_malloc(sizeof(struct type)); + bool nonvoid = parse_type(lexer, out->ret); - if (!parse_block(lexer, &out->block)) { + out->block = must_malloc(sizeof(struct ast_block)); + if (!parse_block(lexer, out->block)) { error(lex_loc(lexer), "syntax error: expected block"); } |