WIP function calls

This commit is contained in:
zongor 2026-05-17 23:09:57 -07:00
parent e968cb6725
commit bb764a3017
17 changed files with 734 additions and 518 deletions

View File

@ -43,4 +43,4 @@ struct symbol_s {
void *node_value(Node *n); void *node_value(Node *n);
#endif #endif

View File

@ -17,8 +17,10 @@ scope_push()
Scope *child = aalloc(arena, sizeof(Scope)); Scope *child = aalloc(arena, sizeof(Scope));
child->symbols = List_init(arena); child->symbols = List_init(arena);
child->parent = parser.current_scope; child->parent = parser.current_scope;
child->locals_offset = 0;
parser.current_scope = child; parser.current_scope = child;
parser.depth++;
} }
void void
@ -26,6 +28,7 @@ scope_pop()
{ {
Scope *prev = parser.current_scope->parent; Scope *prev = parser.current_scope->parent;
parser.current_scope = prev; parser.current_scope = prev;
parser.depth--;
} }
Symbol * Symbol *
@ -37,7 +40,7 @@ scope_get_symbol(Scope *scope, const char *name, u32 name_length)
count = scope->symbols->count; count = scope->symbols->count;
for(i = 0; i < count; i++) { for(i = 0; i < count; i++) {
Symbol *sym = List_get(scope->symbols, i); Symbol *sym = List_get(scope->symbols, i);
if(sleq(sym->name, name, name_length)) return sym; if(sym->name_length == name_length && sleq(sym->name, name, name_length)) return sym;
} }
return scope_get_symbol(scope->parent, name, name_length); return scope_get_symbol(scope->parent, name, name_length);
@ -47,7 +50,12 @@ Symbol *
scope_add_symbol(const char *name, u32 name_length, SymbolType type, u32 size) scope_add_symbol(const char *name, u32 name_length, SymbolType type, u32 size)
{ {
Symbol *sym = scope_get_symbol(parser.current_scope, name, name_length); Symbol *sym = scope_get_symbol(parser.current_scope, name, name_length);
if(sym != nil) return sym; if(sym != nil) {
if(parser.pass)
return sym;
else
emitter.error("duplicate found", 14, parser.previous.line);
}
sym = aalloc(arena, sizeof(Symbol)); sym = aalloc(arena, sizeof(Symbol));
scpy(sym->name, name, name_length); scpy(sym->name, name, name_length);
@ -55,12 +63,16 @@ scope_add_symbol(const char *name, u32 name_length, SymbolType type, u32 size)
sym->type = type; sym->type = type;
sym->secondary_type = SYMBOL_VOID; sym->secondary_type = SYMBOL_VOID;
sym->size = size; sym->size = size;
sym->ref = 0; sym->ref = parser.current_scope->locals_offset;
if(type == SYMBOL_PLEX || type == SYMBOL_METHOD || type == SYMBOL_TRAIT) { parser.current_scope->locals_offset += size;
if(type == SYMBOL_PLEX || type == SYMBOL_METHOD || type == SYMBOL_TRAIT ||
type == SYMBOL_FUNCTION) {
sym->args = List_init(arena); sym->args = List_init(arena);
sym->fields = List_init(arena);
} }
if(type == SYMBOL_PLEX || type == SYMBOL_METHOD || type == SYMBOL_TRAIT)
sym->fields = List_init(arena);
List_push(arena, parser.current_scope->symbols, sym, sizeof(Symbol)); List_push(arena, parser.current_scope->symbols, sym, sizeof(Symbol));
return sym; return sym;
@ -80,7 +92,7 @@ is_type()
} }
SymbolType SymbolType
tokt_to_symt(TokenType t) token_type_to_sym_type(TokenType t)
{ {
switch(t) { switch(t) {
case TOKEN_TYPE_BOOL: case TOKEN_TYPE_BOOL:
@ -153,7 +165,7 @@ match(TokenType type)
void void
expect(TokenType type) expect(TokenType type)
{ {
if(!match(type)) { if(!consume(type)) {
emitter.error(parser.previous.start, parser.previous.length, emitter.error(parser.previous.start, parser.previous.length,
parser.previous.line); parser.previous.line);
} }
@ -185,21 +197,31 @@ define_function()
scope_push(); scope_push();
expect(TOKEN_LPAREN); expect(TOKEN_LPAREN);
advance();
/* parse the args */ /* parse the args */
while(!match(TOKEN_RPAREN)) size += variable_declaration(fn); while(!check(TOKEN_LBRACE)) {
size += variable_declaration(fn);
advance();
advance();
}
if(!match(TOKEN_LBRACE)) { if(is_type()) {
fn->secondary_type = tokt_to_symt(parser.previous.type); /* get return slot */
fn->secondary_type = token_type_to_sym_type(parser.previous.type);
/* now parse the fn body */ /* now parse the fn body */
expect(TOKEN_LBRACE); expect(TOKEN_LBRACE);
} }
/* get the size of all the locals for the function in the body */ /* get the size of all the locals for the function in the body */
while(!match(TOKEN_RBRACE)) while(!match(TOKEN_RBRACE)) {
if(is_type()) size += variable_declaration(fn); if(is_type() && parser.current.type == TOKEN_IDENTIFIER)
size += variable_declaration(fn);
advance();
}
fn->size = size; fn->size = size;
scope_pop();
} }
void void
@ -330,6 +352,11 @@ variable()
parser.previous.line); parser.previous.line);
} }
if (sym->type == SYMBOL_FUNCTION) {
parser.call_fn = sym;
return;
}
parser.current_type = sym->type; parser.current_type = sym->type;
if(match(TOKEN_EQ)) { if(match(TOKEN_EQ)) {
expression(); expression();
@ -435,23 +462,22 @@ variable_declaration(Symbol *def)
i32 size = 0; i32 size = 0;
TokenType tt = parser.previous.type; TokenType tt = parser.previous.type;
Token var = parser.current; Token var = parser.current;
SymbolType st = tokt_to_symt(tt); SymbolType st = token_type_to_sym_type(tt);
Symbol *arg; Symbol *variable;
if (st != SYMBOL_UNDEFINED) { if(st != SYMBOL_UNDEFINED) {
size = emitter.get_size(st); size = emitter.get_size(st);
arg = scope_add_symbol(parser.current.start, parser.current.length, variable =
st, size); scope_add_symbol(parser.current.start, parser.current.length, st, size);
if(def) { if(def) {
List_push(arena, def->args, arg, sizeof(Symbol)); List_push(arena, def->args, variable, sizeof(Symbol));
} else { } else {
emitter.emit_type(st, parser.current.start, parser.current.length, emitter.emit_type(variable, parser.depth);
parser.depth);
parser.current_type = st; parser.current_type = st;
} }
} else { } else {
/* we need to look up the type */ /* we need to look up the type */
emitter.error("Not implemented", 16, parser.previous.line);
} }
advance(); advance();
@ -476,15 +502,11 @@ variable_declaration(Symbol *def)
void void
declaration() declaration()
{ {
/** if(is_type()) {
* maybe a Plex?
* lookup plex defs
* if not then
*/
if(is_type())
variable_declaration(nil); variable_declaration(nil);
else }else{
statement(); statement();
}
} }
void void
@ -552,6 +574,33 @@ block()
consume(TOKEN_RBRACE); consume(TOKEN_RBRACE);
} }
void
function()
{
Symbol *sym = scope_get_symbol(parser.current_scope, parser.previous.start,
parser.previous.length);
emitter.emit_function(sym);
while(!check(TOKEN_LBRACE)) {
advance();
}
block();
emitter.emit_arena_fn_return();
}
void call() {
if (!check(TOKEN_RPAREN)) {
do {
expression();
} while (match(TOKEN_COMMA));
}
consume(TOKEN_RPAREN);
emitter.emit_arena_fn_call(parser.call_fn);
parser.current_type = parser.call_fn->secondary_type;
advance();
return;
}
void void
statement() statement()
{ {
@ -559,6 +608,9 @@ statement()
scope_push(); scope_push();
block(); block();
scope_pop(); scope_pop();
} else if(match(TOKEN_KEYWORD_FN)) {
advance();
function();
} else if(match(TOKEN_KEYWORD_IF)) { } else if(match(TOKEN_KEYWORD_IF)) {
if_statement(); if_statement();
} else if(match(TOKEN_KEYWORD_WHILE)) { } else if(match(TOKEN_KEYWORD_WHILE)) {
@ -618,6 +670,12 @@ unary()
ParseRule rules[] = { ParseRule rules[] = {
/* TOKEN_ERROR */ {nil, nil, PREC_NONE}, /* TOKEN_ERROR */ {nil, nil, PREC_NONE},
/* TOKEN_EOF */ {nil, nil, PREC_NONE}, /* TOKEN_EOF */ {nil, nil, PREC_NONE},
/* TOKEN_LPAREN */ {grouping, call, PREC_CALL},
/* TOKEN_RPAREN */ {nil, nil, PREC_NONE},
/* TOKEN_LBRACE */ {nil, nil, PREC_NONE},
/* TOKEN_RBRACE */ {nil, nil, PREC_NONE},
/* TOKEN_LBRACKET */ {nil, nil, PREC_NONE},
/* TOKEN_RBRACKET */ {nil, nil, PREC_NONE},
/* TOKEN_IDENTIFIER */ {variable, nil, PREC_NONE}, /* TOKEN_IDENTIFIER */ {variable, nil, PREC_NONE},
/* TOKEN_LITERAL_INT */ {number, nil, PREC_NONE}, /* TOKEN_LITERAL_INT */ {number, nil, PREC_NONE},
/* TOKEN_LITERAL_NAT */ {number, nil, PREC_NONE}, /* TOKEN_LITERAL_NAT */ {number, nil, PREC_NONE},
@ -689,12 +747,6 @@ ParseRule rules[] = {
/* TOKEN_COLON */ {nil, nil, PREC_NONE}, /* TOKEN_COLON */ {nil, nil, PREC_NONE},
/* TOKEN_CARET */ {nil, nil, PREC_NONE}, /* TOKEN_CARET */ {nil, nil, PREC_NONE},
/* TOKEN_SEMICOLON */ {nil, nil, PREC_NONE}, /* TOKEN_SEMICOLON */ {nil, nil, PREC_NONE},
/* TOKEN_LPAREN */ {grouping, nil, PREC_NONE},
/* TOKEN_RPAREN */ {nil, nil, PREC_NONE},
/* TOKEN_LBRACE */ {nil, nil, PREC_NONE},
/* TOKEN_RBRACE */ {nil, nil, PREC_NONE},
/* TOKEN_LBRACKET */ {nil, nil, PREC_NONE},
/* TOKEN_RBRACKET */ {nil, nil, PREC_NONE},
/* TOKEN_ARROW_RIGHT */ {nil, nil, PREC_NONE}, /* TOKEN_ARROW_RIGHT */ {nil, nil, PREC_NONE},
/* TOKEN_SLL */ {nil, binary, PREC_NONE}, /* TOKEN_SLL */ {nil, binary, PREC_NONE},
/* TOKEN_SRL */ {nil, binary, PREC_NONE}, /* TOKEN_SRL */ {nil, binary, PREC_NONE},
@ -730,7 +782,6 @@ emit_program(char *source)
{ {
init_lexer(source); init_lexer(source);
advance(); advance();
scope_push();
emitter.prolog(); emitter.prolog();
@ -746,6 +797,7 @@ compile(Arena *a, Emitter e, char *source)
emitter = e; emitter = e;
build_symbol_table(source); build_symbol_table(source);
parser.pass++;
emit_program(source); emit_program(source);
return true; return true;

View File

@ -10,39 +10,43 @@ typedef struct parser_s Parser;
typedef struct parse_rule_s ParseRule; typedef struct parse_rule_s ParseRule;
struct scope_s { struct scope_s {
Scope *parent; /* pointer to this scopes parent to "bubble up"*/ Scope *parent; /* pointer to this scopes parent to "bubble up"*/
List *symbols; /* list of symbols that live in this scope */ List *symbols; /* list of symbols that live in this scope */
u32 locals_offset;
}; };
typedef enum { typedef enum {
PREC_NONE, PREC_NONE,
PREC_ASSIGNMENT, /* = */ PREC_ASSIGNMENT, /* = */
PREC_OR, /* or */ PREC_OR, /* or */
PREC_AND, /* and */ PREC_AND, /* and */
PREC_EQUALITY, /* == != */ PREC_EQUALITY, /* == != */
PREC_COMPARISON, /* < > <= >= */ PREC_COMPARISON, /* < > <= >= */
PREC_TERM, /* + - */ PREC_TERM, /* + - */
PREC_FACTOR, /* * / */ PREC_FACTOR, /* * / */
PREC_UNARY, /* ! - */ PREC_UNARY, /* ! - */
PREC_CAST, /* as */ PREC_CAST, /* as */
PREC_CALL, /* . () */ PREC_CALL, /* . () */
PREC_PRIMARY PREC_PRIMARY
} Precedence; } Precedence;
typedef void (*ParseFn)(); typedef void (*ParseFn)();
struct parse_rule_s { struct parse_rule_s {
ParseFn prefix; ParseFn prefix;
ParseFn infix; ParseFn infix;
Precedence precedence; Precedence precedence;
}; };
struct parser_s { struct parser_s {
Scope *current_scope; Symbol *call_fn;
Scope *current_scope;
Token current; Token current;
Token previous; Token previous;
SymbolType current_type; SymbolType current_type;
u32 depth; u32 depth;
u8 pass;
bool main_found;
}; };
bool compile(Arena *a, Emitter e, char *source); bool compile(Arena *a, Emitter e, char *source);

View File

@ -1,4 +1,4 @@
A permacomputing & game oriented language. A permacomputing and game oriented language designed for constrained systems.
> Permacomputing is a design practice that encourages the maximization of hardware lifespan, minimization of energy usage and focuses on the use of already available computational resources. It values maintenance and refactoring of systems to keep them efficient, instead of planned obsolescence, permacomputing practices planned longevity. It is about using computation only when it has a strengthening effect on ecosystems. > Permacomputing is a design practice that encourages the maximization of hardware lifespan, minimization of energy usage and focuses on the use of already available computational resources. It values maintenance and refactoring of systems to keep them efficient, instead of planned obsolescence, permacomputing practices planned longevity. It is about using computation only when it has a strengthening effect on ecosystems.

8
emit.h
View File

@ -9,7 +9,6 @@ typedef void (*SymbolEmit)(Symbol *sym);
typedef void (*ErrorMsg)(const char *str, i32 length, i32 line); typedef void (*ErrorMsg)(const char *str, i32 length, i32 line);
typedef void (*VoidArgEmit)(); typedef void (*VoidArgEmit)();
typedef void (*StrArgEmit)(const char *str, i32 length); typedef void (*StrArgEmit)(const char *str, i32 length);
typedef void (*TypeVariableEmit)(SymbolType t, const char *str, i32 length, bool local);
typedef void (*ConstEmit)(const char *str, i32 length, bool local); typedef void (*ConstEmit)(const char *str, i32 length, bool local);
typedef void (*VarEmit)(Symbol *sym, bool local); typedef void (*VarEmit)(Symbol *sym, bool local);
typedef void (*I32ArgEmit)(i32 val); typedef void (*I32ArgEmit)(i32 val);
@ -43,9 +42,9 @@ struct emitter_s {
StrArgEmit emit_real; StrArgEmit emit_real;
StrArgEmit emit_byte; StrArgEmit emit_byte;
StrArgEmit emit_str; StrArgEmit emit_str;
TypeVariableEmit emit_type; VarEmit emit_type;
VoidArgEmit emit_array; VoidArgEmit emit_array;
VoidArgEmit emit_function; SymbolEmit emit_function;
VoidArgEmit emit_plex; VoidArgEmit emit_plex;
VoidArgEmit emit_method; VoidArgEmit emit_method;
VoidArgEmit emit_trait; VoidArgEmit emit_trait;
@ -80,7 +79,8 @@ struct emitter_s {
VoidArgEmit emit_strbuf_init; VoidArgEmit emit_strbuf_init;
VoidArgEmit emit_strbuf_append; VoidArgEmit emit_strbuf_append;
VoidArgEmit emit_strbuf_to_str; VoidArgEmit emit_strbuf_to_str;
VoidArgEmit emit_arena_fn_call; SymbolEmit emit_arena_fn_call;
VoidArgEmit emit_arena_fn_return;
VoidArgEmit emit_arena_fn_return_plex; VoidArgEmit emit_arena_fn_return_plex;
VoidArgEmit emit_arena_fn_return_array; VoidArgEmit emit_arena_fn_return_array;
VoidArgEmit emit_arena_fn_return_strbuf; VoidArgEmit emit_arena_fn_return_strbuf;

View File

@ -1,12 +1,12 @@
#include "../../emit.h" #include "../../emit.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
void void
rer_emit_error(const char *str, i32 length, i32 line) rer_emit_error(const char *str, i32 length, i32 line)
{ {
printf("Error at line: %d > %.*s\n ", line, length, str); fprintf(stderr, "\n===\nError at line: %d > %.*s\n===\n", line, length, str);
exit(1); exit(1);
} }
@ -28,7 +28,6 @@ rer_epilogue()
printf("BRK\n\n"); printf("BRK\n\n");
} }
void void
rer_emit_add() rer_emit_add()
{ {
@ -128,122 +127,104 @@ u32
rer_get_size(SymbolType t) rer_get_size(SymbolType t)
{ {
switch(t) { switch(t) {
case SYMBOL_BOOL: return 1; case SYMBOL_BOOL:
case SYMBOL_BYTE: return 1; return 1;
case SYMBOL_INT: return 2; case SYMBOL_BYTE:
case SYMBOL_NAT: return 2; return 1;
case SYMBOL_REAL: return 2; case SYMBOL_INT:
case SYMBOL_STR: return 2; return 2;
case SYMBOL_U8: return 1; case SYMBOL_NAT:
case SYMBOL_I8: return 1; return 2;
case SYMBOL_I16: return 2; case SYMBOL_REAL:
case SYMBOL_U16: return 2; return 2;
case SYMBOL_I32: return 4; case SYMBOL_STR:
case SYMBOL_U32: return 4; return 2;
case SYMBOL_F32: return 4; case SYMBOL_U8:
default: break; return 1;
case SYMBOL_I8:
return 1;
case SYMBOL_I16:
return 2;
case SYMBOL_U16:
return 2;
case SYMBOL_I32:
return 4;
case SYMBOL_U32:
return 4;
case SYMBOL_F32:
return 4;
default:
break;
} }
return 0; return 0;
} }
void void
rer_emit_primitive_type(SymbolType t, const char *str, i32 length, bool local) rer_emit_primitive_type(Symbol *sym, bool local)
{ {
switch(t) { if(local)
case SYMBOL_BOOL: { if(sym->ref)
if(local) printf("STH2kr #%04x ADD2 STA2\n", sym->ref);
printf("!{ &%.*s $2 } ", length, str);
else else
printf("!{ @%.*s $2 } ", length, str); printf("STH2kr STA2\n");
break; else
} switch(sym->type) {
case SYMBOL_BYTE: { case SYMBOL_BOOL: {
if(local) printf("!{ @%.*s $2 } ", sym->name_length, sym->name);
printf("!{ &%.*s $1 } ", length, str); break;
else }
printf("!{ @%.*s $1 } ", length, str); case SYMBOL_BYTE: {
break; printf("!{ @%.*s $1 } ", sym->name_length, sym->name);
} break;
case SYMBOL_INT: { }
if(local) case SYMBOL_INT: {
printf("!{ &%.*s $2 } ", length, str); printf("!{ @%.*s $2 } ", sym->name_length, sym->name);
else break;
printf("!{ @%.*s $2 } ", length, str); }
break; case SYMBOL_NAT: {
} printf("!{ @%.*s $2 } ", sym->name_length, sym->name);
case SYMBOL_NAT: { break;
if(local) }
printf("!{ &%.*s $2 } ", length, str); case SYMBOL_REAL: {
else printf("!{ @%.*s $2 } ", sym->name_length, sym->name);
printf("!{ @%.*s $2 } ", length, str); break;
break; }
} case SYMBOL_STR: {
case SYMBOL_REAL: { printf("!{ @%.*s $2 } ", sym->name_length, sym->name);
if(local) break;
printf("!{ &%.*s $2 } ", length, str); }
else case SYMBOL_U8: {
printf("!{ @%.*s $2 } ", length, str); printf("!{ @%.*s $1 } ", sym->name_length, sym->name);
break; break;
} }
case SYMBOL_STR: { case SYMBOL_I8: {
if(local) printf("!{ @%.*s $1 } ", sym->name_length, sym->name);
printf("!{ &%.*s $2 } ", length, str); break;
else }
printf("!{ @%.*s $2 } ", length, str); case SYMBOL_I16: {
break; printf("!{ @%.*s $2 } ", sym->name_length, sym->name);
} break;
case SYMBOL_U8: { }
if(local) case SYMBOL_U16: {
printf("!{ &%.*s $1 } ", length, str); printf("!{ @%.*s $2 } ", sym->name_length, sym->name);
else break;
printf("!{ @%.*s $1 } ", length, str); }
break; case SYMBOL_I32: {
} printf("!{ @%.*s $4 } ", sym->name_length, sym->name);
case SYMBOL_I8: { break;
if(local) }
printf("!{ &%.*s $1 } ", length, str); case SYMBOL_U32: {
else printf("!{ @%.*s $4 } ", sym->name_length, sym->name);
printf("!{ @%.*s $1 } ", length, str); break;
break; }
} case SYMBOL_F32: {
case SYMBOL_I16: { printf("!{ @%.*s $4 } ", sym->name_length, sym->name);
if(local) break;
printf("!{ &%.*s $2 } ", length, str); }
else default:
printf("!{ @%.*s $2 } ", length, str); break;
break; }
}
case SYMBOL_U16: {
if(local)
printf("!{ &%.*s $2 } ", length, str);
else
printf("!{ @%.*s $2 } ", length, str);
break;
}
case SYMBOL_I32: {
if(local)
printf("!{ &%.*s $4 } ", length, str);
else
printf("!{ @%.*s $4 } ", length, str);
break;
}
case SYMBOL_U32: {
if(local)
printf("!{ &%.*s $4 } ", length, str);
else
printf("!{ @%.*s $4 } ", length, str);
break;
}
case SYMBOL_F32: {
if(local)
printf("!{ &%.*s $4 } ", length, str);
else
printf("!{ @%.*s $4 } ", length, str);
break;
}
default: break;
}
} }
void void
rer_emit_int(const char *str, i32 length) rer_emit_int(const char *str, i32 length)
@ -303,8 +284,21 @@ rer_emit_array()
} }
void void
rer_emit_function() rer_emit_function(Symbol *sym)
{ {
USED(sym);
}
void
rer_emit_arena_fn_return()
{
printf("&return\n\t\tPOP2r JMP2r\n\n");
}
void
rer_emit_arena_fn_call(Symbol *sym)
{
USED(sym);
} }
void void
@ -353,7 +347,10 @@ void
rer_emit_variable(Symbol *sym, bool local) rer_emit_variable(Symbol *sym, bool local)
{ {
if(local) if(local)
printf(",/%.*s LDR2 ", sym->name_length, sym->name); if(sym->ref)
printf("STH2kr #%04x ADD2 LDA2 ", sym->ref);
else
printf("STH2kr LDA2 ");
else else
printf(";%.*s LDA2 ", sym->name_length, sym->name); printf(";%.*s LDA2 ", sym->name_length, sym->name);
} }
@ -362,7 +359,10 @@ void
rer_emit_set_variable(Symbol *sym, bool local) rer_emit_set_variable(Symbol *sym, bool local)
{ {
if(local) if(local)
printf(",/%.*s STR2 ", sym->name_length, sym->name); if(sym->ref)
printf("STH2kr #%04x ADD2 STA2 ", sym->ref);
else
printf("STH2kr STA2 ");
else else
printf(";%.*s STA2 ", sym->name_length, sym->name); printf(";%.*s STA2 ", sym->name_length, sym->name);
} }
@ -477,11 +477,6 @@ rer_emit_strbuf_to_str()
{ {
} }
void
rer_emit_arena_fn_call()
{
}
void void
rer_emit_arena_fn_return_plex() rer_emit_arena_fn_return_plex()
{ {
@ -656,6 +651,7 @@ rer_emitter()
rer_emit_strbuf_append, rer_emit_strbuf_append,
rer_emit_strbuf_to_str, rer_emit_strbuf_to_str,
rer_emit_arena_fn_call, rer_emit_arena_fn_call,
rer_emit_arena_fn_return,
rer_emit_arena_fn_return_plex, rer_emit_arena_fn_return_plex,
rer_emit_arena_fn_return_array, rer_emit_arena_fn_return_array,
rer_emit_arena_fn_return_strbuf, rer_emit_arena_fn_return_strbuf,

View File

@ -7,148 +7,171 @@
#define UXN_OP_K (1 << 7) #define UXN_OP_K (1 << 7)
enum uxn_opcode { enum uxn_opcode {
/* Stack I */ /* Logic */ /* Memory I */ /* Arithmetic*/ BRK = 0x00,
BRK = 0x00, EQU = 0x08, LDZ = 0x10, ADD = 0x18, EQU = 0x08,
INC = 0x01, NEQ = 0x09, STZ = 0x11, SUB = 0x19, LDZ = 0x10,
POP = 0x02, GTH = 0x0A, LDR = 0x12, MUL = 0x1A, ADD = 0x18,
NIP = 0x03, LTH = 0x0B, STR = 0x13, DIV = 0x1B, INC = 0x01,
/* Stack II */ /* Stash */ /* Memory II */ /* Bitwise */ NEQ = 0x09,
SWP = 0x04, JMP = 0x0C, LDA = 0x14, AND = 0x1C, STZ = 0x11,
ROT = 0x05, JCN = 0x0D, STA = 0x15, ORA = 0x1D, SUB = 0x19,
DUP = 0x06, JSR = 0x0E, DEI = 0x16, EOR = 0x1E, POP = 0x02,
OVR = 0x07, STH = 0x0F, DEO = 0x17, SFT = 0x1F, GTH = 0x0A,
LDR = 0x12,
LIT = 0x80, JCI = 0x20, JMI = 0x40, JSI = 0x60, MUL = 0x1A,
NIP = 0x03,
LTH = 0x0B,
STR = 0x13,
DIV = 0x1B,
SWP = 0x04,
JMP = 0x0C,
LDA = 0x14,
AND = 0x1C,
ROT = 0x05,
JCN = 0x0D,
STA = 0x15,
ORA = 0x1D,
DUP = 0x06,
JSR = 0x0E,
DEI = 0x16,
EOR = 0x1E,
OVR = 0x07,
STH = 0x0F,
DEO = 0x17,
SFT = 0x1F,
LIT = 0x80,
JCI = 0x20,
JMI = 0x40,
JSI = 0x60,
}; };
unsigned char __lib_undar[] = { unsigned char __lib_undar[] = {
0x40, 0x73, 0x65, 0x78, 0x74, 0x0a, 0x20, 0x20, 0x23, 0x38, 0x30, 0x20, 0x40, 0x73, 0x65, 0x78, 0x74, 0x0a, 0x20, 0x20, 0x23, 0x38, 0x30, 0x20,
0x41, 0x4e, 0x44, 0x6b, 0x20, 0x45, 0x51, 0x55, 0x20, 0x23, 0x66, 0x66, 0x41, 0x4e, 0x44, 0x6b, 0x20, 0x45, 0x51, 0x55, 0x20, 0x23, 0x66, 0x66,
0x20, 0x4d, 0x55, 0x4c, 0x20, 0x53, 0x57, 0x50, 0x20, 0x4a, 0x4d, 0x50, 0x20, 0x4d, 0x55, 0x4c, 0x20, 0x53, 0x57, 0x50, 0x20, 0x4a, 0x4d, 0x50,
0x32, 0x72, 0x0a, 0x0a, 0x40, 0x61, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x5f, 0x32, 0x72, 0x0a, 0x0a, 0x40, 0x61, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x5f,
0x20, 0x28, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x2a, 0x20, 0x2d, 0x2d, 0x20, 0x20, 0x28, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x2a, 0x20, 0x2d, 0x2d, 0x20,
0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2a, 0x20, 0x29, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2a, 0x20, 0x29, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x4f, 0x56, 0x52, 0x32, 0x72, 0x20, 0x4c, 0x49, 0x54, 0x32, 0x20, 0x20, 0x4f, 0x56, 0x52, 0x32, 0x72, 0x20, 0x4c, 0x49, 0x54, 0x32,
0x72, 0x20, 0x30, 0x30, 0x30, 0x34, 0x20, 0x53, 0x55, 0x42, 0x32, 0x72, 0x72, 0x20, 0x30, 0x30, 0x30, 0x34, 0x20, 0x53, 0x55, 0x42, 0x32, 0x72,
0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x49, 0x4e, 0x43, 0x32, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x49, 0x4e, 0x43, 0x32,
0x20, 0x49, 0x4e, 0x43, 0x32, 0x20, 0x53, 0x54, 0x41, 0x32, 0x0a, 0x20, 0x20, 0x49, 0x4e, 0x43, 0x32, 0x20, 0x53, 0x54, 0x41, 0x32, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x3b, 0x6d, 0x65, 0x6d, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x20, 0x20, 0x20, 0x3b, 0x6d, 0x65, 0x6d, 0x5f, 0x6c, 0x65, 0x6e, 0x67,
0x74, 0x68, 0x5f, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x53, 0x54, 0x48, 0x74, 0x68, 0x5f, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x53, 0x54, 0x48,
0x32, 0x6b, 0x72, 0x20, 0x53, 0x54, 0x41, 0x32, 0x0a, 0x20, 0x20, 0x20, 0x32, 0x6b, 0x72, 0x20, 0x53, 0x54, 0x41, 0x32, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x3b, 0x6d, 0x65, 0x6d, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x3b, 0x6d, 0x65, 0x6d, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68,
0x5f, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x6b, 0x20, 0x53, 0x54, 0x48, 0x32, 0x5f, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x6b, 0x20, 0x53, 0x54, 0x48, 0x32,
0x6b, 0x72, 0x20, 0x49, 0x4e, 0x43, 0x32, 0x20, 0x49, 0x4e, 0x43, 0x32, 0x6b, 0x72, 0x20, 0x49, 0x4e, 0x43, 0x32, 0x20, 0x49, 0x4e, 0x43, 0x32,
0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x41, 0x44, 0x44, 0x32, 0x20, 0x53, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x41, 0x44, 0x44, 0x32, 0x20, 0x53,
0x57, 0x50, 0x32, 0x20, 0x53, 0x54, 0x41, 0x32, 0x0a, 0x20, 0x20, 0x20, 0x57, 0x50, 0x32, 0x20, 0x53, 0x54, 0x41, 0x32, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x3b, 0x6d, 0x65, 0x6d, 0x5f, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x20, 0x3b, 0x6d, 0x65, 0x6d, 0x5f, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b,
0x72, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x41, 0x44, 0x44, 0x32, 0x20, 0x72, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x41, 0x44, 0x44, 0x32, 0x20,
0x21, 0x26, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x21, 0x26, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x23, 0x30, 0x30, 0x30, 0x30, 0x0a, 0x0a, 0x20, 0x20, 0x26, 0x72, 0x20, 0x23, 0x30, 0x30, 0x30, 0x30, 0x0a, 0x0a, 0x20, 0x20, 0x26, 0x72,
0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x4f, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x4f,
0x50, 0x32, 0x72, 0x20, 0x4a, 0x4d, 0x50, 0x32, 0x72, 0x0a, 0x0a, 0x40, 0x50, 0x32, 0x72, 0x20, 0x4a, 0x4d, 0x50, 0x32, 0x72, 0x0a, 0x0a, 0x40,
0x61, 0x6d, 0x63, 0x70, 0x79, 0x5f, 0x20, 0x28, 0x20, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x63, 0x70, 0x79, 0x5f, 0x20, 0x28, 0x20, 0x6c, 0x65, 0x6e,
0x67, 0x74, 0x68, 0x2a, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x2a, 0x20, 0x2d, 0x67, 0x74, 0x68, 0x2a, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x2a, 0x20, 0x2d,
0x2d, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2a, 0x20, 0x29, 0x0a, 0x2d, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2a, 0x20, 0x29, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x4f, 0x56, 0x52, 0x32, 0x72, 0x20, 0x4c, 0x49, 0x20, 0x20, 0x20, 0x20, 0x4f, 0x56, 0x52, 0x32, 0x72, 0x20, 0x4c, 0x49,
0x54, 0x32, 0x72, 0x20, 0x30, 0x30, 0x30, 0x38, 0x20, 0x53, 0x55, 0x42, 0x54, 0x32, 0x72, 0x20, 0x30, 0x30, 0x30, 0x38, 0x20, 0x53, 0x55, 0x42,
0x32, 0x72, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x23, 0x30, 0x32, 0x72, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x23, 0x30,
0x30, 0x30, 0x36, 0x20, 0x41, 0x44, 0x44, 0x32, 0x20, 0x53, 0x54, 0x41, 0x30, 0x30, 0x36, 0x20, 0x41, 0x44, 0x44, 0x32, 0x20, 0x53, 0x54, 0x41,
0x32, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x32, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72,
0x20, 0x23, 0x30, 0x30, 0x30, 0x34, 0x20, 0x41, 0x44, 0x44, 0x32, 0x20, 0x20, 0x23, 0x30, 0x30, 0x30, 0x34, 0x20, 0x41, 0x44, 0x44, 0x32, 0x20,
0x53, 0x54, 0x41, 0x32, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x48, 0x53, 0x54, 0x41, 0x32, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x48,
0x32, 0x6b, 0x72, 0x20, 0x23, 0x30, 0x30, 0x30, 0x34, 0x20, 0x41, 0x44, 0x32, 0x6b, 0x72, 0x20, 0x23, 0x30, 0x30, 0x30, 0x34, 0x20, 0x41, 0x44,
0x44, 0x32, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x61, 0x61, 0x6c, 0x6c, 0x44, 0x32, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x61, 0x61, 0x6c, 0x6c,
0x6f, 0x63, 0x5f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6f, 0x63, 0x5f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x48, 0x32,
0x6b, 0x72, 0x20, 0x49, 0x4e, 0x43, 0x32, 0x20, 0x49, 0x4e, 0x43, 0x32, 0x6b, 0x72, 0x20, 0x49, 0x4e, 0x43, 0x32, 0x20, 0x49, 0x4e, 0x43, 0x32,
0x20, 0x53, 0x54, 0x41, 0x32, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x23, 0x30, 0x20, 0x53, 0x54, 0x41, 0x32, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x23, 0x30,
0x30, 0x30, 0x30, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x53, 0x30, 0x30, 0x30, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x53,
0x54, 0x41, 0x32, 0x0a, 0x0a, 0x20, 0x20, 0x26, 0x62, 0x65, 0x67, 0x69, 0x54, 0x41, 0x32, 0x0a, 0x0a, 0x20, 0x20, 0x26, 0x62, 0x65, 0x67, 0x69,
0x6e, 0x2e, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6e, 0x2e, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x48, 0x32,
0x6b, 0x72, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x53, 0x54, 0x48, 0x32,
0x6b, 0x72, 0x20, 0x23, 0x30, 0x30, 0x30, 0x34, 0x20, 0x41, 0x44, 0x44, 0x6b, 0x72, 0x20, 0x23, 0x30, 0x30, 0x30, 0x34, 0x20, 0x41, 0x44, 0x44,
0x32, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x4c, 0x54, 0x48, 0x32, 0x20, 0x32, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x4c, 0x54, 0x48, 0x32, 0x20,
0x23, 0x30, 0x30, 0x20, 0x45, 0x51, 0x55, 0x20, 0x3f, 0x26, 0x62, 0x72, 0x23, 0x30, 0x30, 0x20, 0x45, 0x51, 0x55, 0x20, 0x3f, 0x26, 0x62, 0x72,
0x65, 0x61, 0x6b, 0x2e, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x65, 0x61, 0x6b, 0x2e, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54,
0x48, 0x32, 0x6b, 0x72, 0x20, 0x23, 0x30, 0x30, 0x30, 0x36, 0x20, 0x41, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x23, 0x30, 0x30, 0x30, 0x36, 0x20, 0x41,
0x44, 0x44, 0x32, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x53, 0x54, 0x48, 0x44, 0x44, 0x32, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x53, 0x54, 0x48,
0x32, 0x6b, 0x72, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x41, 0x44, 0x44, 0x32, 0x6b, 0x72, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x41, 0x44, 0x44,
0x32, 0x20, 0x4c, 0x44, 0x41, 0x20, 0x73, 0x65, 0x78, 0x74, 0x0a, 0x20, 0x32, 0x20, 0x4c, 0x44, 0x41, 0x20, 0x73, 0x65, 0x78, 0x74, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x49, 0x4e, 0x20, 0x20, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x49, 0x4e,
0x43, 0x32, 0x20, 0x49, 0x4e, 0x43, 0x32, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x43, 0x32, 0x20, 0x49, 0x4e, 0x43, 0x32, 0x20, 0x4c, 0x44, 0x41, 0x32,
0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x4c, 0x44, 0x41, 0x32,
0x20, 0x41, 0x44, 0x44, 0x32, 0x20, 0x53, 0x54, 0x41, 0x0a, 0x20, 0x20, 0x20, 0x41, 0x44, 0x44, 0x32, 0x20, 0x53, 0x54, 0x41, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x50, 0x4f, 0x50, 0x0a, 0x0a, 0x20, 0x20, 0x26, 0x63, 0x6f, 0x20, 0x20, 0x50, 0x4f, 0x50, 0x0a, 0x0a, 0x20, 0x20, 0x26, 0x63, 0x6f,
0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x2e, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x2e, 0x31, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x4c, 0x44, 0x41, 0x32,
0x6b, 0x20, 0x49, 0x4e, 0x43, 0x32, 0x6b, 0x20, 0x52, 0x4f, 0x54, 0x32, 0x6b, 0x20, 0x49, 0x4e, 0x43, 0x32, 0x6b, 0x20, 0x52, 0x4f, 0x54, 0x32,
0x20, 0x53, 0x54, 0x41, 0x32, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x4f, 0x20, 0x53, 0x54, 0x41, 0x32, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x4f,
0x50, 0x32, 0x20, 0x21, 0x26, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x2e, 0x31, 0x50, 0x32, 0x20, 0x21, 0x26, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x2e, 0x31,
0x0a, 0x0a, 0x20, 0x20, 0x26, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x2e, 0x31, 0x0a, 0x0a, 0x20, 0x20, 0x26, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x2e, 0x31,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20,
0x49, 0x4e, 0x43, 0x32, 0x20, 0x49, 0x4e, 0x43, 0x32, 0x20, 0x4c, 0x44, 0x49, 0x4e, 0x43, 0x32, 0x20, 0x49, 0x4e, 0x43, 0x32, 0x20, 0x4c, 0x44,
0x41, 0x32, 0x20, 0x21, 0x26, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x41, 0x32, 0x20, 0x21, 0x26, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x23, 0x30, 0x30, 0x30, 0x30, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23, 0x30, 0x30, 0x30, 0x30, 0x0a, 0x0a, 0x20,
0x20, 0x26, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x26, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x50, 0x4f, 0x50, 0x32, 0x72, 0x20, 0x4a, 0x4d, 0x50, 0x32, 0x72, 0x20, 0x50, 0x4f, 0x50, 0x32, 0x72, 0x20, 0x4a, 0x4d, 0x50, 0x32, 0x72,
0x0a, 0x0a, 0x40, 0x6e, 0x61, 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x73, 0x74, 0x0a, 0x0a, 0x40, 0x6e, 0x61, 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x73, 0x74,
0x72, 0x5f, 0x20, 0x28, 0x20, 0x6e, 0x2a, 0x20, 0x2d, 0x2d, 0x20, 0x72, 0x72, 0x5f, 0x20, 0x28, 0x20, 0x6e, 0x2a, 0x20, 0x2d, 0x2d, 0x20, 0x72,
0x65, 0x73, 0x75, 0x6c, 0x74, 0x2a, 0x20, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2a, 0x20, 0x29, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x4f, 0x56, 0x52, 0x32, 0x72, 0x20, 0x4c, 0x49, 0x54, 0x32, 0x72, 0x20, 0x4f, 0x56, 0x52, 0x32, 0x72, 0x20, 0x4c, 0x49, 0x54, 0x32, 0x72,
0x20, 0x30, 0x30, 0x30, 0x61, 0x20, 0x53, 0x55, 0x42, 0x32, 0x72, 0x20, 0x20, 0x30, 0x30, 0x30, 0x61, 0x20, 0x53, 0x55, 0x42, 0x32, 0x72, 0x20,
0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x23, 0x30, 0x30, 0x30, 0x38, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x23, 0x30, 0x30, 0x30, 0x38,
0x20, 0x41, 0x44, 0x44, 0x32, 0x20, 0x53, 0x54, 0x41, 0x32, 0x0a, 0x20, 0x20, 0x41, 0x44, 0x44, 0x32, 0x20, 0x53, 0x54, 0x41, 0x32, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x23, 0x30, 0x30, 0x30, 0x35, 0x20, 0x53, 0x54, 0x48, 0x20, 0x20, 0x20, 0x23, 0x30, 0x30, 0x30, 0x35, 0x20, 0x53, 0x54, 0x48,
0x32, 0x6b, 0x72, 0x20, 0x53, 0x54, 0x41, 0x32, 0x0a, 0x0a, 0x20, 0x20, 0x32, 0x6b, 0x72, 0x20, 0x53, 0x54, 0x41, 0x32, 0x0a, 0x0a, 0x20, 0x20,
0x26, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x2e, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x26, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x2e, 0x31, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x23, 0x30, 0x30, 0x30, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x23, 0x30, 0x30, 0x30,
0x38, 0x20, 0x41, 0x44, 0x44, 0x32, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x38, 0x20, 0x41, 0x44, 0x44, 0x32, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20,
0x23, 0x30, 0x30, 0x30, 0x61, 0x20, 0x4f, 0x56, 0x52, 0x32, 0x20, 0x4f, 0x23, 0x30, 0x30, 0x30, 0x61, 0x20, 0x4f, 0x56, 0x52, 0x32, 0x20, 0x4f,
0x56, 0x52, 0x32, 0x20, 0x44, 0x49, 0x56, 0x32, 0x20, 0x4d, 0x55, 0x4c, 0x56, 0x52, 0x32, 0x20, 0x44, 0x49, 0x56, 0x32, 0x20, 0x4d, 0x55, 0x4c,
0x32, 0x20, 0x53, 0x55, 0x42, 0x32, 0x20, 0x23, 0x30, 0x30, 0x33, 0x30, 0x32, 0x20, 0x53, 0x55, 0x42, 0x32, 0x20, 0x23, 0x30, 0x30, 0x33, 0x30,
0x20, 0x41, 0x44, 0x44, 0x32, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x41, 0x44, 0x44, 0x32, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72,
0x20, 0x49, 0x4e, 0x43, 0x32, 0x20, 0x49, 0x4e, 0x43, 0x32, 0x20, 0x53, 0x20, 0x49, 0x4e, 0x43, 0x32, 0x20, 0x49, 0x4e, 0x43, 0x32, 0x20, 0x53,
0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x6b, 0x20, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x6b, 0x20,
0x23, 0x30, 0x30, 0x30, 0x31, 0x20, 0x53, 0x55, 0x42, 0x32, 0x20, 0x53, 0x23, 0x30, 0x30, 0x30, 0x31, 0x20, 0x53, 0x55, 0x42, 0x32, 0x20, 0x53,
0x57, 0x50, 0x32, 0x20, 0x53, 0x54, 0x41, 0x32, 0x6b, 0x0a, 0x20, 0x20, 0x57, 0x50, 0x32, 0x20, 0x53, 0x54, 0x41, 0x32, 0x6b, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x50, 0x4f, 0x50, 0x32, 0x20, 0x41, 0x44, 0x44, 0x32, 0x20, 0x20, 0x20, 0x50, 0x4f, 0x50, 0x32, 0x20, 0x41, 0x44, 0x44, 0x32, 0x20,
0x53, 0x54, 0x41, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x4f, 0x50, 0x20, 0x53, 0x54, 0x41, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x4f, 0x50, 0x20,
0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x23, 0x30, 0x30, 0x30, 0x38, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x23, 0x30, 0x30, 0x30, 0x38,
0x20, 0x41, 0x44, 0x44, 0x32, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x6b, 0x20, 0x20, 0x41, 0x44, 0x44, 0x32, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x6b, 0x20,
0x23, 0x30, 0x30, 0x30, 0x61, 0x20, 0x44, 0x49, 0x56, 0x32, 0x20, 0x53, 0x23, 0x30, 0x30, 0x30, 0x61, 0x20, 0x44, 0x49, 0x56, 0x32, 0x20, 0x53,
0x57, 0x50, 0x32, 0x20, 0x53, 0x54, 0x41, 0x32, 0x0a, 0x0a, 0x20, 0x20, 0x57, 0x50, 0x32, 0x20, 0x53, 0x54, 0x41, 0x32, 0x0a, 0x0a, 0x20, 0x20,
0x26, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x2e, 0x31, 0x0a, 0x26, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x2e, 0x31, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x23, 0x30, 0x30, 0x30, 0x30, 0x20, 0x53, 0x54, 0x20, 0x20, 0x20, 0x20, 0x23, 0x30, 0x30, 0x30, 0x30, 0x20, 0x53, 0x54,
0x48, 0x32, 0x6b, 0x72, 0x20, 0x23, 0x30, 0x30, 0x30, 0x38, 0x20, 0x41, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x23, 0x30, 0x30, 0x30, 0x38, 0x20, 0x41,
0x44, 0x44, 0x32, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x4c, 0x54, 0x48, 0x44, 0x44, 0x32, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x4c, 0x54, 0x48,
0x32, 0x20, 0x3f, 0x26, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x2e, 0x31, 0x0a, 0x32, 0x20, 0x3f, 0x26, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x2e, 0x31, 0x0a,
0x0a, 0x20, 0x20, 0x26, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x2e, 0x31, 0x0a, 0x0a, 0x20, 0x20, 0x26, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x2e, 0x31, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x23, 0x30, 0x30, 0x30, 0x35, 0x20, 0x53, 0x54, 0x20, 0x20, 0x20, 0x20, 0x23, 0x30, 0x30, 0x30, 0x35, 0x20, 0x53, 0x54,
0x48, 0x32, 0x6b, 0x72, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x53, 0x55, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x53, 0x55,
0x42, 0x32, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x49, 0x4e, 0x42, 0x32, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x49, 0x4e,
0x43, 0x32, 0x20, 0x49, 0x4e, 0x43, 0x32, 0x20, 0x53, 0x54, 0x48, 0x32, 0x43, 0x32, 0x20, 0x49, 0x4e, 0x43, 0x32, 0x20, 0x53, 0x54, 0x48, 0x32,
0x6b, 0x72, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x41, 0x44, 0x44, 0x32, 0x6b, 0x72, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x41, 0x44, 0x44, 0x32,
0x20, 0x61, 0x6d, 0x63, 0x70, 0x79, 0x5f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6d, 0x63, 0x70, 0x79, 0x5f, 0x0a, 0x20, 0x20, 0x20, 0x20,
0x21, 0x26, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x21, 0x26, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x23, 0x30, 0x30, 0x30, 0x30, 0x0a, 0x0a, 0x20, 0x20, 0x26, 0x72, 0x20, 0x23, 0x30, 0x30, 0x30, 0x30, 0x0a, 0x0a, 0x20, 0x20, 0x26, 0x72,
0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x4f, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x4f,
0x50, 0x32, 0x72, 0x20, 0x4a, 0x4d, 0x50, 0x32, 0x72, 0x0a, 0x0a, 0x40, 0x50, 0x32, 0x72, 0x20, 0x4a, 0x4d, 0x50, 0x32, 0x72, 0x0a, 0x0a, 0x40,
0x73, 0x74, 0x72, 0x2f, 0x3c, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3e, 0x20, 0x73, 0x74, 0x72, 0x2f, 0x3c, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3e, 0x20,
0x28, 0x20, 0x73, 0x74, 0x72, 0x2a, 0x20, 0x2d, 0x2d, 0x20, 0x29, 0x0a, 0x28, 0x20, 0x73, 0x74, 0x72, 0x2a, 0x20, 0x2d, 0x2d, 0x20, 0x29, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x4c, 0x44, 0x41, 0x6b, 0x20, 0x44, 0x55, 0x50, 0x20, 0x20, 0x20, 0x20, 0x4c, 0x44, 0x41, 0x6b, 0x20, 0x44, 0x55, 0x50,
0x20, 0x3f, 0x7b, 0x20, 0x50, 0x4f, 0x50, 0x20, 0x50, 0x4f, 0x50, 0x32, 0x20, 0x3f, 0x7b, 0x20, 0x50, 0x4f, 0x50, 0x20, 0x50, 0x4f, 0x50, 0x32,
0x20, 0x4a, 0x4d, 0x50, 0x32, 0x72, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4a, 0x4d, 0x50, 0x32, 0x72, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x23, 0x31, 0x38, 0x20, 0x44, 0x45, 0x4f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x23, 0x31, 0x38, 0x20, 0x44, 0x45, 0x4f, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x49, 0x4e, 0x43, 0x32, 0x20, 0x21, 0x2f, 0x3c, 0x70, 0x72, 0x69, 0x20, 0x49, 0x4e, 0x43, 0x32, 0x20, 0x21, 0x2f, 0x3c, 0x70, 0x72, 0x69,
0x6e, 0x74, 0x3e, 0x0a, 0x0a, 0x40, 0x6d, 0x65, 0x6d, 0x5f, 0x6c, 0x65, 0x6e, 0x74, 0x3e, 0x0a, 0x0a, 0x40, 0x6d, 0x65, 0x6d, 0x5f, 0x6c, 0x65,
0x6e, 0x67, 0x74, 0x68, 0x5f, 0x20, 0x23, 0x30, 0x30, 0x30, 0x30, 0x0a, 0x6e, 0x67, 0x74, 0x68, 0x5f, 0x20, 0x23, 0x30, 0x30, 0x30, 0x30, 0x0a,
0x40, 0x6d, 0x65, 0x6d, 0x5f 0x40, 0x6d, 0x65, 0x6d, 0x5f};
};
unsigned int __lib_undar_len = 1433; unsigned int __lib_undar_len = 1433;
void void
uxn_emit_error(const char *str, i32 length, i32 line) uxn_emit_error(const char *str, i32 length, i32 line)
{ {
printf("Error at line: %d > %.*s\n ", line, length, str); fprintf(stderr, "\n===\nError at line: %d '%.*s'\n===\n", line, length, str);
exit(1); exit(1);
} }
@ -161,13 +184,12 @@ uxn_mem(u32 a)
void void
uxn_prolog() uxn_prolog()
{ {
printf("|100\n"); printf("|100\n\tLIT2r 0000 main POP2r BRK\n\n");
} }
void void
uxn_epilogue() uxn_epilogue()
{ {
printf("BRK\n\n");
for(u32 i = 0; i < __lib_undar_len; i++) putchar(__lib_undar[i]); for(u32 i = 0; i < __lib_undar_len; i++) putchar(__lib_undar[i]);
} }
@ -270,122 +292,104 @@ u32
uxn_get_size(SymbolType t) uxn_get_size(SymbolType t)
{ {
switch(t) { switch(t) {
case SYMBOL_BOOL: return 1; case SYMBOL_BOOL:
case SYMBOL_BYTE: return 1; return 1;
case SYMBOL_INT: return 2; case SYMBOL_BYTE:
case SYMBOL_NAT: return 2; return 1;
case SYMBOL_REAL: return 2; case SYMBOL_INT:
case SYMBOL_STR: return 2; return 2;
case SYMBOL_U8: return 1; case SYMBOL_NAT:
case SYMBOL_I8: return 1; return 2;
case SYMBOL_I16: return 2; case SYMBOL_REAL:
case SYMBOL_U16: return 2; return 2;
case SYMBOL_I32: return 4; case SYMBOL_STR:
case SYMBOL_U32: return 4; return 2;
case SYMBOL_F32: return 4; case SYMBOL_U8:
default: break; return 1;
case SYMBOL_I8:
return 1;
case SYMBOL_I16:
return 2;
case SYMBOL_U16:
return 2;
case SYMBOL_I32:
return 4;
case SYMBOL_U32:
return 4;
case SYMBOL_F32:
return 4;
default:
break;
} }
return 0; return 0;
} }
void void
uxn_emit_primitive_type(SymbolType t, const char *str, i32 length, bool local) uxn_emit_type(Symbol *sym, bool local)
{ {
switch(t) { if(local)
case SYMBOL_BOOL: { if(sym->ref)
if(local) printf("\tSTH2kr #%04x ADD2 LDA2\n", sym->ref);
printf("!{ &%.*s $2 } ", length, str);
else else
printf("!{ @%.*s $2 } ", length, str); printf("\tSTH2kr LDA2\n");
break; else
} switch(sym->type) {
case SYMBOL_BYTE: { case SYMBOL_BOOL: {
if(local) printf("!{ @%.*s $2 } ", sym->name_length, sym->name);
printf("!{ &%.*s $1 } ", length, str); break;
else }
printf("!{ @%.*s $1 } ", length, str); case SYMBOL_BYTE: {
break; printf("!{ @%.*s $1 } ", sym->name_length, sym->name);
} break;
case SYMBOL_INT: { }
if(local) case SYMBOL_INT: {
printf("!{ &%.*s $2 } ", length, str); printf("!{ @%.*s $2 } ", sym->name_length, sym->name);
else break;
printf("!{ @%.*s $2 } ", length, str); }
break; case SYMBOL_NAT: {
} printf("!{ @%.*s $2 } ", sym->name_length, sym->name);
case SYMBOL_NAT: { break;
if(local) }
printf("!{ &%.*s $2 } ", length, str); case SYMBOL_REAL: {
else printf("!{ @%.*s $2 } ", sym->name_length, sym->name);
printf("!{ @%.*s $2 } ", length, str); break;
break; }
} case SYMBOL_STR: {
case SYMBOL_REAL: { printf("!{ @%.*s $2 } ", sym->name_length, sym->name);
if(local) break;
printf("!{ &%.*s $2 } ", length, str); }
else case SYMBOL_U8: {
printf("!{ @%.*s $2 } ", length, str); printf("!{ @%.*s $1 } ", sym->name_length, sym->name);
break; break;
} }
case SYMBOL_STR: { case SYMBOL_I8: {
if(local) printf("!{ @%.*s $1 } ", sym->name_length, sym->name);
printf("!{ &%.*s $2 } ", length, str); break;
else }
printf("!{ @%.*s $2 } ", length, str); case SYMBOL_I16: {
break; printf("!{ @%.*s $2 } ", sym->name_length, sym->name);
} break;
case SYMBOL_U8: { }
if(local) case SYMBOL_U16: {
printf("!{ &%.*s $1 } ", length, str); printf("!{ @%.*s $2 } ", sym->name_length, sym->name);
else break;
printf("!{ @%.*s $1 } ", length, str); }
break; case SYMBOL_I32: {
} printf("!{ @%.*s $4 } ", sym->name_length, sym->name);
case SYMBOL_I8: { break;
if(local) }
printf("!{ &%.*s $1 } ", length, str); case SYMBOL_U32: {
else printf("!{ @%.*s $4 } ", sym->name_length, sym->name);
printf("!{ @%.*s $1 } ", length, str); break;
break; }
} case SYMBOL_F32: {
case SYMBOL_I16: { printf("!{ @%.*s $4 } ", sym->name_length, sym->name);
if(local) break;
printf("!{ &%.*s $2 } ", length, str); }
else default:
printf("!{ @%.*s $2 } ", length, str); break;
break; }
}
case SYMBOL_U16: {
if(local)
printf("!{ &%.*s $2 } ", length, str);
else
printf("!{ @%.*s $2 } ", length, str);
break;
}
case SYMBOL_I32: {
if(local)
printf("!{ &%.*s $4 } ", length, str);
else
printf("!{ @%.*s $4 } ", length, str);
break;
}
case SYMBOL_U32: {
if(local)
printf("!{ &%.*s $4 } ", length, str);
else
printf("!{ @%.*s $4 } ", length, str);
break;
}
case SYMBOL_F32: {
if(local)
printf("!{ &%.*s $4 } ", length, str);
else
printf("!{ @%.*s $4 } ", length, str);
break;
}
default: break;
}
} }
void void
uxn_emit_int(const char *str, i32 length) uxn_emit_int(const char *str, i32 length)
@ -444,9 +448,51 @@ uxn_emit_array()
{ {
} }
void bool
uxn_emit_function() fn_loop_emit_args(void *data)
{ {
Symbol *sym = ((Symbol *)data);
if(sym->ref)
printf("\tSTH2kr #%04x ADD2 STA2\n", sym->ref);
else
printf("\tSTH2kr STA2\n");
return true;
}
bool
fn_loop_emit_args_comment(void *data)
{
Symbol *sym = ((Symbol *)data);
printf("%.*s ", sym->name_length, sym->name);
return true;
}
void
uxn_emit_function(Symbol *sym)
{
printf("@%.*s_ ( ", sym->name_length, sym->name);
List_map(sym->args, fn_loop_emit_args_comment);
printf(" -- ");
if(sym->secondary_type != SYMBOL_UNDEFINED &&
sym->secondary_type != SYMBOL_VOID)
printf(" res ");
printf(")\n");
printf("\tOVR2r LIT2r #%04x SUB2r\n", sym->size);
List_map(sym->args, fn_loop_emit_args);
printf("\n");
}
void
uxn_emit_arena_fn_return()
{
printf("\t&return\n\t\tPOP2r JMP2r\n\n");
}
void
uxn_emit_arena_fn_call(Symbol *sym)
{
printf("%.*s_ ", sym->name_length, sym->name);
} }
void void
@ -495,7 +541,10 @@ void
uxn_emit_variable(Symbol *sym, bool local) uxn_emit_variable(Symbol *sym, bool local)
{ {
if(local) if(local)
printf(",/%.*s LDR2 ", sym->name_length, sym->name); if(sym->ref)
printf("\tSTH2kr #%04x ADD2 LDA2 ", sym->ref);
else
printf("\tSTH2kr LDA2 ");
else else
printf(";%.*s LDA2 ", sym->name_length, sym->name); printf(";%.*s LDA2 ", sym->name_length, sym->name);
} }
@ -504,7 +553,10 @@ void
uxn_emit_set_variable(Symbol *sym, bool local) uxn_emit_set_variable(Symbol *sym, bool local)
{ {
if(local) if(local)
printf(",/%.*s STR2 ", sym->name_length, sym->name); if(sym->ref)
printf("\tSTH2kr #%04x ADD2 STA2 ", sym->ref);
else
printf("\tSTH2kr STA2 ");
else else
printf(";%.*s STA2 ", sym->name_length, sym->name); printf(";%.*s STA2 ", sym->name_length, sym->name);
} }
@ -619,11 +671,6 @@ uxn_emit_strbuf_to_str()
{ {
} }
void
uxn_emit_arena_fn_call()
{
}
void void
uxn_emit_arena_fn_return_plex() uxn_emit_arena_fn_return_plex()
{ {
@ -760,7 +807,7 @@ uxn_emitter()
uxn_emit_real, uxn_emit_real,
uxn_emit_byte, uxn_emit_byte,
uxn_emit_str, uxn_emit_str,
uxn_emit_primitive_type, uxn_emit_type,
uxn_emit_array, uxn_emit_array,
uxn_emit_function, uxn_emit_function,
uxn_emit_plex, uxn_emit_plex,
@ -798,6 +845,7 @@ uxn_emitter()
uxn_emit_strbuf_append, uxn_emit_strbuf_append,
uxn_emit_strbuf_to_str, uxn_emit_strbuf_to_str,
uxn_emit_arena_fn_call, uxn_emit_arena_fn_call,
uxn_emit_arena_fn_return,
uxn_emit_arena_fn_return_plex, uxn_emit_arena_fn_return_plex,
uxn_emit_arena_fn_return_array, uxn_emit_arena_fn_return_array,
uxn_emit_arena_fn_return_strbuf, uxn_emit_arena_fn_return_strbuf,

12
lexer.h
View File

@ -6,6 +6,12 @@
typedef enum { typedef enum {
TOKEN_ERROR, TOKEN_ERROR,
TOKEN_EOF, TOKEN_EOF,
TOKEN_LPAREN,
TOKEN_RPAREN,
TOKEN_LBRACE,
TOKEN_RBRACE,
TOKEN_LBRACKET,
TOKEN_RBRACKET,
TOKEN_IDENTIFIER, TOKEN_IDENTIFIER,
TOKEN_LITERAL_INT, TOKEN_LITERAL_INT,
TOKEN_LITERAL_NAT, TOKEN_LITERAL_NAT,
@ -77,12 +83,6 @@ typedef enum {
TOKEN_COLON, TOKEN_COLON,
TOKEN_CARET, TOKEN_CARET,
TOKEN_SEMICOLON, TOKEN_SEMICOLON,
TOKEN_LPAREN,
TOKEN_RPAREN,
TOKEN_LBRACE,
TOKEN_RBRACE,
TOKEN_LBRACKET,
TOKEN_RBRACKET,
TOKEN_ARROW_RIGHT, TOKEN_ARROW_RIGHT,
TOKEN_SLL, TOKEN_SLL,
TOKEN_SRL, TOKEN_SRL,

116
list.c
View File

@ -3,14 +3,14 @@
List * List *
List_init(Arena *arena) List_init(Arena *arena)
{ {
List *l = (List*)aalloc(arena, sizeof(List)); List *l = (List *)aalloc(arena, sizeof(List));
if (!l) return nil; if(!l) return nil;
l->head = nil; l->head = nil;
l->tail = nil; l->tail = nil;
l->count = 0; l->count = 0;
return l; return l;
} }
void * void *
@ -22,83 +22,83 @@ node_value(Node *n)
void * void *
List_push(Arena *arena, List *list, void *data, u32 data_size) List_push(Arena *arena, List *list, void *data, u32 data_size)
{ {
void *dest; void *dest;
void *ptr = aalloc(arena, sizeof(Node) + data_size); void *ptr = aalloc(arena, sizeof(Node) + data_size);
Node *node = (Node *)ptr; Node *node = (Node *)ptr;
if (!node) return nil; if(!node) return nil;
node->size = data_size; node->size = data_size;
node->next = nil; node->next = nil;
if (!list->head) { if(!list->head) {
list->head = list->tail = node; list->head = list->tail = node;
} else { } else {
list->tail->next = node; list->tail->next = node;
list->tail = node; list->tail = node;
} }
list->count++;
dest = node_value(node); list->count++;
if (data && data_size > 0) {
mcpy(dest, data, data_size);
}
return dest; dest = node_value(node);
if(data && data_size > 0) mcpy(dest, data, data_size);
return dest;
} }
void void
List_map(List *list, list_iter_fn func) List_map(List *list, list_iter_fn func)
{ {
Node *curr; Node *curr;
if (!list || !func) return; if(!list || !func) return;
curr = list->head; curr = list->head;
while (curr) { while(curr) {
if (!func(node_value(curr))) break; if(!func(node_value(curr))) break;
curr = curr->next; curr = curr->next;
} }
} }
void * void *
List_get(List *list, u32 index) List_get(List *list, u32 index)
{ {
u32 i; u32 i;
Node *curr; Node *curr;
if (!list || index >= list->count) return nil; if(!list || index >= list->count) return nil;
curr = list->head; curr = list->head;
for (i = 0; i < index; i++) { for(i = 0; i < index; i++) curr = curr->next;
curr = curr->next;
} return node_value(curr);
return node_value(curr);
} }
void void
List_set(List *list, u32 index, void *data, u32 size) List_set(List *list, u32 index, void *data, u32 size)
{ {
void *target = List_get(list, index); void *target = List_get(list, index);
if (!target) return; if(!target) return;
mcpy(target, data, size); mcpy(target, data, size);
} }
void * void *
List_find(List *list, compare_fn compare, void *target) List_find(List *list, compare_fn compare, void *target)
{ {
Node *curr; Node *curr;
void *data; void *data;
if (!list || !compare) return nil; if(!list || !compare) return nil;
curr = list->head; curr = list->head;
while (curr) { while(curr) {
data = node_value(curr); data = node_value(curr);
if (compare(data, target)) { if(compare(data, target)) return data;
return data; curr = curr->next;
} }
curr = curr->next; return nil;
} }
return nil;
} void *
List_last(List *list)
{
return node_value(list->tail);
}

3
list.h
View File

@ -26,5 +26,6 @@ void List_map(List *list, list_iter_fn func);
void *List_find(List *list, compare_fn compare, void *target); void *List_find(List *list, compare_fn compare, void *target);
void *List_get(List *list, u32 index); void *List_get(List *list, u32 index);
void List_set(List *list, u32 index, void *data, u32 size); void List_set(List *list, u32 index, void *data, u32 size);
void *List_last(List *list);
#endif #endif

View File

@ -1,10 +1,12 @@
/**
* Add two numbers together
*/
function add(int a, int b) int {
return a + b;
}
function main() { function main() {
print(add(1, 1) as str); print(add(1, 1) as str);
return;
}
/**
* Add two numbers together
*/
function add(nat a, nat b) nat {
return a + b;
} }

8
test/attack.ul Executable file
View File

@ -0,0 +1,8 @@
str msg = " damage inflicted!\n"
nat AT = 14;
nat accuracy = 150;
nat dmg = ((AT * accuracy) / 20) - 3;
print(dmg as str);
print(msg);

View File

@ -6,4 +6,4 @@ function fib(nat n) nat {
return fib(n - 2) + fib(n - 1); return fib(n - 2) + fib(n - 1);
} }
print(fib(23) as str); print(fib(23) as str);

113
test/str.ul Executable file → Normal file
View File

@ -1,8 +1,109 @@
str msg = " damage inflicted!\n" /**
nat AT = 14; * Constants
nat accuracy = 150; */
const str nl = "\n";
const str terminal_namespace = "/dev/term/0";
nat dmg = ((AT * accuracy) / 20) - 3; plex Terminal {
nat handle;
}
print(dmg as str); /**
print(msg); * Print with a newline
*/
function pln(str string) {
Terminal term = open(terminal_namespace, 0);
write(term, string, string.length);
write(term, nl, nl.length);
// implied return because it is a void function.
}
/**
* Concatinates 2 strings
*/
function concat(str src1, str src2) str {
str result = malloc(src1.length + src2.length);
// note result[0].ref is much different than result.ref[0] !
// result[0].ref means the pointer at char 0 (pointer to first char)
memcpy(result[0].ref, src1.ref);
memcpy(result[src1.length].ref, src2.ref);
return result;
}
/**
* finds index of string, -1 if not found
*/
function str_index_of(str haystack, byte needle) int {
int i = -1;
for (byte c in haystack) {
if (c == needle) {
break;
}
}
return i;
}
/**
* checks if 2 strings are equal
*/
function str_eq(str src1, str src2) bool {
if (src1.length != src2.length) return false;
do (int i=0; src1.length; i++) {
if (src1[i] != src2[i]) return false;
}
return true;
}
/**
* Slice string
*/
function str_slice(str src, int start, int stop) str {
int len = stop - start;
str result = malloc(len);
do (int i=start; i<stop; i++) {
result[i] = src[i];
}
return result;
}
/**
* int to string
*/
function itos(int src) str {
}
/**
* nat to string
*/
function ntos(nat src) str {
}
/**
* real to string
*/
function rtos(real src) str {
}
/**
* string to int
*/
function stoi(str src) int {
}
/**
* string to nat
*/
function ston(str src) nat {
}
/**
* string to real
*/
function stor(str src) real {
}

View File

@ -10,11 +10,15 @@ const byte WHITE = 255;
/** /**
* Devices * Devices
*/ */
plex Terminal { interface Device {
nat handle; nat handle;
} }
plex Screen { plex Terminal implements Device {
nat handle;
}
plex Screen implements Device {
nat handle; nat handle;
nat width; nat width;
nat height; nat height;
@ -25,7 +29,7 @@ plex Screen {
} }
} }
plex Mouse { plex Mouse implements Device {
nat handle; nat handle;
nat x; nat x;
nat y; nat y;
@ -45,7 +49,7 @@ function main() {
print(screen.width as str); print(screen.width as str);
print(screen.size as str); print(screen.size as str);
unsafe { unsafe {
print(screen.buffer.ptr as str); pln(screen.buffer.ptr as str);
} }
Mouse mouse = open(mouse_namespace, 0); Mouse mouse = open(mouse_namespace, 0);
@ -65,7 +69,7 @@ function main() {
/** /**
* Print with a newline * Print with a newline
*/ */
function print(str message) { function pln(str message) {
Terminal term = open(terminal_namespace, 0); Terminal term = open(terminal_namespace, 0);
write(term, message, message.length); write(term, message, message.length);
write(term, nl, nl.length); write(term, nl, nl.length);