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:
Jose Luis Montañes Ojados
2026-02-16 18:31:39 +01:00
parent a36e52a9c3
commit 21efb0563b
3 changed files with 40 additions and 12 deletions

View File

@@ -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!")

View File

@@ -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++;

View File

@@ -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);
} }