From c7f287ca7b33bc025e71e0ef7ced79bb52d526b9 Mon Sep 17 00:00:00 2001 From: Blendi Date: Tue, 14 Apr 2026 08:16:02 +0200 Subject: [PATCH] parser progress --- src/main.c | 2 +- src/parser.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++- src/parser.h | 3 ++ 3 files changed, 94 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index 0c55a22..1dbc43a 100644 --- a/src/main.c +++ b/src/main.c @@ -33,7 +33,7 @@ void print_node(noomP_Node* node, noom_uint_t depth) { int main(int argc, char** argv) { // uhh uhhh uhhhhh - const char* code = "local a = 5"; + const char* code = "if 6 then local a = 2; end"; noom_uint_t pos = 0; printf("LEX OUTPUT:\n"); diff --git a/src/parser.c b/src/parser.c index 0727330..5fa1f2b 100644 --- a/src/parser.c +++ b/src/parser.c @@ -74,7 +74,38 @@ noomP_Node* noomP_parseExpression(noomP_Parser* parser) { return 0; } -noomP_Node* noomP_parseStatement(noomP_Parser* parser) { +noomP_Node* noomP_parseBlock(noomP_Parser* parser) { // todo: maybe specify the ending keyword? how do we end on elseif, else? + // block starter has been eaten already; we just go until end + noomP_Node* node = noomP_allocNode(parser); + if (node == 0) return 0; // OOM :( + + node->type = NOOMP_NODE_BLOCK; + node->source_offset = parser->lex_offset; + + noomL_Token token; + + while (1) { + // check if end reached + noomP_peek(parser, &token); + + if (token.type == NOOML_TOKEN_KEYWORD) { + if (noom_streql(parser->code + token.offset, token.length, "end", 3)) { + // it's so joever + noomP_skip(parser, &token); + break; + } + } + + noomP_Node* stmt = noomP_parseStatement(parser); + if (stmt == 0) return 0; + + noomP_addSubnode(node, stmt); + } + + return node; +} + +noomP_Node* noomP_parseRawStatement(noomP_Parser* parser) { noomL_Token token; noomP_peek(parser, &token); @@ -140,12 +171,70 @@ noomP_Node* noomP_parseStatement(noomP_Parser* parser) { } return localNode; + } else if (noom_streql(parser->code + token.offset, token.length, "if", 2)) { + noomP_skip(parser, &token); + + noomP_Node* ifStatement = noomP_allocNode(parser); + if (ifStatement == 0) return 0; + + ifStatement->type = NOOMP_NODE_IFSTATEMENT; + ifStatement->source_offset = token.offset; + + noomP_Node* condition = noomP_parseExpression(parser); + if (condition == 0) return 0; + + noomP_addSubnode(ifStatement, condition); + + noomP_peek(parser, &token); + + if (token.type != NOOML_TOKEN_KEYWORD) return 0; // unexpected + if (!noom_streql(parser->code + token.offset, token.length, "then", 4)) return 0; // unexpected + + noomP_skip(parser, &token); + + noomP_Node* block = noomP_parseBlock(parser); // TODO: elseif, else + if (block == 0) return 0; + + noomP_addSubnode(ifStatement, block); + + return ifStatement; } } + while (1) { + noomP_peek(parser, &token); + if (token.type == NOOML_TOKEN_SYMBOL) { + if (noom_streql(parser->code + token.offset, token.length, ";", 1)) { + noomP_skip(parser, &token); + continue; + } + } + break; + } + return 0; } +noomP_Node* noomP_parseStatement(noomP_Parser* parser) { + noomL_Token token; + + noomP_Node* stmt = noomP_parseRawStatement(parser); + if (stmt == 0) return 0; + + while (1) { + noomP_peek(parser, &token); + if (token.type == NOOML_TOKEN_SYMBOL) { + if (noom_streql(parser->code + token.offset, token.length, ";", 1)) { + noomP_skip(parser, &token); + continue; + } + } + break; + } + + return stmt; +} + int noomP_parse(const char* code, const char* filename, noomP_Node** outpointer, noomP_Node** last_node) { noomP_Parser parser; noomP_initParser(&parser, code, filename); diff --git a/src/parser.h b/src/parser.h index 77383f6..36fd135 100644 --- a/src/parser.h +++ b/src/parser.h @@ -6,7 +6,10 @@ typedef enum noomP_NodeType { NOOMP_NODE_VARNAME, NOOMP_NODE_NUMBERLITERAL, NOOMP_NODE_LOCALDECLARATION, + NOOMP_NODE_IFSTATEMENT, + NOOMP_NODE_BLOCK, } noomP_NodeType; + typedef struct noomP_Node { noomP_NodeType type;