Incrementally build the compiler from the assembler
This commit is contained in:
parent
374a5d5c5d
commit
56550a3690
File diff suppressed because it is too large
Load Diff
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
function main () {
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main function
|
||||
*/
|
||||
function main() {
|
||||
int tmp0 = x;
|
||||
int tmp1 = y;
|
||||
int tmp2 = add(tmp0, tmp1);
|
||||
str tmp3 = tmp2 as str;
|
||||
pln(tmp3);
|
||||
function add (int a, int b) {
|
||||
int result;
|
||||
add_int a b -> result;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add two numbers together
|
||||
*/
|
||||
function add(int a, int b) int {
|
||||
int tmp0 = a + b;
|
||||
return tmp0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print with a newline
|
||||
*/
|
||||
function pln(str message) {
|
||||
str term_ns = term_namespace;
|
||||
int mode = 0;
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
function main () {
|
||||
int str_n;
|
||||
|
||||
load_immediate 35 -> $0;
|
||||
call fib ($0) -> $0;
|
||||
int_to_string $0 -> str_n;
|
||||
call pln (str_n);
|
||||
exit 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main function
|
||||
*/
|
||||
function main() {
|
||||
int fib = 35;
|
||||
int ans = fib(35);
|
||||
str ans_s = ans as str;
|
||||
pln(ans_s);
|
||||
function fib (int n) {
|
||||
load_immediate 2 -> $1;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively calculate fibonacci
|
||||
*/
|
||||
function fib(int n) int {
|
||||
int base_check = 2;
|
||||
function pln (str message) {
|
||||
ptr term;
|
||||
int msg_length;
|
||||
str nl;
|
||||
int nl_length;
|
||||
int mode;
|
||||
str term_ns;
|
||||
|
||||
jump_lt_int base_case n base_check;
|
||||
jump end1;
|
||||
do 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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
function main () {
|
||||
str msg;
|
||||
|
||||
load_address hello -> msg;
|
||||
call pln (msg);
|
||||
exit 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main function
|
||||
*/
|
||||
function main() {
|
||||
str msg = hello;
|
||||
pln(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print with a newline
|
||||
*/
|
||||
function pln(str message) {
|
||||
str term_ns = term_namespace;
|
||||
int mode = 0;
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
114
test/loop.uir.ul
114
test/loop.uir.ul
|
|
@ -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";
|
||||
|
||||
function main () {
|
||||
real a;
|
||||
int i;
|
||||
int mode $11;
|
||||
str term $10;
|
||||
|
||||
plex Terminal {
|
||||
nat handle;
|
||||
// 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 {
|
||||
add_real a $5 -> a;
|
||||
add_int i $3 -> i;
|
||||
jump_ge_int loop_body i $2;
|
||||
}
|
||||
|
||||
load_address terminal_namespace -> term;
|
||||
load_immediate 0 -> mode;
|
||||
syscall OPEN term mode term; // Terminal term = open("/dev/term/0", 0);
|
||||
|
||||
nat b $1;
|
||||
real_to_nat a -> b;
|
||||
load_address prompt -> $7;
|
||||
string_length $7 -> $8;
|
||||
syscall WRITE term $7 $8; // print prompt
|
||||
|
||||
str user_string $9;
|
||||
load_immediate 32 -> $8;
|
||||
malloc $8 -> user_string;
|
||||
syscall READ term user_string $8; // read in max 32 byte string
|
||||
|
||||
call pln (user_string);
|
||||
nat_to_string b -> $4;
|
||||
call pln ($4);
|
||||
real_to_string a -> $3;
|
||||
call pln ($3);
|
||||
exit 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main function
|
||||
*/
|
||||
function main() {
|
||||
str term_ns = term_namespace;
|
||||
int mode = 0;
|
||||
function pln (str message) {
|
||||
ptr term;
|
||||
int msg_length;
|
||||
str nl;
|
||||
int nl_length;
|
||||
int mode;
|
||||
str term_ns;
|
||||
|
||||
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;
|
||||
loop loop_body {
|
||||
a = a + tmp2;
|
||||
i = i - tmp1;
|
||||
jump_ge_int loop_body i tmp0;
|
||||
}
|
||||
|
||||
nat b = a as nat;
|
||||
str local_prompt = prompt;
|
||||
pln(local_prompt);
|
||||
|
||||
nat size = 32;
|
||||
str user_string = malloc(size);
|
||||
read(term, user_string, size);
|
||||
|
||||
str a_str = a as str;
|
||||
pln(a_str);
|
||||
|
||||
str b_str = b as str;
|
||||
pln(b_str);
|
||||
|
||||
pln(user_string);
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print with a newline
|
||||
*/
|
||||
function pln(str message) {
|
||||
str term_ns = term_namespace;
|
||||
int mode = 0;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
function main () {
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main function
|
||||
*/
|
||||
function main() {
|
||||
Terminal term = open("/dev/term/0", 0);
|
||||
pln(term, "Enter a string: ");
|
||||
pln(term, term.read(32));
|
||||
return 0;
|
||||
}
|
||||
function pln (str message) {
|
||||
ptr term;
|
||||
int msg_length;
|
||||
str nl;
|
||||
int nl_length;
|
||||
int mode;
|
||||
str term_ns;
|
||||
|
||||
/**
|
||||
* Print with a newline
|
||||
*/
|
||||
function pln(Terminal term, str message) {
|
||||
write(term, message, message.length);
|
||||
write(term, nl, nl.length);
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,56 +230,73 @@ 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;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue