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

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

View File

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

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 (*VoidArgEmit)();
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 (*VarEmit)(Symbol *sym, bool local);
typedef void (*I32ArgEmit)(i32 val);
@ -43,9 +42,9 @@ struct emitter_s {
StrArgEmit emit_real;
StrArgEmit emit_byte;
StrArgEmit emit_str;
TypeVariableEmit emit_type;
VarEmit emit_type;
VoidArgEmit emit_array;
VoidArgEmit emit_function;
SymbolEmit emit_function;
VoidArgEmit emit_plex;
VoidArgEmit emit_method;
VoidArgEmit emit_trait;
@ -80,7 +79,8 @@ struct emitter_s {
VoidArgEmit emit_strbuf_init;
VoidArgEmit emit_strbuf_append;
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_array;
VoidArgEmit emit_arena_fn_return_strbuf;

View File

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

View File

@ -7,148 +7,171 @@
#define UXN_OP_K (1 << 7)
enum uxn_opcode {
/* Stack I */ /* Logic */ /* Memory I */ /* Arithmetic*/
BRK = 0x00, EQU = 0x08, LDZ = 0x10, ADD = 0x18,
INC = 0x01, NEQ = 0x09, STZ = 0x11, SUB = 0x19,
POP = 0x02, GTH = 0x0A, LDR = 0x12, MUL = 0x1A,
NIP = 0x03, LTH = 0x0B, STR = 0x13, DIV = 0x1B,
/* Stack II */ /* Stash */ /* Memory II */ /* Bitwise */
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,
BRK = 0x00,
EQU = 0x08,
LDZ = 0x10,
ADD = 0x18,
INC = 0x01,
NEQ = 0x09,
STZ = 0x11,
SUB = 0x19,
POP = 0x02,
GTH = 0x0A,
LDR = 0x12,
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[] = {
0x40, 0x73, 0x65, 0x78, 0x74, 0x0a, 0x20, 0x20, 0x23, 0x38, 0x30, 0x20,
0x41, 0x4e, 0x44, 0x6b, 0x20, 0x45, 0x51, 0x55, 0x20, 0x23, 0x66, 0x66,
0x20, 0x4d, 0x55, 0x4c, 0x20, 0x53, 0x57, 0x50, 0x20, 0x4a, 0x4d, 0x50,
0x32, 0x72, 0x0a, 0x0a, 0x40, 0x61, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x5f,
0x20, 0x28, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x2a, 0x20, 0x2d, 0x2d, 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,
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, 0x49, 0x4e, 0x43, 0x32, 0x20, 0x53, 0x54, 0x41, 0x32, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x3b, 0x6d, 0x65, 0x6d, 0x5f, 0x6c, 0x65, 0x6e, 0x67,
0x74, 0x68, 0x5f, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x53, 0x54, 0x48,
0x32, 0x6b, 0x72, 0x20, 0x53, 0x54, 0x41, 0x32, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x3b, 0x6d, 0x65, 0x6d, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68,
0x5f, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x6b, 0x20, 0x53, 0x54, 0x48, 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,
0x57, 0x50, 0x32, 0x20, 0x53, 0x54, 0x41, 0x32, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x3b, 0x6d, 0x65, 0x6d, 0x5f, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b,
0x72, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x41, 0x44, 0x44, 0x32, 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,
0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x4f,
0x50, 0x32, 0x72, 0x20, 0x4a, 0x4d, 0x50, 0x32, 0x72, 0x0a, 0x0a, 0x40,
0x61, 0x6d, 0x63, 0x70, 0x79, 0x5f, 0x20, 0x28, 0x20, 0x6c, 0x65, 0x6e,
0x67, 0x74, 0x68, 0x2a, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x2a, 0x20, 0x2d,
0x2d, 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, 0x72, 0x20, 0x30, 0x30, 0x30, 0x38, 0x20, 0x53, 0x55, 0x42,
0x32, 0x72, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x23, 0x30,
0x30, 0x30, 0x36, 0x20, 0x41, 0x44, 0x44, 0x32, 0x20, 0x53, 0x54, 0x41,
0x32, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72,
0x20, 0x23, 0x30, 0x30, 0x30, 0x34, 0x20, 0x41, 0x44, 0x44, 0x32, 0x20,
0x53, 0x54, 0x41, 0x32, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x48,
0x32, 0x6b, 0x72, 0x20, 0x23, 0x30, 0x30, 0x30, 0x34, 0x20, 0x41, 0x44,
0x44, 0x32, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x61, 0x61, 0x6c, 0x6c,
0x6f, 0x63, 0x5f, 0x0a, 0x20, 0x20, 0x20, 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, 0x20, 0x20, 0x23, 0x30,
0x30, 0x30, 0x30, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x53,
0x54, 0x41, 0x32, 0x0a, 0x0a, 0x20, 0x20, 0x26, 0x62, 0x65, 0x67, 0x69,
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, 0x23, 0x30, 0x30, 0x30, 0x34, 0x20, 0x41, 0x44, 0x44,
0x32, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x4c, 0x54, 0x48, 0x32, 0x20,
0x23, 0x30, 0x30, 0x20, 0x45, 0x51, 0x55, 0x20, 0x3f, 0x26, 0x62, 0x72,
0x65, 0x61, 0x6b, 0x2e, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54,
0x48, 0x32, 0x6b, 0x72, 0x20, 0x23, 0x30, 0x30, 0x30, 0x36, 0x20, 0x41,
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, 0x20, 0x4c, 0x44, 0x41, 0x20, 0x73, 0x65, 0x78, 0x74, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x49, 0x4e,
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, 0x41, 0x44, 0x44, 0x32, 0x20, 0x53, 0x54, 0x41, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x50, 0x4f, 0x50, 0x0a, 0x0a, 0x20, 0x20, 0x26, 0x63, 0x6f,
0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x2e, 0x31, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x4c, 0x44, 0x41, 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,
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, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20,
0x49, 0x4e, 0x43, 0x32, 0x20, 0x49, 0x4e, 0x43, 0x32, 0x20, 0x4c, 0x44,
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, 0x26, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x50, 0x4f, 0x50, 0x32, 0x72, 0x20, 0x4a, 0x4d, 0x50, 0x32, 0x72,
0x0a, 0x0a, 0x40, 0x6e, 0x61, 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x73, 0x74,
0x72, 0x5f, 0x20, 0x28, 0x20, 0x6e, 0x2a, 0x20, 0x2d, 0x2d, 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, 0x72,
0x20, 0x30, 0x30, 0x30, 0x61, 0x20, 0x53, 0x55, 0x42, 0x32, 0x72, 0x20,
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, 0x20, 0x20, 0x23, 0x30, 0x30, 0x30, 0x35, 0x20, 0x53, 0x54, 0x48,
0x32, 0x6b, 0x72, 0x20, 0x53, 0x54, 0x41, 0x32, 0x0a, 0x0a, 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,
0x38, 0x20, 0x41, 0x44, 0x44, 0x32, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20,
0x23, 0x30, 0x30, 0x30, 0x61, 0x20, 0x4f, 0x56, 0x52, 0x32, 0x20, 0x4f,
0x56, 0x52, 0x32, 0x20, 0x44, 0x49, 0x56, 0x32, 0x20, 0x4d, 0x55, 0x4c,
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, 0x49, 0x4e, 0x43, 0x32, 0x20, 0x49, 0x4e, 0x43, 0x32, 0x20, 0x53,
0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x6b, 0x20,
0x23, 0x30, 0x30, 0x30, 0x31, 0x20, 0x53, 0x55, 0x42, 0x32, 0x20, 0x53,
0x57, 0x50, 0x32, 0x20, 0x53, 0x54, 0x41, 0x32, 0x6b, 0x0a, 0x20, 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, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x23, 0x30, 0x30, 0x30, 0x38,
0x20, 0x41, 0x44, 0x44, 0x32, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x6b, 0x20,
0x23, 0x30, 0x30, 0x30, 0x61, 0x20, 0x44, 0x49, 0x56, 0x32, 0x20, 0x53,
0x57, 0x50, 0x32, 0x20, 0x53, 0x54, 0x41, 0x32, 0x0a, 0x0a, 0x20, 0x20,
0x26, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x2e, 0x31, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x23, 0x30, 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, 0x4c, 0x54, 0x48,
0x32, 0x20, 0x3f, 0x26, 0x62, 0x65, 0x67, 0x69, 0x6e, 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,
0x48, 0x32, 0x6b, 0x72, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x53, 0x55,
0x42, 0x32, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x49, 0x4e,
0x43, 0x32, 0x20, 0x49, 0x4e, 0x43, 0x32, 0x20, 0x53, 0x54, 0x48, 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,
0x21, 0x26, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 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, 0x50, 0x4f,
0x50, 0x32, 0x72, 0x20, 0x4a, 0x4d, 0x50, 0x32, 0x72, 0x0a, 0x0a, 0x40,
0x73, 0x74, 0x72, 0x2f, 0x3c, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3e, 0x20,
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, 0x3f, 0x7b, 0x20, 0x50, 0x4f, 0x50, 0x20, 0x50, 0x4f, 0x50, 0x32,
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, 0x49, 0x4e, 0x43, 0x32, 0x20, 0x21, 0x2f, 0x3c, 0x70, 0x72, 0x69,
0x6e, 0x74, 0x3e, 0x0a, 0x0a, 0x40, 0x6d, 0x65, 0x6d, 0x5f, 0x6c, 0x65,
0x6e, 0x67, 0x74, 0x68, 0x5f, 0x20, 0x23, 0x30, 0x30, 0x30, 0x30, 0x0a,
0x40, 0x6d, 0x65, 0x6d, 0x5f
};
0x40, 0x73, 0x65, 0x78, 0x74, 0x0a, 0x20, 0x20, 0x23, 0x38, 0x30, 0x20,
0x41, 0x4e, 0x44, 0x6b, 0x20, 0x45, 0x51, 0x55, 0x20, 0x23, 0x66, 0x66,
0x20, 0x4d, 0x55, 0x4c, 0x20, 0x53, 0x57, 0x50, 0x20, 0x4a, 0x4d, 0x50,
0x32, 0x72, 0x0a, 0x0a, 0x40, 0x61, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x5f,
0x20, 0x28, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x2a, 0x20, 0x2d, 0x2d, 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,
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, 0x49, 0x4e, 0x43, 0x32, 0x20, 0x53, 0x54, 0x41, 0x32, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x3b, 0x6d, 0x65, 0x6d, 0x5f, 0x6c, 0x65, 0x6e, 0x67,
0x74, 0x68, 0x5f, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x53, 0x54, 0x48,
0x32, 0x6b, 0x72, 0x20, 0x53, 0x54, 0x41, 0x32, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x3b, 0x6d, 0x65, 0x6d, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68,
0x5f, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x6b, 0x20, 0x53, 0x54, 0x48, 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,
0x57, 0x50, 0x32, 0x20, 0x53, 0x54, 0x41, 0x32, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x3b, 0x6d, 0x65, 0x6d, 0x5f, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b,
0x72, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x41, 0x44, 0x44, 0x32, 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,
0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x4f,
0x50, 0x32, 0x72, 0x20, 0x4a, 0x4d, 0x50, 0x32, 0x72, 0x0a, 0x0a, 0x40,
0x61, 0x6d, 0x63, 0x70, 0x79, 0x5f, 0x20, 0x28, 0x20, 0x6c, 0x65, 0x6e,
0x67, 0x74, 0x68, 0x2a, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x2a, 0x20, 0x2d,
0x2d, 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, 0x72, 0x20, 0x30, 0x30, 0x30, 0x38, 0x20, 0x53, 0x55, 0x42,
0x32, 0x72, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x23, 0x30,
0x30, 0x30, 0x36, 0x20, 0x41, 0x44, 0x44, 0x32, 0x20, 0x53, 0x54, 0x41,
0x32, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72,
0x20, 0x23, 0x30, 0x30, 0x30, 0x34, 0x20, 0x41, 0x44, 0x44, 0x32, 0x20,
0x53, 0x54, 0x41, 0x32, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x48,
0x32, 0x6b, 0x72, 0x20, 0x23, 0x30, 0x30, 0x30, 0x34, 0x20, 0x41, 0x44,
0x44, 0x32, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x61, 0x61, 0x6c, 0x6c,
0x6f, 0x63, 0x5f, 0x0a, 0x20, 0x20, 0x20, 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, 0x20, 0x20, 0x23, 0x30,
0x30, 0x30, 0x30, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x53,
0x54, 0x41, 0x32, 0x0a, 0x0a, 0x20, 0x20, 0x26, 0x62, 0x65, 0x67, 0x69,
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, 0x23, 0x30, 0x30, 0x30, 0x34, 0x20, 0x41, 0x44, 0x44,
0x32, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x4c, 0x54, 0x48, 0x32, 0x20,
0x23, 0x30, 0x30, 0x20, 0x45, 0x51, 0x55, 0x20, 0x3f, 0x26, 0x62, 0x72,
0x65, 0x61, 0x6b, 0x2e, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54,
0x48, 0x32, 0x6b, 0x72, 0x20, 0x23, 0x30, 0x30, 0x30, 0x36, 0x20, 0x41,
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, 0x20, 0x4c, 0x44, 0x41, 0x20, 0x73, 0x65, 0x78, 0x74, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x49, 0x4e,
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, 0x41, 0x44, 0x44, 0x32, 0x20, 0x53, 0x54, 0x41, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x50, 0x4f, 0x50, 0x0a, 0x0a, 0x20, 0x20, 0x26, 0x63, 0x6f,
0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x2e, 0x31, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x4c, 0x44, 0x41, 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,
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, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20,
0x49, 0x4e, 0x43, 0x32, 0x20, 0x49, 0x4e, 0x43, 0x32, 0x20, 0x4c, 0x44,
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, 0x26, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x50, 0x4f, 0x50, 0x32, 0x72, 0x20, 0x4a, 0x4d, 0x50, 0x32, 0x72,
0x0a, 0x0a, 0x40, 0x6e, 0x61, 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x73, 0x74,
0x72, 0x5f, 0x20, 0x28, 0x20, 0x6e, 0x2a, 0x20, 0x2d, 0x2d, 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, 0x72,
0x20, 0x30, 0x30, 0x30, 0x61, 0x20, 0x53, 0x55, 0x42, 0x32, 0x72, 0x20,
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, 0x20, 0x20, 0x23, 0x30, 0x30, 0x30, 0x35, 0x20, 0x53, 0x54, 0x48,
0x32, 0x6b, 0x72, 0x20, 0x53, 0x54, 0x41, 0x32, 0x0a, 0x0a, 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,
0x38, 0x20, 0x41, 0x44, 0x44, 0x32, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20,
0x23, 0x30, 0x30, 0x30, 0x61, 0x20, 0x4f, 0x56, 0x52, 0x32, 0x20, 0x4f,
0x56, 0x52, 0x32, 0x20, 0x44, 0x49, 0x56, 0x32, 0x20, 0x4d, 0x55, 0x4c,
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, 0x49, 0x4e, 0x43, 0x32, 0x20, 0x49, 0x4e, 0x43, 0x32, 0x20, 0x53,
0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x6b, 0x20,
0x23, 0x30, 0x30, 0x30, 0x31, 0x20, 0x53, 0x55, 0x42, 0x32, 0x20, 0x53,
0x57, 0x50, 0x32, 0x20, 0x53, 0x54, 0x41, 0x32, 0x6b, 0x0a, 0x20, 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, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x23, 0x30, 0x30, 0x30, 0x38,
0x20, 0x41, 0x44, 0x44, 0x32, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x6b, 0x20,
0x23, 0x30, 0x30, 0x30, 0x61, 0x20, 0x44, 0x49, 0x56, 0x32, 0x20, 0x53,
0x57, 0x50, 0x32, 0x20, 0x53, 0x54, 0x41, 0x32, 0x0a, 0x0a, 0x20, 0x20,
0x26, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x2e, 0x31, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x23, 0x30, 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, 0x4c, 0x54, 0x48,
0x32, 0x20, 0x3f, 0x26, 0x62, 0x65, 0x67, 0x69, 0x6e, 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,
0x48, 0x32, 0x6b, 0x72, 0x20, 0x4c, 0x44, 0x41, 0x32, 0x20, 0x53, 0x55,
0x42, 0x32, 0x20, 0x53, 0x54, 0x48, 0x32, 0x6b, 0x72, 0x20, 0x49, 0x4e,
0x43, 0x32, 0x20, 0x49, 0x4e, 0x43, 0x32, 0x20, 0x53, 0x54, 0x48, 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,
0x21, 0x26, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 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, 0x50, 0x4f,
0x50, 0x32, 0x72, 0x20, 0x4a, 0x4d, 0x50, 0x32, 0x72, 0x0a, 0x0a, 0x40,
0x73, 0x74, 0x72, 0x2f, 0x3c, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3e, 0x20,
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, 0x3f, 0x7b, 0x20, 0x50, 0x4f, 0x50, 0x20, 0x50, 0x4f, 0x50, 0x32,
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, 0x49, 0x4e, 0x43, 0x32, 0x20, 0x21, 0x2f, 0x3c, 0x70, 0x72, 0x69,
0x6e, 0x74, 0x3e, 0x0a, 0x0a, 0x40, 0x6d, 0x65, 0x6d, 0x5f, 0x6c, 0x65,
0x6e, 0x67, 0x74, 0x68, 0x5f, 0x20, 0x23, 0x30, 0x30, 0x30, 0x30, 0x0a,
0x40, 0x6d, 0x65, 0x6d, 0x5f};
unsigned int __lib_undar_len = 1433;
void
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);
}
@ -161,13 +184,12 @@ uxn_mem(u32 a)
void
uxn_prolog()
{
printf("|100\n");
printf("|100\n\tLIT2r 0000 main POP2r BRK\n\n");
}
void
uxn_epilogue()
{
printf("BRK\n\n");
for(u32 i = 0; i < __lib_undar_len; i++) putchar(__lib_undar[i]);
}
@ -270,122 +292,104 @@ u32
uxn_get_size(SymbolType t)
{
switch(t) {
case SYMBOL_BOOL: return 1;
case SYMBOL_BYTE: return 1;
case SYMBOL_INT: return 2;
case SYMBOL_NAT: return 2;
case SYMBOL_REAL: return 2;
case SYMBOL_STR: return 2;
case SYMBOL_U8: 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;
case SYMBOL_BOOL:
return 1;
case SYMBOL_BYTE:
return 1;
case SYMBOL_INT:
return 2;
case SYMBOL_NAT:
return 2;
case SYMBOL_REAL:
return 2;
case SYMBOL_STR:
return 2;
case SYMBOL_U8:
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;
}
void
uxn_emit_primitive_type(SymbolType t, const char *str, i32 length, bool local)
uxn_emit_type(Symbol *sym, bool local)
{
switch(t) {
case SYMBOL_BOOL: {
if(local)
printf("!{ &%.*s $2 } ", length, str);
if(local)
if(sym->ref)
printf("\tSTH2kr #%04x ADD2 LDA2\n", sym->ref);
else
printf("!{ @%.*s $2 } ", length, str);
break;
}
case SYMBOL_BYTE: {
if(local)
printf("!{ &%.*s $1 } ", length, str);
else
printf("!{ @%.*s $1 } ", length, str);
break;
}
case SYMBOL_INT: {
if(local)
printf("!{ &%.*s $2 } ", length, str);
else
printf("!{ @%.*s $2 } ", length, str);
break;
}
case SYMBOL_NAT: {
if(local)
printf("!{ &%.*s $2 } ", length, str);
else
printf("!{ @%.*s $2 } ", length, str);
break;
}
case SYMBOL_REAL: {
if(local)
printf("!{ &%.*s $2 } ", length, str);
else
printf("!{ @%.*s $2 } ", length, str);
break;
}
case SYMBOL_STR: {
if(local)
printf("!{ &%.*s $2 } ", length, str);
else
printf("!{ @%.*s $2 } ", length, str);
break;
}
case SYMBOL_U8: {
if(local)
printf("!{ &%.*s $1 } ", length, str);
else
printf("!{ @%.*s $1 } ", length, str);
break;
}
case SYMBOL_I8: {
if(local)
printf("!{ &%.*s $1 } ", length, str);
else
printf("!{ @%.*s $1 } ", length, str);
break;
}
case SYMBOL_I16: {
if(local)
printf("!{ &%.*s $2 } ", length, str);
else
printf("!{ @%.*s $2 } ", length, str);
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;
}
printf("\tSTH2kr LDA2\n");
else
switch(sym->type) {
case SYMBOL_BOOL: {
printf("!{ @%.*s $2 } ", sym->name_length, sym->name);
break;
}
case SYMBOL_BYTE: {
printf("!{ @%.*s $1 } ", sym->name_length, sym->name);
break;
}
case SYMBOL_INT: {
printf("!{ @%.*s $2 } ", sym->name_length, sym->name);
break;
}
case SYMBOL_NAT: {
printf("!{ @%.*s $2 } ", sym->name_length, sym->name);
break;
}
case SYMBOL_REAL: {
printf("!{ @%.*s $2 } ", sym->name_length, sym->name);
break;
}
case SYMBOL_STR: {
printf("!{ @%.*s $2 } ", sym->name_length, sym->name);
break;
}
case SYMBOL_U8: {
printf("!{ @%.*s $1 } ", sym->name_length, sym->name);
break;
}
case SYMBOL_I8: {
printf("!{ @%.*s $1 } ", sym->name_length, sym->name);
break;
}
case SYMBOL_I16: {
printf("!{ @%.*s $2 } ", sym->name_length, sym->name);
break;
}
case SYMBOL_U16: {
printf("!{ @%.*s $2 } ", sym->name_length, sym->name);
break;
}
case SYMBOL_I32: {
printf("!{ @%.*s $4 } ", sym->name_length, sym->name);
break;
}
case SYMBOL_U32: {
printf("!{ @%.*s $4 } ", sym->name_length, sym->name);
break;
}
case SYMBOL_F32: {
printf("!{ @%.*s $4 } ", sym->name_length, sym->name);
break;
}
default:
break;
}
}
void
uxn_emit_int(const char *str, i32 length)
@ -444,9 +448,51 @@ uxn_emit_array()
{
}
void
uxn_emit_function()
bool
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
@ -495,7 +541,10 @@ void
uxn_emit_variable(Symbol *sym, bool 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
printf(";%.*s LDA2 ", sym->name_length, sym->name);
}
@ -504,7 +553,10 @@ void
uxn_emit_set_variable(Symbol *sym, bool 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
printf(";%.*s STA2 ", sym->name_length, sym->name);
}
@ -619,11 +671,6 @@ uxn_emit_strbuf_to_str()
{
}
void
uxn_emit_arena_fn_call()
{
}
void
uxn_emit_arena_fn_return_plex()
{
@ -760,7 +807,7 @@ uxn_emitter()
uxn_emit_real,
uxn_emit_byte,
uxn_emit_str,
uxn_emit_primitive_type,
uxn_emit_type,
uxn_emit_array,
uxn_emit_function,
uxn_emit_plex,
@ -798,6 +845,7 @@ uxn_emitter()
uxn_emit_strbuf_append,
uxn_emit_strbuf_to_str,
uxn_emit_arena_fn_call,
uxn_emit_arena_fn_return,
uxn_emit_arena_fn_return_plex,
uxn_emit_arena_fn_return_array,
uxn_emit_arena_fn_return_strbuf,

12
lexer.h
View File

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

106
list.c
View File

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

1
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_get(List *list, u32 index);
void List_set(List *list, u32 index, void *data, u32 size);
void *List_last(List *list);
#endif

View File

@ -1,10 +1,12 @@
/**
* Add two numbers together
*/
function add(int a, int b) int {
return a + b;
}
function main() {
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);

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

@ -1,8 +1,109 @@
str msg = " damage inflicted!\n"
nat AT = 14;
nat accuracy = 150;
/**
* Constants
*/
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
*/
plex Terminal {
interface Device {
nat handle;
}
plex Screen {
plex Terminal implements Device {
nat handle;
}
plex Screen implements Device {
nat handle;
nat width;
nat height;
@ -25,7 +29,7 @@ plex Screen {
}
}
plex Mouse {
plex Mouse implements Device {
nat handle;
nat x;
nat y;
@ -45,7 +49,7 @@ function main() {
print(screen.width as str);
print(screen.size as str);
unsafe {
print(screen.buffer.ptr as str);
pln(screen.buffer.ptr as str);
}
Mouse mouse = open(mouse_namespace, 0);
@ -65,7 +69,7 @@ function main() {
/**
* Print with a newline
*/
function print(str message) {
function pln(str message) {
Terminal term = open(terminal_namespace, 0);
write(term, message, message.length);
write(term, nl, nl.length);