Allow function calls in expressions and add len() built-in
- Parse function calls in parse_term() so they work inside expressions (e.g. z = len(x), y = len(x) + 1) - Add len() built-in for string length in evaluator
This commit is contained in:
@@ -1,11 +1,2 @@
|
|||||||
x = "Hello world!"
|
x = "Hello"
|
||||||
y = 21
|
println(len(x) + 3)
|
||||||
println()
|
|
||||||
println(x)
|
|
||||||
print("y=")
|
|
||||||
println(y)
|
|
||||||
|
|
||||||
dummy()
|
|
||||||
|
|
||||||
if y > 1:
|
|
||||||
println("OK!")
|
|
||||||
@@ -65,6 +65,8 @@ ASTNode *make_node(NodeType type) {
|
|||||||
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
|
ASTNode *parse_expr(Token *tokens);
|
||||||
|
|
||||||
ASTNode *parse_term(Token *tokens) {
|
ASTNode *parse_term(Token *tokens) {
|
||||||
if (tokens[pos].type == TOK_INT) {
|
if (tokens[pos].type == TOK_INT) {
|
||||||
ASTNode *node = make_node(NODE_INT_LIT);
|
ASTNode *node = make_node(NODE_INT_LIT);
|
||||||
@@ -77,8 +79,32 @@ ASTNode *parse_term(Token *tokens) {
|
|||||||
pos++;
|
pos++;
|
||||||
return node;
|
return node;
|
||||||
} else if (tokens[pos].type == TOK_ID) {
|
} else if (tokens[pos].type == TOK_ID) {
|
||||||
printf("Parsing token: %s\n", tokens[pos].value);
|
if (tokens[pos +1].type == TOK_LPAREN) {
|
||||||
|
// Function call
|
||||||
|
char *name = tokens[pos].value;
|
||||||
|
pos++; // consumir ID
|
||||||
|
pos++; // consumir (
|
||||||
|
|
||||||
|
// Parsear argumentos
|
||||||
|
ASTNode **args =
|
||||||
|
(ASTNode **)malloc(sizeof(ASTNode *) * 16); // Max 16 parametros
|
||||||
|
int arg_count = 0;
|
||||||
|
|
||||||
|
if (tokens[pos].type != TOK_RPAREN) {
|
||||||
|
args[arg_count++] = parse_expr(tokens);
|
||||||
|
while (tokens[pos].type == TOK_COMMA) {
|
||||||
|
pos++; // Consumir ","
|
||||||
|
args[arg_count++] = parse_expr(tokens);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pos++; // consumir ")"
|
||||||
|
ASTNode *node = make_node(NODE_CALL);
|
||||||
|
node->data.call.name = name;
|
||||||
|
node->data.call.args = args;
|
||||||
|
node->data.call.arg_count = arg_count;
|
||||||
|
return node;
|
||||||
|
|
||||||
|
}
|
||||||
ASTNode *node = make_node(NODE_VAR);
|
ASTNode *node = make_node(NODE_VAR);
|
||||||
node->data.string_val = tokens[pos].value;
|
node->data.string_val = tokens[pos].value;
|
||||||
pos++;
|
pos++;
|
||||||
|
|||||||
@@ -168,6 +168,17 @@ size_t eval(ASTNode *node, Environment *env, void *allocator, int debug,
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (strcmp(node->data.call.name, "len") == 0) {
|
||||||
|
if (node->data.call.arg_count == 1) {
|
||||||
|
size_t val = eval(node->data.call.args[0], env, allocator, debug, gc);
|
||||||
|
Object *obj = (Object *) JLANG_RESOLVE(allocator, val);
|
||||||
|
|
||||||
|
if (obj->type == OBJ_STRING) {
|
||||||
|
return obj_new_int(allocator, obj->data.string_val.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
printf("ERROR: funcion '%s' no definida\n", node->data.call.name);
|
printf("ERROR: funcion '%s' no definida\n", node->data.call.name);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user