Add string type support: literals, concatenation, println, and if eval

- Implement string literal tokenization and parsing (lexer + parser)
- Add string concatenation with + operator in evaluator
- Add println keyword for printing with newline
- Add NODE_IF evaluation in VM
- Fix null terminator bug in string concat buffer
This commit is contained in:
Jose Luis Montañes Ojados
2026-02-16 17:39:52 +01:00
parent 667e5564b8
commit dd67537598
6 changed files with 88 additions and 10 deletions

View File

@@ -13,9 +13,10 @@ typedef enum {
NODE_ASSIGN, // asignacion: x = expr
NODE_BINOP, // operacion binaria: a + b
NODE_PRINT, // print(expr)
NODE_IF, // if cond: bloque
NODE_WHILE, // while cond: bloque
NODE_BLOCK, // secuencia de statements
NODE_PRINTLN,
NODE_IF, // if cond: bloque
NODE_WHILE, // while cond: bloque
NODE_BLOCK, // secuencia de statements
} NodeType;
typedef struct ASTNode {
@@ -64,6 +65,11 @@ ASTNode *parse_term(Token *tokens) {
node->data.int_val = atoi(tokens[pos].value);
pos++;
return node;
} else if (tokens[pos].type == TOK_STRING) {
ASTNode *node = make_node(NODE_STRING_LIT);
node->data.string_val = tokens[pos].value;
pos++;
return node;
} else if (tokens[pos].type == TOK_ID) {
ASTNode *node = make_node(NODE_VAR);
node->data.string_val = tokens[pos].value;
@@ -79,7 +85,7 @@ ASTNode *parse_term(Token *tokens) {
neg->data.binop.right = term;
return neg;
}
printf("ERROR: esperaba INT o ID, encontré tipo %d\n", tokens[pos].type);
printf("ERROR: esperaba INT o ID, encontre tipo %d\n", tokens[pos].type);
exit(1);
}
@@ -123,6 +129,15 @@ ASTNode *parse_statement(Token *tokens) {
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
ASTNode *cond = parse_expr(tokens);
@@ -247,6 +262,11 @@ void ast_print(ASTNode *node, const char *prefix, int is_last) {
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++) {