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