forked from NeoFlock/noom
parser: returns
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 = "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");
|
||||
|
||||
85
src/parser.c
85
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user