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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user