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:
5
projects/resta.j
Normal file
5
projects/resta.j
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
x=2
|
||||||
|
y=5
|
||||||
|
z = x + y
|
||||||
|
zz = z * x
|
||||||
|
print zz
|
||||||
@@ -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++;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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) {
|
/*
|
||||||
printf(" ");
|
if (n < bytePerRow - 1) {
|
||||||
}
|
printf(" ");
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
printf("\033[0m");
|
printf("\033[0m");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,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);
|
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: {
|
||||||
size_t val = eval(node->data.print.expr, env, allocator);
|
size_t val = eval(node->data.print.expr, env, allocator);
|
||||||
|
|||||||
Reference in New Issue
Block a user