diff options
Diffstat (limited to 'compiler/parser')
-rw-r--r-- | compiler/parser/proc.c | 22 | ||||
-rw-r--r-- | compiler/parser/stmt.c | 62 |
2 files changed, 75 insertions, 9 deletions
diff --git a/compiler/parser/proc.c b/compiler/parser/proc.c index bbbdad1..b32f5e9 100644 --- a/compiler/parser/proc.c +++ b/compiler/parser/proc.c @@ -7,6 +7,7 @@ #include <stdbool.h> #include "debug.h" #include "parser/proc.h" +#include "parser/stmt.h" #include "parser/type.h" #include "parser.h" @@ -119,26 +120,29 @@ parse_proc(struct parser *ctx) } } - /* Add procedure to parser's registry */ - hashmap_add(ctx->procs, &proc->hashmap_entry); - /* We are finished now if this is just a declaration */ if (ctx->tok.kind == TK_SEMICOLON) { + proc->node = NULL; + + /* Add procedure to parser's registry */ + hashmap_add(ctx->procs, &proc->hashmap_entry); + next_token(ctx); return; } if (ctx->tok.kind != TK_LBRACE) { + proc->node = NULL; tok_error(&ctx->tok, "Expected \";\" or \"{\"\n"); return; } - /* TODO: Parse body/code */ + /* Allocate AST root node for body */ + proc->node = ast_new_node(NK_PROCEDURE); - if (next_token(ctx)->kind != TK_RBRACE) { - tok_error(&ctx->tok, "Expected \"}\" after procedure body\n"); - return; - } + /* Parse procedure body (code) */ + parse_stmt_block(ctx, proc->node, proc); - next_token(ctx); + /* Add procedure to parser's registry */ + hashmap_add(ctx->procs, &proc->hashmap_entry); } diff --git a/compiler/parser/stmt.c b/compiler/parser/stmt.c new file mode 100644 index 0000000..6fe3d6d --- /dev/null +++ b/compiler/parser/stmt.c @@ -0,0 +1,62 @@ +/* + * Statement parser. + * Copyright (c) 2023-2024, Quinn Stephens and the OSMORA team. + * Provided under the BSD 3-Clause license. + */ + +#include <stdbool.h> +#include "debug.h" +#include "parser/ast.h" +#include "parser/stmt.h" +#include "parser/proc.h" +#include "parser.h" + +static bool +parse_ret(struct parser *ctx, struct ast_node *parent, struct procedure *proc) +{ + struct ast_node *node; + + (void)proc; + + debug("Parsing return statement...\n"); + + /* TODO: Parse return value */ + next_token(ctx); + + if (ctx->tok.kind != TK_SEMICOLON) { + tok_error(&ctx->tok, "Expected \";\"\n"); + return false; + } + next_token(ctx); + + node = ast_new_node(NK_RETURN); + ast_append_child(parent, node); + + return true; +} + +void +parse_stmt_block(struct parser *ctx, struct ast_node *parent, struct procedure *proc) +{ + bool success; + + debug("Parsing statement block...\n"); + + next_token(ctx); + while (ctx->tok.kind != TK_RBRACE) { + switch (ctx->tok.kind) { + case TK_RET: + success = parse_ret(ctx, parent, proc); + break; + default: + tok_error(&ctx->tok, "Expected statement\n"); + success = false; + break; + } + + if (!success) { + return; + } + } + next_token(ctx); +} |