From 411481214671de97a08d18245e505dd6f75d8d1a Mon Sep 17 00:00:00 2001 From: zongor Date: Sat, 20 Dec 2025 00:42:28 -0800 Subject: [PATCH] Update assembler to add scopes --- src/arch/emscripten/main.c | 4 +- src/arch/linux/main.c | 32 +++-- src/tools/assembler/assembler.c | 117 +++++++++++----- src/tools/assembler/assembler.h | 19 ++- src/tools/compiler/compiler.c | 235 ++++---------------------------- src/tools/compiler/parser.c | 2 +- src/tools/compiler/parser.h | 4 + test/add.ul.ir | 9 +- test/fib.ul.ir | 10 +- test/hello.ul.ir | 8 +- test/loop.ul.ir | 26 ++-- test/malloc.ul.ir | 21 +-- test/paint-bw.ul.ir | 21 +-- test/paint.ul.ir | 24 ++-- test/simple.ul.ir | 6 +- test/window.ul.ir | 16 ++- 16 files changed, 236 insertions(+), 318 deletions(-) diff --git a/src/arch/emscripten/main.c b/src/arch/emscripten/main.c index 8067a09..e22622c 100644 --- a/src/arch/emscripten/main.c +++ b/src/arch/emscripten/main.c @@ -89,7 +89,7 @@ void mainloop() { } int cycles_this_frame = 0; - int max_cycles_per_frame = 2000; + int max_cycles_per_frame = 1000; while (cycles_this_frame < max_cycles_per_frame) { if (!step_vm(&vm)) { emscripten_cancel_main_loop(); @@ -181,4 +181,4 @@ int main(int argc, char **argv) { emscripten_set_main_loop(mainloop, 0, 1); return 0; -} \ No newline at end of file +} diff --git a/src/arch/linux/main.c b/src/arch/linux/main.c index 7a4453c..27ec9a9 100644 --- a/src/arch/linux/main.c +++ b/src/arch/linux/main.c @@ -130,24 +130,29 @@ bool compileAndSave(const char *source_file, const char *output_file, VM *vm) { } #ifdef STATIC - #define SYMBOLS_COUNT 2048 - Symbol symbols[SYMBOLS_COUNT]; + #define SCOPES_COUNT 2048 + SymbolTable scopes[SCOPES_COUNT]; #endif -void symbol_table_init(SymbolTable *t) { +void symbol_table_init(ScopeTable *t) { #ifdef STATIC - memset(symbols, 0, SYMBOLS_COUNT*sizeof(Symbol)); - t->symbols = symbols; + memset(scopes, 0, SCOPES_COUNT*sizeof(SymbolTable)); + t->scopes = scopes; t->count = 0; - t->capacity = SYMBOLS_COUNT; + t->capacity = SCOPES_COUNT; #else - t->symbols = calloc(16, sizeof(Symbol)); + t->scopes = calloc(16, sizeof(SymbolTable)); t->count = 0; t->capacity = 16; #endif + + // Make sure that all the parents are the 'global' namespace. + for (u32 i = 0; i < t->capacity; i++) { + t->scopes[i].parent = -1; + } } -bool resize_or_check_size(SymbolTable *table) { +bool table_realloc(ScopeTable *table) { #ifdef STATIC if (table->count >= table->capacity) { return false; @@ -155,7 +160,12 @@ bool resize_or_check_size(SymbolTable *table) { #else if (table->count >= table->capacity) { table->capacity *= 2; - table->symbols = realloc(table->symbols, table->capacity * sizeof(Symbol)); + table->scopes = realloc(table->scopes, table->capacity * sizeof(SymbolTable)); + + // Make sure that all the parents are the 'global' namespace. + for (u32 i = table->count; i < table->capacity; i++) { + table->scopes[i].parent = -1; + } } #endif return true; @@ -183,11 +193,11 @@ bool assembleAndSave(const char *source_file, const char *output_file, VM *vm) { source[read] = '\0'; fclose(f); - SymbolTable table = {0}; + ScopeTable table = {0}; symbol_table_init(&table); assemble(vm, &table, source); #ifndef STATIC - free(table.symbols); + free(table.scopes); #endif if (output_file) { diff --git a/src/tools/assembler/assembler.c b/src/tools/assembler/assembler.c index 00ed047..5d73fde 100644 --- a/src/tools/assembler/assembler.c +++ b/src/tools/assembler/assembler.c @@ -162,35 +162,46 @@ void emit_u32(VM *vm, u32 value) { write_u32(vm, code, vm->cp, value); } -Symbol *symbol_table_lookup(SymbolTable *table, const char *name, u32 length) { - for (u32 i = 0; i < table->count; i++) { - if (table->symbols[i].name_length == length) { - if (strleq(table->symbols[i].name, name, length)) { - return &table->symbols[i]; +Symbol *symbol_table_lookup(ScopeTable *table, const char *name, u32 length, + i32 scope_ref) { + SymbolTable st = table->scopes[scope_ref]; + for (u32 i = 0; i < st.count; i++) { + if (st.symbols[i].name_length == length) { + if (strleq(st.symbols[i].name, name, length)) { + return &table->scopes[scope_ref].symbols[i]; } } } - return nil; + if (st.parent < 0) + return nil; + return symbol_table_lookup(table, name, length, st.parent); } -u32 symbol_table_add(SymbolTable *table, Symbol s) { - Symbol *sym = symbol_table_lookup(table, s.name, s.name_length); +u8 symbol_table_add(ScopeTable *table, Symbol s) { + Symbol *sym = + symbol_table_lookup(table, s.name, s.name_length, table->scope_ref); if (sym != nil) { fprintf(stderr, - "Error: Symbol '%.*s' already defined, the assembler is not smart " - "enough to do scope properly so please pick a different variable " - "name (hard I know)\n", + "Error: Symbol '%.*s' already defined, in this scope" + " please pick a different variable name or create a new scope.\n", s.name_length, s.name); exit(1); } - if (!resize_or_check_size(table)) { + if (table->scopes[table->scope_ref].count + 1 > 255) { + fprintf(stderr, "Error: Only 255 symbols are allowed per scope" + " first off: impressive; secondly:" + " just create a new scope and keep going.\n"); + exit(1); + } + + if (!table_realloc(table)) { fprintf(stderr, "Error: Symbol table is out of memory! This is likely because you " - "built the assembler in static mode, increase the static size." - "if you built using malloc, that means your computer is out of " - "memory. Close a few tabs in your web browser and try again." - "Count was %d, while capacity was %d\n", + " built the assembler in static mode, increase the static size." + " if you built using malloc, that means your computer is out of" + " memory. Close a few tabs in your web browser and try again." + " Count was %d, while capacity was %d\n", table->count, table->capacity); exit(1); } @@ -203,15 +214,14 @@ u32 symbol_table_add(SymbolTable *table, Symbol s) { printf("code[%d] = %s\n", s.ref, s.name); } #endif - - table->symbols[table->count] = s; - u32 index = table->count; - table->count++; + table->scopes[table->scope_ref].symbols[table->scopes[table->scope_ref].count] = s; + u8 index = table->scopes[table->scope_ref].count; + table->scopes[table->scope_ref].count++; return index; } -u32 get_ref(SymbolTable *st, const char *name, u32 length) { - Symbol *sym = symbol_table_lookup(st, name, length); +u32 get_ref(ScopeTable *st, const char *name, u32 length) { + Symbol *sym = symbol_table_lookup(st, name, length, st->scope_ref); if (!sym) { fprintf(stderr, "Error: Assembler has no idea what Symbol '%.*s' means.\n", length, name); @@ -221,7 +231,7 @@ u32 get_ref(SymbolTable *st, const char *name, u32 length) { return sym->ref; } -u32 get_ptr(Token token, SymbolTable *st) { +u32 get_ptr(Token token, ScopeTable *st) { if (token.type == TOKEN_IDENTIFIER) { return get_ref(st, token.start, token.length); } @@ -246,7 +256,7 @@ u32 get_ptr(Token token, SymbolTable *st) { exit(1); } -u32 get_reg(Token token, SymbolTable *st) { +u32 get_reg(Token token, ScopeTable *st) { if (token.type == TOKEN_IDENTIFIER) { return get_ref(st, token.start, token.length); } @@ -303,7 +313,7 @@ Token next_token_is(TokenType type) { /** * Global . */ -bool define_global(VM *vm, SymbolTable *st) { +bool define_global(VM *vm, ScopeTable *st) { Symbol s; Token token_type = next_token(); @@ -472,7 +482,7 @@ bool define_global(VM *vm, SymbolTable *st) { /** * Var . */ -void define_var(SymbolTable *st, Token regType) { +void define_var(ScopeTable *st, Token regType) { Symbol s; s.scope = VAR; switch (regType.type) { @@ -553,7 +563,7 @@ void define_var(SymbolTable *st, Token regType) { /** * function . */ -void define_function(VM *vm, SymbolTable *st) { +void define_function(VM *vm, ScopeTable *st) { Symbol s; s.scope = LOCAL; s.type = FUNCTION; @@ -570,6 +580,12 @@ void define_function(VM *vm, SymbolTable *st) { next_token_is(TOKEN_LPAREN); + i32 temp = st->scope_ref; + + st->count++; + st->scopes[st->count].parent = st->scope_ref; + st->scope_ref = (i32)st->count; + Token next = next_token(); while (next.type != TOKEN_RPAREN) { define_var(st, next); @@ -585,13 +601,17 @@ void define_function(VM *vm, SymbolTable *st) { } } s.ref = vm->cp; + next = next_token_is(TOKEN_LBRACE); + + st->scope_ref = temp; // need to add to the parents scope symbol_table_add(st, s); + st->scope_ref = (i32)st->count; } /** * Branch. */ -void define_branch(VM *vm, SymbolTable *st) { +void define_branch(VM *vm, ScopeTable *st) { Symbol s; s.scope = LOCAL; s.type = VOID; @@ -702,7 +722,8 @@ int get_instruction_byte_size(const char *opname) { } #define FAKE_OP(op) \ - } else if (strleq(token.start, op, token.length)) { \ + } \ + else if (strleq(token.start, op, token.length)) { \ do { \ while (token.type != TOKEN_SEMICOLON) { \ token = next_token(); \ @@ -716,7 +737,7 @@ int get_instruction_byte_size(const char *opname) { /** * Build the symbol table and calculate the types/size/offsets of all values. */ -void build_symbol_table(VM *vm, char *source, SymbolTable *st) { +void build_symbol_table(VM *vm, char *source, ScopeTable *st) { Token token; init_lexer(source); do { @@ -727,6 +748,22 @@ void build_symbol_table(VM *vm, char *source, SymbolTable *st) { } if (token.type != TOKEN_EOF) { + + if (token.type == TOKEN_LBRACE) { + st->count++; + st->scopes[st->count].parent = st->scope_ref; + st->scope_ref = (i32)st->count; + continue; + } + + if (token.type == TOKEN_RBRACE) { + i32 current_scope = st->scope_ref; + i32 parent = st->scopes[current_scope].parent; + if (parent < 0) parent = 0; + st->scope_ref = parent; + continue; + } + if (token.type == TOKEN_KEYWORD_GLOBAL) { define_global(vm, st); continue; @@ -931,7 +968,7 @@ void build_symbol_table(VM *vm, char *source, SymbolTable *st) { /** * 2nd pass, emit the bytecode */ -void emit_bytecode(VM *vm, char *source, SymbolTable *st) { +void emit_bytecode(VM *vm, char *source, ScopeTable *st) { Token token; init_lexer(source); do { @@ -941,6 +978,21 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { break; } if (token.type != TOKEN_EOF) { + + if (token.type == TOKEN_LBRACE) { + st->count++; + st->scopes[st->count].parent = st->scope_ref; + st->scope_ref = (i32)st->count; + continue; + } + + if (token.type == TOKEN_RBRACE) { + i32 current_scope = st->scope_ref; + i32 parent = st->scopes[current_scope].parent; + if (parent < 0) parent = 0; + st->scope_ref = parent; + continue; + } if (token.type == TOKEN_KEYWORD_GLOBAL) { /* ignore, already processed */ @@ -2417,8 +2469,9 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) { /** * Emit bytecode to the VM from the source string. */ -void assemble(VM *vm, SymbolTable *st, char *source) { +void assemble(VM *vm, ScopeTable *st, char *source) { build_symbol_table(vm, source, st); vm->cp = 0; /* actually start emitting code */ + st->count = 0; emit_bytecode(vm, source, st); } diff --git a/src/tools/assembler/assembler.h b/src/tools/assembler/assembler.h index 106aee5..95edd43 100644 --- a/src/tools/assembler/assembler.h +++ b/src/tools/assembler/assembler.h @@ -26,6 +26,8 @@ typedef enum { typedef struct symbol_s Symbol; typedef struct symbol_tab_s SymbolTable; +typedef struct scope_tab_s ScopeTable; +typedef struct assembler_s Assembler; #define MAX_SYMBOL_NAME_LENGTH 64 struct symbol_s { @@ -38,13 +40,20 @@ struct symbol_s { }; struct symbol_tab_s { - Symbol *symbols; - u32 count; - u32 capacity; + Symbol symbols[256]; + u8 count; + i32 parent; }; -void assemble(VM *vm, SymbolTable *st, char *source); -extern bool resize_or_check_size(SymbolTable *table);/* implement this in arch/ not here */ +struct scope_tab_s { + SymbolTable *scopes; + u32 count; + u32 capacity; + i32 scope_ref; +}; + +void assemble(VM *vm, ScopeTable *st, char *source); +extern bool table_realloc(ScopeTable *table);/* implement this in arch/ not here */ const char *opcode_to_string(Opcode op); diff --git a/src/tools/compiler/compiler.c b/src/tools/compiler/compiler.c index 5899df6..04e6ae0 100644 --- a/src/tools/compiler/compiler.c +++ b/src/tools/compiler/compiler.c @@ -3,188 +3,18 @@ #include "../../vm/common.h" #include "../../vm/opcodes.h" #include "../../vm/libc.h" +#include "../../vm/fixed.h" #include #include #include -NamesTable *names_table_init() { - NamesTable *table = malloc(sizeof(NamesTable)); - table->names = malloc(16 * sizeof(char *)); - table->count = 0; - table->capacity = 16; - return table; -} - -FunctionTable *function_table_init() { - FunctionTable *table = malloc(sizeof(FunctionTable)); - table->symbols = malloc(16 * sizeof(FunctionDef)); - table->count = 0; - table->capacity = 16; - return table; -} - -ArrayTable *array_table_init() { - ArrayTable *table = malloc(sizeof(ArrayTable)); - table->symbols = malloc(16 * sizeof(ArrayDef)); - table->count = 0; - table->capacity = 16; - return table; -} - -PlexTable *plex_table_init() { - PlexTable *table = malloc(sizeof(PlexTable)); - table->symbols = malloc(16 * sizeof(PlexDef)); - table->count = 0; - table->capacity = 16; - return table; -} - -PlexFieldsTable *plex_fields_table_init() { - PlexFieldsTable *table = malloc(sizeof(PlexFieldsTable)); - table->plex_refs = malloc(64 * sizeof(u32)); - table->fields = malloc(64 * sizeof(ValueType)); - table->count = 0; - table->capacity = 64; - return table; -} - -u32 names_table_add(NamesTable *table, const char *name) { - for (u32 i = 0; i < table->count; i++) { - if (strcmp(table->names[i], name) == 0) { - return (u32)i; - } - } - - if (table->count >= table->capacity) { - table->capacity *= 2; - table->names = realloc(table->names, table->capacity * sizeof(char *)); - } - - table->names[table->count] = malloc(strlen(name) + 1); - strcpy(table->names[table->count], name); - u32 index = (u32)table->count; - table->count++; - return index; -} - -u32 function_table_add(FunctionTable *table, FunctionDef def) { - if (table->count >= table->capacity) { - table->capacity *= 2; - table->symbols = - realloc(table->symbols, table->capacity * sizeof(FunctionDef)); - } - - table->symbols[table->count] = def; - u32 index = (u32)table->count; - table->count++; - return index; -} - -u32 array_table_add(ArrayTable *table, ArrayDef def) { - if (table->count >= table->capacity) { - table->capacity *= 2; - table->symbols = realloc(table->symbols, table->capacity * sizeof(ArrayDef)); - } - - table->symbols[table->count] = def; - u32 index = (u32)table->count; - table->count++; - return index; -} - -u32 plex_add(PlexTable *plex_table, u32 name, u32 size, u32 field_start, - u32 field_count) { - if (plex_table->count >= plex_table->capacity) { - plex_table->capacity *= 2; - plex_table->symbols = - realloc(plex_table->symbols, plex_table->capacity * sizeof(PlexDef)); - } - - plex_table->symbols[plex_table->count].name = name; - plex_table->symbols[plex_table->count].size = size; - plex_table->symbols[plex_table->count].field_ref_start = field_start; - plex_table->symbols[plex_table->count].field_count = field_count; - - u32 index = (u32)plex_table->count; - plex_table->count++; - return index; -} - -u32 plex_fields_add(PlexFieldsTable *fields_table, u32 plex_ref, - ValueType field) { - if (fields_table->count + 1 > fields_table->capacity) { - u32 new_capacity = fields_table->capacity * 2; - if (new_capacity < fields_table->count + 1) { - new_capacity = fields_table->count + 1; - } - fields_table->plex_refs = - realloc(fields_table->plex_refs, new_capacity * sizeof(u32)); - fields_table->fields = - realloc(fields_table->fields, new_capacity * sizeof(ValueType)); - fields_table->capacity = new_capacity; - } - - u32 start_index = fields_table->count; - fields_table->plex_refs[start_index] = plex_ref; - fields_table->fields[start_index] = field; - fields_table->count++; - return start_index; -} - -int plex_get_field_index_by_name(PlexTable *plex_table, - PlexFieldsTable *fields_table, - NamesTable *names_table, u32 plex_index, - const char *field_name) { - if (plex_index >= plex_table->count) - return -1; - - PlexDef *plex_def = &plex_table->symbols[plex_index]; - u32 field_start = plex_def->field_ref_start; - u32 field_count = plex_def->field_count; - - for (u32 i = 0; i < field_count; i++) { - u32 field_table_index = field_start + i; - ValueType *field = &fields_table->fields[field_table_index]; - - if (field->name < names_table->count) { - if (strcmp(names_table->names[field->name], field_name) == 0) { - return (int)i; // Return field index within the plex - } - } - } - return -1; // Not found -} - -ValueType *plex_get_field(PlexTable *plex_table, PlexFieldsTable *fields_table, - u32 plex_index, u32 field_in_plex_index) { - if (plex_index >= plex_table->count) - return nil; - - PlexDef *plex_def = &plex_table->symbols[plex_index]; - if (field_in_plex_index >= plex_def->field_count) - return nil; - - u32 field_table_index = plex_def->field_ref_start + field_in_plex_index; - return &fields_table->fields[field_table_index]; -} - -ValueType *plex_get_field_by_name(PlexTable *plex_table, - PlexFieldsTable *fields_table, - NamesTable *names_table, u32 plex_index, - const char *field_name) { - int field_index = plex_get_field_index_by_name( - plex_table, fields_table, names_table, plex_index, field_name); - if (field_index == -1) - return nil; - - return plex_get_field(plex_table, fields_table, plex_index, (u32)field_index); -} - typedef struct { Token current; Token previous; + Token before; bool hadError; bool panicMode; + i8 rp; } Parser; typedef enum { @@ -209,13 +39,6 @@ typedef struct { Precedence precedence; } ParseRule; -typedef struct { - SymbolTable table; - Symbol current; - Symbol last; - i8 rp; // Next free register -} Compiler; - Parser parser; const char *internalErrorMsg = @@ -269,30 +92,24 @@ void consume(TokenType type, const char *message) { errorAtCurrent(message); } -static int allocateRegister(Compiler *c) { +static int allocateRegister() { char buffer[38]; - if (c->rp + 1 > 31) { - sprintf(buffer, "Out of registers (used %d, max 32)", c->rp + 1); + if (parser.rp + 1 > 31) { + sprintf(buffer, "Out of registers (used %d, max 32)", parser.rp + 1); error(buffer); return -1; } - return c->rp++; + return parser.rp++; } -static void popRegister(Compiler *c) { - if (c->rp - 1 > 0) { - c->rp--; +static void popRegister() { + if (parser.rp - 1 > 0) { + parser.rp--; } } -static void freeRegister(Compiler *c, u8 reg) { - if (reg == c->rp - 1) { - c->rp--; - } -} - -static void clearRegisters(Compiler *c, u8 reg) { c->rp = 0; } +static void clearRegisters(u8 reg) { parser.rp = 0; } void emit_byte(VM *vm, u8 byte) { vm->code[vm->cp++] = byte; } @@ -312,20 +129,17 @@ static bool match(TokenType type) { return true; } -static void expression(Compiler *c, VM *vm) { - USED(c); +static void expression(VM *vm) { USED(vm); } -void number(Compiler *c, VM *vm) { +void number(VM *vm) { emit_opcode(vm, OP_LOAD_IMM); - int reg = allocateRegister(c); + int reg = allocateRegister(); if (reg < 0) return; emit_byte(vm, reg); - c->last = Symbol{ .type=parser.previous.type }; - switch (parser.previous.type) { case TOKEN_LITERAL_INT: { char *endptr; @@ -351,16 +165,16 @@ void number(Compiler *c, VM *vm) { errorAtCurrent("Invalid number format"); } -static void unary(Compiler *c, VM *vm) { +static void unary(VM *vm) { TokenType operatorType = parser.previous.type; // Compile the operand. - expression(c, vm); + expression(vm); // Emit the operator instruction. switch (operatorType) { case TOKEN_MINUS: { - switch (c->last.type) { + switch (parser.previous.type) { case TOKEN_LITERAL_NAT: emit_opcode(vm, OP_NEG_NAT); case TOKEN_LITERAL_REAL: @@ -378,16 +192,16 @@ static void unary(Compiler *c, VM *vm) { } } -static void emitHalt(Compiler *c, VM *vm) { +static void emitHalt(VM *vm) { emit_opcode(vm, OP_EXIT); advance(); - number(c, vm); + number(vm); } -static void endCompiler(Compiler *c, VM *vm) { emitHalt(c, vm); } +static void endCompiler(VM *vm) { emitHalt(vm); } -static void grouping(Compiler *c, VM *vm) { - expression(c, vm); +static void grouping(VM *vm) { + expression(vm); consume(TOKEN_RPAREN, "Expect ')' after expression."); } @@ -399,11 +213,10 @@ bool compile(const char *source, VM *vm) { parser.hadError = false; parser.panicMode = false; - Compiler compiler; advance(); - expression(&compiler, vm); + expression(vm); consume(TOKEN_EOF, "Expect end of expression."); - endCompiler(&compiler, vm); + endCompiler(vm); return parser.hadError; } diff --git a/src/tools/compiler/parser.c b/src/tools/compiler/parser.c index 291a3a3..375222c 100644 --- a/src/tools/compiler/parser.c +++ b/src/tools/compiler/parser.c @@ -1,7 +1,7 @@ #include #include "../../vm/common.h" -#include "lexer.h" +#include "parser.h" typedef struct { const char *start; diff --git a/src/tools/compiler/parser.h b/src/tools/compiler/parser.h index 5f83f08..714cf38 100644 --- a/src/tools/compiler/parser.h +++ b/src/tools/compiler/parser.h @@ -16,6 +16,8 @@ typedef enum { TOKEN_TYPE_NAT, TOKEN_TYPE_REAL, TOKEN_TYPE_STR, + TOKEN_TYPE_BOOL, + TOKEN_TYPE_VOID, TOKEN_KEYWORD_PLEX, TOKEN_KEYWORD_FN, TOKEN_KEYWORD_CONST, @@ -35,6 +37,8 @@ typedef enum { TOKEN_KEYWORD_WRITE, TOKEN_KEYWORD_REFRESH, TOKEN_KEYWORD_CLOSE, + TOKEN_KEYWORD_LOOP, + TOKEN_KEYWORD_DO, TOKEN_KEYWORD_NIL, TOKEN_KEYWORD_TRUE, TOKEN_KEYWORD_FALSE, diff --git a/test/add.ul.ir b/test/add.ul.ir index 8073af3..0ca47a4 100644 --- a/test/add.ul.ir +++ b/test/add.ul.ir @@ -3,20 +3,22 @@ global str new_line = "\n"; global int x = 1; global int y = 1; -function main () +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; +} -function add (int a $0, int b $1) +function add (int a $0, int b $1) { int result $2; add_int a b -> result; return result; +} -function pln (str message $0) +function pln (str message $0) { plex term $1; int msg_length $2; str nl $3; @@ -33,3 +35,4 @@ function pln (str message $0) string_length nl -> nl_length; syscall WRITE term nl nl_length; return; +} diff --git a/test/fib.ul.ir b/test/fib.ul.ir index caf8152..50b2cb5 100644 --- a/test/fib.ul.ir +++ b/test/fib.ul.ir @@ -1,7 +1,7 @@ global str terminal_namespace = "/dev/term/0"; global str new_line = "\n"; -function main () +function main () { int str_n $1; load_immediate 35 -> $0; @@ -9,8 +9,9 @@ function main () int_to_string $0 -> str_n; call pln (str_n); exit 0; +} -function fib (int n $0) +function fib (int n $0) { load_immediate 2 -> $1; jump_lt_int base_case n $1; @@ -28,8 +29,9 @@ function fib (int n $0) else base_case; return n; +} -function pln (str message $0) +function pln (str message $0) { plex term $1; int msg_length $2; str nl $3; @@ -46,4 +48,4 @@ function pln (str message $0) string_length nl -> nl_length; syscall WRITE term nl nl_length; return; - \ No newline at end of file +} diff --git a/test/hello.ul.ir b/test/hello.ul.ir index d43c9fa..9789e11 100644 --- a/test/hello.ul.ir +++ b/test/hello.ul.ir @@ -2,14 +2,15 @@ global str terminal_namespace = "/dev/term/0"; global str new_line = "\n"; global str hello = "nuqneH 'u'?"; -function main () +function main () { str msg $0; load_address hello -> msg; call pln (msg); exit 0; +} -function pln (str message $0) +function pln (str message $0) { plex term $1; int msg_length $2; str nl $3; @@ -25,4 +26,5 @@ function pln (str message $0) load_address new_line -> nl; string_length nl -> nl_length; syscall WRITE term nl nl_length; - return; \ No newline at end of file + return; +} diff --git a/test/loop.ul.ir b/test/loop.ul.ir index 2edad6a..278c338 100644 --- a/test/loop.ul.ir +++ b/test/loop.ul.ir @@ -2,36 +2,38 @@ global str terminal_namespace = "/dev/term/0"; global str prompt = "Enter a string:"; global str new_line = "\n"; -function main () +function main () { real a $0; int i $1; - int in_mode $11; - str in_term $10; + int mode $11; + str term $10; + // 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 + loop loop_body { add_real a $5 -> a; add_int i $3 -> i; - jump_ge_int loop_body i $2; + jump_ge_int loop_body i $2; + } - load_address terminal_namespace -> in_term; - load_immediate 0 -> in_mode; - syscall OPEN in_term in_mode in_term; // Terminal term = open("/dev/term/0", 0); + 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 in_term $7 $8; // print prompt + syscall WRITE term $7 $8; // print prompt str user_string $9; load_immediate 32 -> $8; malloc $8 -> user_string; - syscall READ in_term user_string $8; // read in max 32 byte string + syscall READ term user_string $8; // read in max 32 byte string call pln (user_string); nat_to_string b -> $4; @@ -39,8 +41,9 @@ function main () real_to_string a -> $3; call pln ($3); exit 0; +} -function pln (str message $0) +function pln (str message $0) { plex term $1; int msg_length $2; str nl $3; @@ -56,3 +59,4 @@ function pln (str message $0) string_length nl -> nl_length; syscall WRITE term nl nl_length; return; +} diff --git a/test/malloc.ul.ir b/test/malloc.ul.ir index dca8380..d67eb54 100644 --- a/test/malloc.ul.ir +++ b/test/malloc.ul.ir @@ -2,27 +2,28 @@ global str terminal_namespace = "/dev/term/0"; global str prompt = "Enter a string:"; global str new_line = "\n"; -function main () - int in_mode $11; - str in_term $10; +function main () { + int mode $11; + str term $10; - load_address terminal_namespace -> in_term; - load_immediate 0 -> in_mode; - syscall OPEN in_term in_mode in_term; // Terminal term = open("/dev/term/0", 0); + 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 in_term $7 $8; // print prompt + syscall WRITE term $7 $8; // print prompt str user_string $9; load_immediate 32 -> $8; malloc $8 -> user_string; - syscall READ in_term user_string $8; // read in max 32 byte string + syscall READ term user_string $8; // read in max 32 byte string call pln (user_string); exit 0; +} -function pln (str message $0) +function pln (str message $0) { plex term $1; int msg_length $2; str nl $3; @@ -39,4 +40,4 @@ function pln (str message $0) string_length nl -> nl_length; syscall WRITE term nl nl_length; return; - \ No newline at end of file +} diff --git a/test/paint-bw.ul.ir b/test/paint-bw.ul.ir index 3fd24c5..9c3d77d 100644 --- a/test/paint-bw.ul.ir +++ b/test/paint-bw.ul.ir @@ -7,7 +7,7 @@ global byte GRAY = 146; global byte LIGHT_GRAY = 182; global byte SELECTED_COLOR = 255; -function main () +function main () { // Open screen plex screen $0; str screen_name $18; @@ -51,7 +51,7 @@ function main () nat m_zero $11; - loop draw_loop + loop draw_loop { // load mouse click data syscall REFRESH mouse; @@ -92,13 +92,14 @@ function main () call draw_box (screen_buffer width selected_color mouse_x mouse_y brush_size brush_size); - jump draw_loop; + jump draw_loop; + } // Flush and exit exit 0; 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) + int box_x $2, int box_y $3, byte check_color $4, int bsize $5) { // Compute right int right_edge $6; @@ -118,9 +119,10 @@ function set_color_if_clicked (int click_x $0, int click_y $1, else fail return; +} function draw_outlined_swatch(nat dos_base $0, - byte swatch_color $1, int x $2, int y $3, int dos_width $4) + byte swatch_color $1, int x $2, int y $3, int dos_width $4) { // Constants nat background_color $5; @@ -152,10 +154,11 @@ function draw_outlined_swatch(nat dos_base $0, call draw_box (dos_base dos_width swatch_color $9 $10 fill_size fill_size); return; +} function draw_box (nat db_base $0, nat screen_width $1, byte box_color $2, nat x_start $3, nat y_start $4, - nat db_width $5, nat height $6) + nat db_width $5, nat height $6) { // Compute start address: base + y*640 + x nat offset $15; @@ -172,9 +175,11 @@ function draw_box (nat db_base $0, nat screen_width $1, int zero $26; load_immediate 0 -> zero; - loop draw_box_outer + loop draw_box_outer { 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; + jump_gt_int draw_box_outer height zero; + } return; +} \ No newline at end of file diff --git a/test/paint.ul.ir b/test/paint.ul.ir index 5a1c18c..98d9e77 100644 --- a/test/paint.ul.ir +++ b/test/paint.ul.ir @@ -34,7 +34,7 @@ global byte DARK_ORANGE = 208; global byte GOLD = 244; global byte SELECTED_COLOR = 255; -function main () +function main () { // Open screen plex screen $0; str screen_name $18; @@ -118,14 +118,14 @@ function main () nat m_zero $11; - loop draw_loop + loop draw_loop { // load mouse click data syscall REFRESH mouse; byte left_down $9; load_offset_8 mouse 16 -> left_down; // load btn1 pressed - jump_eq_nat draw_loop left_down m_zero; + jump_eq_nat draw_loop left_down m_zero; // if (!btn1.left) continue; nat mouse_x $7; nat mouse_y $8; @@ -206,13 +206,15 @@ function main () call draw_box (screen_buffer width selected_color mouse_x mouse_y brush_size brush_size); - jump draw_loop; + jump draw_loop; + } // Flush and exit exit 0; +} 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) + int box_x $2, int box_y $3, byte check_color $4, int bsize $5) { // Compute right int right_edge $6; @@ -232,9 +234,10 @@ function set_color_if_clicked (int click_x $0, int click_y $1, else fail return; +} function draw_outlined_swatch(nat dos_base $0, - byte swatch_color $1, int x $2, int y $3, int dos_width $4) + byte swatch_color $1, int x $2, int y $3, int dos_width $4) { // Constants nat background_color $5; @@ -266,10 +269,11 @@ function draw_outlined_swatch(nat dos_base $0, call draw_box (dos_base dos_width swatch_color $9 $10 fill_size fill_size); return; +} function draw_box (nat db_base $0, nat screen_width $1, byte box_color $2, nat x_start $3, nat y_start $4, - nat db_width $5, nat height $6) + nat db_width $5, nat height $6) { // Compute start address: base + y*640 + x nat offset $15; @@ -286,9 +290,11 @@ function draw_box (nat db_base $0, nat screen_width $1, int zero $26; load_immediate 0 -> zero; - loop draw_box_outer + loop draw_box_outer { 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; + jump_gt_int draw_box_outer height zero; + } return; +} \ No newline at end of file diff --git a/test/simple.ul.ir b/test/simple.ul.ir index 3c04c23..11fc1d1 100644 --- a/test/simple.ul.ir +++ b/test/simple.ul.ir @@ -1,15 +1,16 @@ global str terminal_namespace = "/dev/term/0"; global str new_line = "\n"; -function main () +function main () { load_immediate 1.0 -> $0; load_immediate 2.0 -> $1; add_real $0 $1 -> $0; real_to_string $0 -> $0; call pln ($0); exit 0; +} -function pln (str message $0) +function pln (str message $0) { plex term $1; int msg_length $2; str nl $3; @@ -26,3 +27,4 @@ function pln (str message $0) string_length nl -> nl_length; syscall WRITE term nl nl_length; return; +} diff --git a/test/window.ul.ir b/test/window.ul.ir index 185cfd0..877bf3d 100644 --- a/test/window.ul.ir +++ b/test/window.ul.ir @@ -4,7 +4,7 @@ global str terminal_namespace = "/dev/term/0"; global str new_line = "\n"; global byte WHITE = 255; -function main () +function main () { plex screen $0; plex mouse $1; str tmp_str $2; @@ -47,13 +47,13 @@ function main () syscall WRITE screen screen_buffer buffer_size; // redraw - loop draw_loop + loop draw_loop { // load mouse click data syscall REFRESH mouse; load_offset_8 mouse 16 -> left_down; - jump_eq_nat draw_loop left_down mode; // mode = 0 / false + jump_eq_nat draw_loop left_down mode; // if (!left_down) continue; load_offset_32 mouse 8 -> x; load_offset_32 mouse 12 -> y; @@ -70,10 +70,13 @@ function main () syscall WRITE screen screen_buffer buffer_size; // redraw - jump draw_loop; - exit 0; + jump draw_loop; + } -function pln (str message $0) + exit 0; +} + +function pln (str message $0) { plex term $1; int msg_length $2; str nl $3; @@ -90,3 +93,4 @@ function pln (str message $0) string_length nl -> nl_length; syscall WRITE term nl nl_length; return; +}