diff --git a/src/main.c b/src/main.c index 36fe064..6492f17 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 = "function a.b:aaa(a) local a = 2 end"; + const char* code = "local function a(a, ...) local a = 2 end"; noom_uint_t pos = 0; printf("LEX OUTPUT:\n"); diff --git a/src/parser.c b/src/parser.c index e40ce17..a35a9e3 100644 --- a/src/parser.c +++ b/src/parser.c @@ -43,6 +43,8 @@ const char *noomP_formatNodeType(noomP_NodeType node_type) { return "method call"; case NOOMP_NODE_FUNCTIONDECLARATION: return "function declaration"; + case NOOMP_NODE_LOCALFUNCTIONDECLARATION: + return "local function declaration"; case NOOMP_NODE_FUNCTIONPARAMETERS: return "function parameters"; case NOOMP_NODE_FUNCTIONNAME: @@ -647,6 +649,46 @@ noomP_Node* noomP_parseRawStatement(noomP_Parser* parser) { if (noom_streql(parser->code + token.offset, token.length, "local", 5)) { noomP_skip(parser, &token); + noomP_peek(parser, &token); + + if (token.type == NOOML_TOKEN_KEYWORD && noom_streql(parser->code + token.offset, token.length, "function", 8)) { + noomP_skip(parser, &token); + + noomP_Node* funcNode = noomP_allocNode(parser); + if (funcNode == 0) return 0; + + funcNode->type = NOOMP_NODE_LOCALFUNCTIONDECLARATION; + funcNode->source_offset = token.offset; + + noomP_peek(parser, &token); + if (token.type != NOOML_TOKEN_IDENTIFIER) return 0; + noomP_skip(parser, &token); + + noomP_Node* nameNode = noomP_allocNode(parser); + if (nameNode == 0) return 0; + + nameNode->type = NOOMP_NODE_VARNAME; + nameNode->source_offset = token.offset; + + noomP_addSubnode(funcNode, nameNode); + + noomP_Node* params = noomP_parseFunctionParameters(parser); + if (params == 0) return 0; + noomP_addSubnode(funcNode, params); + + noomP_Node* block = noomP_parseBlock(parser); + if (block == 0) return 0; + noomP_addSubnode(funcNode, block); + + noomP_peek(parser, &token); + if (token.type != NOOML_TOKEN_KEYWORD || !noom_streql(parser->code + token.offset, token.length, "end", 3)) { + return 0; + } + noomP_skip(parser, &token); + + return funcNode; + } + noomP_Node* localNode = noomP_allocNode(parser); if (localNode == 0) return 0; // no memory :( diff --git a/src/parser.h b/src/parser.h index dd2fcd8..b3a524f 100644 --- a/src/parser.h +++ b/src/parser.h @@ -30,6 +30,7 @@ typedef enum noomP_NodeType { NOOMP_NODE_METHODCALL, NOOMP_NODE_FUNCTIONDECLARATION, + NOOMP_NODE_LOCALFUNCTIONDECLARATION, NOOMP_NODE_FUNCTIONPARAMETERS, NOOMP_NODE_FUNCTIONNAME,