1
0
Fork 0

Incrementally build the compiler from the assembler

This commit is contained in:
zongor 2026-02-17 20:41:23 -08:00
parent 374a5d5c5d
commit 56550a3690
9 changed files with 2292 additions and 475 deletions

File diff suppressed because it is too large Load Diff

View File

@ -119,10 +119,10 @@ static TokenType checkKeyword(int start, int length, const char *rest,
}
static TokenType identifierType() {
switch (lexer.start[0]) {
switch (parser.start[0]) {
case 'a':
if (lexer.current - lexer.start > 1) {
switch (lexer.start[1]) {
if (parser.current - parser.start > 1) {
switch (parser.start[1]) {
case 'n':
return checkKeyword(2, 1, "d", TOKEN_OPERATOR_AND);
case 's':
@ -131,8 +131,8 @@ static TokenType identifierType() {
}
break;
case 'c':
if (lexer.current - lexer.start > 1) {
switch (lexer.start[1]) {
if (parser.current - parser.start > 1) {
switch (parser.start[1]) {
case 'l':
return checkKeyword(2, 3, "ose", TOKEN_KEYWORD_CLOSE);
case 'o':
@ -143,8 +143,8 @@ static TokenType identifierType() {
case 'e':
return checkKeyword(1, 3, "lse", TOKEN_KEYWORD_ELSE);
case 'f':
if (lexer.current - lexer.start > 1) {
switch (lexer.start[1]) {
if (parser.current - parser.start > 1) {
switch (parser.start[1]) {
case 'a':
return checkKeyword(2, 3, "lse", TOKEN_KEYWORD_FALSE);
case 'o':
@ -156,8 +156,8 @@ static TokenType identifierType() {
}
break;
case 'i':
if (lexer.current - lexer.start > 1) {
switch (lexer.start[1]) {
if (parser.current - parser.start > 1) {
switch (parser.start[1]) {
case 'f':
return checkKeyword(2, 0, "", TOKEN_KEYWORD_IF);
case 's':
@ -169,8 +169,8 @@ static TokenType identifierType() {
case '3':
return checkKeyword(2, 1, "2", TOKEN_TYPE_INT);
case 'n':
if (lexer.current - lexer.start > 2) {
switch (lexer.start[2]) {
if (parser.current - parser.start > 2) {
switch (parser.start[2]) {
case 'i':
return checkKeyword(3, 2, "t", TOKEN_KEYWORD_INIT);
case 't':
@ -182,8 +182,8 @@ static TokenType identifierType() {
}
break;
case 'n':
if (lexer.current - lexer.start > 1) {
switch (lexer.start[1]) {
if (parser.current - parser.start > 1) {
switch (parser.start[1]) {
case 'a':
return checkKeyword(2, 1, "t", TOKEN_TYPE_NAT);
case 'i':
@ -192,8 +192,8 @@ static TokenType identifierType() {
}
break;
case 'o':
if (lexer.current - lexer.start > 1) {
switch (lexer.start[1]) {
if (parser.current - parser.start > 1) {
switch (parser.start[1]) {
case 'p':
return checkKeyword(2, 2, "en", TOKEN_KEYWORD_OPEN);
case 'r':
@ -202,19 +202,21 @@ static TokenType identifierType() {
}
break;
case 'p':
if (lexer.current - lexer.start > 1) {
switch (lexer.start[1]) {
if (parser.current - parser.start > 1) {
switch (parser.start[1]) {
case 't':
return checkKeyword(2, 1, "r", TOKEN_TYPE_PTR);
case 'l':
return checkKeyword(2, 2, "ex", TOKEN_KEYWORD_PLEX);
}
}
break;
case 'r':
if (lexer.current - lexer.start > 1) {
switch (lexer.start[1]) {
if (parser.current - parser.start > 1) {
switch (parser.start[1]) {
case 'e':
if (lexer.current - lexer.start > 2) {
switch (lexer.start[2]) {
if (parser.current - parser.start > 2) {
switch (parser.start[2]) {
case 'a':
return checkKeyword(3, 1, "d", TOKEN_KEYWORD_READ);
case 't':
@ -226,11 +228,11 @@ static TokenType identifierType() {
}
break;
case 's':
if (lexer.current - lexer.start > 1) {
switch (lexer.start[1]) {
if (parser.current - parser.start > 1) {
switch (parser.start[1]) {
case 't':
if (lexer.current - lexer.start > 2) {
switch (lexer.start[2]) {
if (parser.current - parser.start > 2) {
switch (parser.start[2]) {
case 'r':
return checkKeyword(2, 0, "", TOKEN_TYPE_STR);
case 'a':
@ -241,8 +243,8 @@ static TokenType identifierType() {
}
break;
case 't':
if (lexer.current - lexer.start > 1) {
switch (lexer.start[1]) {
if (parser.current - parser.start > 1) {
switch (parser.start[1]) {
case 'h':
return checkKeyword(2, 2, "is", TOKEN_KEYWORD_THIS);
case 'r':
@ -251,8 +253,8 @@ static TokenType identifierType() {
}
break;
case 'u':
if (lexer.current - lexer.start > 1) {
switch (lexer.start[1]) {
if (parser.current - parser.start > 1) {
switch (parser.start[1]) {
case 's':
return checkKeyword(2, 1, "e", TOKEN_KEYWORD_USE);
case '8':
@ -265,8 +267,8 @@ static TokenType identifierType() {
}
break;
case 'w':
if (lexer.current - lexer.start > 1) {
switch (lexer.start[1]) {
if (parser.current - parser.start > 1) {
switch (parser.start[1]) {
case 'h':
return checkKeyword(2, 3, "ile", TOKEN_KEYWORD_WHILE);
case 'r':
@ -401,6 +403,8 @@ const char *token_type_to_string(TokenType type) {
return "TYPE_REAL";
case TOKEN_TYPE_STR:
return "TYPE_STR";
case TOKEN_TYPE_PTR:
return "TYPE_PTR";
case TOKEN_KEYWORD_PLEX:
return "KEYWORD_PLEX";
case TOKEN_KEYWORD_FN:
@ -433,8 +437,8 @@ const char *token_type_to_string(TokenType type) {
return "TOKEN_KEYWORD_READ";
case TOKEN_KEYWORD_WRITE:
return "TOKEN_KEYWORD_WRITE";
case TOKEN_KEYWORD_REFRESH:
return "TOKEN_KEYWORD_REFRESH";
case TOKEN_KEYWORD_STAT:
return "TOKEN_KEYWORD_STAT";
case TOKEN_KEYWORD_CLOSE:
return "TOKEN_KEYWORD_CLOSE";
case TOKEN_KEYWORD_NIL:

View File

@ -18,6 +18,7 @@ typedef enum {
TOKEN_TYPE_STR,
TOKEN_TYPE_BOOL,
TOKEN_TYPE_VOID,
TOKEN_TYPE_PTR,
TOKEN_KEYWORD_PLEX,
TOKEN_KEYWORD_FN,
TOKEN_KEYWORD_CONST,
@ -34,7 +35,7 @@ typedef enum {
TOKEN_KEYWORD_OPEN,
TOKEN_KEYWORD_READ,
TOKEN_KEYWORD_WRITE,
TOKEN_KEYWORD_REFRESH,
TOKEN_KEYWORD_STAT,
TOKEN_KEYWORD_CLOSE,
TOKEN_KEYWORD_LOOP,
TOKEN_KEYWORD_DO,

View File

@ -1,47 +1,38 @@
/**
* Constants
*/
str term_namespace = "/dev/term/0";
str nl = "\n";
int x = 0;
str terminal_namespace = "/dev/term/0";
str new_line = "\n";
int x = 1;
int y = 1;
plex Terminal {
nat handle;
}
/**
* Main function
*/
function main () {
int tmp0 = x;
int tmp1 = y;
int tmp2 = add(tmp0, tmp1);
str tmp3 = tmp2 as str;
pln(tmp3);
load_absolute_32 x -> $0;
load_absolute_32 y -> $1;
call add ($0 $1) -> $2;
int_to_string $2 -> $3;
call pln ($3);
exit 0;
}
/**
* Add two numbers together
*/
function add(int a, int b) int {
int tmp0 = a + b;
return tmp0;
function add (int a, int b) {
int result;
add_int a b -> result;
return result;
}
/**
* Print with a newline
*/
function pln (str message) {
str term_ns = term_namespace;
int mode = 0;
ptr term;
int msg_length;
str nl;
int nl_length;
int mode;
str term_ns;
Terminal term = open(term_ns, mode);
int msg_len = message.length;
write(term, message, msg_len);
str nl_local = nl;
int nl_len = nl.length;
write(term, nl_local, nl_len);
load_immediate 0 -> mode;
load_address terminal_namespace -> term_ns;
syscall OPEN term_ns mode term;
string_length message -> msg_length;
syscall WRITE term message msg_length;
load_address new_line -> nl;
string_length nl -> nl_length;
syscall WRITE term nl nl_length;
return;
}

View File

@ -1,60 +1,51 @@
/**
* Constants
*/
str term_namespace = "/dev/term/0";
str nl = "\n";
str terminal_namespace = "/dev/term/0";
str new_line = "\n";
plex Terminal {
nat handle;
}
/**
* Main function
*/
function main () {
int fib = 35;
int ans = fib(35);
str ans_s = ans as str;
pln(ans_s);
int str_n;
load_immediate 35 -> $0;
call fib ($0) -> $0;
int_to_string $0 -> str_n;
call pln (str_n);
exit 0;
}
/**
* Recursively calculate fibonacci
*/
function fib(int n) int {
int base_check = 2;
function fib (int n) {
load_immediate 2 -> $1;
jump_lt_int base_case n base_check;
jump end1;
do base_case;
jump_lt_int base_case n $1;
load_immediate 2 -> $3;
sub_int n $3 -> $4;
call fib ($4) -> $5;
load_immediate 1 -> $3;
sub_int n $3 -> $4;
call fib ($4) -> $6;
add_int $6 $5 -> $7;
return $7;
else base_case;
return n;
else base_case_end;
int tmp_c2 = 2;
int tmp_c2_n = n - tmp_c2;
int ans_c2 = fib(tmp_c2_n);
int tmp_c1 = 1;
int tmp_c1_n = tmp_c1 - n;
int ans_c1 = fib(tmp_c1_n);
int ans = tmp_c1_n + tmp_c2_n;
return ans;
}
/**
* Print with a newline
*/
function pln (str message) {
str term_ns = term_namespace;
int mode = 0;
ptr term;
int msg_length;
str nl;
int nl_length;
int mode;
str term_ns;
Terminal term = open(term_ns, mode);
int msg_len = message.length;
write(term, message, msg_len);
str nl_local = nl;
int nl_len = nl.length;
write(term, nl_local, nl_len);
load_immediate 0 -> mode;
load_address terminal_namespace -> term_ns;
syscall OPEN term_ns mode term;
string_length message -> msg_length;
syscall WRITE term message msg_length;
load_address new_line -> nl;
string_length nl -> nl_length;
syscall WRITE term nl nl_length;
return;
}

View File

@ -1,32 +1,30 @@
str term_namespace = "/dev/term/0";
str terminal_namespace = "/dev/term/0";
str new_line = "\n";
str hello = "nuqneH 'u'?";
str nl = "\n";
plex Terminal {
nat handle;
}
/**
* Main function
*/
function main () {
str msg = hello;
pln(msg);
str msg;
load_address hello -> msg;
call pln (msg);
exit 0;
}
/**
* Print with a newline
*/
function pln (str message) {
str term_ns = term_namespace;
int mode = 0;
ptr term;
int msg_length;
str nl;
int nl_length;
int mode;
str term_ns;
Terminal term = open(term_ns, mode);
int msg_len = message.length;
write(term, message, msg_len);
str nl_local = nl;
int nl_len = nl.length;
write(term, nl_local, nl_len);
load_immediate 0 -> mode;
load_address terminal_namespace -> term_ns;
syscall OPEN term_ns mode term;
string_length message -> msg_length;
syscall WRITE term message msg_length;
load_address new_line -> nl;
string_length nl -> nl_length;
syscall WRITE term nl nl_length;
return;
}

View File

@ -1,65 +1,63 @@
str term_namespace = "/dev/term/0";
str terminal_namespace = "/dev/term/0";
str prompt = "Enter a string:";
str nl = "\n";
str new_line = "\n";
plex Terminal {
nat handle;
}
/**
* Main function
*/
function main () {
str term_ns = term_namespace;
int mode = 0;
real a;
int i;
int mode $11;
str term $10;
Terminal term = open(term_ns, mode);
real a = 5.0;
// do (int i = 5000; i >= 0, i = i - 1)
int i = 5000;
int tmp0 = 0;
int tmp1 = 1;
int tmp2 = 5.0;
// do (i = 5000; i >= 0, i = i - 1)
load_immediate 5.0 -> a;
load_immediate 5000 -> i;
load_immediate 0 -> $2;
load_immediate -1 -> $3;
load_immediate 5.0 -> $5;
loop loop_body {
a = a + tmp2;
i = i - tmp1;
jump_ge_int loop_body i tmp0;
add_real a $5 -> a;
add_int i $3 -> i;
jump_ge_int loop_body i $2;
}
nat b = a as nat;
str local_prompt = prompt;
pln(local_prompt);
load_address terminal_namespace -> term;
load_immediate 0 -> mode;
syscall OPEN term mode term; // Terminal term = open("/dev/term/0", 0);
nat size = 32;
str user_string = malloc(size);
read(term, user_string, size);
nat b $1;
real_to_nat a -> b;
load_address prompt -> $7;
string_length $7 -> $8;
syscall WRITE term $7 $8; // print prompt
str a_str = a as str;
pln(a_str);
str user_string $9;
load_immediate 32 -> $8;
malloc $8 -> user_string;
syscall READ term user_string $8; // read in max 32 byte string
str b_str = b as str;
pln(b_str);
pln(user_string);
call pln (user_string);
nat_to_string b -> $4;
call pln ($4);
real_to_string a -> $3;
call pln ($3);
exit 0;
}
/**
* Print with a newline
*/
function pln (str message) {
str term_ns = term_namespace;
int mode = 0;
ptr term;
int msg_length;
str nl;
int nl_length;
int mode;
str term_ns;
Terminal term = open(term_ns, mode);
int msg_len = message.length;
write(term, message, msg_len);
str nl_local = nl;
int nl_len = nl.length;
write(term, nl_local, nl_len);
load_immediate 0 -> mode;
load_address terminal_namespace -> term_ns;
syscall OPEN term_ns mode term;
string_length message -> msg_length;
syscall WRITE term message msg_length;
load_address new_line -> nl;
string_length nl -> nl_length;
syscall WRITE term nl nl_length;
return;
}

View File

@ -1,26 +1,43 @@
/**
* Constants
*/
const str nl = "\n";
str terminal_namespace = "/dev/term/0";
str prompt = "Enter a string:";
str new_line = "\n";
plex Terminal {
nat handle;
}
/**
* Main function
*/
function main () {
Terminal term = open("/dev/term/0", 0);
pln(term, "Enter a string: ");
pln(term, term.read(32));
return 0;
int mode;
str term;
load_address terminal_namespace -> term;
load_immediate 0 -> mode;
syscall OPEN term mode term; // Terminal term = open("/dev/term/0", 0);
load_address prompt -> $7;
string_length $7 -> $8;
syscall WRITE term $7 $8; // print prompt
str user_string;
load_immediate 32 -> $8;
malloc $8 -> user_string;
syscall READ term user_string $8; // read in max 32 byte string
call pln (user_string);
exit 0;
}
/**
* Print with a newline
*/
function pln(Terminal term, str message) {
write(term, message, message.length);
write(term, nl, nl.length);
function pln (str message) {
ptr term;
int msg_length;
str nl;
int nl_length;
int mode;
str term_ns;
load_immediate 0 -> mode;
load_address terminal_namespace -> term_ns;
syscall OPEN term_ns mode term;
string_length message -> msg_length;
syscall WRITE term message msg_length;
load_address new_line -> nl;
string_length nl -> nl_length;
syscall WRITE term nl nl_length;
return;
}

View File

@ -34,188 +34,195 @@ byte DARK_ORANGE = 208;
byte GOLD = 244;
byte SELECTED_COLOR = 255;
plex Screen {
nat handle;
nat width;
nat height;
byte[] buffer;
}
plex Mouse {
nat handle;
nat x;
nat y;
bool left;
bool right;
bool middle;
bool btn4;
}
function main () {
str screen_name = screen_namespace;
int mode = 0;
Screen screen = open(screen_name, mode);
// Open screen
ptr screen $0;
str screen_name $18;
int mode $11;
nat screen_buffer $21;
nat width = screen.width;
nat size = screen.size;
nat screen_offset = 16;
nat screen_buffer = screen_buffer + screen_offset;
// use load immediate because it a pointer to a string, not a value
load_address screen_namespace -> screen_name;
load_immediate 0 -> mode;
syscall OPEN screen_name mode screen; // Screen screen = open("/dev/screen/0", 0);
nat width $20;
nat size $22;
load_offset_32 screen 8 -> width; // load width
load_offset_32 screen 12 -> size; // load size
load_immediate 16 -> $1; // offset for screen buffer
add_nat screen $1 -> screen_buffer;
// open mouse
str mouse_name = mouse_namespace;
Mouse mouse = open(mouse_name, mode);
ptr mouse $15;
str mouse_name $16;
load_address mouse_namespace -> mouse_name;
syscall OPEN mouse_name mode mouse; // Mouse mouse = open("/dev/mouse/0", 0);
byte color = BLACK;
nat x_pos = 1;
nat y_pos = 1;
draw_outlined_swatch(screen_buffer, color, x_pos, y_pos, width);
byte color $1;
nat x_pos $12;
nat y_pos $13;
color = WHITE;
x_pos = 21;
y_pos = 1;
draw_outlined_swatch(screen_buffer, color, x_pos, y_pos, width);
load_absolute_8 BLACK -> color;
load_immediate 1 -> x_pos;
load_immediate 1 -> y_pos;
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
color = CHARCOAL;
x_pos = 1;
y_pos = 21;
draw_outlined_swatch(screen_buffer, color, x_pos, y_pos, width);
load_absolute_8 WHITE -> color;
load_immediate 21 -> x_pos;
load_immediate 1 -> y_pos;
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
color = DARK_GRAY;
x_pos = 21;
y_pos = 21;
draw_outlined_swatch(screen_buffer, color, x_pos, y_pos, width);
load_absolute_8 CHARCOAL -> color;
load_immediate 1 -> x_pos;
load_immediate 21 -> y_pos;
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
color = RED;
x_pos = 1;
y_pos = 41;
draw_outlined_swatch(screen_buffer, color, x_pos, y_pos, width);
load_absolute_8 DARK_GRAY -> color;
load_immediate 21 -> x_pos;
load_immediate 21 -> y_pos;
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
color = ORANGE;
x_pos = 21;
y_pos = 41;
draw_outlined_swatch(screen_buffer, color, x_pos, y_pos, width);
load_absolute_8 RED -> color;
load_immediate 1 -> x_pos;
load_immediate 41 -> y_pos;
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
color = YELLOW;
x_pos = 1;
y_pos = 61;
draw_outlined_swatch(screen_buffer, color, x_pos, y_pos, width);
load_absolute_8 ORANGE -> color;
load_immediate 21 -> x_pos;
load_immediate 41 -> y_pos;
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
color = GREEN;
x_pos = 21;
y_pos = 61;
draw_outlined_swatch(screen_buffer, color, x_pos, y_pos, width);
load_absolute_8 YELLOW -> color;
load_immediate 1 -> x_pos;
load_immediate 61 -> y_pos;
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
color = BLUE;
x_pos = 1;
y_pos = 81;
draw_outlined_swatch(screen_buffer, color, x_pos, y_pos, width);
load_absolute_8 GREEN -> color;
load_immediate 21 -> x_pos;
load_immediate 61 -> y_pos;
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
color = PURPLE;
x_pos = 21;
y_pos = 81;
draw_outlined_swatch(screen_buffer, color, x_pos, y_pos, width);
load_absolute_8 BLUE -> color;
load_immediate 1 -> x_pos;
load_immediate 81 -> y_pos;
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
load_absolute_8 PURPLE -> color;
load_immediate 21 -> x_pos;
load_immediate 81 -> y_pos;
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
// screen.draw
write(screen, screen_buffer, size);
syscall WRITE screen screen_buffer size;
nat zero = 0;
nat m_zero $11;
loop draw {
loop draw_loop {
// load mouse click data
refresh(mouse);
syscall REFRESH mouse;
byte left_down = mouse.down;
byte left_down $9;
load_offset_8 mouse 16 -> left_down; // load btn1 pressed
jump_eq_nat draw left_down zero; // if (!btn1.left) continue;
jump_eq_nat draw_loop left_down m_zero; // if (!btn1.left) continue;
nat mouse_x = mouse.x;
nat mouse_y = mouse.y;
nat mouse_x $7;
nat mouse_y $8;
load_offset_32 mouse 8 -> mouse_x; // load x
load_offset_32 mouse 12 -> mouse_y; // load y
nat box_size = 20;
nat box_size $14;
load_immediate 20 -> box_size;
// first row
color = BLACK;
x_pos = 1;
y_pos = 1;
draw_outlined_swatch(screen_buffer, color, x_pos, y_pos, width);
set_color(mouse_x, mouse_y, x_pos, y_pos, color, box_size);
load_absolute_8 BLACK -> color;
load_immediate 1 -> x_pos;
load_immediate 1 -> y_pos;
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
call set_color_if_clicked (mouse_x mouse_y x_pos y_pos color box_size);
color = WHITE;
x_pos = 21;
y_pos = 1;
draw_outlined_swatch(screen_buffer, color, x_pos, y_pos, width);
set_color(mouse_x, mouse_y, x_pos, y_pos, color, box_size);
load_absolute_8 WHITE -> color;
load_immediate 21 -> x_pos;
load_immediate 1 -> y_pos;
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
call set_color_if_clicked (mouse_x mouse_y x_pos y_pos color box_size);
color = CHARCOAL;
x_pos = 1;
y_pos = 21;
draw_outlined_swatch(screen_buffer, color, x_pos, y_pos, width);
set_color(mouse_x, mouse_y, x_pos, y_pos, color, box_size);
load_absolute_8 CHARCOAL -> color;
load_immediate 1 -> x_pos;
load_immediate 21 -> y_pos;
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
call set_color_if_clicked (mouse_x mouse_y x_pos y_pos color box_size);
DARK_GRAY -> color;
x_pos = 21;
y_pos = 21;
draw_outlined_swatch(screen_buffer, color, x_pos, y_pos, width);
set_color(mouse_x, mouse_y, x_pos, y_pos, color, box_size);
load_absolute_8 DARK_GRAY -> color;
load_immediate 21 -> x_pos;
load_immediate 21 -> y_pos;
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
call set_color_if_clicked (mouse_x mouse_y x_pos y_pos color box_size);
color = RED;
x_pos = 1;
y_pos = 41;
draw_outlined_swatch(screen_buffer, color, x_pos, y_pos, width);
set_color(mouse_x, mouse_y, x_pos, y_pos, color, box_size);
load_absolute_8 RED -> color;
load_immediate 1 -> x_pos;
load_immediate 41 -> y_pos;
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
call set_color_if_clicked (mouse_x mouse_y x_pos y_pos color box_size);
color = ORANGE;
x_pos = 21;
y_pos = 41;
draw_outlined_swatch(screen_buffer, color, x_pos, y_pos, width);
set_color(mouse_x, mouse_y, x_pos, y_pos, color, box_size);
load_absolute_8 ORANGE -> color;
load_immediate 21 -> x_pos;
load_immediate 41 -> y_pos;
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
call set_color_if_clicked (mouse_x mouse_y x_pos y_pos color box_size);
color = YELLOW;
x_pos = 1;
y_pos = 61;
draw_outlined_swatch(screen_buffer, color, x_pos, y_pos, width);
set_color(mouse_x, mouse_y, x_pos, y_pos, color, box_size);
load_absolute_8 YELLOW -> color;
load_immediate 1 -> x_pos;
load_immediate 61 -> y_pos;
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
call set_color_if_clicked (mouse_x mouse_y x_pos y_pos color box_size);
color = GREEN;
x_pos = 21;
y_pos = 61;
draw_outlined_swatch(screen_buffer, color, x_pos, y_pos, width);
set_color(mouse_x, mouse_y, x_pos, y_pos, color, box_size);
load_absolute_8 GREEN -> color;
load_immediate 21 -> x_pos;
load_immediate 61 -> y_pos;
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
call set_color_if_clicked (mouse_x mouse_y x_pos y_pos color box_size);
color = BLUE;
x_pos = 1;
y_pos = 81;
draw_outlined_swatch(screen_buffer, color, x_pos, y_pos, width);
set_color(mouse_x, mouse_y, x_pos, y_pos, color, box_size);
load_absolute_8 BLUE -> color;
load_immediate 1 -> x_pos;
load_immediate 81 -> y_pos;
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
call set_color_if_clicked (mouse_x mouse_y x_pos y_pos color box_size);
color = PURPLE;
x_pos = 21;
y_pos = 81;
draw_outlined_swatch(screen_buffer, color, x_pos, y_pos, width);
set_color(mouse_x, mouse_y, x_pos, y_pos, color, box_size);
load_absolute_8 PURPLE -> color;
load_immediate 21 -> x_pos;
load_immediate 81 -> y_pos;
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
call set_color_if_clicked (mouse_x mouse_y x_pos y_pos color box_size);
write(screen, screen_buffer, size);
syscall WRITE screen screen_buffer size;
byte selected_color = SELECTED_COLOR;
byte selected_color $25;
load_absolute_8 SELECTED_COLOR -> selected_color;
nat brush_size = 5;
nat brush_size $19;
load_immediate 5 -> brush_size;
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);
jump draw;
jump draw_loop;
}
// Flush and exit
exit 0;
}
function set_color (int click_x, int click_y, int box_x, int box_y, byte check_color, int size) {
function set_color_if_clicked (int click_x $0, int click_y $1,
int box_x $2, int box_y $3, byte check_color $4, int bsize $5) {
// Compute right
int right_edge = box_x + size;
int right_edge $6;
add_int box_x bsize -> right_edge;
// Compute bottom = box_y + size
int bottom_edge = box_y + size;
// Compute bottom = box_y + bsize
int bottom_edge $7;
add_int box_y bsize -> bottom_edge;
// Bounds check: x in [box_x, right] and y in [box_y, bottom]
jump_lt_int fail click_x box_x;
@ -223,55 +230,72 @@ function set_color (int click_x, int click_y, int box_x, int box_y, byte check_c
jump_lt_int fail click_y box_y;
jump_gt_int fail click_y bottom_edge;
SELECTED_COLOR = check_color;
store_absolute_8 check_color -> SELECTED_COLOR;
else fail
return;
}
function draw_outlined_swatch(nat base, byte swatch_color, int x, int y, int width) {
function draw_outlined_swatch(nat base,
byte swatch_color, int x, int y, int width) {
nat background_color = GRAY;
byte selected_color = SELECTED_COLOR;
// Constants
nat background_color;
load_absolute_8 GRAY -> background_color;
byte selected_color;
load_absolute_8 SELECTED_COLOR -> selected_color;
jump_eq_int set_selected swatch_color selected_color;
jump end_set_selected;
do set_selected
background_color = DARK_GRAY;
load_absolute_8 DARK_GRAY -> background_color;
else end_set_selected
nat outline_size = 20;
nat fill_size = 17;
nat outline_size;
load_immediate 20 -> outline_size;
draw_box(base, width, background_color, x, y, outline_size, outline_size);
nat fill_size;
load_immediate 17 -> fill_size;
nat offset = 2;
int xO = x + offset; // x + 2
int yO = y + offset; // y + 2
nat offset;
load_immediate 2 -> offset;
draw_box(base, width, swatch_color, xO, yO, fill_size, fill_size);
call draw_box (base width background_color x y outline_size outline_size);
int x_off;
int y_off;
add_int x offset -> x_off; // x + 2
add_int y offset -> y_off; // y + 2
call draw_box (base width swatch_color x_off y_off fill_size fill_size);
return;
}
function draw_box (nat base, nat screen_width, byte box_color,
nat x, nat y, nat width, nat height) {
nat fat_ptr_size = 4;
function draw_box (nat db_base, nat screen_width,
byte box_color, nat x_start, nat y_start,
nat db_width, nat height) {
// Compute start address: base + y*640 + x
nat offset = y * screen_width;
offset = offset + x;
offset = offset + base;
offset = offset + fat_ptr_size; // need to add offset for fat pointer size
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;
load_immediate 4 -> fat_ptr_size;
add_nat offset fat_ptr_size -> offset; // need to add offset for fat pointer size
int i = 1;
int zero = 0;
int i;
load_immediate 1 -> i;
int zero;
load_immediate 0 -> zero;
loop draw_box_outer {
memset(offset, width, box_color); // draw row
offset = offset + screen_width; // next row += 640
height = height - i; // decrement row count
memset_8 box_color db_width -> offset; // draw row
add_int offset screen_width -> offset; // next row += 640
sub_int height i -> height; // decrement row count
jump_gt_int draw_box_outer height zero;
}
return;