1
0
Fork 0

implement automatic register handling with scope.

This commit is contained in:
zongor 2026-02-17 22:26:55 -08:00
parent 56550a3690
commit 292aca1251
7 changed files with 125 additions and 126 deletions

View File

@ -132,46 +132,11 @@ u32 get_reg(Token token, ScopeTable *st) {
return get_ref(st, token.start, token.length); return get_ref(st, token.start, token.length);
} }
if (token.type == TOKEN_BIG_MONEY) { fprintf(stderr, "Error: Not a symbol at line %d: %.*s\n",
token = next_token();
return atoi(token.start);
}
fprintf(stderr, "Error: Not a register or symbol at line %d: %.*s\n",
token.line, token.length, token.start); token.line, token.length, token.start);
exit(1); exit(1);
} }
Token next_id_or_reg() {
Token token = next_token();
if (token.type == TOKEN_IDENTIFIER) {
return token;
}
if (token.type == TOKEN_BIG_MONEY) {
token = next_token();
return token;
}
printf("Not an ID or register at line %d: %.*s\n", token.line, token.length,
token.start);
exit(1);
return token;
}
Token next_id_or_ptr() {
Token token = next_token();
if (token.type != TOKEN_IDENTIFIER && token.type != TOKEN_LITERAL_NAT &&
token.type != TOKEN_LITERAL_INT && token.type != TOKEN_LITERAL_REAL) {
printf("Not an ID or register at line %d: %.*s\n", token.line, token.length,
token.start);
exit(1);
}
return token;
}
Token next_token_is(TokenType type) { Token next_token_is(TokenType type) {
Token token = next_token(); Token token = next_token();
if (token.type != type) { if (token.type != type) {
@ -191,10 +156,9 @@ bool parse_const(VM *vm, ScopeTable *st) {
/** /**
* Global . * Global .
*/ */
bool define_global(VM *vm, ScopeTable *st) { bool define_global(VM *vm, ScopeTable *st, Token token_type) {
Symbol s; Symbol s;
Token token_type = next_token();
switch (token_type.type) { switch (token_type.type) {
case TOKEN_TYPE_BOOL: case TOKEN_TYPE_BOOL:
s.type = BOOL; s.type = BOOL;
@ -432,11 +396,8 @@ void define_var(ScopeTable *st, Token regType) {
s.name_length = name.length; s.name_length = name.length;
Token next = next_token(); Token next = next_token();
if (next.type == TOKEN_BIG_MONEY) { if (next.type == TOKEN_SEMICOLON) {
Token reg_num = next_token_is(TOKEN_LITERAL_INT); s.ref = st->current_reg++;
s.ref = atoi(reg_num.start);
} else if (next.type == TOKEN_SEMICOLON) {
s.ref = st->scopes[st->scope_ref].count;
} else { } else {
printf("Unexpected token ERROR at line %d: %.*s\n", regType.line, regType.length, printf("Unexpected token ERROR at line %d: %.*s\n", regType.line, regType.length,
regType.start); regType.start);
@ -461,6 +422,10 @@ void define_function(VM *vm, ScopeTable *st) {
Symbol s; Symbol s;
s.scope = LOCAL; s.scope = LOCAL;
s.type = FUNCTION; s.type = FUNCTION;
/* push the last used reg on the stack */
st->last_used_registers[st->reg_count++] = st->current_reg;
st->current_reg = 0;
Token name = next_token_is(TOKEN_IDENTIFIER); Token name = next_token_is(TOKEN_IDENTIFIER);
if (name.length > MAX_SYMBOL_NAME_LENGTH) { if (name.length > MAX_SYMBOL_NAME_LENGTH) {
@ -499,6 +464,9 @@ void define_function(VM *vm, ScopeTable *st) {
st->scope_ref = temp; // need to add to the parents scope st->scope_ref = temp; // need to add to the parents scope
symbol_table_add(st, s); symbol_table_add(st, s);
st->scope_ref = (i32)st->count; st->scope_ref = (i32)st->count;
/* pop the current reg off the stack */
st->current_reg = st->last_used_registers[--st->reg_count];
} }
/** /**
@ -680,7 +648,7 @@ void build_symbol_table(VM *vm, char *source, ScopeTable *st) {
define_var(st, token); define_var(st, token);
next_token_is(TOKEN_SEMICOLON); next_token_is(TOKEN_SEMICOLON);
} else { } else {
define_global(vm, st); define_global(vm, st, token);
} }
continue; continue;
} }
@ -2373,6 +2341,7 @@ bool compile(VM *vm, ScopeTable *st, char *source) {
build_symbol_table(vm, source, st); build_symbol_table(vm, source, st);
vm->cp = 0; /* actually start emitting code */ vm->cp = 0; /* actually start emitting code */
st->count = 0; st->count = 0;
st->reg_count = 0;
emit_bytecode(vm, source, st); emit_bytecode(vm, source, st);
return true; return true;
} }

View File

@ -84,6 +84,9 @@ struct scope_tab_s {
u32 capacity; u32 capacity;
i32 scope_ref; i32 scope_ref;
u32 depth; u32 depth;
u8 last_used_registers[1024];
u32 reg_count;
u8 current_reg;
}; };
bool compile(VM *vm, ScopeTable *st, char *source); bool compile(VM *vm, ScopeTable *st, char *source);

View File

@ -4,15 +4,20 @@ int x = 1;
int y = 1; int y = 1;
function main () { function main () {
load_absolute_32 x -> $0; int local_x;
load_absolute_32 y -> $1; int local_y;
call add ($0 $1) -> $2; int result;
int_to_string $2 -> $3; int result_str;
call pln ($3);
load_absolute_32 x -> local_x;
load_absolute_32 y -> local_y;
call add (local_x local_y) -> result;
int_to_string result -> result_str;
call pln (result_str);
exit 0; exit 0;
} }
function add (int a, int b) { function add (int a, int b) int {
int result; int result;
add_int a b -> result; add_int a b -> result;
return result; return result;

View File

@ -2,30 +2,38 @@ str terminal_namespace = "/dev/term/0";
str new_line = "\n"; str new_line = "\n";
function main () { function main () {
int result;
int str_n; int str_n;
load_immediate 35 -> $0; load_immediate 35 -> result;
call fib ($0) -> $0; call fib (result) -> result;
int_to_string $0 -> str_n; int_to_string result -> str_n;
call pln (str_n); call pln (str_n);
exit 0; exit 0;
} }
function fib (int n) { function fib (int n) {
load_immediate 2 -> $1; int result;
load_immediate 2 -> result;
jump_lt_int base_case n $1; jump_lt_int base_case n result;
load_immediate 2 -> $3; int two;
sub_int n $3 -> $4; int tmp_n;
call fib ($4) -> $5; int result_a;
int result_b;
load_immediate 1 -> $3; load_immediate 2 -> two;
sub_int n $3 -> $4; sub_int n two -> tmp_n;
call fib ($4) -> $6; call fib (tmp_n) -> result_a;
add_int $6 $5 -> $7; int one;
return $7; load_immediate 1 -> one;
sub_int n one -> tmp_n;
call fib (tmp_n) -> result_b;
add_int result_b result_a -> result;
return result;
else base_case; else base_case;
return n; return n;

View File

@ -5,41 +5,50 @@ str new_line = "\n";
function main () { function main () {
real a; real a;
int i; int i;
int mode $11; int mode;
str term $10; str term;
int zero;
int decrement;
real five;
// do (i = 5000; i >= 0, i = i - 1) // do (i = 5000; i >= 0, i = i - 1)
load_immediate 5.0 -> a; load_immediate 5.0 -> a;
load_immediate 5000 -> i; load_immediate 5000 -> i;
load_immediate 0 -> $2; load_immediate 0 -> zero;
load_immediate -1 -> $3; load_immediate -1 -> decrement;
load_immediate 5.0 -> $5; load_immediate 5.0 -> five;
loop loop_body { loop loop_body {
add_real a $5 -> a; add_real a five -> a;
add_int i $3 -> i; add_int i decrement -> i;
jump_ge_int loop_body i $2; jump_ge_int loop_body i zero;
} }
load_address terminal_namespace -> term; load_address terminal_namespace -> term;
load_immediate 0 -> mode; load_immediate 0 -> mode;
syscall OPEN term mode term; // Terminal term = open("/dev/term/0", 0); syscall OPEN term mode term; // Terminal term = open("/dev/term/0", 0);
nat b $1; nat b;
str prompt_str;
nat prompt_len;
real_to_nat a -> b; real_to_nat a -> b;
load_address prompt -> $7; load_address prompt -> prompt_str;
string_length $7 -> $8; string_length prompt_str -> prompt_len;
syscall WRITE term $7 $8; // print prompt syscall WRITE term prompt_str prompt_len; // print prompt
str user_string $9; str user_string;
load_immediate 32 -> $8; nat user_max_string_size;
malloc $8 -> user_string; load_immediate 32 -> user_max_string_size;
syscall READ term user_string $8; // read in max 32 byte string malloc user_max_string_size -> user_string;
syscall READ term user_string user_max_string_size; // read in max 32 byte string
str b_string;
str a_string;
call pln (user_string); call pln (user_string);
nat_to_string b -> $4; nat_to_string b -> b_string;
call pln ($4); call pln (b_string);
real_to_string a -> $3; real_to_string a -> a_string;
call pln ($3); call pln (a_string);
exit 0; exit 0;
} }

View File

@ -10,14 +10,17 @@ function main () {
load_immediate 0 -> mode; load_immediate 0 -> mode;
syscall OPEN term mode term; // Terminal term = open("/dev/term/0", 0); syscall OPEN term mode term; // Terminal term = open("/dev/term/0", 0);
load_address prompt -> $7; str prompt_string;
string_length $7 -> $8; nat prompt_len;
syscall WRITE term $7 $8; // print prompt load_address prompt -> prompt_string;
string_length prompt_string -> prompt_len;
syscall WRITE term prompt_string prompt_len; // print prompt
str user_string; str user_string;
load_immediate 32 -> $8; nat user_max_string_size;
malloc $8 -> user_string; load_immediate 32 -> user_max_string_size;
syscall READ term user_string $8; // read in max 32 byte string malloc user_max_string_size -> user_string;
syscall READ term user_string user_max_string_size; // read in max 32 byte string
call pln (user_string); call pln (user_string);
exit 0; exit 0;

View File

@ -36,32 +36,34 @@ byte SELECTED_COLOR = 255;
function main () { function main () {
// Open screen // Open screen
ptr screen $0; ptr screen;
str screen_name $18; str screen_name;
int mode $11; int mode;
nat screen_buffer $21; nat screen_buffer;
// use load immediate because it a pointer to a string, not a value // use load immediate because it a pointer to a string, not a value
load_address screen_namespace -> screen_name; load_address screen_namespace -> screen_name;
load_immediate 0 -> mode; load_immediate 0 -> mode;
syscall OPEN screen_name mode screen; // Screen screen = open("/dev/screen/0", 0); syscall OPEN screen_name mode screen; // Screen screen = open("/dev/screen/0", 0);
nat width $20; nat width;
nat size $22; nat size;
load_offset_32 screen 8 -> width; // load width load_offset_32 screen 8 -> width; // load width
load_offset_32 screen 12 -> size; // load size load_offset_32 screen 12 -> size; // load size
load_immediate 16 -> $1; // offset for screen buffer
add_nat screen $1 -> screen_buffer; nat offset;
load_immediate 16 -> offset; // offset for screen buffer
add_nat screen offset -> screen_buffer;
// open mouse // open mouse
ptr mouse $15; ptr mouse;
str mouse_name $16; str mouse_name;
load_address mouse_namespace -> mouse_name; load_address mouse_namespace -> mouse_name;
syscall OPEN mouse_name mode mouse; // Mouse mouse = open("/dev/mouse/0", 0); syscall OPEN mouse_name mode mouse; // Mouse mouse = open("/dev/mouse/0", 0);
byte color $1; byte color;
nat x_pos $12; nat x_pos;
nat y_pos $13; nat y_pos;
load_absolute_8 BLACK -> color; load_absolute_8 BLACK -> color;
load_immediate 1 -> x_pos; load_immediate 1 -> x_pos;
@ -116,23 +118,24 @@ function main () {
// screen.draw // screen.draw
syscall WRITE screen screen_buffer size; syscall WRITE screen screen_buffer size;
nat m_zero $11; nat zero;
load_immediate 0 -> zero;
loop draw_loop { loop draw_loop {
// load mouse click data // load mouse click data
syscall REFRESH mouse; syscall REFRESH mouse;
byte left_down $9; byte left_down;
load_offset_8 mouse 16 -> left_down; // load btn1 pressed load_offset_8 mouse 16 -> left_down; // load btn1 pressed
jump_eq_nat draw_loop left_down m_zero; // if (!btn1.left) continue; jump_eq_nat draw_loop left_down zero; // if (!btn1.left) continue;
nat mouse_x $7; nat mouse_x;
nat mouse_y $8; nat mouse_y;
load_offset_32 mouse 8 -> mouse_x; // load x load_offset_32 mouse 8 -> mouse_x; // load x
load_offset_32 mouse 12 -> mouse_y; // load y load_offset_32 mouse 12 -> mouse_y; // load y
nat box_size $14; nat box_size;
load_immediate 20 -> box_size; load_immediate 20 -> box_size;
// first row // first row
@ -198,10 +201,10 @@ function main () {
syscall WRITE screen screen_buffer size; syscall WRITE screen screen_buffer size;
byte selected_color $25; byte selected_color;
load_absolute_8 SELECTED_COLOR -> selected_color; load_absolute_8 SELECTED_COLOR -> selected_color;
nat brush_size $19; nat brush_size;
load_immediate 5 -> brush_size; load_immediate 5 -> brush_size;
call draw_box (screen_buffer width selected_color mouse_x mouse_y brush_size brush_size); call draw_box (screen_buffer width selected_color mouse_x mouse_y brush_size brush_size);
@ -213,16 +216,15 @@ function main () {
exit 0; exit 0;
} }
function set_color_if_clicked (int click_x $0, int click_y $1, function set_color_if_clicked (int click_x, int click_y, int box_x, int box_y, byte check_color, int size) {
int box_x $2, int box_y $3, byte check_color $4, int bsize $5) {
// Compute right // Compute right
int right_edge $6; int right_edge;
add_int box_x bsize -> right_edge; add_int box_x size -> right_edge;
// Compute bottom = box_y + bsize // Compute bottom = box_y + size
int bottom_edge $7; int bottom_edge;
add_int box_y bsize -> bottom_edge; add_int box_y size -> bottom_edge;
// Bounds check: x in [box_x, right] and y in [box_y, bottom] // Bounds check: x in [box_x, right] and y in [box_y, bottom]
jump_lt_int fail click_x box_x; jump_lt_int fail click_x box_x;
@ -236,8 +238,7 @@ function set_color_if_clicked (int click_x $0, int click_y $1,
return; return;
} }
function draw_outlined_swatch(nat base, function draw_outlined_swatch(nat base, byte color, int x, int y, int width) {
byte swatch_color, int x, int y, int width) {
// Constants // Constants
nat background_color; nat background_color;
@ -246,7 +247,7 @@ function draw_outlined_swatch(nat base,
byte selected_color; byte selected_color;
load_absolute_8 SELECTED_COLOR -> selected_color; load_absolute_8 SELECTED_COLOR -> selected_color;
jump_eq_int set_selected swatch_color selected_color; jump_eq_int set_selected color selected_color;
jump end_set_selected; jump end_set_selected;
do set_selected do set_selected
load_absolute_8 DARK_GRAY -> background_color; load_absolute_8 DARK_GRAY -> background_color;
@ -265,10 +266,10 @@ function draw_outlined_swatch(nat base,
int x_off; int x_off;
int y_off; int y_off;
add_int x offset -> x_off; // x + 2 add_int x offset -> x_off; // x + 2
add_int y offset -> y_off; // y + 2 add_int y offset -> y_off; // y + 2
call draw_box (base width swatch_color x_off y_off fill_size fill_size); call draw_box (base width color x_off y_off fill_size fill_size);
return; return;
} }
@ -278,12 +279,13 @@ function draw_box (nat db_base, nat screen_width,
nat db_width, nat height) { nat db_width, nat height) {
// Compute start address: base + y*640 + x // Compute start address: base + y*640 + x
nat offset;
mul_int y_start screen_width -> offset;
add_int offset x_start -> offset;
add_nat offset db_base -> offset;
nat fat_ptr_size; nat fat_ptr_size;
load_immediate 4 -> fat_ptr_size; load_immediate 4 -> fat_ptr_size;
nat offset;
mul_nat y_start screen_width -> offset;
add_nat offset x_start -> offset;
add_nat offset db_base -> offset;
add_nat offset fat_ptr_size -> offset; // need to add offset for fat pointer size add_nat offset fat_ptr_size -> offset; // need to add offset for fat pointer size
int i; int i;