fix casting, add strings, add libundar for uxntal, add chibicc-uxn generator files,

This commit is contained in:
zongor 2026-04-23 00:01:11 -07:00
parent cf1f665e56
commit fbfb24d1e5
16 changed files with 803 additions and 158 deletions

View File

@ -27,16 +27,26 @@ cd undar-lang && ./build
* Memory Management
All memory used by the program exists in one big bump allocator.
When a function gets called, it creates a new arena in memory starting at the end of the previous frame. (or at the beginning of memory if no function has been called)
Variables allocated in the frame's arena are owned by default by the frame they are allocated in.
When variables get modified within the current frame they will get updated in that frame in their current location in the arena.
All complex types (Plex, arrays, strings) use fat pointers where they have a header of the length of that block and a "next" ptr that refers to the next allocated block for that value
If the size of the variable changes (like adding a value to the end of a array), a link is added to the internal list that points to a new block is allocated at the end of the arena of the size of that value, so they are variable sized blocks
When a variable is passed to a child function primitive types are pass by value, complex types (Arrays, Plexes, Strings) are pass by reference.
Variables passed as arguments to the child follow the same rules except when the size of a complex type changes, then a new value is added as a link from the parent to the child and the new value is allocated at the end of the childs arena (but the owner is still the parent).
When a function "returns" the frame is deallocated and all values allocated by it is freed; thus freeing memory deterministically.
Only a single variable may be returned from a function. When a variable is returned if it is primitive it is just passed back to the parent. If it is complex the value is coalesced into a single contiguous values and the link in the parent is updated to point at the "new" end of the arena. If the parents block is at the end the entire block is coalesced into a single contiguous block.
this allows for the low resource usage of a C but the convenience of a garbage collected language like C# or Go but without the GC pauses.
This allows for the low resource usage of a C but the convenience of a garbage collected language like C# or Go but without the GC pauses.
**Built in Types**
@ -71,4 +81,5 @@ this allows for the low resource usage of a C but the convenience of a garbage c
- [[https://lua.org][Lua]] - Friendly syntax, portable, and minimal VM.
- [[https://www.craftinginterpreters.com/the-lox-language.html][Lox]] - Lexer & Parser logic.
- [[https://wiki.xxiivv.com/site/uxn.html][Uxn]] - Major inspiration.
- [[https://github.com/lynn/chibicc][chibicc-uxn]] - Generated uxntal code for the undar-uxn libc.
- Retro Systems - N64, PS1, Mac Classic, Windows 95 - UI esthetics

View File

@ -95,7 +95,7 @@ advance()
return false;
}
}
static bool
bool
check(TokenType type)
{
return parser.current.type == type;
@ -112,7 +112,7 @@ consume(TokenType type)
return false;
}
static bool
bool
match(TokenType type)
{
if(!check(type)) return false;
@ -120,13 +120,13 @@ match(TokenType type)
return true;
}
static void expression();
static void statement();
static void declaration();
static ParseRule *get_rule(TokenType type);
static void parse_precedence(Precedence precedence);
void expression();
void statement();
void declaration();
ParseRule *get_rule(TokenType type);
void parse_precedence(Precedence precedence);
static void
void
binary()
{
TokenType operatorType = parser.previous.type;
@ -188,7 +188,7 @@ binary()
}
}
static void
void
literal()
{
switch(parser.previous.type) {
@ -206,13 +206,13 @@ literal()
}
}
static void
void
expression()
{
parse_precedence(PREC_ASSIGNMENT);
}
static void
void
variable()
{
Symbol *sym = scope_get_symbol(parser.current_scope, parser.previous.start,
@ -226,25 +226,25 @@ variable()
emitter.emit_variable(sym, parser.depth);
}
static void
void
cast_type()
{
TokenType cast_type = parser.current.type;
SymbolType st = parser.current_type;
TokenType cast_type = parser.current.type;
advance();
switch(cast_type) {
case TOKEN_TYPE_INT:{
switch(st) {
case SYMBOL_NAT:{
case SYMBOL_INT: {
switch(cast_type) {
case TOKEN_TYPE_NAT: {
emitter.emit_cast_int_to_nat();
break;
}
case SYMBOL_REAL:{
case TOKEN_TYPE_REAL: {
emitter.emit_cast_int_to_real();
break;
}
case SYMBOL_STR:{
case TOKEN_TYPE_STR: {
emitter.emit_cast_int_to_str();
break;
}
@ -254,17 +254,17 @@ cast_type()
break;
}
case TOKEN_TYPE_NAT:{
switch(st) {
case SYMBOL_INT:{
case SYMBOL_NAT: {
switch(cast_type) {
case TOKEN_TYPE_INT: {
emitter.emit_cast_nat_to_int();
break;
}
case SYMBOL_REAL:{
case TOKEN_TYPE_REAL: {
emitter.emit_cast_nat_to_real();
break;
}
case SYMBOL_STR:{
case TOKEN_TYPE_STR: {
emitter.emit_cast_nat_to_str();
break;
}
@ -273,17 +273,17 @@ cast_type()
}
break;
}
case TOKEN_TYPE_REAL:{
switch(st) {
case SYMBOL_NAT:{
case SYMBOL_REAL: {
switch(cast_type) {
case TOKEN_TYPE_NAT: {
emitter.emit_cast_real_to_nat();
break;
}
case SYMBOL_INT:{
case TOKEN_TYPE_INT: {
emitter.emit_cast_real_to_int();
break;
}
case SYMBOL_STR:{
case TOKEN_TYPE_STR: {
emitter.emit_cast_real_to_str();
break;
}
@ -292,17 +292,17 @@ cast_type()
}
break;
}
case TOKEN_TYPE_STR:{
switch(st) {
case SYMBOL_NAT:{
case SYMBOL_STR: {
switch(cast_type) {
case TOKEN_TYPE_NAT: {
emitter.emit_cast_str_to_nat();
break;
}
case SYMBOL_REAL:{
case TOKEN_TYPE_REAL: {
emitter.emit_cast_str_to_real();
break;
}
case SYMBOL_INT:{
case TOKEN_TYPE_INT: {
emitter.emit_cast_str_to_int();
break;
}
@ -314,15 +314,9 @@ cast_type()
default:
emitter.error("Not castable to this type", 26, parser.previous.line);
}
emitter.emit_open_paren();
expression();
emitter.emit_close_paren();
}
static void
void
variable_declaration()
{
@ -332,70 +326,80 @@ variable_declaration()
switch(tt) {
case TOKEN_TYPE_INT: {
size = emitter.emit_int_type(parser.current.start, parser.current.length, parser.depth);
size = emitter.emit_int_type(parser.current.start, parser.current.length,
parser.depth);
scope_add_symbol(parser.current.start, parser.current.length, SYMBOL_INT,
size);
parser.current_type = SYMBOL_INT;
break;
}
case TOKEN_TYPE_NAT: {
size = emitter.emit_nat_type(parser.current.start, parser.current.length, parser.depth);
size = emitter.emit_nat_type(parser.current.start, parser.current.length,
parser.depth);
scope_add_symbol(parser.current.start, parser.current.length, SYMBOL_NAT,
size);
parser.current_type = SYMBOL_NAT;
break;
}
case TOKEN_TYPE_REAL: {
size = emitter.emit_real_type(parser.current.start, parser.current.length, parser.depth);
size = emitter.emit_real_type(parser.current.start, parser.current.length,
parser.depth);
scope_add_symbol(parser.current.start, parser.current.length, SYMBOL_REAL,
size);
parser.current_type = SYMBOL_REAL;
break;
}
case TOKEN_TYPE_STR: {
size = emitter.emit_str_type(parser.current.start, parser.current.length, parser.depth);
size = emitter.emit_str_type(parser.current.start, parser.current.length,
parser.depth);
scope_add_symbol(parser.current.start, parser.current.length, SYMBOL_STR,
size);
parser.current_type = SYMBOL_STR;
break;
}
case TOKEN_TYPE_BOOL: {
size = emitter.emit_bool_type(parser.current.start, parser.current.length, parser.depth);
size = emitter.emit_bool_type(parser.current.start, parser.current.length,
parser.depth);
scope_add_symbol(parser.current.start, parser.current.length, SYMBOL_BOOL,
size);
parser.current_type = SYMBOL_BOOL;
break;
}
case TOKEN_TYPE_BYTE: {
size = emitter.emit_byte_type(parser.current.start, parser.current.length, parser.depth);
size = emitter.emit_byte_type(parser.current.start, parser.current.length,
parser.depth);
scope_add_symbol(parser.current.start, parser.current.length, SYMBOL_U8,
size);
parser.current_type = SYMBOL_BYTE;
break;
}
case TOKEN_TYPE_U8: {
size = emitter.emit_u8_type(parser.current.start, parser.current.length, parser.depth);
size = emitter.emit_u8_type(parser.current.start, parser.current.length,
parser.depth);
scope_add_symbol(parser.current.start, parser.current.length, SYMBOL_U8,
size);
parser.current_type = SYMBOL_U8;
break;
}
case TOKEN_TYPE_I8: {
size = emitter.emit_i8_type(parser.current.start, parser.current.length, parser.depth);
size = emitter.emit_i8_type(parser.current.start, parser.current.length,
parser.depth);
scope_add_symbol(parser.current.start, parser.current.length, SYMBOL_I8,
size);
parser.current_type = SYMBOL_I8;
break;
}
case TOKEN_TYPE_U16: {
size = emitter.emit_u16_type(parser.current.start, parser.current.length, parser.depth);
size = emitter.emit_u16_type(parser.current.start, parser.current.length,
parser.depth);
scope_add_symbol(parser.current.start, parser.current.length, SYMBOL_U16,
size);
parser.current_type = SYMBOL_U16;
break;
}
case TOKEN_TYPE_I16: {
size = emitter.emit_i16_type(parser.current.start, parser.current.length, parser.depth);
size = emitter.emit_i16_type(parser.current.start, parser.current.length,
parser.depth);
scope_add_symbol(parser.current.start, parser.current.length, SYMBOL_I16,
size);
parser.current_type = SYMBOL_I16;
@ -420,7 +424,7 @@ variable_declaration()
parser.current_type = SYMBOL_UNDEFINED;
}
static void
void
declaration()
{
/**
@ -428,14 +432,13 @@ declaration()
* lookup plex defs
* if not then
*/
if(is_type())
variable_declaration();
else
statement();
}
static void
void
print_statement()
{
expression();
@ -444,7 +447,7 @@ print_statement()
emitter.emit_print();
}
static void
void
putchar_statement()
{
expression();
@ -453,7 +456,7 @@ putchar_statement()
emitter.emit_putchar();
}
static void
void
getchar_statement()
{
expression();
@ -462,7 +465,7 @@ getchar_statement()
emitter.emit_putchar();
}
static void
void
if_statement()
{
consume(TOKEN_LPAREN);
@ -473,7 +476,7 @@ if_statement()
emitter.emit_patch_jump();
}
static void
void
block()
{
while(!check(TOKEN_RBRACE) && !check(TOKEN_EOF)) declaration();
@ -481,7 +484,7 @@ block()
consume(TOKEN_RBRACE);
}
static void
void
statement()
{
if(match(TOKEN_LBRACE)) {
@ -501,7 +504,7 @@ statement()
}
}
static void
void
grouping()
{
emitter.emit_open_paren();
@ -512,19 +515,19 @@ grouping()
consume(TOKEN_RPAREN);
}
static void
void
number()
{
emitter.emit_int(parser.previous.start, parser.previous.length);
}
static void
void
string()
{
emitter.emit_str(parser.previous.start, parser.previous.length);
}
static void
void
unary()
{
TokenType operatorType = parser.previous.type;
@ -625,9 +628,9 @@ ParseRule rules[] = {
/* TOKEN_ARROW_RIGHT */ {nil, nil, PREC_NONE},
/* TOKEN_SLL */ {nil, binary, PREC_NONE},
/* TOKEN_SRL */ {nil, binary, PREC_NONE},
/*TOKEN_KEYWORD_PRINT*/{nil, binary, PREC_NONE} };
/*TOKEN_KEYWORD_PRINT*/ {nil, binary, PREC_NONE}};
static void
void
parse_precedence(Precedence precedence)
{
ParseFn prefixRule;
@ -646,7 +649,7 @@ parse_precedence(Precedence precedence)
}
}
static ParseRule *
ParseRule *
get_rule(TokenType type)
{
return &rules[type];

View File

@ -14,3 +14,25 @@ so its a ptr to the next link followed by the size followed by an array of raw d
When modified it just adds the new values to the end of the list.
The list then can be "collapsed" back into a simple array.
** Core x86 ISA -> RISC-like
*** Math
RISC : ADD SUB AND OR XOR SHL SHR
x86 : ADD SUB AND OR XOR SHL SHR
- flags don't matter unless there is a conditional branch immediately after without a CMP/TEST in-between
*** MEM
RISC : LOAD [Base + Offset]
x86 : MOV Reg, [Base + Offset]
RISC : STORE [Base + Offset]
x86 : MOV [Base + Offset], Reg
*** Branch
RISC : Branch Eq
x86 : CMP JE
** Stack based system in machine code
x86 ARM32 RISC-V
TOS (Top of Stack) = EAX W0 R0
TOS - 1 = ECX W1 T1
TOS - 2 = EDX W2 T2
Memory Stack = Hardware Ptr (ESP, SP, SP)

View File

@ -2,25 +2,6 @@
#include <stdio.h>
#include <stdlib.h>
#define RER_OP_2 (1 << 5)
#define RER_OP_R (1 << 6)
#define RER_OP_K (1 << 7)
enum rer_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,
};
void
rer_emit_error(const char *str, i32 length, i32 line)
{
@ -43,7 +24,7 @@ rer_prolog()
void
rer_epilogue()
{
printf("\n\n@str/<print> ( str* -- )\n\
printf("BRK\n\n@str/<print> ( str* -- )\n\
LDAk DUP ?{ POP POP2 JMP2r }\n\
#18 DEO\n\
INC2 !/<print>\n");
@ -136,7 +117,7 @@ rer_emit_neg()
void
rer_emit_not()
{
printf("#FFFF EOR2 ");
printf("#ffff EOR2 ");
}
void
@ -148,11 +129,11 @@ i32
rer_emit_bool_type(const char *str, i32 length, bool local)
{
if(local)
printf("!{ &%.*s $1 } ", length, str);
printf("!{ &%.*s $2 } ", length, str);
else
printf("!{ @%.*s $1 } ", length, str);
printf("!{ @%.*s $2 } ", length, str);
return 1;
return 2;
}
i32
@ -577,6 +558,26 @@ rer_emit_patch_jump()
printf("} ");
}
i32
rer_emit_const_type(SymbolType type, const char *var, i32 var_length, const char *val, i32 val_legnth, bool local) {
if(local)
printf("&%.*s ", var_length, var);
else
printf("@%.*s ", var_length, var);
if (type == SYMBOL_STR) {
for (i32 i = 1; i < val_legnth - 1 ; i++) {
printf("#%02x ", val[i]);
}
} else {
i32 i = (i32)strtol(val, nil, 10);
printf("#%04x ", i);
}
return 2;
}
Emitter
rer_emitter()
{

View File

@ -21,6 +21,131 @@ enum uxn_opcode {
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
};
unsigned int __lib_undar_len = 1433;
void
uxn_emit_error(const char *str, i32 length, i32 line)
{
@ -43,10 +168,10 @@ uxn_prolog()
void
uxn_epilogue()
{
printf("BRK\n\n@str/<print> ( str* -- )\n\
LDAk DUP ?{ POP POP2 JMP2r }\n\
#18 DEO\n\
INC2 !/<print>\n");
printf("\n\n");
for (u32 i = 0; i < __lib_undar_len; i++) {
putchar(__lib_undar[i]);
}
}
void
@ -313,9 +438,7 @@ uxn_emit_str(const char *str, i32 length)
/* set a pointer to the string literal and then jump over it */
printf(";{ #0002 ADD2 } !{ ");
for (i32 i = 1; i < length - 1 ; i++) {
printf("#%02x ", str[i]);
}
for(i32 i = 1; i < length - 1; i++) printf("#%02x ", str[i]);
printf("#00 } ");
}
@ -418,6 +541,7 @@ uxn_emit_stat()
void
uxn_emit_end_statement()
{
printf("\n");
}
void
@ -433,46 +557,55 @@ uxn_emit_plex_def()
void
uxn_emit_cast_int_to_nat()
{
printf("int_to_nat_ ");
}
void
uxn_emit_cast_int_to_real()
{
printf("int_to_real_ ");
}
void
uxn_emit_cast_int_to_str()
{
printf("int_to_str_ ");
}
void
uxn_emit_cast_nat_to_int()
{
printf("nat_to_int_ ");
}
void
uxn_emit_cast_nat_to_real()
{
printf("nat_to_real_ ");
}
void
uxn_emit_cast_nat_to_str()
{
printf("nat_to_str_ ");
}
void
uxn_emit_cast_real_to_int()
{
printf("real_to_int_ ");
}
void
uxn_emit_cast_real_to_nat()
{
printf("real_to_nat_ ");
}
void
uxn_emit_cast_real_to_str()
{
printf("real_to_str_ ");
}
void
@ -564,7 +697,6 @@ uxn_emit_print()
printf("str/<print> ");
}
void
uxn_emit_jump()
{

View File

@ -0,0 +1,11 @@
// Raw interface to uxn's "devices"
void deo(char data, char device);
void deo2(int data, char device);
char dei(char device);
int dei2(char device);
int __builtin_va_arg();
typedef void *va_list;
#define va_start(ap, va)
#define va_end(ap)
#define va_arg(ap, ty) __builtin_va_arg()

View File

@ -0,0 +1,133 @@
#include "uxn.h"
void exit(char status);
typedef struct {
char operation; // 1 = copy
int length;
int src_page;
void* src_addr;
int dst_page;
void* dst_addr;
} Expansion;
// https://wiki.xxiivv.com/site/varvara.html
#define expansion(ptr) deo2(ptr, 0x02)
#define friend(func) deo2(func, 0x04)
#define set_palette(r, g, b) (deo2(r, 0x08), deo2(g, 0x0a), deo2(b, 0x0c))
#define debug() deo(0x01, 0x0e)
#define console_read() dei(0x12)
#define console_type() dei(0x17)
#define console_write(c) deo(c, 0x18) // stdout
#define console_error(c) deo(c, 0x19) // stderr
#define getchar console_read
#define putchar console_write
#define set_screen_size(width, height) (deo2(width, 0x22), deo2(height, 0x24))
#define screen_width() dei2(0x22)
#define screen_height() dei2(0x24)
#define set_screen_auto(a) deo(a, 0x26)
#define set_screen_x(x) deo2(x, 0x28)
#define set_screen_y(y) deo2(y, 0x2a)
#define set_screen_xy(x,y) (set_screen_x(x), set_screen_y(y))
#define screen_x() dei2(0x28)
#define screen_y() dei2(0x2a)
#define set_screen_addr(a) deo2(a, 0x2c)
#define draw_pixel(a) deo(a, 0x2e)
#define draw_sprite(a) deo(a, 0x2f)
#define audio_position(ch, a) dei2(0x32 + 0x10*ch)
#define audio_output(ch) dei(a, 0x34 + 0x10*ch)
#define set_audio_adsr(ch, adsr) deo2(adsr, 0x38 + 0x10*ch)
#define set_audio_length(ch, length) deo2(length, 0x3a + 0x10*ch)
#define set_audio_addr(ch, addr) deo2(addr, 0x3c + 0x10*ch)
#define set_audio_volume(ch, volume) deo(volume, 0x3e + 0x10*ch)
#define play_audio(ch, pitch) deo(pitch, 0x3f + 0x10*ch)
#define controller_button() dei(0x82)
#define controller_key() dei(0x83)
#define mouse_x() dei2(0x92)
#define mouse_y() dei2(0x94)
#define mouse_state() dei(0x96)
#define mouse_scrollx() dei2(0x9a)
#define mouse_scrolly() dei2(0x9c)
/// Read up to n bytes from file "name" into addr, then return bytes read.
#define file_read(name, n, addr) (deo2(name, 0xa8), deo2(n, 0xaa), deo2(addr, 0xac), dei2(0xa2))
#define _file_write(name, n, addr, append) (deo(append, 0xa7), deo2(name, 0xa8), deo2(n, 0xaa), deo2(addr, 0xae), dei2(0xa2))
/// Write n bytes from addr into file "name", then return bytes written.
#define file_write(name, n, addr) _file_write(name, n, addr, 0)
#define file_append(name, n, addr) _file_write(name, n, addr, 1)
#define file_delete(name) (deo2(name, 0xa8), deo(1, 0xa6))
#define datetime_year() dei2(0xc0)
#define datetime_month() dei(0xc2)
#define datetime_day() dei(0xc3)
#define datetime_hour() dei(0xc4)
#define datetime_minute() dei(0xc5)
#define datetime_second() dei(0xc6)
#define datetime_dotw() dei(0xc7)
#define datetime_doty() dei2(0xc8)
#define datetime_isdst() dei(0xca)
// Pixel values (| with color number)
// (Layer + operation + corner)
#define BgDot 0x00
#define BgFillBR 0x80
#define BgFillBL 0x90
#define BgFillTR 0xa0
#define BgFillTL 0xb0
#define FgDot 0x40
#define FgFillBR 0xc0
#define FgFillBL 0xd0
#define FgFillTR 0xe0
#define FgFillTL 0xf0
// Sprite values (| with blend number)
// (Layer + bit depth + flip axes)
#define Bg1 0x00
#define Bg1X 0x10
#define Bg1Y 0x20
#define Bg1XY 0x30
#define Fg1 0x40
#define Fg1X 0x50
#define Fg1Y 0x60
#define Fg1XY 0x70
#define Bg2 0x80
#define Bg2X 0x90
#define Bg2Y 0xa0
#define Bg2XY 0xb0
#define Fg2 0xc0
#define Fg2X 0xd0
#define Fg2Y 0xe0
#define Fg2XY 0xf0
// Auto values
#define Auto1 0x00
#define Auto1x 0x01
#define Auto1y 0x02
#define Auto1a 0x04
#define Auto1ax 0x05
#define Auto1ay 0x06
#define Auto2 0x10
#define Auto2x 0x11
#define Auto2y 0x12
#define Auto2a 0x14
#define Auto2ax 0x15
#define Auto2ay 0x16
// Button values
#define ButtonCtrl 0x01
#define ButtonA 0x01
#define ButtonAlt 0x02
#define ButtonB 0x02
#define ButtonShift 0x04
#define ButtonSelect 0x04
#define ButtonStart 0x08
#define ButtonHome 0x08
#define ButtonUp 0x10
#define ButtonDown 0x20
#define ButtonLeft 0x40
#define ButtonRight 0x80

84
emit/uxn/lib/undar.c Normal file
View File

@ -0,0 +1,84 @@
#include "chibicc-uxn/varvara.h"
char mem[100];
unsigned mem_length;
char *
aalloc(unsigned size)
{
unsigned pos = mem_length;
mem_length += size;
return (char *)&mem[pos];
}
char *
areturn(unsigned checkpoint, char *src, unsigned size)
{
char *dest = (char *)&mem[checkpoint];
if(src == dest) return src;
for (unsigned i = 0; i < size; i++) {
dest[i] = src[i];
}
mem_length = checkpoint + size;
/* zero out the end of the memory copy (for strings mostly) */
mem[mem_length] = 0;
return dest;
}
void
afree()
{
mem_length = 0;
}
char *
amcpy(char *from, unsigned length)
{
char *ptr = aalloc(length);
for (unsigned i = 0; i < length; i++) {
ptr[i] = from[i];
}
return ptr;
}
char* nat_to_str(unsigned n) {
char buffer[5];
unsigned i = 5;
do {
buffer[--i] = '0' + n % 10;
n /= 10;
} while(n > 0);
return amcpy(buffer + i, 5 - i);
}
char* int_to_str(int n) {
char buffer[6];
unsigned i = 6;
_Bool neg = n < 0;
if (neg) n = -n;
do {
buffer[--i] = '0' + n % 10;
n /= 10;
} while(n > 0);
if(neg) buffer[--i] = '-';
return amcpy(buffer + i, 6 - i);
}
unsigned
int_to_nat(int n)
{
return (unsigned)n;
}
int
nat_to_int(unsigned n)
{
return (int)n;
}

148
emit/uxn/lib/undar.tal Normal file
View File

@ -0,0 +1,148 @@
@sext
#80 ANDk EQU #ff MUL SWP JMP2r
@sdiv
OVR #80 AND ?&b_neg &b_pos OVR2 POP #80 AND ?&a_neg_b_pos DIV2 JMP2r &a_neg_b_pos SWP2 #0000 SWP2 SUB2 SWP2 DIV2 #0000 SWP2 SUB2 JMP2r
&b_neg #0000 SWP2 SUB2 OVR2 POP #80 AND ?&a_neg_b_neg DIV2 #0000 SWP2 SUB2 JMP2r
&a_neg_b_neg #0000 ROT2 SUB2 SWP2 DIV2 JMP2r
@aalloc_ ( size* -- result* )
OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2
;mem_length_ LDA2 STH2kr STA2
;mem_length_ LDA2k STH2kr INC2 INC2 LDA2 ADD2 SWP2 STA2
;mem_ STH2kr LDA2 ADD2 !&return
#0000
&return
POP2r JMP2r
@areturn_ ( size* src* checkpoint* -- result* )
OVR2r LIT2r 000a SUB2r STH2kr #0008 ADD2 STA2
STH2kr #0006 ADD2 STA2
STH2kr #0004 ADD2 STA2
;mem_ STH2kr #0008 ADD2 LDA2 ADD2 STH2kr INC2 INC2 STA2
STH2kr #0006 ADD2 LDA2 STH2kr INC2 INC2 LDA2 NEQ2 ?&end.1
STH2kr #0006 ADD2 LDA2 !&return
&end.1
#0000 STH2kr STA2
&begin.2
STH2kr LDA2 STH2kr #0004 ADD2 LDA2 LTH2 #00 EQU ?&break.2
STH2kr #0006 ADD2 LDA2 STH2kr LDA2 ADD2 LDA sext
STH2kr INC2 INC2 LDA2 STH2kr LDA2 ADD2 STA
POP
&continue.2
STH2kr LDA2k INC2k ROT2 STA2
POP2 !&begin.2
&break.2
STH2kr #0008 ADD2 LDA2 STH2kr #0004 ADD2 LDA2 ADD2 ;mem_length_ STA2
#0000 ;mem_ ;mem_length_ LDA2 ADD2 STA
POP STH2kr INC2 INC2 LDA2 !&return
#0000
&return
POP2r JMP2r
@afree_ ( -- result* )
OVR2r #0000 ;mem_length_ STA2
#0000
&return
POP2r JMP2r
@amcpy_ ( length* from* -- result* )
OVR2r LIT2r 0008 SUB2r STH2kr #0006 ADD2 STA2
STH2kr #0004 ADD2 STA2
STH2kr #0004 ADD2 LDA2 aalloc_
STH2kr INC2 INC2 STA2
#0000 STH2kr STA2
&begin.1
STH2kr LDA2 STH2kr #0004 ADD2 LDA2 LTH2 #00 EQU ?&break.1
STH2kr #0006 ADD2 LDA2 STH2kr LDA2 ADD2 LDA sext
STH2kr INC2 INC2 LDA2 STH2kr LDA2 ADD2 STA
POP
&continue.1
STH2kr LDA2k INC2k ROT2 STA2
POP2 !&begin.1
&break.1
STH2kr INC2 INC2 LDA2 !&return
#0000
&return
POP2r JMP2r
@nat_to_str_ ( n* -- result* )
OVR2r LIT2r 000a SUB2r STH2kr #0008 ADD2 STA2
#0005 STH2kr STA2
&begin.1
STH2kr #0008 ADD2 LDA2 #000a OVR2 OVR2 DIV2 MUL2 SUB2 #0030 ADD2 STH2kr INC2 INC2 STH2kr LDA2k #0001 SUB2 SWP2 STA2k
POP2 ADD2 STA
POP STH2kr #0008 ADD2 LDA2k #000a DIV2 SWP2 STA2
&continue.1
#0000 STH2kr #0008 ADD2 LDA2 LTH2 ?&begin.1
&break.1
#0005 STH2kr LDA2 SUB2 STH2kr INC2 INC2 STH2kr LDA2 ADD2 amcpy_
!&return
#0000
&return
POP2r JMP2r
@int_to_str_ ( n* -- result* )
OVR2r LIT2r 000c SUB2r STH2kr #000a ADD2 STA2
#0006 STH2kr INC2 INC2 STA2
STH2kr #000a ADD2 LDA2 #8000 EOR2 #8000 LTH2 #00 SWP #0000 NEQ2 #00 SWP STH2kr STA
POP LDAkr STHr sext
#0000 EQU2 ?&end.1
#0000 STH2kr #000a ADD2 LDA2 SUB2 STH2kr #000a ADD2 STA2
&end.1
&begin.2
STH2kr #000a ADD2 LDA2 #000a OVR2 OVR2 sdiv/b_pos
MUL2 SUB2 #0030 ADD2 STH2kr #0004 ADD2 STH2kr INC2 INC2 LDA2k #0001 SUB2 SWP2 STA2k
POP2 ADD2 STA
POP STH2kr #000a ADD2 LDA2k #000a sdiv/b_pos
SWP2 STA2
&continue.2
#8000 STH2kr #000a ADD2 LDA2 #8000 EOR2 LTH2 ?&begin.2
&break.2
LDAkr STHr sext
#0000 EQU2 ?&end.3
#002d STH2kr #0004 ADD2 STH2kr INC2 INC2 LDA2k #0001 SUB2 SWP2 STA2k
POP2 ADD2 STA
POP
&end.3
#0006 STH2kr INC2 INC2 LDA2 SUB2 STH2kr #0004 ADD2 STH2kr INC2 INC2 LDA2 ADD2 amcpy_
!&return
#0000
&return
POP2r JMP2r
@int_to_nat_ ( n* -- result* )
OVR2r LIT2r 0002 SUB2r STH2kr STA2
STH2kr LDA2 !&return
#0000
&return
POP2r JMP2r
@nat_to_int_ ( n* -- result* )
OVR2r LIT2r 0002 SUB2r STH2kr STA2
STH2kr LDA2 !&return
#0000
&return
POP2r JMP2r

8
test/bang.tal Normal file
View File

@ -0,0 +1,8 @@
|100
!{ @flag $1 } #0000 ;flag STA2 ;flag LDA2 #ffff EOR2 ?{ ;{ #0002 ADD2 } !{ #66 #6c #61 #67 #20 #69 #73 #20 #66 #61 #6c #73 #65 #00 } str/<print> } BRK
@str/<print> ( str* -- )
LDAk DUP ?{ POP POP2 JMP2r }
#18 DEO
INC2 !/<print>

2
test/global.tal Normal file
View File

@ -0,0 +1,2 @@
|100
!{ @i $2 } #007a ;i STA2 !{ @j $2 } #0020 ;j STA2 ;i LDA2 ;j LDA2 SUB2 #18 DEO

8
test/hello.tal Normal file
View File

@ -0,0 +1,8 @@
|100
!{ @msg $2 } ;{ #0002 ADD2 } !{ #6e #75 #71 #6e #65 #48 #20 #27 #75 #27 #3f #00 } ;msg STA2 ;msg LDA2 str/<print>
@str/<print> ( str* -- )
LDAk DUP ?{ POP POP2 JMP2r }
#18 DEO
INC2 !/<print>

View File

@ -1,2 +0,0 @@
|100 @main ( -> )
!{ &i $2 } #007a ,/i STR2 !{ &j $2 } #0020 ,/j STR2 ,/i LDR2 ,/j LDR2 SUB2 #18 DEO

11
test/str.c Executable file
View File

@ -0,0 +1,11 @@
#include <stdio.h>
char* msg = " damage inflicted!\n";
int main() {
unsigned AT = 14;
unsigned accuracy = 150;
unsigned dmg = ((AT * accuracy) / 20) - 3;
printf("%d%s", dmg, msg);
}

73
test/str.tal Normal file
View File

@ -0,0 +1,73 @@
|100
!{ @msg $2 } ;{ #0002 ADD2 } !{ #20 #64 #61 #6d #61 #67 #65 #20 #69 #6e #66 #6c #69 #63 #74 #65 #64 #21 #5c #6e #00 } ;msg STA2
!{ @AT $2 } #000e ;AT STA2
!{ @accuracy $2 } #0096 ;accuracy STA2
!{ @dmg $2 } ;AT LDA2 ;accuracy LDA2 MUL2 #0014 DIV2 #0003 SUB2 ;dmg STA2
;dmg LDA2 nat_to_str_
str/<print> ;msg LDA2
str/<print>
@sext
#80 ANDk EQU #ff MUL SWP JMP2r
@aalloc_ ( size* -- result* )
OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2
;mem_length_ LDA2 STH2kr STA2
;mem_length_ LDA2k STH2kr INC2 INC2 LDA2 ADD2 SWP2 STA2
;mem_ STH2kr LDA2 ADD2 !&return
#0000
&return
POP2r JMP2r
@amcpy_ ( length* from* -- result* )
OVR2r LIT2r 0008 SUB2r STH2kr #0006 ADD2 STA2
STH2kr #0004 ADD2 STA2
STH2kr #0004 ADD2 LDA2 aalloc_
STH2kr INC2 INC2 STA2
#0000 STH2kr STA2
&begin.1
STH2kr LDA2 STH2kr #0004 ADD2 LDA2 LTH2 #00 EQU ?&break.1
STH2kr #0006 ADD2 LDA2 STH2kr LDA2 ADD2 LDA sext
STH2kr INC2 INC2 LDA2 STH2kr LDA2 ADD2 STA
POP
&continue.1
STH2kr LDA2k INC2k ROT2 STA2
POP2 !&begin.1
&break.1
STH2kr INC2 INC2 LDA2 !&return
#0000
&return
POP2r JMP2r
@nat_to_str_ ( n* -- result* )
OVR2r LIT2r 000a SUB2r STH2kr #0008 ADD2 STA2
#0005 STH2kr STA2
&begin.1
STH2kr #0008 ADD2 LDA2 #000a OVR2 OVR2 DIV2 MUL2 SUB2 #0030 ADD2 STH2kr INC2 INC2 STH2kr LDA2k #0001 SUB2 SWP2 STA2k
POP2 ADD2 STA
POP STH2kr #0008 ADD2 LDA2k #000a DIV2 SWP2 STA2
&continue.1
#0000 STH2kr #0008 ADD2 LDA2 LTH2 ?&begin.1
&break.1
#0005 STH2kr LDA2 SUB2 STH2kr INC2 INC2 STH2kr LDA2 ADD2 amcpy_
!&return
#0000
&return
POP2r JMP2r
@str/<print> ( str* -- )
LDAk DUP ?{ POP POP2 JMP2r }
#18 DEO
INC2 !/<print>
@mem_length_ #0000
@mem_

View File

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