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

@@ -54,6 +54,8 @@ size_t eval(ASTNode *node, Environment *env, void *allocator, int debug,
}
switch (node->type) {
case NODE_STRING_LIT:
return obj_new_string(allocator, node->data.string_val);
case NODE_INT_LIT:
return obj_new_int(allocator, node->data.int_val);
case NODE_VAR:
@@ -73,6 +75,22 @@ size_t eval(ASTNode *node, Environment *env, void *allocator, int debug,
// Operar (ints por ahora)
if (node->data.binop.op == '+') {
if (l->type == OBJ_STRING) {
int n = l->data.string_val.length + r->data.string_val.length;
char *tempBuff = (char *)malloc(n + 1);
// Copy left text
memcpy(tempBuff, JLANG_RESOLVE(allocator, l->data.string_val.chars),
l->data.string_val.length);
// Copy right text
memcpy(tempBuff + l->data.string_val.length, JLANG_RESOLVE(allocator, r->data.string_val.chars),
r->data.string_val.length);
tempBuff[n] = '\0';
size_t newObj = obj_new_string(allocator, tempBuff);
free(tempBuff);
return newObj;
}
return obj_new_int(allocator, l->data.int_val + r->data.int_val);
} else if (node->data.binop.op == '-') {
return obj_new_int(allocator, l->data.int_val - r->data.int_val);
@@ -87,6 +105,11 @@ size_t eval(ASTNode *node, Environment *env, void *allocator, int debug,
}
}
case NODE_PRINT: {
size_t val = eval(node->data.print.expr, env, allocator, debug, gc);
obj_print(allocator, val, "");
return val;
}
case NODE_PRINTLN: {
size_t val = eval(node->data.print.expr, env, allocator, debug, gc);
obj_print(allocator, val, "");
printf("\n");
@@ -101,7 +124,7 @@ size_t eval(ASTNode *node, Environment *env, void *allocator, int debug,
}
gc_collect(allocator, roots, env->count);
}
for (int i = 0; i < node->data.block.count; i++)
eval(node->data.block.stmts[i], env, allocator, debug, gc);
return 0;
@@ -113,6 +136,15 @@ size_t eval(ASTNode *node, Environment *env, void *allocator, int debug,
break;
eval(node->data.while_loop.body, env, allocator, debug, gc);
}
return 0;
case NODE_IF: {
size_t cond = eval(node->data.while_loop.cond, env, allocator, debug, gc);
Object *obj = (Object *)JLANG_RESOLVE(allocator, cond);
if (obj->data.int_val > 0) {
eval(node->data.while_loop.body, env, allocator, debug, gc);
}
break;
}
default:
break;
}