forked from NeoFlock/noom
elseif, else
This commit is contained in:
@@ -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");
|
||||||
|
|||||||
61
src/parser.c
61
src/parser.c
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user