forked from NeoFlock/noom
parser: for loops
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) {
|
||||
// uhh uhhh uhhhhh
|
||||
const char* code = "function fact(n) if n == 0 then return 1 end return n*fact(n-1) end";
|
||||
const char* code = "for k,v,a,b,c in 8,5,6,3,2,5 do end";
|
||||
noom_uint_t pos = 0;
|
||||
|
||||
printf("LEX OUTPUT:\n");
|
||||
|
||||
123
src/parser.c
123
src/parser.c
@@ -13,6 +13,10 @@ const char *noomP_formatNodeType(noomP_NodeType node_type) {
|
||||
return "if statement";
|
||||
case NOOMP_NODE_WHILELOOP:
|
||||
return "while loop";
|
||||
case NOOMP_NODE_FORLOOP:
|
||||
return "for loop";
|
||||
case NOOMP_NODE_FORLOOPIN:
|
||||
return "for loop (in)";
|
||||
case NOOMP_NODE_BLOCK:
|
||||
return "block";
|
||||
case NOOMP_NODE_ATTRIBUTE:
|
||||
@@ -1107,6 +1111,125 @@ noomP_Node* noomP_parseRawStatement(noomP_Parser* parser) {
|
||||
if (!is_done) return 0; //darn it
|
||||
|
||||
return ret;
|
||||
} else if (noom_streql(parser->code + token.offset, token.length, "for", 3)) {
|
||||
// yay...
|
||||
noomP_skip(parser, &token);
|
||||
|
||||
noomP_Node* forl = noomP_allocNode(parser);
|
||||
if (forl == 0) return 0;
|
||||
|
||||
forl->type = NOOMP_NODE_FORLOOP; // might be changed to FORLOOPIN later.
|
||||
forl->source_offset = token.offset;
|
||||
|
||||
noomP_peek(parser, &token);
|
||||
if (token.type != NOOML_TOKEN_IDENTIFIER) return 0;
|
||||
noom_uint_t vname = token.offset;
|
||||
noomP_skip(parser, &token);
|
||||
|
||||
noomP_Node* name_node = noomP_allocNode(parser);
|
||||
if (name_node == 0) return 0;
|
||||
|
||||
name_node->type = NOOMP_NODE_VARNAME;
|
||||
name_node->source_offset = vname;
|
||||
|
||||
noomP_addSubnode(forl, name_node);
|
||||
|
||||
noomP_peek(parser, &token);
|
||||
|
||||
if (token.type == NOOML_TOKEN_SYMBOL && noom_streql(parser->code + token.offset, token.length, "=", 1)) {
|
||||
noomP_skip(parser, &token);
|
||||
|
||||
// ehhh i'll do a stupid
|
||||
noom_uint_t numc = 0;
|
||||
while (1) {
|
||||
noomP_Node* expr = noomP_parseExpression(parser);
|
||||
if (expr == 0) return 0;
|
||||
|
||||
noomP_addSubnode(forl, expr);
|
||||
numc++;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (numc < 2 || numc > 3) return 0; // damn :(
|
||||
} else {
|
||||
forl->type = NOOMP_NODE_FORLOOPIN;
|
||||
|
||||
if (token.type == NOOML_TOKEN_SYMBOL && noom_streql(parser->code + token.offset, token.length, ",", 1)) {
|
||||
noomP_skip(parser, &token);
|
||||
|
||||
while (1) {
|
||||
noomP_peek(parser, &token);
|
||||
if (token.type != NOOML_TOKEN_IDENTIFIER) return 0;
|
||||
noomP_skip(parser, &token);
|
||||
|
||||
noomP_Node* namemoment = noomP_allocNode(parser);
|
||||
if (namemoment == 0) return 0;
|
||||
|
||||
namemoment->type = NOOMP_NODE_VARNAME;
|
||||
namemoment->source_offset = token.offset;
|
||||
|
||||
noomP_addSubnode(forl, namemoment);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// okay. that took a while. now for the in and the expressions
|
||||
noomP_peek(parser, &token);
|
||||
if (token.type != NOOML_TOKEN_KEYWORD || !noom_streql(parser->code + token.offset, token.length, "in", 2)) {
|
||||
return 0;
|
||||
}
|
||||
noomP_skip(parser, &token);
|
||||
|
||||
// exprlist time
|
||||
while (1) {
|
||||
noomP_Node* expr = noomP_parseExpression(parser);
|
||||
if (expr == 0) return 0;
|
||||
|
||||
noomP_addSubnode(forl, 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// making this the same for all of them: do [block] end
|
||||
noomP_peek(parser, &token);
|
||||
if (token.type != NOOML_TOKEN_KEYWORD || !noom_streql(parser->code + token.offset, token.length, "do", 2)) {
|
||||
return 0;
|
||||
}
|
||||
noomP_skip(parser, &token);
|
||||
|
||||
noomP_Node* block = noomP_parseBlock(parser);
|
||||
if (block == 0) return 0;
|
||||
|
||||
noomP_addSubnode(forl, 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 forl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ typedef enum noomP_NodeType {
|
||||
NOOMP_NODE_LOCALDECLARATION,
|
||||
NOOMP_NODE_IFSTATEMENT,
|
||||
NOOMP_NODE_WHILELOOP,
|
||||
NOOMP_NODE_FORLOOP,
|
||||
NOOMP_NODE_FORLOOPIN,
|
||||
NOOMP_NODE_BLOCK,
|
||||
|
||||
NOOMP_NODE_ATTRIBUTE,
|
||||
|
||||
Reference in New Issue
Block a user