elseif, else

This commit is contained in:
2026-04-16 11:53:26 +02:00
parent 9ac3df1f37
commit b260b49b62
2 changed files with 57 additions and 6 deletions

View File

@@ -33,7 +33,7 @@ void print_node(noomP_Node* node, noom_uint_t depth) {
int main(int argc, char** argv) { int main(int argc, char** argv) {
// uhh uhhh uhhhhh // uhh uhhh uhhhhh
const char* code = "if false or true then local a = 5 end"; const char* code = "if false or true then elseif true or false then else end";
noom_uint_t pos = 0; noom_uint_t pos = 0;
printf("LEX OUTPUT:\n"); printf("LEX OUTPUT:\n");

View File

@@ -284,8 +284,8 @@ noomP_Node* noomP_parseExpression(noomP_Parser* parser) {
return noomP_parseOperatorExpression(parser, 0, 0); return noomP_parseOperatorExpression(parser, 0, 0);
} }
noomP_Node* noomP_parseBlock(noomP_Parser* parser) { // todo: maybe specify the ending keyword? how do we end on elseif, else? noomP_Node* noomP_parseBlock(noomP_Parser* parser) { // stops on end, else or elseif.
// block starter has been eaten already; we just go until end // block starter has been eaten already; we just go until ending keyword
noomP_Node* node = noomP_allocNode(parser); noomP_Node* node = noomP_allocNode(parser);
if (node == 0) return 0; // OOM :( if (node == 0) return 0; // OOM :(
@@ -300,8 +300,10 @@ noomP_Node* noomP_parseBlock(noomP_Parser* parser) { // todo: maybe specify the
if (token.type == NOOML_TOKEN_KEYWORD) { if (token.type == NOOML_TOKEN_KEYWORD) {
if (noom_streql(parser->code + token.offset, token.length, "end", 3)) { if (noom_streql(parser->code + token.offset, token.length, "end", 3)) {
// it's so joever break;
noomP_skip(parser, &token); } else if (noom_streql(parser->code + token.offset, token.length, "elseif", 6)) {
break;
} else if (noom_streql(parser->code + token.offset, token.length, "else", 4)) {
break; break;
} }
} }
@@ -402,11 +404,60 @@ noomP_Node* noomP_parseRawStatement(noomP_Parser* parser) {
noomP_skip(parser, &token); noomP_skip(parser, &token);
noomP_Node* block = noomP_parseBlock(parser); // TODO: elseif, else noomP_Node* block = noomP_parseBlock(parser);
if (block == 0) return 0; if (block == 0) return 0;
noomP_addSubnode(ifStatement, block); noomP_addSubnode(ifStatement, block);
while (1) { // else, elseif
noomP_peek(parser, &token);
if (token.type != NOOML_TOKEN_KEYWORD) return 0; // unexpected
if (noom_streql(parser->code + token.offset, token.length, "elseif", 6)) {
noomP_skip(parser, &token);
noomP_Node* elseIfCondition = noomP_parseExpression(parser);
if (elseIfCondition == 0) return 0;
noomP_addSubnode(ifStatement, elseIfCondition);
// now we need to check for "then"
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);
// now the block
noomP_Node* elseIfBlock = noomP_parseBlock(parser);
if (elseIfBlock == 0) return 0;
noomP_addSubnode(ifStatement, elseIfBlock);
// could be even more
} else if (noom_streql(parser->code + token.offset, token.length, "else", 4)) {
noomP_skip(parser, &token);
noomP_Node* elseBlock = noomP_parseBlock(parser);
if (elseBlock == 0) return 0;
// we know it's an else if it's an odd number. no need to do anything special.
noomP_addSubnode(ifStatement, elseBlock);
break; // this must be the last one; end is handled after the loop
} else if (noom_streql(parser->code + token.offset, token.length, "end", 3)) {
break; // will check for end outside the loop because else and things
} else {
// unexpected
return 0;
}
}
noomP_peek(parser, &token);
if (token.type != NOOML_TOKEN_KEYWORD) return 0; // unexpected
if (!noom_streql(parser->code + token.offset, token.length, "end", 3)) return 0; // unexpected
noomP_skip(parser, &token);
return ifStatement; return ifStatement;
} }
} }