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.
This commit is contained in:
Jose Luis Montañes Ojados
2026-02-16 02:24:37 +01:00
parent 01740d4892
commit 14b6a2ddd2
5 changed files with 34 additions and 8 deletions

5
projects/resta.j Normal file
View File

@@ -0,0 +1,5 @@
x=2
y=5
z = x + y
zz = z * x
print zz

View File

@@ -81,6 +81,12 @@ Token *tokenize(const char *source, int *token_count) {
} else if (c == '-') { } else if (c == '-') {
tokens[count++] = make_token(TOK_MINUS, "-"); tokens[count++] = make_token(TOK_MINUS, "-");
pos++; pos++;
} else if (c == '*') {
tokens[count++] = make_token(TOK_STAR, "*");
pos++;
} else if (c == '/') {
tokens[count++] = make_token(TOK_SLASH, "/");
pos++;
} else if (c == '=') { } else if (c == '=') {
tokens[count++] = make_token(TOK_ASSIGN, "="); tokens[count++] = make_token(TOK_ASSIGN, "=");
pos++; pos++;

View File

@@ -80,9 +80,9 @@ ASTNode *parse_expr(Token *tokens)
{ {
ASTNode *left = parse_term(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++; pos++;
ASTNode *right = parse_term(tokens); ASTNode *right = parse_term(tokens);

View File

@@ -199,7 +199,8 @@ void JLANG_visualize(void *ptr) {
} }
} else { } else {
// Mark all block as JLANG_NOT_USE // 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 { } else {
break; break;
@@ -215,7 +216,6 @@ void JLANG_visualize(void *ptr) {
int bytePerRow = 40; int bytePerRow = 40;
int totalRows = _ceil(allocPtr->size / bytePerRow); int totalRows = _ceil(allocPtr->size / bytePerRow);
printf("totalRows=%d\n", totalRows);
char *currentMemPtr = allocPtr->memory; char *currentMemPtr = allocPtr->memory;
@@ -242,9 +242,11 @@ void JLANG_visualize(void *ptr) {
printf("%.2x", (unsigned char)*(currentMemPtr + (n + i * bytePerRow))); printf("%.2x", (unsigned char)*(currentMemPtr + (n + i * bytePerRow)));
/*
if (n < bytePerRow - 1) { if (n < bytePerRow - 1) {
printf(" "); printf(" ");
} }
*/
printf("\033[0m"); printf("\033[0m");
} }

View File

@@ -44,7 +44,16 @@ void env_set(Environment *env, const char *name, size_t value)
env->count++; env->count++;
} }
int step = 0;
size_t eval(ASTNode *node, Environment *env, void *allocator) { 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) { switch (node->type) {
case NODE_INT_LIT: case NODE_INT_LIT:
return obj_new_int(allocator, node->data.int_val); return obj_new_int(allocator, node->data.int_val);
@@ -68,6 +77,10 @@ size_t eval(ASTNode *node, Environment *env, void *allocator) {
return obj_new_int(allocator, l->data.int_val + r->data.int_val); return obj_new_int(allocator, l->data.int_val + r->data.int_val);
} else if (node->data.binop.op == '-') { } else if (node->data.binop.op == '-') {
return obj_new_int(allocator, l->data.int_val - r->data.int_val); 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: { case NODE_PRINT: {