From 0449d9b84e4133b577a9ecad31a56c059f35b2d2 Mon Sep 17 00:00:00 2001 From: zongor Date: Sun, 28 Jun 2026 23:51:58 -0700 Subject: [PATCH] more advanced array stuff, hacked in read/write literals for uxn --- arch/linux/main.c | 4 +- compiler.c | 78 +++++++---- emit.h | 2 + emit/rer/emit.c | 2 + emit/uxn/emit.c | 31 ++++- lexer.c | 17 +++ lexer.h | 4 +- test/array.ul | 3 +- test/bf.ul | 44 +++--- test/rw.ul | 4 + test/tal/array.tal | 6 +- test/tal/bf.tal | 330 +++++++++++++++++++++++++++++++++++++++++++++ test/tal/rw.tal | 279 ++++++++++++++++++++++++++++++++++++++ tests | 1 + 14 files changed, 745 insertions(+), 60 deletions(-) create mode 100644 test/rw.ul create mode 100644 test/tal/bf.tal create mode 100644 test/tal/rw.tal diff --git a/arch/linux/main.c b/arch/linux/main.c index d9933e4..8bfc51f 100644 --- a/arch/linux/main.c +++ b/arch/linux/main.c @@ -77,14 +77,14 @@ main(int argc, char **argv) Node *curr = code->head; while (curr) { char* tmp_str = node_value(curr); - write(STDOUT_FILENO, tmp_str, curr->size); + printf("%.*s", curr->size, tmp_str); curr = curr->next; } curr = memory->head; while (curr) { char* tmp_str = node_value(curr); - write(STDOUT_FILENO, tmp_str, curr->size); + printf("%.*s", curr->size, tmp_str); curr = curr->next; } diff --git a/compiler.c b/compiler.c index d7c6991..b4d7994 100644 --- a/compiler.c +++ b/compiler.c @@ -371,21 +371,6 @@ void declaration(); ParseRule *get_rule(TokenType type); void parse_precedence(Precedence precedence); - -/** -FIXME: we need to move the string to be on the heap instead of the stack -so we need special handling in variable_dec - -During the first pass we need to append the string label @variable -and then the hexed out literal. - -every time we reference the string we should reference the global ptr. - -If the string gets appended then we should copy and use the local varaiable - -but for string conts or array conts we should use the global ref '@' -*/ - u32 variable_declaration(Symbol *def) { @@ -422,10 +407,15 @@ variable_declaration(Symbol *def) if(match(TOKEN_RBRACKET)) break; expect(TOKEN_COMMA); } - } - expect(TOKEN_SEMICOLON); - emitter.emit_array(arena, memory, variable, array_literal); + expect(TOKEN_SEMICOLON); + emitter.emit_array(arena, memory, variable, array_literal); + } else { + expect(TOKEN_SEMICOLON); + + emitter.emit_array(arena, memory, variable, nil); + emitter.emit_zero_block(arena, memory, variable->size * emitter.get_size(variable->secondary_type)); + } return variable->size; } @@ -574,12 +564,22 @@ variable() if (match(TOKEN_LBRACKET)) { expression(); - emitter.emit_address(arena, code, emitter.get_size(sym->secondary_type)); - emitter.emit_mul(arena, code); + emitter.emit_address(arena, code, emitter.get_size(sym->secondary_type)); + emitter.emit_mul(arena, code); emitter.emit_add(arena, code); + /* add offset of "length"*/ + emitter.emit_nat(arena, code, "2", 1); + emitter.emit_add(arena, code); emitter.emit_deref(arena, code); while (!match(TOKEN_RBRACKET)) { } + } else if (match(TOKEN_DOT)) { + if (sleq("length", parser.current.start, parser.current.length)) { + emitter.emit_deref(arena, code); + } else { + emitter.error("arrays currently can only get their length, don't do anything fancy yet...", 75, parser.current.line); + } + advance(); } return; } @@ -729,13 +729,14 @@ if_statement() void while_statement() { - emitter.emit_while(arena, code, emitter.loops); + u32 this_while = emitter.loops++; + emitter.emit_while(arena, code, this_while); consume(TOKEN_LPAREN); expression(); consume(TOKEN_RPAREN); emitter.emit_while_postfix(arena, code); statement(); - emitter.emit_patch_while(arena, code, emitter.loops++); + emitter.emit_patch_while(arena, code, this_while); } void @@ -835,6 +836,12 @@ string() emitter.emit_str(arena, code, parser.previous.start, parser.previous.length); } +void +character() +{ + emitter.emit_char(arena, code, parser.previous.start, parser.previous.length); +} + void unary() { @@ -853,6 +860,21 @@ unary() } } +void +read() +{ + emitter.emit_read(arena, code); +} + +void +write() +{ + consume(TOKEN_EQ); + advance(); + variable(); + emitter.emit_write(arena, code); +} + ParseRule rules[] = { /* TOKEN_ERROR */ {nil, nil, PREC_NONE}, /* TOKEN_EOF */ {nil, nil, PREC_NONE}, @@ -893,8 +915,8 @@ ParseRule rules[] = { /* TOKEN_KEYWORD_INIT */ {nil, nil, PREC_NONE}, /* TOKEN_KEYWORD_THIS */ {nil, nil, PREC_NONE}, /* TOKEN_KEYWORD_OPEN */ {nil, nil, PREC_NONE}, - /* TOKEN_KEYWORD_READ */ {nil, nil, PREC_NONE}, - /* TOKEN_KEYWORD_WRITE */ {nil, nil, PREC_NONE}, + /* TOKEN_KEYWORD_READ */ {read, nil, PREC_NONE}, + /* TOKEN_KEYWORD_WRITE */ { write, nil, PREC_NONE}, /* TOKEN_KEYWORD_STAT */ {nil, nil, PREC_NONE}, /* TOKEN_KEYWORD_CLOSE */ {nil, nil, PREC_NONE}, /* TOKEN_KEYWORD_LOOP */ {nil, nil, PREC_NONE}, @@ -934,7 +956,13 @@ ParseRule rules[] = { /* TOKEN_ARROW_RIGHT */ {nil, nil, PREC_NONE}, /* TOKEN_SLL */ {nil, binary, PREC_NONE}, /* TOKEN_SRL */ {nil, binary, PREC_NONE}, - /* TOKEN_KEYWORD_PRINT*/ {nil, binary, PREC_NONE}}; + /* TOKEN_KEYWORD_PRINT*/ {nil, binary, PREC_NONE}, + /* TOKEN_KEYWORD_TRAIT*/ {nil, nil, PREC_NONE}, + /* TOKEN_KEYWORD_HALT*/ {nil, nil, PREC_NONE}, + /* TOKEN_KEYWORD_DEVMAP*/ {nil, nil, PREC_NONE}, + /* TOKEN_KEYWORD_BYTE*/ {nil, nil, PREC_NONE}, + /* TOKEN_KEYWORD_CHAR*/ {character, nil, PREC_NONE}, + }; void parse_precedence(Precedence precedence) diff --git a/emit.h b/emit.h index f88939c..137e947 100644 --- a/emit.h +++ b/emit.h @@ -105,6 +105,8 @@ struct emitter_s { VoidArgEmit emit_deref; VoidArgEmit emit_ref; U32ArgEmit emit_address; + U32ArgEmit emit_zero_block; + StrArgEmit emit_char; }; Emitter rer_emitter(); diff --git a/emit/rer/emit.c b/emit/rer/emit.c index 33bcde5..211f32c 100644 --- a/emit/rer/emit.c +++ b/emit/rer/emit.c @@ -773,5 +773,7 @@ rer_emitter() nil, nil, nil, + nil, + nil, }; } diff --git a/emit/uxn/emit.c b/emit/uxn/emit.c index b97a76b..959ff8e 100644 --- a/emit/uxn/emit.c +++ b/emit/uxn/emit.c @@ -783,6 +783,14 @@ uxn_emit_byte(Arena *a, List *out, const char *str, i32 length) USED(length); } +void +uxn_emit_char(Arena *a, List *out, const char *str, i32 length) +{ + sprintf(uxn_temp_strbuf, "#%04x ", (char)str[0]); + StrBuf_append(a, out, uxn_temp_strbuf); + USED(length); +} + void uxn_emit_str(Arena *a, List *out, const char *str, i32 length) { @@ -844,8 +852,10 @@ uxn_emit_array(Arena *a, List *out, Symbol *sym, List *in) sprintf(uxn_temp_strbuf, "@%.*s ", sym->name_length, sym->name); StrBuf_append(a, out, uxn_temp_strbuf); - //sprintf(uxn_temp_strbuf, "%04x ", in->count); - //StrBuf_append(a, out, uxn_temp_strbuf); + if (!in) return; + + sprintf(uxn_temp_strbuf, "%04x ", in->count); + StrBuf_append(a, out, uxn_temp_strbuf); switch(t) { case SYMBOL_BOOL: { @@ -1098,15 +1108,13 @@ uxn_emit_set_variable(Arena *a, List *out, Symbol *sym, bool local) void uxn_emit_write(Arena *a, List *out) { - USED(a); - USED(out); + StrBuf_append(a, out, "#18 DEO "); } void uxn_emit_read(Arena *a, List *out) { - USED(a); - USED(out); + StrBuf_append(a, out, "#12 DEI "); } void @@ -1365,6 +1373,13 @@ uxn_emit_address(Arena *a, List *out, u32 ptr) StrBuf_append(a, out, uxn_temp_strbuf); } +void +uxn_emit_zero_block(Arena *a, List *out, u32 ptr) +{ + sprintf(uxn_temp_strbuf, "$%d ", ptr); + StrBuf_append(a, out, uxn_temp_strbuf); +} + Emitter uxn_emitter() { @@ -1456,6 +1471,8 @@ uxn_emitter() uxn_emit_deref_prolog, uxn_emit_deref, nil, - uxn_emit_address + uxn_emit_address, + uxn_emit_zero_block, + uxn_emit_char, }; } diff --git a/lexer.c b/lexer.c index dbcd6bf..151e918 100644 --- a/lexer.c +++ b/lexer.c @@ -382,6 +382,21 @@ string() return make_token(TOKEN_LITERAL_STR); } +static Token +character() +{ + advance(); + if(peek() != '\'' && !is_at_end()) { + advance(); + } + + if(is_at_end()) return error_token("Unterminated string."); + + /* The closing quote. */ + advance(); + return make_token(TOKEN_LITERAL_CHAR); +} + Token next_token() { @@ -444,6 +459,8 @@ next_token() : TOKEN_GT); case '"': return string(); + case '\'': + return character(); } return error_token("Unexpected character."); diff --git a/lexer.h b/lexer.h index f8bbc94..ba595f7 100644 --- a/lexer.h +++ b/lexer.h @@ -87,7 +87,9 @@ typedef enum { TOKEN_KEYWORD_PRINT, TOKEN_KEYWORD_TRAIT, TOKEN_KEYWORD_HALT, - TOKEN_KEYWORD_DEVMAP /* device memory map */ + TOKEN_KEYWORD_DEVMAP, /* device memory map */ + TOKEN_LITERAL_BYTE, + TOKEN_LITERAL_CHAR } TokenType; typedef struct token_s Token; diff --git a/test/array.ul b/test/array.ul index b950410..325e1c2 100644 --- a/test/array.ul +++ b/test/array.ul @@ -2,8 +2,7 @@ nat[6] fixed_size = [1, 2, 3, 4, 5, 6]; nat i = 0; -//while (i < fixed_size.length) { -while (i < 6) { +while (i < fixed_size.length) { print(fixed_size[i] as str); print(" "); i = i + 1; diff --git a/test/bf.ul b/test/bf.ul index 7c129e9..73861d8 100644 --- a/test/bf.ul +++ b/test/bf.ul @@ -1,20 +1,20 @@ -plex Console -{ - ref function vector(void):void; - byte read; - u32 pad; - byte type; - byte write; - byte error; - u16 pad2; - ref byte[] addr; - byte mode; - byte exec; -} +//plex Console +//{ +// ref function vector(void):void; +// byte read; +// u32 pad; +// byte type; +// byte write; +// byte error; +// u16 pad2; +// ref byte[] addr; +// byte mode; +// byte exec; +//} +// +//Console console = devmap(0x10, Console); -Console console = devmap(0x10, Console); - -byte memory[10000]; +byte[10000] memory; str code = "++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++."; bf(code); halt; @@ -23,8 +23,10 @@ function bf(str code) { nat mp; // memory pointer nat ip = 0; // instruction pointer - while (ip < code.length) { - if (ip > code.length) { return; } +// while (ip < code.length) { +// if (ip > code.length) { return; } + while (ip < 106) { + if (ip < 0 or ip > 106) { return; } if (mp > memory.length) { return; } if (code[ip] == '>') { mp = mp + 1; @@ -35,9 +37,11 @@ function bf(str code) } else if (code[ip] == '-') { memory[mp] = memory[mp] - 1; } else if (code[ip] == '.') { - console.write = memory[mp]; + // console.write = memory[mp]; + write = memory[mp]; } else if (code[ip] == ',') { - memory[mp] = console.read; + // memory[mp] = console.read; + memory[mp] = read; } else if (code[ip] == '[') { if(!memory[mp]) { nat nc = 1; diff --git a/test/rw.ul b/test/rw.ul new file mode 100644 index 0000000..ae57f81 --- /dev/null +++ b/test/rw.ul @@ -0,0 +1,4 @@ + +byte t = read; +write = t; +halt; \ No newline at end of file diff --git a/test/tal/array.tal b/test/tal/array.tal index 4d4897c..f9c4d99 100644 --- a/test/tal/array.tal +++ b/test/tal/array.tal @@ -2,8 +2,8 @@ LIT2r 0000 !{ @i $2 } #0000 ;i STA2 -&while.0 ;i LDA2 #0006 LTH2 #03 JCN !{ -;fixed_size ;i LDA2 #0002 MUL2 ADD2 LDA2 nat_to_str_ str/ +&while.0 ;i LDA2 ;fixed_size LDA2 LTH2 #03 JCN !{ +;fixed_size ;i LDA2 #0002 MUL2 ADD2 #0002 ADD2 LDA2 nat_to_str_ str/ ;{ #0002 ADD2 } !{ 20 00 } str/ ;i LDA2 #0001 ADD2 ;i STA2 !&while.0 } ;{ #0002 ADD2 } !{ 0a 00 } str/ @@ -276,5 +276,5 @@ POP2r BRK @sext INC2 !/ @mem_length_ #0000 -@mem_ @fixed_size 0001 0002 0003 0004 0005 0006 +@mem_ @fixed_size 0006 0001 0002 0003 0004 0005 0006 diff --git a/test/tal/bf.tal b/test/tal/bf.tal new file mode 100644 index 0000000..415b19a --- /dev/null +++ b/test/tal/bf.tal @@ -0,0 +1,330 @@ +|100 + LIT2r 0000 + +!{ @code $2 } ;{ #0002 ADD2 } !{ 2b 2b 2b 2b 2b 2b 2b 2b 5b 3e 2b 2b 2b 2b 5b 3e 2b 2b 3e 2b 2b 2b 3e 2b 2b 2b 3e 2b 3c 3c 3c 3c 2d 5d 3e 2b 3e 2b 3e 2d 3e 3e 2b 5b 3c 5d 3c 2d 5d 3e 3e 2e 3e 2d 2d 2d 2e 2b 2b 2b 2b 2b 2b 2b 2e 2e 2b 2b 2b 2e 3e 3e 2e 3c 2d 2e 3c 2e 2b 2b 2b 2e 2d 2d 2d 2d 2d 2d 2e 2d 2d 2d 2d 2d 2d 2d 2d 2e 3e 3e 2b 2e 3e 2b 2b 2e 00 } ;code STA2 +;code LDA2 bf_ POP2r BRK @bf_ ( code -- ) + OVR2r LIT2r 000a SUB2r + STH2kr STA2 + + STH2kr #2712 ADD2 LDA2 + + STH2kr #2714 ADD2 LDA2 +#0000 STH2kr #2714 ADD2 STA2 + +&while.0 STH2kr #2714 ADD2 LDA2 #006a LTH2 #03 JCN !{ + STH2kr #0004 ADD2 LDA2 #0000 LTH2 #03 JCN !{ +!&if_end.0 } &if_end.0 + STH2kr #0004 ADD2 LDA2 #006a GTH2 !&return STH2kr #0002 ADD2 LDA2 ;memory LDA2 GTH2 #03 JCN !{ +!&return !&if_end.1 } &if_end.1 + STH2kr LDA2 #03 JCN !{ +!&if_end.2 } &if_end.2 + STH2kr #0004 ADD2 LDA2 #0027 STH2kr #0002 ADD2 LDA2 #0001 ADD2 STH2kr #0002 ADD2 STA2 STH2kr LDA2 #03 JCN !{ +!&if_end.3 } &if_end.3 + STH2kr #0004 ADD2 LDA2 #0027 STH2kr #0002 ADD2 LDA2 #0001 SUB2 STH2kr #0002 ADD2 STA2 STH2kr LDA2 #03 JCN !{ +!&if_end.4 } &if_end.4 + STH2kr #0004 ADD2 LDA2 #0027 ;memory STH2kr #0002 ADD2 LDA2 #0001 MUL2 ADD2 #0002 ADD2 LDA2 ;memory STH2kr #0002 ADD2 LDA2 #0001 MUL2 ADD2 #0002 ADD2 LDA2 #0001 ADD2 STH2kr LDA2 #03 JCN !{ +!&if_end.5 } &if_end.5 + STH2kr #0004 ADD2 LDA2 #0027 ;memory STH2kr #0002 ADD2 LDA2 #0001 MUL2 ADD2 #0002 ADD2 LDA2 ;memory STH2kr #0002 ADD2 LDA2 #0001 MUL2 ADD2 #0002 ADD2 LDA2 #0001 SUB2 STH2kr LDA2 #03 JCN !{ +!&if_end.6 } &if_end.6 + STH2kr #0004 ADD2 LDA2 #0027 ;memory STH2kr #0002 ADD2 LDA2 #0001 MUL2 ADD2 #0002 ADD2 LDA2 #18 DEO STH2kr LDA2 #03 JCN !{ +!&if_end.7 } &if_end.7 + STH2kr #0004 ADD2 LDA2 #0027 ;memory STH2kr #0002 ADD2 LDA2 #0001 MUL2 ADD2 #0002 ADD2 LDA2 #12 DEI STH2kr LDA2 #03 JCN !{ +!&if_end.8 } &if_end.8 + STH2kr #0004 ADD2 LDA2 #0027 ;memory STH2kr #0002 ADD2 LDA2 #0001 MUL2 ADD2 #0002 ADD2 LDA2 #0000 EQU2 #03 JCN !{ + STH2kr LDA2 +#0001 STH2kr STA2 + +&while.1 STH2kr LDA2 #0000 GTH2 #03 JCN !{ + STH2kr #0004 ADD2 LDA2 #0001 ADD2 STH2kr #0004 ADD2 STA2 STH2kr LDA2 #03 JCN !{ +!&if_end.9 } &if_end.9 + STH2kr #0004 ADD2 LDA2 #0027 STH2kr LDA2 #0001 ADD2 STH2kr STA2 STH2kr LDA2 #03 JCN !{ +!&if_end.10 } &if_end.10 + STH2kr #0004 ADD2 LDA2 #0027 STH2kr LDA2 #0001 SUB2 STH2kr STA2 !&while.1 } +!&if_end.11 } &if_end.11 + STH2kr LDA2 #03 JCN !{ +!&if_end.12 } &if_end.12 + STH2kr #0004 ADD2 LDA2 #0027 ;memory STH2kr #0002 ADD2 LDA2 #0001 MUL2 ADD2 #0002 ADD2 LDA2 #03 JCN !{ + STH2kr LDA2 +#0001 STH2kr STA2 + +&while.2 STH2kr LDA2 #0000 GTH2 #03 JCN !{ + STH2kr #0004 ADD2 LDA2 #0001 SUB2 STH2kr #0004 ADD2 STA2 STH2kr LDA2 #03 JCN !{ +!&if_end.13 } &if_end.13 + STH2kr #0004 ADD2 LDA2 #0027 STH2kr LDA2 #0001 ADD2 STH2kr STA2 STH2kr LDA2 #03 JCN !{ +!&if_end.14 } &if_end.14 + STH2kr #0004 ADD2 LDA2 #0027 STH2kr LDA2 #0001 SUB2 STH2kr STA2 !&while.2 } +!&if_end.15 } &if_end.15 + STH2kr #0004 ADD2 LDA2 #0001 ADD2 STH2kr #0004 ADD2 STA2 !&while.0 } + &return + POP2r JMP2r + +@sext + #80 ANDk EQU #ff MUL SWP JMP2r +@sdiv + OVR #80 AND ?&b_neg &b_pos OVR2 POP #80 AND ?&a_neg_b_pos DIV2 JMP2r &a_neg_b_pos SWP2 #0000 SWP2 SUB2 SWP2 DIV2 #0000 SWP2 SUB2 JMP2r + &b_neg #0000 SWP2 SUB2 OVR2 POP #80 AND ?&a_neg_b_neg DIV2 #0000 SWP2 SUB2 JMP2r + &a_neg_b_neg #0000 ROT2 SUB2 SWP2 DIV2 JMP2r + +@aalloc_ ( size* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + ;mem_length_ LDA2 STH2kr STA2 + ;mem_length_ LDA2k STH2kr INC2 INC2 LDA2 ADD2 SWP2 STA2 + ;mem_ STH2kr LDA2 ADD2 !&return + #0000 + + &return + POP2r JMP2r + +@areturn_ ( size* src* checkpoint* -- result* ) + OVR2r LIT2r 000a SUB2r STH2kr #0008 ADD2 STA2 + STH2kr #0006 ADD2 STA2 + STH2kr #0004 ADD2 STA2 + ;mem_ STH2kr #0008 ADD2 LDA2 ADD2 STH2kr INC2 INC2 STA2 + STH2kr #0006 ADD2 LDA2 STH2kr INC2 INC2 LDA2 NEQ2 ?&end.1 + STH2kr #0006 ADD2 LDA2 !&return + + &end.1 + #0000 STH2kr STA2 + + &begin.2 + STH2kr LDA2 STH2kr #0004 ADD2 LDA2 LTH2 #00 EQU ?&break.2 + STH2kr #0006 ADD2 LDA2 STH2kr LDA2 ADD2 LDA sext + STH2kr INC2 INC2 LDA2 STH2kr LDA2 ADD2 STA + POP + + &continue.2 + STH2kr LDA2k INC2k ROT2 STA2 + POP2 !&begin.2 + + &break.2 + STH2kr #0008 ADD2 LDA2 STH2kr #0004 ADD2 LDA2 ADD2 ;mem_length_ STA2 + #0000 ;mem_ ;mem_length_ LDA2 ADD2 STA + POP STH2kr INC2 INC2 LDA2 !&return + #0000 + + &return + POP2r JMP2r + +@afree_ ( -- result* ) + OVR2r #0000 ;mem_length_ STA2 + #0000 + + &return + POP2r JMP2r + +@amcpy_ ( length* from* -- result* ) + OVR2r LIT2r 0008 SUB2r STH2kr #0006 ADD2 STA2 + STH2kr #0004 ADD2 STA2 + STH2kr #0004 ADD2 LDA2 aalloc_ + STH2kr INC2 INC2 STA2 + #0000 STH2kr STA2 + + &begin.1 + STH2kr LDA2 STH2kr #0004 ADD2 LDA2 LTH2 #00 EQU ?&break.1 + STH2kr #0006 ADD2 LDA2 STH2kr LDA2 ADD2 LDA sext + STH2kr INC2 INC2 LDA2 STH2kr LDA2 ADD2 STA + POP + + &continue.1 + STH2kr LDA2k INC2k ROT2 STA2 + POP2 !&begin.1 + + &break.1 + STH2kr INC2 INC2 LDA2 !&return + #0000 + + &return + POP2r JMP2r + +@nat_to_str_ ( n* -- result* ) + OVR2r LIT2r 000a SUB2r STH2kr #0008 ADD2 STA2 + #0005 STH2kr STA2 + + &begin.1 + STH2kr #0008 ADD2 LDA2 #000a OVR2 OVR2 DIV2 MUL2 SUB2 #0030 ADD2 STH2kr INC2 INC2 STH2kr LDA2k #0001 SUB2 SWP2 STA2k + POP2 ADD2 STA + POP STH2kr #0008 ADD2 LDA2k #000a DIV2 SWP2 STA2 + + &continue.1 + #0000 STH2kr #0008 ADD2 LDA2 LTH2 ?&begin.1 + + &break.1 + #0005 STH2kr LDA2 SUB2 STH2kr INC2 INC2 STH2kr LDA2 ADD2 amcpy_ + !&return + #0000 + + &return + POP2r JMP2r + +@int_to_str_ ( n* -- result* ) + OVR2r LIT2r 000c SUB2r STH2kr #000a ADD2 STA2 + #0006 STH2kr INC2 INC2 STA2 + STH2kr #000a ADD2 LDA2 #8000 EOR2 #8000 LTH2 #00 SWP #0000 NEQ2 #00 SWP STH2kr STA + POP LDAkr STHr sext + #0000 EQU2 ?&end.1 + #0000 STH2kr #000a ADD2 LDA2 SUB2 STH2kr #000a ADD2 STA2 + + &end.1 + + &begin.2 + STH2kr #000a ADD2 LDA2 #000a OVR2 OVR2 sdiv/b_pos + MUL2 SUB2 #0030 ADD2 STH2kr #0004 ADD2 STH2kr INC2 INC2 LDA2k #0001 SUB2 SWP2 STA2k + POP2 ADD2 STA + POP STH2kr #000a ADD2 LDA2k #000a sdiv/b_pos + SWP2 STA2 + + &continue.2 + #8000 STH2kr #000a ADD2 LDA2 #8000 EOR2 LTH2 ?&begin.2 + + &break.2 + LDAkr STHr sext + #0000 EQU2 ?&end.3 + #002d STH2kr #0004 ADD2 STH2kr INC2 INC2 LDA2k #0001 SUB2 SWP2 STA2k + POP2 ADD2 STA + POP + + &end.3 + #0006 STH2kr INC2 INC2 LDA2 SUB2 STH2kr #0004 ADD2 STH2kr INC2 INC2 LDA2 ADD2 amcpy_ + !&return + #0000 + + &return + POP2r JMP2r + +@int_to_nat_ ( n* -- result* ) + OVR2r LIT2r 0002 SUB2r STH2kr STA2 + STH2kr LDA2 !&return + #0000 + + &return + POP2r JMP2r + +@nat_to_int_ ( n* -- result* ) + OVR2r LIT2r 0002 SUB2r STH2kr STA2 + STH2kr LDA2 !&return + #0000 + + &return + POP2r JMP2r + +@int_add_ ( b* a* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + STH2kr STA2 + STH2kr INC2 INC2 LDA2 STH2kr LDA2 ADD2 !&return + #0000 + + &return + POP2r JMP2r + +@int_sub_ ( b* a* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + STH2kr STA2 + STH2kr INC2 INC2 LDA2 STH2kr LDA2 SUB2 !&return + #0000 + + &return + POP2r JMP2r + +@int_mul_ ( b* a* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + STH2kr STA2 + STH2kr INC2 INC2 LDA2 STH2kr LDA2 MUL2 !&return + #0000 + + &return + POP2r JMP2r + +@int_div_ ( b* a* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + STH2kr STA2 + STH2kr INC2 INC2 LDA2 STH2kr LDA2 sdiv + !&return + #0000 + + &return + POP2r JMP2r + +@int_eq_ ( b* a* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + STH2kr STA2 + STH2kr INC2 INC2 LDA2 STH2kr LDA2 EQU2 #00 SWP !&return + #0000 + + &return + POP2r JMP2r + +@int_ne_ ( b* a* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + STH2kr STA2 + STH2kr INC2 INC2 LDA2 STH2kr LDA2 NEQ2 #00 SWP !&return + #0000 + + &return + POP2r JMP2r + +@int_lt_ ( b* a* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + STH2kr STA2 + STH2kr INC2 INC2 LDA2 #8000 EOR2 STH2kr LDA2 #8000 EOR2 LTH2 #00 SWP !&return + #0000 + + &return + POP2r JMP2r + +@int_le_ ( b* a* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + STH2kr STA2 + STH2kr INC2 INC2 LDA2 #8000 EOR2 STH2kr LDA2 #8000 EOR2 GTH2 #00 SWP #01 EOR !&return + #0000 + + &return + POP2r JMP2r + +@int_gt_ ( b* a* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + STH2kr STA2 + STH2kr LDA2 #8000 EOR2 STH2kr INC2 INC2 LDA2 #8000 EOR2 LTH2 #00 SWP !&return + #0000 + + &return + POP2r JMP2r + +@int_ge_ ( b* a* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + STH2kr STA2 + STH2kr LDA2 #8000 EOR2 STH2kr INC2 INC2 LDA2 #8000 EOR2 GTH2 #00 SWP #01 EOR !&return + #0000 + + &return + POP2r JMP2r + +@int_neg_ ( f* -- result* ) + OVR2r LIT2r 0002 SUB2r STH2kr STA2 + #0000 STH2kr LDA2 SUB2 !&return + #0000 + + &return + POP2r JMP2r + +@int_abs_ ( f* -- result* ) + OVR2r LIT2r 0002 SUB2r STH2kr STA2 + STH2kr LDA2 #8000 EOR2 #8000 LTH2 ?&then.1 + STH2kr LDA2 !&end.1 + + &then.1 + #0000 STH2kr LDA2 SUB2 + + &end.1 + !&return + #0000 + + &return + POP2r JMP2r + +@str/ ( str* -- ) + LDAk DUP ?{ POP POP2 JMP2r } + #18 DEO + INC2 !/ + +@mem_length_ #0000 +@mem_ @memory $10000 \ No newline at end of file diff --git a/test/tal/rw.tal b/test/tal/rw.tal new file mode 100644 index 0000000..b49e866 --- /dev/null +++ b/test/tal/rw.tal @@ -0,0 +1,279 @@ +|10 @Console/vector $2 &read $5 &type $1 &write $1 &error $1 +|100 + ;on-console .Console/vector DEO2 + BRK + +@on-console ( -> ) + LIT2r 0000 + +!{ @t $1 } #12 DEI ;t STA2 +;t LDA2 #18 DEO POP2r BRK @sext + #80 ANDk EQU #ff MUL SWP JMP2r +@sdiv + OVR #80 AND ?&b_neg &b_pos OVR2 POP #80 AND ?&a_neg_b_pos DIV2 JMP2r &a_neg_b_pos SWP2 #0000 SWP2 SUB2 SWP2 DIV2 #0000 SWP2 SUB2 JMP2r + &b_neg #0000 SWP2 SUB2 OVR2 POP #80 AND ?&a_neg_b_neg DIV2 #0000 SWP2 SUB2 JMP2r + &a_neg_b_neg #0000 ROT2 SUB2 SWP2 DIV2 JMP2r + +@aalloc_ ( size* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + ;mem_length_ LDA2 STH2kr STA2 + ;mem_length_ LDA2k STH2kr INC2 INC2 LDA2 ADD2 SWP2 STA2 + ;mem_ STH2kr LDA2 ADD2 !&return + #0000 + + &return + POP2r JMP2r + +@areturn_ ( size* src* checkpoint* -- result* ) + OVR2r LIT2r 000a SUB2r STH2kr #0008 ADD2 STA2 + STH2kr #0006 ADD2 STA2 + STH2kr #0004 ADD2 STA2 + ;mem_ STH2kr #0008 ADD2 LDA2 ADD2 STH2kr INC2 INC2 STA2 + STH2kr #0006 ADD2 LDA2 STH2kr INC2 INC2 LDA2 NEQ2 ?&end.1 + STH2kr #0006 ADD2 LDA2 !&return + + &end.1 + #0000 STH2kr STA2 + + &begin.2 + STH2kr LDA2 STH2kr #0004 ADD2 LDA2 LTH2 #00 EQU ?&break.2 + STH2kr #0006 ADD2 LDA2 STH2kr LDA2 ADD2 LDA sext + STH2kr INC2 INC2 LDA2 STH2kr LDA2 ADD2 STA + POP + + &continue.2 + STH2kr LDA2k INC2k ROT2 STA2 + POP2 !&begin.2 + + &break.2 + STH2kr #0008 ADD2 LDA2 STH2kr #0004 ADD2 LDA2 ADD2 ;mem_length_ STA2 + #0000 ;mem_ ;mem_length_ LDA2 ADD2 STA + POP STH2kr INC2 INC2 LDA2 !&return + #0000 + + &return + POP2r JMP2r + +@afree_ ( -- result* ) + OVR2r #0000 ;mem_length_ STA2 + #0000 + + &return + POP2r JMP2r + +@amcpy_ ( length* from* -- result* ) + OVR2r LIT2r 0008 SUB2r STH2kr #0006 ADD2 STA2 + STH2kr #0004 ADD2 STA2 + STH2kr #0004 ADD2 LDA2 aalloc_ + STH2kr INC2 INC2 STA2 + #0000 STH2kr STA2 + + &begin.1 + STH2kr LDA2 STH2kr #0004 ADD2 LDA2 LTH2 #00 EQU ?&break.1 + STH2kr #0006 ADD2 LDA2 STH2kr LDA2 ADD2 LDA sext + STH2kr INC2 INC2 LDA2 STH2kr LDA2 ADD2 STA + POP + + &continue.1 + STH2kr LDA2k INC2k ROT2 STA2 + POP2 !&begin.1 + + &break.1 + STH2kr INC2 INC2 LDA2 !&return + #0000 + + &return + POP2r JMP2r + +@nat_to_str_ ( n* -- result* ) + OVR2r LIT2r 000a SUB2r STH2kr #0008 ADD2 STA2 + #0005 STH2kr STA2 + + &begin.1 + STH2kr #0008 ADD2 LDA2 #000a OVR2 OVR2 DIV2 MUL2 SUB2 #0030 ADD2 STH2kr INC2 INC2 STH2kr LDA2k #0001 SUB2 SWP2 STA2k + POP2 ADD2 STA + POP STH2kr #0008 ADD2 LDA2k #000a DIV2 SWP2 STA2 + + &continue.1 + #0000 STH2kr #0008 ADD2 LDA2 LTH2 ?&begin.1 + + &break.1 + #0005 STH2kr LDA2 SUB2 STH2kr INC2 INC2 STH2kr LDA2 ADD2 amcpy_ + !&return + #0000 + + &return + POP2r JMP2r + +@int_to_str_ ( n* -- result* ) + OVR2r LIT2r 000c SUB2r STH2kr #000a ADD2 STA2 + #0006 STH2kr INC2 INC2 STA2 + STH2kr #000a ADD2 LDA2 #8000 EOR2 #8000 LTH2 #00 SWP #0000 NEQ2 #00 SWP STH2kr STA + POP LDAkr STHr sext + #0000 EQU2 ?&end.1 + #0000 STH2kr #000a ADD2 LDA2 SUB2 STH2kr #000a ADD2 STA2 + + &end.1 + + &begin.2 + STH2kr #000a ADD2 LDA2 #000a OVR2 OVR2 sdiv/b_pos + MUL2 SUB2 #0030 ADD2 STH2kr #0004 ADD2 STH2kr INC2 INC2 LDA2k #0001 SUB2 SWP2 STA2k + POP2 ADD2 STA + POP STH2kr #000a ADD2 LDA2k #000a sdiv/b_pos + SWP2 STA2 + + &continue.2 + #8000 STH2kr #000a ADD2 LDA2 #8000 EOR2 LTH2 ?&begin.2 + + &break.2 + LDAkr STHr sext + #0000 EQU2 ?&end.3 + #002d STH2kr #0004 ADD2 STH2kr INC2 INC2 LDA2k #0001 SUB2 SWP2 STA2k + POP2 ADD2 STA + POP + + &end.3 + #0006 STH2kr INC2 INC2 LDA2 SUB2 STH2kr #0004 ADD2 STH2kr INC2 INC2 LDA2 ADD2 amcpy_ + !&return + #0000 + + &return + POP2r JMP2r + +@int_to_nat_ ( n* -- result* ) + OVR2r LIT2r 0002 SUB2r STH2kr STA2 + STH2kr LDA2 !&return + #0000 + + &return + POP2r JMP2r + +@nat_to_int_ ( n* -- result* ) + OVR2r LIT2r 0002 SUB2r STH2kr STA2 + STH2kr LDA2 !&return + #0000 + + &return + POP2r JMP2r + +@int_add_ ( b* a* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + STH2kr STA2 + STH2kr INC2 INC2 LDA2 STH2kr LDA2 ADD2 !&return + #0000 + + &return + POP2r JMP2r + +@int_sub_ ( b* a* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + STH2kr STA2 + STH2kr INC2 INC2 LDA2 STH2kr LDA2 SUB2 !&return + #0000 + + &return + POP2r JMP2r + +@int_mul_ ( b* a* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + STH2kr STA2 + STH2kr INC2 INC2 LDA2 STH2kr LDA2 MUL2 !&return + #0000 + + &return + POP2r JMP2r + +@int_div_ ( b* a* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + STH2kr STA2 + STH2kr INC2 INC2 LDA2 STH2kr LDA2 sdiv + !&return + #0000 + + &return + POP2r JMP2r + +@int_eq_ ( b* a* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + STH2kr STA2 + STH2kr INC2 INC2 LDA2 STH2kr LDA2 EQU2 #00 SWP !&return + #0000 + + &return + POP2r JMP2r + +@int_ne_ ( b* a* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + STH2kr STA2 + STH2kr INC2 INC2 LDA2 STH2kr LDA2 NEQ2 #00 SWP !&return + #0000 + + &return + POP2r JMP2r + +@int_lt_ ( b* a* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + STH2kr STA2 + STH2kr INC2 INC2 LDA2 #8000 EOR2 STH2kr LDA2 #8000 EOR2 LTH2 #00 SWP !&return + #0000 + + &return + POP2r JMP2r + +@int_le_ ( b* a* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + STH2kr STA2 + STH2kr INC2 INC2 LDA2 #8000 EOR2 STH2kr LDA2 #8000 EOR2 GTH2 #00 SWP #01 EOR !&return + #0000 + + &return + POP2r JMP2r + +@int_gt_ ( b* a* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + STH2kr STA2 + STH2kr LDA2 #8000 EOR2 STH2kr INC2 INC2 LDA2 #8000 EOR2 LTH2 #00 SWP !&return + #0000 + + &return + POP2r JMP2r + +@int_ge_ ( b* a* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + STH2kr STA2 + STH2kr LDA2 #8000 EOR2 STH2kr INC2 INC2 LDA2 #8000 EOR2 GTH2 #00 SWP #01 EOR !&return + #0000 + + &return + POP2r JMP2r + +@int_neg_ ( f* -- result* ) + OVR2r LIT2r 0002 SUB2r STH2kr STA2 + #0000 STH2kr LDA2 SUB2 !&return + #0000 + + &return + POP2r JMP2r + +@int_abs_ ( f* -- result* ) + OVR2r LIT2r 0002 SUB2r STH2kr STA2 + STH2kr LDA2 #8000 EOR2 #8000 LTH2 ?&then.1 + STH2kr LDA2 !&end.1 + + &then.1 + #0000 STH2kr LDA2 SUB2 + + &end.1 + !&return + #0000 + + &return + POP2r JMP2r + +@str/ ( str* -- ) + LDAk DUP ?{ POP POP2 JMP2r } + #18 DEO + INC2 !/ + +@mem_length_ #0000 +@mem_ \ No newline at end of file diff --git a/tests b/tests index 780e1dd..b2f08fa 100755 --- a/tests +++ b/tests @@ -36,3 +36,4 @@ tests "if.ul" "x is 20" ./cli ./test/if.ul tests "while.ul" "0123456789" ./cli ./test/while.ul tests "fib.ul" "28657" ./cli ./test/fib.ul tests "attack.ul" "102 damage inflicted!" ./cli ./test/attack.ul +tests "array.ul" "1 2 3 4 5 6 " ./cli ./test/array.ul \ No newline at end of file