diff --git a/projects/str.j b/projects/str.j new file mode 100644 index 0000000..e2d32a2 --- /dev/null +++ b/projects/str.j @@ -0,0 +1,12 @@ +x = 0 +while x < 10: + x = x + 1 + +if x > 9: + println "fin" + + +x = "a" +y = x * 1 +z = y + 2 +println "a" + z \ No newline at end of file diff --git a/projects/test.j b/projects/test.j new file mode 100644 index 0000000..a9a3b91 --- /dev/null +++ b/projects/test.j @@ -0,0 +1,3 @@ +x = 5 +z = x > 2 +print x + z \ No newline at end of file diff --git a/src/frontend/lexer.h b/src/frontend/lexer.h index 8cb22f7..85476db 100644 --- a/src/frontend/lexer.h +++ b/src/frontend/lexer.h @@ -14,10 +14,11 @@ typedef enum { TOK_STRING, // "hola" // Identificadores y keywords - TOK_ID, // x, foo, mi_var - TOK_PRINT, // print - TOK_IF, // if - TOK_WHILE, // while + TOK_ID, // x, foo, mi_var + TOK_PRINT, // print + TOK_PRINTLN, // println + TOK_IF, // if + TOK_WHILE, // while // Operadores TOK_ASSIGN, // = @@ -117,6 +118,14 @@ Token *tokenize(const char *source, int *token_count) { } else if (c == ':') { tokens[count++] = make_token(TOK_COLON, ":"); pos++; + } else if (c == '"') { + // Leer todo hasta el proximo '"' + pos++; // consumir '"' + int start = pos; + while (source[pos] != '"') + pos++; + tokens[count++] = make_token(TOK_STRING, substr(source, start, pos)); + pos++; // consumir '"' } else if (c >= '0' && c <= '9') { // Leer todos los digitos consecutivos int start = pos; @@ -137,6 +146,8 @@ Token *tokenize(const char *source, int *token_count) { tokens[count++] = make_token(TOK_WHILE, word); } else if (strcmp(word, "if") == 0) { tokens[count++] = make_token(TOK_IF, word); + } else if (strcmp(word, "println") == 0) { + tokens[count++] = make_token(TOK_PRINTLN, word); } else { tokens[count++] = make_token(TOK_ID, word); } diff --git a/src/frontend/parser.h b/src/frontend/parser.h index bc99316..dc4297e 100644 --- a/src/frontend/parser.h +++ b/src/frontend/parser.h @@ -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++) { diff --git a/src/main.c b/src/main.c index dfcc845..9e74372 100644 --- a/src/main.c +++ b/src/main.c @@ -37,7 +37,7 @@ int main(int argc, char **argv) { eval(block, &env, allocPtr, 0, 1); printf("heapSize=%zu\n", allocPtr->size); - // JLANG_visualize(allocPtr); + JLANG_visualize(allocPtr); return 0; } \ No newline at end of file diff --git a/src/vm/eval.h b/src/vm/eval.h index 66b4b93..0f04d85 100644 --- a/src/vm/eval.h +++ b/src/vm/eval.h @@ -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; }