Replace print/println keywords with generic function call mechanism

- Add NODE_CALL with name, args, and arg_count to parser
- Add TOK_COMMA token and tokenize (, ), , in lexer
- Remove TOK_PRINT/TOK_PRINTLN keywords; print/println are now regular
  identifiers resolved as built-in functions in the evaluator
- Add NODE_CALL debug output in ast_print
This commit is contained in:
Jose Luis Montañes Ojados
2026-02-16 18:14:39 +01:00
parent dd67537598
commit a36e52a9c3
4 changed files with 97 additions and 37 deletions

View File

@@ -17,6 +17,7 @@ typedef enum {
NODE_IF, // if cond: bloque
NODE_WHILE, // while cond: bloque
NODE_BLOCK, // secuencia de statements
NODE_CALL,
} NodeType;
typedef struct ASTNode {
@@ -48,6 +49,11 @@ typedef struct ASTNode {
struct ASTNode *cond;
struct ASTNode *body;
} if_statement; // NODE_IF
struct {
char *name;
struct ASTNode **args;
int arg_count;
} call;
} data;
} ASTNode;
@@ -71,10 +77,13 @@ ASTNode *parse_term(Token *tokens) {
pos++;
return node;
} else if (tokens[pos].type == TOK_ID) {
printf("Parsing token: %s\n", tokens[pos].value);
ASTNode *node = make_node(NODE_VAR);
node->data.string_val = tokens[pos].value;
pos++;
return node;
} else if (tokens[pos].type == TOK_MINUS) {
pos++; // consumir '-'
ASTNode *term = parse_term(tokens);
@@ -85,7 +94,9 @@ ASTNode *parse_term(Token *tokens) {
neg->data.binop.right = term;
return neg;
}
printf("ERROR: esperaba INT o ID, encontre tipo %d\n", tokens[pos].type);
printf("ERROR: esperaba INT o ID, encontre tipo %d value: %s\n",
tokens[pos].type, tokens[pos].value);
exit(1);
}
@@ -110,6 +121,32 @@ ASTNode *parse_expr(Token *tokens) {
ASTNode *parse_statement(Token *tokens) {
if (tokens[pos].type == TOK_ID) {
if (tokens[pos + 1].type == TOK_LPAREN) {
// Es una funcion
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;
}
char *name = tokens[pos].value;
pos++; // consumir ID
pos++; // consumir "="
@@ -120,23 +157,6 @@ ASTNode *parse_statement(Token *tokens) {
node->data.assign.value = value;
return node;
}
if (tokens[pos].type == TOK_PRINT) {
pos++; // consumir "print"
ASTNode *expr = parse_expr(tokens);
ASTNode *node = make_node(NODE_PRINT);
node->data.print.expr = expr;
return node;
}
if (tokens[pos].type == TOK_PRINTLN) {
pos++; // consumir "println"
ASTNode *expr = parse_expr(tokens);
ASTNode *node = make_node(NODE_PRINTLN);
node->data.print.expr = expr;
return node;
}
if (tokens[pos].type == TOK_WHILE) {
pos++; // consumir while
@@ -257,16 +277,6 @@ void ast_print(ASTNode *node, const char *prefix, int is_last) {
ast_print(node->data.binop.right, new_prefix, 1);
break;
case NODE_PRINT:
printf("NODE_PRINT\n");
ast_print(node->data.print.expr, new_prefix, 1);
break;
case NODE_PRINTLN:
printf("NODE_PRINTLN\n");
ast_print(node->data.print.expr, new_prefix, 1);
break;
case NODE_BLOCK:
printf("NODE_BLOCK\n");
for (int i = 0; i < node->data.block.count; i++) {
@@ -281,6 +291,14 @@ void ast_print(ASTNode *node, const char *prefix, int is_last) {
ast_print(node->data.while_loop.body, new_prefix, 1);
break;
case NODE_CALL:
printf("NODE_CALL(\"%s\")\n", node->data.call.name);
for (int i = 0; i < node->data.call.arg_count; i++) {
ast_print(node->data.call.args[i], new_prefix,
i == node->data.call.arg_count - 1);
}
break;
default:
printf("UNKNOWN\n");
break;