From 14b6a2ddd2b621ba9bee4589af807e160ade4afd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Luis=20Monta=C3=B1es=20Ojados?= Date: Mon, 16 Feb 2026 02:24:37 +0100 Subject: [PATCH] Add * and / operators, VM step debugger, and visualizer tweaks Support multiply and divide in lexer, parser and eval. Add step-by-step VM debug output with AST and heap visualization. Remove spacing in visualizer hex output. --- projects/resta.j | 5 +++++ src/frontend/lexer.h | 6 ++++++ src/frontend/parser.h | 4 ++-- src/memory/allocator.h | 12 +++++++----- src/vm/eval.h | 15 ++++++++++++++- 5 files changed, 34 insertions(+), 8 deletions(-) create mode 100644 projects/resta.j diff --git a/projects/resta.j b/projects/resta.j new file mode 100644 index 0000000..8d6baca --- /dev/null +++ b/projects/resta.j @@ -0,0 +1,5 @@ +x=2 +y=5 +z = x + y +zz = z * x +print zz \ No newline at end of file diff --git a/src/frontend/lexer.h b/src/frontend/lexer.h index 3ffc9fe..9c06998 100644 --- a/src/frontend/lexer.h +++ b/src/frontend/lexer.h @@ -81,6 +81,12 @@ Token *tokenize(const char *source, int *token_count) { } else if (c == '-') { tokens[count++] = make_token(TOK_MINUS, "-"); pos++; + } else if (c == '*') { + tokens[count++] = make_token(TOK_STAR, "*"); + pos++; + } else if (c == '/') { + tokens[count++] = make_token(TOK_SLASH, "/"); + pos++; } else if (c == '=') { tokens[count++] = make_token(TOK_ASSIGN, "="); pos++; diff --git a/src/frontend/parser.h b/src/frontend/parser.h index 26a48a8..ba25103 100644 --- a/src/frontend/parser.h +++ b/src/frontend/parser.h @@ -80,9 +80,9 @@ ASTNode *parse_expr(Token *tokens) { ASTNode *left = parse_term(tokens); - while (tokens[pos].type == TOK_PLUS || tokens[pos].type == TOK_MINUS) + while (tokens[pos].type == TOK_PLUS || tokens[pos].type == TOK_MINUS || tokens[pos].type == TOK_STAR || tokens[pos].type == TOK_SLASH) { - char op = tokens[pos].value[0]; // + o - + char op = tokens[pos].value[0]; // +,-,*,/ pos++; ASTNode *right = parse_term(tokens); diff --git a/src/memory/allocator.h b/src/memory/allocator.h index 01dacd4..575f722 100644 --- a/src/memory/allocator.h +++ b/src/memory/allocator.h @@ -199,7 +199,8 @@ void JLANG_visualize(void *ptr) { } } else { // Mark all block as JLANG_NOT_USE - memset(byteMapPtr + blockIndex, JLANG_NOT_USE, sizeof(JLANG_metadata) + currentHeader->size); + memset(byteMapPtr + blockIndex, JLANG_NOT_USE, + sizeof(JLANG_metadata) + currentHeader->size); } } else { break; @@ -215,7 +216,6 @@ void JLANG_visualize(void *ptr) { int bytePerRow = 40; int totalRows = _ceil(allocPtr->size / bytePerRow); - printf("totalRows=%d\n", totalRows); char *currentMemPtr = allocPtr->memory; @@ -242,9 +242,11 @@ void JLANG_visualize(void *ptr) { printf("%.2x", (unsigned char)*(currentMemPtr + (n + i * bytePerRow))); - if (n < bytePerRow - 1) { - printf(" "); - } + /* + if (n < bytePerRow - 1) { + printf(" "); + } + */ printf("\033[0m"); } diff --git a/src/vm/eval.h b/src/vm/eval.h index fffdb3c..dfca63b 100644 --- a/src/vm/eval.h +++ b/src/vm/eval.h @@ -44,7 +44,16 @@ void env_set(Environment *env, const char *name, size_t value) env->count++; } +int step = 0; + size_t eval(ASTNode *node, Environment *env, void *allocator) { + step++; + printf("===== VM Step: %d =====\n", step); + printf("executing node:\n"); + ast_debug(node); + printf("\n"); + JLANG_visualize(allocator); + switch (node->type) { case NODE_INT_LIT: return obj_new_int(allocator, node->data.int_val); @@ -68,7 +77,11 @@ size_t eval(ASTNode *node, Environment *env, void *allocator) { 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); - } + } else if (node->data.binop.op == '*') { + 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); + } } case NODE_PRINT: { size_t val = eval(node->data.print.expr, env, allocator);