From 7ad81d55e208a63a9bc83f3dc7c3640f9ce8306e Mon Sep 17 00:00:00 2001 From: Blendi Date: Wed, 29 Apr 2026 12:28:14 +0200 Subject: [PATCH] parser: returns --- src/main.c | 2 +- src/parser.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/parser.h | 2 ++ 3 files changed, 88 insertions(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index c388cf1..2a8558a 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 = function(a,b,c,...) print('hi'); end"; + const char* code = "function fact(n) if n == 0 then return 1 end return n*fact(n-1) end"; noom_uint_t pos = 0; printf("LEX OUTPUT:\n"); diff --git a/src/parser.c b/src/parser.c index 149a908..0c1963d 100644 --- a/src/parser.c +++ b/src/parser.c @@ -51,6 +51,8 @@ const char *noomP_formatNodeType(noomP_NodeType node_type) { return "function parameters"; case NOOMP_NODE_FUNCTIONNAME: return "function name"; + case NOOMP_NODE_RETURN: + return "return"; case NOOMP_NODE_FIELDNAME: return "field name"; case NOOMP_NODE_METHODNAME: @@ -655,6 +657,8 @@ noomP_Node* noomP_parseBlock(noomP_Parser* parser) { // stops on end, else or el break; } else if (noom_streql(parser->code + token.offset, token.length, "else", 4)) { break; + } else if (noom_streql(parser->code + token.offset, token.length, "until", 5)) { + break; } } @@ -1022,6 +1026,87 @@ noomP_Node* noomP_parseRawStatement(noomP_Parser* parser) { noomP_skip(parser, &token); return func; + } else if (noom_streql(parser->code + token.offset, token.length, "return", 6)) { + noomP_skip(parser, &token); + + noomP_Node* ret = noomP_allocNode(parser); + if (ret == 0) return 0; + + ret->type = NOOMP_NODE_RETURN; + ret->source_offset = token.offset; + + // return is special; it must explicitly handle semicolons. + // this is because it must check for a block ender (end, elseif, else, until, eof) TODO: make sure this is correct. + // could also just make this return (or outpointer) some value that says "no more allowed in this block" instead? + + noomP_peek(parser, &token); + + int is_empty = 0; + if (token.type == NOOML_TOKEN_SYMBOL) { + if (noom_streql(parser->code + token.offset, token.length, ";", 1)) { + is_empty = 1; + } + } else if (token.type == NOOML_TOKEN_KEYWORD) { + if (noom_streql(parser->code + token.offset, token.length, "end", 3)) { + is_empty = 1; + } else if (noom_streql(parser->code + token.offset, token.length, "elseif", 6)) { + is_empty = 1; + } else if (noom_streql(parser->code + token.offset, token.length, "else", 4)) { + is_empty = 1; + } else if (noom_streql(parser->code + token.offset, token.length, "until", 1)) { + is_empty = 1; + } + } else if (token.type == NOOML_TOKEN_EOF) { + is_empty = 1; + } + + if (!is_empty) { + while (1) { + noomP_Node* expr = noomP_parseExpression(parser); + if (expr == 0) return 0; + + noomP_addSubnode(ret, expr); + + noomP_peek(parser, &token); + + if (token.type == NOOML_TOKEN_SYMBOL && noom_streql(parser->code + token.offset, token.length, ",", 1)) { + noomP_skip(parser, &token); + } else { + break; + } + } + } + + while (1) { // remove semis so we can check for ender after. + noomP_peek(parser, &token); + + if (token.type == NOOML_TOKEN_SYMBOL && noom_streql(parser->code + token.offset, token.length, ";", 1)) { + noomP_skip(parser, &token); + } else { + break; + } + } + + noomP_peek(parser, &token); + // now we have to make sure we he have an ender; + int is_done = 0; + if (token.type == NOOML_TOKEN_KEYWORD) { + if (noom_streql(parser->code + token.offset, token.length, "end", 3)) { + is_done = 1; + } else if (noom_streql(parser->code + token.offset, token.length, "elseif", 6)) { + is_done = 1; + } else if (noom_streql(parser->code + token.offset, token.length, "else", 4)) { + is_done = 1; + } else if (noom_streql(parser->code + token.offset, token.length, "until", 1)) { + is_done = 1; + } + } else if (token.type == NOOML_TOKEN_EOF) { + is_done = 1; + } + + if (!is_done) return 0; //darn it + + return ret; } } diff --git a/src/parser.h b/src/parser.h index 4861aa0..f0e0b74 100644 --- a/src/parser.h +++ b/src/parser.h @@ -35,6 +35,8 @@ typedef enum noomP_NodeType { NOOMP_NODE_FUNCTIONPARAMETERS, NOOMP_NODE_FUNCTIONNAME, + NOOMP_NODE_RETURN, + NOOMP_NODE_FIELDNAME, NOOMP_NODE_METHODNAME, // only used in function decl as of right now.