Change to output a string buffer instead of raw printf
This commit is contained in:
parent
1ec9f7a2d1
commit
974d282d7a
|
|
@ -1,6 +1,7 @@
|
||||||
#include "../../compiler.h"
|
#include "../../compiler.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
readFile(const char *path)
|
readFile(const char *path)
|
||||||
|
|
@ -67,10 +68,28 @@ main(int argc, char **argv)
|
||||||
u8 tape[MEM_SIZE];
|
u8 tape[MEM_SIZE];
|
||||||
Arena a = {tape, 0, MEM_SIZE};
|
Arena a = {tape, 0, MEM_SIZE};
|
||||||
|
|
||||||
|
List *code = List_init(&a);
|
||||||
|
List *memory = List_init(&a);
|
||||||
|
|
||||||
char *source = readFile(argv[2]);
|
char *source = readFile(argv[2]);
|
||||||
compile(&a, e, source);
|
compile(&a, code, memory, e, source);
|
||||||
|
|
||||||
|
Node *curr = code->head;
|
||||||
|
while (curr) {
|
||||||
|
char* tmp_str = node_value(curr);
|
||||||
|
write(STDOUT_FILENO, tmp_str, curr->size);
|
||||||
|
curr = curr->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
curr = memory->head;
|
||||||
|
while (curr) {
|
||||||
|
char* tmp_str = node_value(curr);
|
||||||
|
write(STDOUT_FILENO, tmp_str, curr->size);
|
||||||
|
curr = curr->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
afree(&a);
|
||||||
free(source);
|
free(source);
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
139
compiler.c
139
compiler.c
|
|
@ -8,6 +8,8 @@
|
||||||
Emitter emitter = {0};
|
Emitter emitter = {0};
|
||||||
Parser parser = {0};
|
Parser parser = {0};
|
||||||
Arena *arena;
|
Arena *arena;
|
||||||
|
List *code;
|
||||||
|
List *memory;
|
||||||
|
|
||||||
/****************************************************
|
/****************************************************
|
||||||
* Scope
|
* Scope
|
||||||
|
|
@ -371,6 +373,20 @@ variable_declaration(Symbol *def)
|
||||||
while(!check(TOKEN_RBRACKET)) {
|
while(!check(TOKEN_RBRACKET)) {
|
||||||
advance();
|
advance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variable = scope_get_symbol(parser.current_scope,
|
||||||
|
parser.previous.start,
|
||||||
|
parser.previous.length);
|
||||||
|
|
||||||
|
if (check(TOKEN_EQ)) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
while(!check(TOKEN_SEMICOLON)) {
|
||||||
|
advance();
|
||||||
|
}
|
||||||
|
|
||||||
|
return variable->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(st != SYMBOL_UNDEFINED) {
|
if(st != SYMBOL_UNDEFINED) {
|
||||||
|
|
@ -383,7 +399,7 @@ variable_declaration(Symbol *def)
|
||||||
if(def) {
|
if(def) {
|
||||||
List_push(arena, def->args, variable, sizeof(Symbol));
|
List_push(arena, def->args, variable, sizeof(Symbol));
|
||||||
} else {
|
} else {
|
||||||
emitter.emit_type(variable, parser.depth);
|
emitter.emit_type(arena, code, variable, parser.depth);
|
||||||
parser.current_type = st;
|
parser.current_type = st;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -400,13 +416,13 @@ variable_declaration(Symbol *def)
|
||||||
if(parser.pass == 0) return size;
|
if(parser.pass == 0) return size;
|
||||||
|
|
||||||
if(match(TOKEN_EQ)) {
|
if(match(TOKEN_EQ)) {
|
||||||
emitter.emit_set_value();
|
emitter.emit_set_value(arena, code);
|
||||||
expression();
|
expression();
|
||||||
emitter.emit_constant(variable, parser.depth);
|
emitter.emit_constant(arena, code, variable, parser.depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
consume(TOKEN_SEMICOLON);
|
consume(TOKEN_SEMICOLON);
|
||||||
emitter.emit_end_statement();
|
emitter.emit_end_statement(arena, code);
|
||||||
parser.current_type = SYMBOL_UNDEFINED;
|
parser.current_type = SYMBOL_UNDEFINED;
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
@ -421,52 +437,52 @@ binary()
|
||||||
|
|
||||||
switch(operatorType) {
|
switch(operatorType) {
|
||||||
case TOKEN_BANG_EQ:
|
case TOKEN_BANG_EQ:
|
||||||
emitter.emit_ne();
|
emitter.emit_ne(arena, code);
|
||||||
break;
|
break;
|
||||||
case TOKEN_EQ_EQ:
|
case TOKEN_EQ_EQ:
|
||||||
emitter.emit_eq();
|
emitter.emit_eq(arena, code);
|
||||||
break;
|
break;
|
||||||
case TOKEN_GT:
|
case TOKEN_GT:
|
||||||
emitter.emit_gt();
|
emitter.emit_gt(arena, code);
|
||||||
break;
|
break;
|
||||||
case TOKEN_GTE:
|
case TOKEN_GTE:
|
||||||
emitter.emit_ge();
|
emitter.emit_ge(arena, code);
|
||||||
break;
|
break;
|
||||||
case TOKEN_LT:
|
case TOKEN_LT:
|
||||||
emitter.emit_lt();
|
emitter.emit_lt(arena, code);
|
||||||
break;
|
break;
|
||||||
case TOKEN_LTE:
|
case TOKEN_LTE:
|
||||||
emitter.emit_le();
|
emitter.emit_le(arena, code);
|
||||||
break;
|
break;
|
||||||
case TOKEN_PLUS:
|
case TOKEN_PLUS:
|
||||||
emitter.emit_add();
|
emitter.emit_add(arena, code);
|
||||||
break;
|
break;
|
||||||
case TOKEN_MINUS:
|
case TOKEN_MINUS:
|
||||||
emitter.emit_sub();
|
emitter.emit_sub(arena, code);
|
||||||
break;
|
break;
|
||||||
case TOKEN_STAR:
|
case TOKEN_STAR:
|
||||||
emitter.emit_mul();
|
emitter.emit_mul(arena, code);
|
||||||
break;
|
break;
|
||||||
case TOKEN_SLASH:
|
case TOKEN_SLASH:
|
||||||
emitter.emit_div();
|
emitter.emit_div(arena, code);
|
||||||
break;
|
break;
|
||||||
case TOKEN_OPERATOR_AND:
|
case TOKEN_OPERATOR_AND:
|
||||||
emitter.emit_and();
|
emitter.emit_and(arena, code);
|
||||||
break;
|
break;
|
||||||
case TOKEN_OPERATOR_OR:
|
case TOKEN_OPERATOR_OR:
|
||||||
emitter.emit_or();
|
emitter.emit_or(arena, code);
|
||||||
break;
|
break;
|
||||||
case TOKEN_OPERATOR_XOR:
|
case TOKEN_OPERATOR_XOR:
|
||||||
emitter.emit_xor();
|
emitter.emit_xor(arena, code);
|
||||||
break;
|
break;
|
||||||
case TOKEN_OPERATOR_MOD:
|
case TOKEN_OPERATOR_MOD:
|
||||||
emitter.emit_mod();
|
emitter.emit_mod(arena, code);
|
||||||
break;
|
break;
|
||||||
case TOKEN_SLL:
|
case TOKEN_SLL:
|
||||||
emitter.emit_sll();
|
emitter.emit_sll(arena, code);
|
||||||
break;
|
break;
|
||||||
case TOKEN_SRL:
|
case TOKEN_SRL:
|
||||||
emitter.emit_srl();
|
emitter.emit_srl(arena, code);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
|
|
@ -478,13 +494,13 @@ literal()
|
||||||
{
|
{
|
||||||
switch(parser.previous.type) {
|
switch(parser.previous.type) {
|
||||||
case TOKEN_KEYWORD_FALSE:
|
case TOKEN_KEYWORD_FALSE:
|
||||||
emitter.emit_false();
|
emitter.emit_false(arena, code);
|
||||||
break;
|
break;
|
||||||
case TOKEN_KEYWORD_TRUE:
|
case TOKEN_KEYWORD_TRUE:
|
||||||
emitter.emit_true();
|
emitter.emit_true(arena, code);
|
||||||
break;
|
break;
|
||||||
case TOKEN_KEYWORD_NIL:
|
case TOKEN_KEYWORD_NIL:
|
||||||
emitter.emit_nil();
|
emitter.emit_nil(arena, code);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
|
|
@ -515,9 +531,9 @@ variable()
|
||||||
parser.current_type = sym->type;
|
parser.current_type = sym->type;
|
||||||
if(match(TOKEN_EQ)) {
|
if(match(TOKEN_EQ)) {
|
||||||
expression();
|
expression();
|
||||||
emitter.emit_set_variable(sym, sym->scope);
|
emitter.emit_set_variable(arena, code, sym, sym->scope);
|
||||||
} else {
|
} else {
|
||||||
emitter.emit_variable(sym, sym->scope);
|
emitter.emit_variable(arena, code, sym, sym->scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -539,15 +555,15 @@ cast_type()
|
||||||
case SYMBOL_INT: {
|
case SYMBOL_INT: {
|
||||||
switch(cast_type) {
|
switch(cast_type) {
|
||||||
case TOKEN_TYPE_NAT: {
|
case TOKEN_TYPE_NAT: {
|
||||||
emitter.emit_cast_int_to_nat();
|
emitter.emit_cast_int_to_nat(arena, code);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TOKEN_TYPE_REAL: {
|
case TOKEN_TYPE_REAL: {
|
||||||
emitter.emit_cast_int_to_real();
|
emitter.emit_cast_int_to_real(arena, code);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TOKEN_TYPE_STR: {
|
case TOKEN_TYPE_STR: {
|
||||||
emitter.emit_cast_int_to_str();
|
emitter.emit_cast_int_to_str(arena, code);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
@ -559,15 +575,15 @@ cast_type()
|
||||||
case SYMBOL_NAT: {
|
case SYMBOL_NAT: {
|
||||||
switch(cast_type) {
|
switch(cast_type) {
|
||||||
case TOKEN_TYPE_INT: {
|
case TOKEN_TYPE_INT: {
|
||||||
emitter.emit_cast_nat_to_int();
|
emitter.emit_cast_nat_to_int(arena, code);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TOKEN_TYPE_REAL: {
|
case TOKEN_TYPE_REAL: {
|
||||||
emitter.emit_cast_nat_to_real();
|
emitter.emit_cast_nat_to_real(arena, code);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TOKEN_TYPE_STR: {
|
case TOKEN_TYPE_STR: {
|
||||||
emitter.emit_cast_nat_to_str();
|
emitter.emit_cast_nat_to_str(arena, code);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
@ -578,15 +594,15 @@ cast_type()
|
||||||
case SYMBOL_REAL: {
|
case SYMBOL_REAL: {
|
||||||
switch(cast_type) {
|
switch(cast_type) {
|
||||||
case TOKEN_TYPE_NAT: {
|
case TOKEN_TYPE_NAT: {
|
||||||
emitter.emit_cast_real_to_nat();
|
emitter.emit_cast_real_to_nat(arena, code);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TOKEN_TYPE_INT: {
|
case TOKEN_TYPE_INT: {
|
||||||
emitter.emit_cast_real_to_int();
|
emitter.emit_cast_real_to_int(arena, code);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TOKEN_TYPE_STR: {
|
case TOKEN_TYPE_STR: {
|
||||||
emitter.emit_cast_real_to_str();
|
emitter.emit_cast_real_to_str(arena, code);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
@ -597,15 +613,15 @@ cast_type()
|
||||||
case SYMBOL_STR: {
|
case SYMBOL_STR: {
|
||||||
switch(cast_type) {
|
switch(cast_type) {
|
||||||
case TOKEN_TYPE_NAT: {
|
case TOKEN_TYPE_NAT: {
|
||||||
emitter.emit_cast_str_to_nat();
|
emitter.emit_cast_str_to_nat(arena, code);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TOKEN_TYPE_REAL: {
|
case TOKEN_TYPE_REAL: {
|
||||||
emitter.emit_cast_str_to_real();
|
emitter.emit_cast_str_to_real(arena, code);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TOKEN_TYPE_INT: {
|
case TOKEN_TYPE_INT: {
|
||||||
emitter.emit_cast_str_to_int();
|
emitter.emit_cast_str_to_int(arena, code);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
@ -632,8 +648,8 @@ print_statement()
|
||||||
{
|
{
|
||||||
expression();
|
expression();
|
||||||
consume(TOKEN_SEMICOLON);
|
consume(TOKEN_SEMICOLON);
|
||||||
emitter.emit_print();
|
emitter.emit_print(arena, code);
|
||||||
emitter.emit_end_statement();
|
emitter.emit_end_statement(arena, code);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -642,28 +658,28 @@ if_statement()
|
||||||
consume(TOKEN_LPAREN);
|
consume(TOKEN_LPAREN);
|
||||||
expression();
|
expression();
|
||||||
consume(TOKEN_RPAREN);
|
consume(TOKEN_RPAREN);
|
||||||
emitter.emit_if();
|
emitter.emit_if(arena, code);
|
||||||
statement();
|
statement();
|
||||||
|
|
||||||
emitter.emit_patch_if(emitter.ifs);
|
emitter.emit_patch_if(arena, code, emitter.ifs);
|
||||||
if(match(TOKEN_KEYWORD_ELSE)) {
|
if(match(TOKEN_KEYWORD_ELSE)) {
|
||||||
emitter.else_if_depth++;
|
emitter.else_if_depth++;
|
||||||
statement();
|
statement();
|
||||||
emitter.else_if_depth--;
|
emitter.else_if_depth--;
|
||||||
}
|
}
|
||||||
if(emitter.else_if_depth == 0) emitter.emit_patch_if_done(emitter.ifs++);
|
if(emitter.else_if_depth == 0) emitter.emit_patch_if_done(arena, code, emitter.ifs++);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
while_statement()
|
while_statement()
|
||||||
{
|
{
|
||||||
emitter.emit_while(emitter.loops);
|
emitter.emit_while(arena, code, emitter.loops);
|
||||||
consume(TOKEN_LPAREN);
|
consume(TOKEN_LPAREN);
|
||||||
expression();
|
expression();
|
||||||
consume(TOKEN_RPAREN);
|
consume(TOKEN_RPAREN);
|
||||||
emitter.emit_while_postfix();
|
emitter.emit_while_postfix(arena, code);
|
||||||
statement();
|
statement();
|
||||||
emitter.emit_patch_while(emitter.loops++);
|
emitter.emit_patch_while(arena, code, emitter.loops++);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -679,13 +695,13 @@ function()
|
||||||
{
|
{
|
||||||
Symbol *sym = scope_get_symbol(parser.current_scope, parser.previous.start,
|
Symbol *sym = scope_get_symbol(parser.current_scope, parser.previous.start,
|
||||||
parser.previous.length);
|
parser.previous.length);
|
||||||
emitter.emit_function(sym);
|
emitter.emit_function(arena, code, sym);
|
||||||
scope_push();
|
scope_push();
|
||||||
while(!check(TOKEN_RPAREN)) advance();
|
while(!check(TOKEN_RPAREN)) advance();
|
||||||
consume(TOKEN_RPAREN);
|
consume(TOKEN_RPAREN);
|
||||||
consume(TOKEN_LBRACE);
|
consume(TOKEN_LBRACE);
|
||||||
block();
|
block();
|
||||||
emitter.emit_arena_fn_return();
|
emitter.emit_arena_fn_return(arena, code);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -698,7 +714,7 @@ call()
|
||||||
}
|
}
|
||||||
consume(TOKEN_RPAREN);
|
consume(TOKEN_RPAREN);
|
||||||
|
|
||||||
emitter.emit_arena_fn_call(parser.call_fn);
|
emitter.emit_arena_fn_call(arena, code, parser.call_fn);
|
||||||
parser.current_type = parser.call_fn->secondary_type;
|
parser.current_type = parser.call_fn->secondary_type;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -707,11 +723,11 @@ void
|
||||||
return_statement()
|
return_statement()
|
||||||
{
|
{
|
||||||
if(match(TOKEN_SEMICOLON)) {
|
if(match(TOKEN_SEMICOLON)) {
|
||||||
emitter.emit_early_return();
|
emitter.emit_early_return(arena, code);
|
||||||
} else {
|
} else {
|
||||||
expression();
|
expression();
|
||||||
consume(TOKEN_SEMICOLON);
|
consume(TOKEN_SEMICOLON);
|
||||||
emitter.emit_early_return();
|
emitter.emit_early_return(arena, code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -734,7 +750,7 @@ statement()
|
||||||
} else if(match(TOKEN_KEYWORD_PRINT)) {
|
} else if(match(TOKEN_KEYWORD_PRINT)) {
|
||||||
print_statement();
|
print_statement();
|
||||||
} else if(match(TOKEN_KEYWORD_HALT)) {
|
} else if(match(TOKEN_KEYWORD_HALT)) {
|
||||||
emitter.emit_halt();
|
emitter.emit_halt(arena, code);
|
||||||
} else {
|
} else {
|
||||||
expression();
|
expression();
|
||||||
}
|
}
|
||||||
|
|
@ -743,24 +759,24 @@ statement()
|
||||||
void
|
void
|
||||||
grouping()
|
grouping()
|
||||||
{
|
{
|
||||||
emitter.emit_open_paren();
|
emitter.emit_open_paren(arena, code);
|
||||||
|
|
||||||
expression();
|
expression();
|
||||||
|
|
||||||
emitter.emit_close_paren();
|
emitter.emit_close_paren(arena, code);
|
||||||
consume(TOKEN_RPAREN);
|
consume(TOKEN_RPAREN);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
number()
|
number()
|
||||||
{
|
{
|
||||||
emitter.emit_int(parser.previous.start, parser.previous.length);
|
emitter.emit_int(arena, code, parser.previous.start, parser.previous.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
string()
|
string()
|
||||||
{
|
{
|
||||||
emitter.emit_str(parser.previous.start, parser.previous.length);
|
emitter.emit_str(arena, code, parser.previous.start, parser.previous.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -771,10 +787,10 @@ unary()
|
||||||
|
|
||||||
switch(operatorType) {
|
switch(operatorType) {
|
||||||
case TOKEN_MINUS:
|
case TOKEN_MINUS:
|
||||||
emitter.emit_neg();
|
emitter.emit_neg(arena, code);
|
||||||
break;
|
break;
|
||||||
case TOKEN_BANG:
|
case TOKEN_BANG:
|
||||||
emitter.emit_not();
|
emitter.emit_not(arena, code);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
|
|
@ -895,18 +911,19 @@ emit_program(char *source)
|
||||||
init_lexer(source);
|
init_lexer(source);
|
||||||
advance();
|
advance();
|
||||||
|
|
||||||
emitter.prolog();
|
emitter.prolog(arena, code);
|
||||||
|
emitter.epilogue(arena, memory);
|
||||||
|
|
||||||
while(!match(TOKEN_EOF)) declaration();
|
while(!match(TOKEN_EOF)) declaration();
|
||||||
|
|
||||||
emitter.epilogue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
compile(Arena *a, Emitter e, char *source)
|
compile(Arena *a, List *c, List* m, Emitter e, char *source)
|
||||||
{
|
{
|
||||||
arena = a;
|
arena = a;
|
||||||
emitter = e;
|
emitter = e;
|
||||||
|
code = c;
|
||||||
|
memory = m;
|
||||||
parser.scopes = List_init(arena);
|
parser.scopes = List_init(arena);
|
||||||
|
|
||||||
build_symbol_table(source);
|
build_symbol_table(source);
|
||||||
|
|
|
||||||
|
|
@ -42,15 +42,15 @@ struct parse_rule_s {
|
||||||
struct parser_s {
|
struct parser_s {
|
||||||
Symbol *call_fn;
|
Symbol *call_fn;
|
||||||
Scope *current_scope;
|
Scope *current_scope;
|
||||||
u32 scope_idx;
|
|
||||||
List *scopes;
|
List *scopes;
|
||||||
Token current;
|
Token current;
|
||||||
Token previous;
|
Token previous;
|
||||||
SymbolType current_type;
|
SymbolType current_type;
|
||||||
|
u32 scope_idx;
|
||||||
u32 depth;
|
u32 depth;
|
||||||
u8 pass;
|
u8 pass;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool compile(Arena *a, Emitter e, char *source);
|
bool compile(Arena *a, List *c, List *m, Emitter e, char *source);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
11
emit.h
11
emit.h
|
|
@ -2,15 +2,16 @@
|
||||||
#define UNDAR_EMIT_H
|
#define UNDAR_EMIT_H
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "strbuf.h"
|
||||||
#include "libc.h"
|
#include "libc.h"
|
||||||
|
|
||||||
typedef u32 (*SymbolSize)(SymbolType t);
|
typedef u32 (*SymbolSize)(SymbolType t);
|
||||||
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 (*SymbolEmit)(Arena *a, List *out, Symbol *sym);
|
||||||
typedef void (*StrArgEmit)(const char *str, i32 length);
|
typedef void (*VoidArgEmit)(Arena *a, List *out);
|
||||||
typedef void (*VarEmit)(Symbol *sym, bool local);
|
typedef void (*StrArgEmit)(Arena *a, List *out, const char *str, i32 length);
|
||||||
typedef void (*I32ArgEmit)(i32 val);
|
typedef void (*VarEmit)(Arena *a, List *out, Symbol *sym, bool local);
|
||||||
|
typedef void (*I32ArgEmit)(Arena *a, List *out, i32 val);
|
||||||
|
|
||||||
typedef struct emitter_s Emitter;
|
typedef struct emitter_s Emitter;
|
||||||
struct emitter_s {
|
struct emitter_s {
|
||||||
|
|
|
||||||
544
emit/rer/emit.c
544
emit/rer/emit.c
|
|
@ -2,11 +2,12 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
char rer_temp_strbuf[256];
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_error(const char *str, i32 length, i32 line)
|
rer_emit_error(const char *str, i32 length, i32 line)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "\n===\nError at line: %d > %.*s\n===\n", line, length, str);
|
fprintf(stderr, "\n===\nError at line: %d '%.*s'\n===\n", line, length, str);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -17,110 +18,114 @@ rer_mem(u32 a)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_prolog()
|
rer_prolog(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("|100\n");
|
/*StrBuf_append(a, out, "|100\n\tLIT2r 0000 main_ POP2r BRK\n\n");*/
|
||||||
|
StrBuf_append(a, out, "|100\n\tLIT2r 0000\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_epilogue()
|
rer_epilogue(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("BRK\n\n");
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_add()
|
rer_emit_add(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("ADD2 ");
|
StrBuf_append(a, out, "ADD2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_sub()
|
rer_emit_sub(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("SUB2 ");
|
StrBuf_append(a, out, "SUB2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_mul()
|
rer_emit_mul(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("MUL2 ");
|
StrBuf_append(a, out, "MUL2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_div()
|
rer_emit_div(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("DIV2 ");
|
StrBuf_append(a, out, "DIV2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_lt()
|
rer_emit_lt(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("LTH2 ");
|
StrBuf_append(a, out, "LTH2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_le()
|
rer_emit_le(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("ROT SWP LTH ?{ LTH #00 EQU JMPr } GTH JMPr ");
|
StrBuf_append(a, out, "ROT SWP LTH ?{ LTH #00 EQU JMPr } GTH JMPr ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_gt()
|
rer_emit_gt(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("GTH2 ");
|
StrBuf_append(a, out, "GTH2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_ge()
|
rer_emit_ge(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("ROT SWP GTH ?{ GTH #00 EQU JMPr } LTH JMPr ");
|
StrBuf_append(a, out, "ROT SWP GTH ?{ GTH #00 EQU JMPr } LTH JMPr ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_ne()
|
rer_emit_ne(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("NEQ2 ");
|
StrBuf_append(a, out, "NEQ2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_eq()
|
rer_emit_eq(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("EQU2 ");
|
StrBuf_append(a, out, "EQU2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_false()
|
rer_emit_false(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("#0000 ");
|
StrBuf_append(a, out, "#0000 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_true()
|
rer_emit_true(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("#0001 ");
|
StrBuf_append(a, out, "#0001 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_nil()
|
rer_emit_nil(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("#0000 ");
|
StrBuf_append(a, out, "#0000 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_neg()
|
rer_emit_neg(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("#0000 SUB2 ");
|
StrBuf_append(a, out, "#0000 SUB2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_not()
|
rer_emit_not(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("#0000 EQU2 ");
|
StrBuf_append(a, out, "#0000 EQU2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_void()
|
rer_emit_void(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32
|
u32
|
||||||
|
|
@ -161,434 +166,517 @@ rer_get_size(SymbolType t)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_primitive_type(Symbol *sym, bool local)
|
rer_emit_type(Arena *a, List *out, Symbol *sym, bool local)
|
||||||
{
|
{
|
||||||
if(local)
|
if(local) {
|
||||||
if(sym->ref)
|
if(sym->ref) {
|
||||||
printf("STH2kr #%04x ADD2 STA2\n", sym->ref);
|
sprintf(rer_temp_strbuf, "\tSTH2kr #%04x ADD2 LDA2\n", sym->ref);
|
||||||
else
|
StrBuf_append(a, out, rer_temp_strbuf);
|
||||||
printf("STH2kr STA2\n");
|
} else {
|
||||||
else
|
sprintf(rer_temp_strbuf, "\tSTH2kr LDA2\n");
|
||||||
switch(sym->type) {
|
StrBuf_append(a, out, rer_temp_strbuf);
|
||||||
case SYMBOL_BOOL: {
|
|
||||||
printf("!{ @%.*s $2 } ", sym->name_length, sym->name);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case SYMBOL_BYTE: {
|
} else {
|
||||||
printf("!{ @%.*s $1 } ", sym->name_length, sym->name);
|
sprintf(rer_temp_strbuf, "!{ @%.*s $%d } ", sym->name_length, sym->name,
|
||||||
break;
|
rer_get_size(sym->type));
|
||||||
}
|
StrBuf_append(a, out, rer_temp_strbuf);
|
||||||
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
|
void
|
||||||
rer_emit_int(const char *str, i32 length)
|
rer_emit_int(Arena *a, List *out, const char *str, i32 length)
|
||||||
{
|
{
|
||||||
i32 i = (i32)strtol(str, nil, 10);
|
i32 i = (i32)strtol(str, nil, 10);
|
||||||
printf("#%04x ", i);
|
sprintf(rer_temp_strbuf, "#%04x ", i);
|
||||||
|
StrBuf_append(a, out, rer_temp_strbuf);
|
||||||
USED(length);
|
USED(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_nat(const char *str, i32 length)
|
rer_emit_nat(Arena *a, List *out, const char *str, i32 length)
|
||||||
{
|
{
|
||||||
u32 i = (u32)strtol(str, nil, 10);
|
u32 i = (u32)strtol(str, nil, 10);
|
||||||
printf("#%04x ", i);
|
sprintf(rer_temp_strbuf, "#%04x ", i);
|
||||||
|
StrBuf_append(a, out, rer_temp_strbuf);
|
||||||
USED(length);
|
USED(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_real(const char *str, i32 length)
|
rer_emit_real(Arena *a, List *out, const char *str, i32 length)
|
||||||
{
|
{
|
||||||
USED(str);
|
USED(str);
|
||||||
USED(length);
|
USED(length);
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
/// TODO: implement this
|
/// TODO: implement this
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_byte(const char *str, i32 length)
|
rer_emit_byte(Arena *a, List *out, const char *str, i32 length)
|
||||||
{
|
{
|
||||||
u8 i = (u8)strtol(str, nil, 10);
|
u8 i = (u8)strtol(str, nil, 10);
|
||||||
printf("#%04x ", i);
|
sprintf(rer_temp_strbuf, "#%04x ", i);
|
||||||
|
StrBuf_append(a, out, rer_temp_strbuf);
|
||||||
USED(length);
|
USED(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_str(const char *str, i32 length)
|
rer_emit_str(Arena *a, List *out, const char *str, i32 length)
|
||||||
{
|
{
|
||||||
/* set a pointer to the string literal and then jump over it */
|
/* set a pointer to the string literal and then jump over it */
|
||||||
printf(";{ #0002 ADD2 } !{ ");
|
StrBuf_append(a, out, ";{ #0002 ADD2 } !{ ");
|
||||||
|
|
||||||
for(i32 i = 1; i < length - 1; i++) printf("%02x ", str[i]);
|
i32 i = 1;
|
||||||
|
while(i < length - 1) {
|
||||||
|
char c = str[i++];
|
||||||
|
if(c == '\\' && i < length - 1) {
|
||||||
|
switch(str[i++]) {
|
||||||
|
case 'n':
|
||||||
|
c = '\n';
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
c = '\t';
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
c = '\r';
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
case '"':
|
||||||
|
case '\'':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
i--; /* Rewind for unknown escapes */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sprintf(rer_temp_strbuf, "%02x ", c);
|
||||||
|
StrBuf_append(a, out, rer_temp_strbuf);
|
||||||
|
}
|
||||||
|
|
||||||
printf("00 } ");
|
StrBuf_append(a, out, "00 } ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_constant(Symbol *sym, bool local)
|
rer_emit_constant(Arena *a, List *out, Symbol *sym, bool local)
|
||||||
{
|
{
|
||||||
if(local)
|
if(local) {
|
||||||
if(sym->ref)
|
if(sym->ref) {
|
||||||
printf("\tSTH2kr #%04x ADD2 LDA2\n", sym->ref);
|
sprintf(rer_temp_strbuf, "\tSTH2kr #%04x ADD2 STA2\n", sym->ref);
|
||||||
else
|
StrBuf_append(a, out, rer_temp_strbuf);
|
||||||
printf("\tSTH2kr LDA2\n");
|
} else {
|
||||||
else
|
sprintf(rer_temp_strbuf, "\tSTH2kr STA2\n");
|
||||||
printf(";%.*s STA2 ", sym->name_length, sym->name);
|
StrBuf_append(a, out, rer_temp_strbuf);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sprintf(rer_temp_strbuf, ";%.*s STA2 ", sym->name_length, sym->name);
|
||||||
|
StrBuf_append(a, out, rer_temp_strbuf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_array()
|
rer_emit_array(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rer_fn_loop_emit_args(Arena *a, List *out, void *data)
|
||||||
|
{
|
||||||
|
Symbol *sym = ((Symbol *)data);
|
||||||
|
|
||||||
|
if(sym->ref) {
|
||||||
|
sprintf(rer_temp_strbuf, "\tSTH2kr #%04x ADD2 STA2\n", sym->ref);
|
||||||
|
StrBuf_append(a, out, rer_temp_strbuf);
|
||||||
|
} else {
|
||||||
|
sprintf(rer_temp_strbuf, "\tSTH2kr STA2\n");
|
||||||
|
|
||||||
|
StrBuf_append(a, out, rer_temp_strbuf);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rer_fn_loop_emit_args_comment(Arena *a, List *out, void *data)
|
||||||
|
{
|
||||||
|
Symbol *sym = ((Symbol *)data);
|
||||||
|
sprintf(rer_temp_strbuf, "%.*s ", sym->name_length, sym->name);
|
||||||
|
StrBuf_append(a, out, rer_temp_strbuf);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_function(Symbol *sym)
|
rer_emit_function(Arena *a, List *out, Symbol *sym)
|
||||||
{
|
{
|
||||||
USED(sym);
|
sprintf(rer_temp_strbuf, "@%.*s_ ( ", sym->name_length, sym->name);
|
||||||
|
StrBuf_append(a, out, rer_temp_strbuf);
|
||||||
|
List_map_out(a, out, sym->args, rer_fn_loop_emit_args_comment);
|
||||||
|
sprintf(rer_temp_strbuf, " -- ");
|
||||||
|
StrBuf_append(a, out, rer_temp_strbuf);
|
||||||
|
if(sym->secondary_type != SYMBOL_UNDEFINED &&
|
||||||
|
sym->secondary_type != SYMBOL_VOID) {
|
||||||
|
sprintf(rer_temp_strbuf, " res ");
|
||||||
|
StrBuf_append(a, out, rer_temp_strbuf);
|
||||||
|
}
|
||||||
|
sprintf(rer_temp_strbuf, ")\n");
|
||||||
|
StrBuf_append(a, out, rer_temp_strbuf);
|
||||||
|
if(sym->size > 0) {
|
||||||
|
sprintf(rer_temp_strbuf, "\tOVR2r LIT2r %04x SUB2r\n", sym->size);
|
||||||
|
StrBuf_append(a, out, rer_temp_strbuf);
|
||||||
|
}
|
||||||
|
List_map_out(a, out, sym->args, rer_fn_loop_emit_args);
|
||||||
|
StrBuf_append(a, out, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_arena_fn_return()
|
rer_emit_arena_fn_return(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("&return\n\t\tPOP2r JMP2r\n\n");
|
StrBuf_append(a, out, "\t&return\n\t\tPOP2r JMP2r\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_arena_fn_call(Symbol *sym)
|
rer_emit_arena_fn_call(Arena *a, List *out, Symbol *sym)
|
||||||
{
|
{
|
||||||
USED(sym);
|
sprintf(rer_temp_strbuf, "%.*s_ ", sym->name_length, sym->name);
|
||||||
|
StrBuf_append(a, out, rer_temp_strbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_plex()
|
rer_emit_plex(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_method()
|
rer_emit_method(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_trait()
|
rer_emit_trait(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_const()
|
rer_emit_const(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_putchar()
|
rer_emit_open_paren(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("#18 DEO ");
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_getchar()
|
rer_emit_close_paren(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("#12 DEI ");
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_open_paren()
|
rer_emit_variable(Arena *a, List *out, Symbol *sym, bool local)
|
||||||
{
|
{
|
||||||
|
if(local) {
|
||||||
|
if(sym->ref) {
|
||||||
|
sprintf(rer_temp_strbuf, "\tSTH2kr #%04x ADD2 LDA2 ", sym->ref);
|
||||||
|
StrBuf_append(a, out, rer_temp_strbuf);
|
||||||
|
} else {
|
||||||
|
sprintf(rer_temp_strbuf, "\tSTH2kr LDA2 ");
|
||||||
|
StrBuf_append(a, out, rer_temp_strbuf);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sprintf(rer_temp_strbuf, ";%.*s LDA2 ", sym->name_length, sym->name);
|
||||||
|
StrBuf_append(a, out, rer_temp_strbuf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_close_paren()
|
rer_emit_set_variable(Arena *a, List *out, Symbol *sym, bool local)
|
||||||
{
|
{
|
||||||
|
if(local) {
|
||||||
|
if(sym->ref) {
|
||||||
|
sprintf(rer_temp_strbuf, "\tSTH2kr #%04x ADD2 STA2 ", sym->ref);
|
||||||
|
StrBuf_append(a, out, rer_temp_strbuf);
|
||||||
|
} else {
|
||||||
|
sprintf(rer_temp_strbuf, "\tSTH2kr STA2 ");
|
||||||
|
StrBuf_append(a, out, rer_temp_strbuf);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sprintf(rer_temp_strbuf, ";%.*s STA2 ", sym->name_length, sym->name);
|
||||||
|
StrBuf_append(a, out, rer_temp_strbuf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_variable(Symbol *sym, bool local)
|
rer_emit_write(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
if(local)
|
USED(a);
|
||||||
if(sym->ref)
|
USED(out);
|
||||||
printf("STH2kr #%04x ADD2 LDA2 ", sym->ref);
|
|
||||||
else
|
|
||||||
printf("STH2kr LDA2 ");
|
|
||||||
else
|
|
||||||
printf(";%.*s LDA2 ", sym->name_length, sym->name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_set_variable(Symbol *sym, bool local)
|
rer_emit_read(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
if(local)
|
USED(a);
|
||||||
if(sym->ref)
|
USED(out);
|
||||||
printf("STH2kr #%04x ADD2 STA2 ", sym->ref);
|
|
||||||
else
|
|
||||||
printf("STH2kr STA2 ");
|
|
||||||
else
|
|
||||||
printf(";%.*s STA2 ", sym->name_length, sym->name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_write()
|
rer_emit_open(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_read()
|
rer_emit_close(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_open()
|
rer_emit_stat(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_close()
|
rer_emit_end_statement(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
StrBuf_append(a, out, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_stat()
|
rer_emit_set_value(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_end_statement()
|
rer_emit_plex_def(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("\n");
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_set_value()
|
rer_emit_cast_int_to_nat(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
StrBuf_append(a, out, "int_to_nat_ ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_plex_def()
|
rer_emit_cast_int_to_real(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
StrBuf_append(a, out, "int_to_real_ ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_cast_int_to_nat()
|
rer_emit_cast_int_to_str(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("int_to_nat_ ");
|
StrBuf_append(a, out, "int_to_str_ ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_cast_int_to_real()
|
rer_emit_cast_nat_to_int(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("int_to_real_ ");
|
StrBuf_append(a, out, "nat_to_int_ ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_cast_int_to_str()
|
rer_emit_cast_nat_to_real(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("int_to_str_ ");
|
StrBuf_append(a, out, "nat_to_real_ ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_cast_nat_to_int()
|
rer_emit_cast_nat_to_str(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("nat_to_int_ ");
|
StrBuf_append(a, out, "nat_to_str_ ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_cast_nat_to_real()
|
rer_emit_cast_real_to_int(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("nat_to_real_ ");
|
StrBuf_append(a, out, "real_to_int_ ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_cast_nat_to_str()
|
rer_emit_cast_real_to_nat(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("nat_to_str_ ");
|
StrBuf_append(a, out, "real_to_nat_ ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_cast_real_to_int()
|
rer_emit_cast_real_to_str(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("real_to_int_ ");
|
StrBuf_append(a, out, "real_to_str_ ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_cast_real_to_nat()
|
rer_emit_strbuf_init(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("real_to_nat_ ");
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_cast_real_to_str()
|
rer_emit_strbuf_append(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("real_to_str_ ");
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_strbuf_init()
|
rer_emit_strbuf_to_str(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_strbuf_append()
|
rer_emit_arena_fn_return_plex(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_strbuf_to_str()
|
rer_emit_arena_fn_return_array(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_arena_fn_return_plex()
|
rer_emit_arena_fn_return_strbuf(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_arena_fn_return_array()
|
rer_emit_cast_str_to_int(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
|
}
|
||||||
|
void
|
||||||
|
rer_emit_cast_str_to_nat(Arena *a, List *out)
|
||||||
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
|
}
|
||||||
|
void
|
||||||
|
rer_emit_cast_str_to_real(Arena *a, List *out)
|
||||||
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_arena_fn_return_strbuf()
|
rer_emit_sll(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
StrBuf_append(a, out, "#40 SFT SFT ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_cast_str_to_int()
|
rer_emit_srl(Arena *a, List *out)
|
||||||
{
|
|
||||||
}
|
|
||||||
void
|
|
||||||
rer_emit_cast_str_to_nat()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
void
|
|
||||||
rer_emit_cast_str_to_real()
|
|
||||||
{
|
{
|
||||||
|
StrBuf_append(a, out, "SFT ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_sll()
|
rer_emit_xor(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("#40 SFT SFT ");
|
StrBuf_append(a, out, "EOR2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_srl()
|
rer_emit_mod(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("SFT ");
|
StrBuf_append(a, out, "DIV2k MUL2 SUB2 ");
|
||||||
|
}
|
||||||
|
void
|
||||||
|
rer_emit_or(Arena *a, List *out)
|
||||||
|
{
|
||||||
|
StrBuf_append(a, out, "ORA2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_xor()
|
rer_emit_and(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("EOR2 ");
|
StrBuf_append(a, out, "AND2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_mod()
|
rer_emit_print(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("DIV2k MUL2 SUB2 ");
|
StrBuf_append(a, out, "str/<print> ");
|
||||||
}
|
|
||||||
void
|
|
||||||
rer_emit_or()
|
|
||||||
{
|
|
||||||
printf("ORA2 ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_and()
|
rer_emit_if(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("AND2 ");
|
StrBuf_append(a, out, "#03 JCN !{ \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_print()
|
rer_emit_patch_if(Arena *a, List *out, i32 local_ifs)
|
||||||
{
|
{
|
||||||
printf("str/<print> ");
|
sprintf(rer_temp_strbuf, "!&if_end.%d } ", local_ifs);
|
||||||
|
StrBuf_append(a, out, rer_temp_strbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_if()
|
rer_emit_patch_if_done(Arena *a, List *out, i32 local_ifs)
|
||||||
{
|
{
|
||||||
printf("#03 JCN !{ \n");
|
sprintf(rer_temp_strbuf, "&if_end.%d \n", local_ifs);
|
||||||
|
StrBuf_append(a, out, rer_temp_strbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_patch_if(i32 local_ifs)
|
rer_emit_while(Arena *a, List *out, i32 local_whiles)
|
||||||
{
|
{
|
||||||
printf("!&if_end.%d } ", local_ifs);
|
sprintf(rer_temp_strbuf, "&while.%d ", local_whiles);
|
||||||
|
StrBuf_append(a, out, rer_temp_strbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_patch_if_done(i32 local_ifs)
|
rer_emit_while_postfix(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("&if_end.%d \n", local_ifs);
|
StrBuf_append(a, out, "#03 JCN !{ \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_while(i32 local_whiles)
|
rer_emit_patch_while(Arena *a, List *out, i32 local_whiles)
|
||||||
{
|
{
|
||||||
printf("&while.%d ", local_whiles);
|
sprintf(rer_temp_strbuf, "!&while.%d } \n", local_whiles);
|
||||||
|
StrBuf_append(a, out, rer_temp_strbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_while_postfix()
|
rer_emit_early_return(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("#03 JCN !{ \n");
|
StrBuf_append(a, out, "!&return ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_patch_while(i32 local_whiles)
|
rer_emit_halt(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("!&while.%d } \n", local_whiles);
|
StrBuf_append(a, out, "POP2r BRK ");
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
rer_emit_halt()
|
|
||||||
{
|
|
||||||
printf("POP2r BRK ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Emitter
|
Emitter
|
||||||
|
|
@ -622,7 +710,7 @@ rer_emitter()
|
||||||
rer_emit_real,
|
rer_emit_real,
|
||||||
rer_emit_byte,
|
rer_emit_byte,
|
||||||
rer_emit_str,
|
rer_emit_str,
|
||||||
rer_emit_primitive_type,
|
rer_emit_type,
|
||||||
rer_emit_array,
|
rer_emit_array,
|
||||||
rer_emit_function,
|
rer_emit_function,
|
||||||
rer_emit_plex,
|
rer_emit_plex,
|
||||||
|
|
@ -677,7 +765,7 @@ rer_emitter()
|
||||||
rer_emit_while,
|
rer_emit_while,
|
||||||
rer_emit_while_postfix,
|
rer_emit_while_postfix,
|
||||||
rer_emit_patch_while,
|
rer_emit_patch_while,
|
||||||
rer_emit_arena_fn_return,
|
rer_emit_early_return,
|
||||||
rer_emit_halt,
|
rer_emit_halt,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
454
emit/uxn/emit.c
454
emit/uxn/emit.c
|
|
@ -2,6 +2,8 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
char uxn_temp_strbuf[256];
|
||||||
|
|
||||||
#define UXN_OP_2 (1 << 5)
|
#define UXN_OP_2 (1 << 5)
|
||||||
#define UXN_OP_R (1 << 6)
|
#define UXN_OP_R (1 << 6)
|
||||||
#define UXN_OP_K (1 << 7)
|
#define UXN_OP_K (1 << 7)
|
||||||
|
|
@ -44,7 +46,7 @@ enum uxn_opcode {
|
||||||
JMI = 0x40,
|
JMI = 0x40,
|
||||||
JSI = 0x60,
|
JSI = 0x60,
|
||||||
};
|
};
|
||||||
unsigned char emit_uxn_lib_undar_tal[] = {
|
char emit_uxn_lib_undar_tal[] = {
|
||||||
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,
|
||||||
|
|
@ -562,8 +564,7 @@ unsigned char emit_uxn_lib_undar_tal[] = {
|
||||||
0x49, 0x4e, 0x43, 0x32, 0x20, 0x21, 0x2f, 0x3c, 0x70, 0x72, 0x69, 0x6e,
|
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, 0x40,
|
0x67, 0x74, 0x68, 0x5f, 0x20, 0x23, 0x30, 0x30, 0x30, 0x30, 0x0a, 0x40,
|
||||||
0x6d, 0x65, 0x6d, 0x5f, 0x20, 0x20, 0x20, 0x20
|
0x6d, 0x65, 0x6d, 0x5f, 0x20, 0x20, 0x20, 0x20};
|
||||||
};
|
|
||||||
unsigned int emit_uxn_lib_undar_tal_len = 6212;
|
unsigned int emit_uxn_lib_undar_tal_len = 6212;
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -580,111 +581,114 @@ uxn_mem(u32 a)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_prolog()
|
uxn_prolog(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
/*printf("|100\n\tLIT2r 0000 main_ POP2r BRK\n\n");*/
|
/*StrBuf_append(a, out, "|100\n\tLIT2r 0000 main_ POP2r BRK\n\n");*/
|
||||||
printf("|100\n\tLIT2r 0000\n\n");
|
StrBuf_append(a, out, "|100\n\tLIT2r 0000\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_epilogue()
|
uxn_epilogue(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
for(u32 i = 0; i < emit_uxn_lib_undar_tal_len; i++) putchar(emit_uxn_lib_undar_tal[i]);
|
StrBuf_append_exactly(a, out, emit_uxn_lib_undar_tal,
|
||||||
|
emit_uxn_lib_undar_tal_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_add()
|
uxn_emit_add(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("ADD2 ");
|
StrBuf_append(a, out, "ADD2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_sub()
|
uxn_emit_sub(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("SUB2 ");
|
StrBuf_append(a, out, "SUB2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_mul()
|
uxn_emit_mul(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("MUL2 ");
|
StrBuf_append(a, out, "MUL2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_div()
|
uxn_emit_div(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("DIV2 ");
|
StrBuf_append(a, out, "DIV2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_lt()
|
uxn_emit_lt(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("LTH2 ");
|
StrBuf_append(a, out, "LTH2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_le()
|
uxn_emit_le(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("ROT SWP LTH ?{ LTH #00 EQU JMPr } GTH JMPr ");
|
StrBuf_append(a, out, "ROT SWP LTH ?{ LTH #00 EQU JMPr } GTH JMPr ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_gt()
|
uxn_emit_gt(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("GTH2 ");
|
StrBuf_append(a, out, "GTH2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_ge()
|
uxn_emit_ge(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("ROT SWP GTH ?{ GTH #00 EQU JMPr } LTH JMPr ");
|
StrBuf_append(a, out, "ROT SWP GTH ?{ GTH #00 EQU JMPr } LTH JMPr ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_ne()
|
uxn_emit_ne(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("NEQ2 ");
|
StrBuf_append(a, out, "NEQ2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_eq()
|
uxn_emit_eq(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("EQU2 ");
|
StrBuf_append(a, out, "EQU2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_false()
|
uxn_emit_false(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("#0000 ");
|
StrBuf_append(a, out, "#0000 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_true()
|
uxn_emit_true(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("#0001 ");
|
StrBuf_append(a, out, "#0001 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_nil()
|
uxn_emit_nil(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("#0000 ");
|
StrBuf_append(a, out, "#0000 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_neg()
|
uxn_emit_neg(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("#0000 SUB2 ");
|
StrBuf_append(a, out, "#0000 SUB2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_not()
|
uxn_emit_not(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("#0000 EQU2 ");
|
StrBuf_append(a, out, "#0000 EQU2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_void()
|
uxn_emit_void(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32
|
u32
|
||||||
|
|
@ -725,60 +729,71 @@ uxn_get_size(SymbolType t)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_type(Symbol *sym, bool local)
|
uxn_emit_type(Arena *a, List *out, Symbol *sym, bool local)
|
||||||
{
|
{
|
||||||
if(local)
|
if(local) {
|
||||||
if(sym->ref)
|
if(sym->ref) {
|
||||||
printf("\tSTH2kr #%04x ADD2 LDA2\n", sym->ref);
|
sprintf(uxn_temp_strbuf, "\tSTH2kr #%04x ADD2 LDA2\n", sym->ref);
|
||||||
else
|
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||||
printf("\tSTH2kr LDA2\n");
|
} else {
|
||||||
else
|
sprintf(uxn_temp_strbuf, "\tSTH2kr LDA2\n");
|
||||||
printf("!{ @%.*s $%d } ", sym->name_length, sym->name, uxn_get_size(sym->type));
|
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sprintf(uxn_temp_strbuf, "!{ @%.*s $%d } ", sym->name_length, sym->name,
|
||||||
|
uxn_get_size(sym->type));
|
||||||
|
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_int(const char *str, i32 length)
|
uxn_emit_int(Arena *a, List *out, const char *str, i32 length)
|
||||||
{
|
{
|
||||||
i32 i = (i32)strtol(str, nil, 10);
|
i32 i = (i32)strtol(str, nil, 10);
|
||||||
printf("#%04x ", i);
|
sprintf(uxn_temp_strbuf, "#%04x ", i);
|
||||||
|
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||||
USED(length);
|
USED(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_nat(const char *str, i32 length)
|
uxn_emit_nat(Arena *a, List *out, const char *str, i32 length)
|
||||||
{
|
{
|
||||||
u32 i = (u32)strtol(str, nil, 10);
|
u32 i = (u32)strtol(str, nil, 10);
|
||||||
printf("#%04x ", i);
|
sprintf(uxn_temp_strbuf, "#%04x ", i);
|
||||||
|
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||||
USED(length);
|
USED(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_real(const char *str, i32 length)
|
uxn_emit_real(Arena *a, List *out, const char *str, i32 length)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
USED(str);
|
USED(str);
|
||||||
USED(length);
|
USED(length);
|
||||||
/// TODO: implement this
|
/// TODO: implement this
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_byte(const char *str, i32 length)
|
uxn_emit_byte(Arena *a, List *out, const char *str, i32 length)
|
||||||
{
|
{
|
||||||
u8 i = (u8)strtol(str, nil, 10);
|
u8 i = (u8)strtol(str, nil, 10);
|
||||||
printf("#%04x ", i);
|
sprintf(uxn_temp_strbuf, "#%04x ", i);
|
||||||
|
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||||
USED(length);
|
USED(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_str(const char *str, i32 length)
|
uxn_emit_str(Arena *a, List *out, const char *str, i32 length)
|
||||||
{
|
{
|
||||||
/* set a pointer to the string literal and then jump over it */
|
/* set a pointer to the string literal and then jump over it */
|
||||||
printf(";{ #0002 ADD2 } !{ ");
|
StrBuf_append(a, out, ";{ #0002 ADD2 } !{ ");
|
||||||
|
|
||||||
i32 i = 1;
|
i32 i = 1;
|
||||||
while (i < length - 1) {
|
while(i < length - 1) {
|
||||||
char c = str[i++];
|
char c = str[i++];
|
||||||
if (c == '\\' && i < length - 1) {
|
if(c == '\\' && i < length - 1) {
|
||||||
switch (str[i++]) {
|
switch(str[i++]) {
|
||||||
case 'n':
|
case 'n':
|
||||||
c = '\n';
|
c = '\n';
|
||||||
break;
|
break;
|
||||||
|
|
@ -796,356 +811,435 @@ uxn_emit_str(const char *str, i32 length)
|
||||||
i--; /* Rewind for unknown escapes */
|
i--; /* Rewind for unknown escapes */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("%02x ", c);
|
sprintf(uxn_temp_strbuf, "%02x ", c);
|
||||||
|
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("00 } ");
|
StrBuf_append(a, out, "00 } ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_constant(Symbol *sym, bool local)
|
uxn_emit_constant(Arena *a, List *out, Symbol *sym, bool local)
|
||||||
{
|
{
|
||||||
if(local)
|
if(local) {
|
||||||
if(sym->ref)
|
if(sym->ref) {
|
||||||
printf("\tSTH2kr #%04x ADD2 STA2\n", sym->ref);
|
sprintf(uxn_temp_strbuf, "\tSTH2kr #%04x ADD2 STA2\n", sym->ref);
|
||||||
else
|
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||||
printf("\tSTH2kr STA2\n");
|
} else {
|
||||||
else
|
sprintf(uxn_temp_strbuf, "\tSTH2kr STA2\n");
|
||||||
printf(";%.*s STA2 ", sym->name_length, sym->name);
|
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sprintf(uxn_temp_strbuf, ";%.*s STA2 ", sym->name_length, sym->name);
|
||||||
|
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_array()
|
uxn_emit_array(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
fn_loop_emit_args(void *data)
|
fn_loop_emit_args(Arena *a, List *out, void *data)
|
||||||
{
|
{
|
||||||
Symbol *sym = ((Symbol *)data);
|
Symbol *sym = ((Symbol *)data);
|
||||||
|
|
||||||
if(sym->ref)
|
if(sym->ref) {
|
||||||
printf("\tSTH2kr #%04x ADD2 STA2\n", sym->ref);
|
sprintf(uxn_temp_strbuf, "\tSTH2kr #%04x ADD2 STA2\n", sym->ref);
|
||||||
else
|
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||||
printf("\tSTH2kr STA2\n");
|
} else {
|
||||||
|
sprintf(uxn_temp_strbuf, "\tSTH2kr STA2\n");
|
||||||
|
|
||||||
|
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
fn_loop_emit_args_comment(void *data)
|
fn_loop_emit_args_comment(Arena *a, List *out, void *data)
|
||||||
{
|
{
|
||||||
Symbol *sym = ((Symbol *)data);
|
Symbol *sym = ((Symbol *)data);
|
||||||
printf("%.*s ", sym->name_length, sym->name);
|
sprintf(uxn_temp_strbuf, "%.*s ", sym->name_length, sym->name);
|
||||||
|
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_function(Symbol *sym)
|
uxn_emit_function(Arena *a, List *out, Symbol *sym)
|
||||||
{
|
{
|
||||||
printf("@%.*s_ ( ", sym->name_length, sym->name);
|
sprintf(uxn_temp_strbuf, "@%.*s_ ( ", sym->name_length, sym->name);
|
||||||
List_map(sym->args, fn_loop_emit_args_comment);
|
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||||
printf(" -- ");
|
List_map_out(a, out, sym->args, fn_loop_emit_args_comment);
|
||||||
|
sprintf(uxn_temp_strbuf, " -- ");
|
||||||
|
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||||
if(sym->secondary_type != SYMBOL_UNDEFINED &&
|
if(sym->secondary_type != SYMBOL_UNDEFINED &&
|
||||||
sym->secondary_type != SYMBOL_VOID)
|
sym->secondary_type != SYMBOL_VOID) {
|
||||||
printf(" res ");
|
sprintf(uxn_temp_strbuf, " res ");
|
||||||
printf(")\n");
|
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||||
if (sym->size > 0)
|
}
|
||||||
printf("\tOVR2r LIT2r %04x SUB2r\n", sym->size);
|
sprintf(uxn_temp_strbuf, ")\n");
|
||||||
List_map(sym->args, fn_loop_emit_args);
|
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||||
printf("\n");
|
if(sym->size > 0) {
|
||||||
|
sprintf(uxn_temp_strbuf, "\tOVR2r LIT2r %04x SUB2r\n", sym->size);
|
||||||
|
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||||
|
}
|
||||||
|
List_map_out(a, out, sym->args, fn_loop_emit_args);
|
||||||
|
StrBuf_append(a, out, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_arena_fn_return()
|
uxn_emit_arena_fn_return(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("\t&return\n\t\tPOP2r JMP2r\n\n");
|
StrBuf_append(a, out, "\t&return\n\t\tPOP2r JMP2r\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_arena_fn_call(Symbol *sym)
|
uxn_emit_arena_fn_call(Arena *a, List *out, Symbol *sym)
|
||||||
{
|
{
|
||||||
printf("%.*s_ ", sym->name_length, sym->name);
|
sprintf(uxn_temp_strbuf, "%.*s_ ", sym->name_length, sym->name);
|
||||||
|
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_plex()
|
uxn_emit_plex(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_method()
|
uxn_emit_method(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_trait()
|
uxn_emit_trait(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_const()
|
uxn_emit_const(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_open_paren()
|
uxn_emit_open_paren(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_close_paren()
|
uxn_emit_close_paren(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_variable(Symbol *sym, bool local)
|
uxn_emit_variable(Arena *a, List *out, Symbol *sym, bool local)
|
||||||
{
|
{
|
||||||
if(local)
|
if(local) {
|
||||||
if(sym->ref)
|
if(sym->ref) {
|
||||||
printf("\tSTH2kr #%04x ADD2 LDA2 ", sym->ref);
|
sprintf(uxn_temp_strbuf, "\tSTH2kr #%04x ADD2 LDA2 ", sym->ref);
|
||||||
else
|
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||||
printf("\tSTH2kr LDA2 ");
|
} else {
|
||||||
else
|
sprintf(uxn_temp_strbuf, "\tSTH2kr LDA2 ");
|
||||||
printf(";%.*s LDA2 ", sym->name_length, sym->name);
|
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sprintf(uxn_temp_strbuf, ";%.*s LDA2 ", sym->name_length, sym->name);
|
||||||
|
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_set_variable(Symbol *sym, bool local)
|
uxn_emit_set_variable(Arena *a, List *out, Symbol *sym, bool local)
|
||||||
{
|
{
|
||||||
if(local)
|
if(local) {
|
||||||
if(sym->ref)
|
if(sym->ref) {
|
||||||
printf("\tSTH2kr #%04x ADD2 STA2 ", sym->ref);
|
sprintf(uxn_temp_strbuf, "\tSTH2kr #%04x ADD2 STA2 ", sym->ref);
|
||||||
else
|
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||||
printf("\tSTH2kr STA2 ");
|
} else {
|
||||||
else
|
sprintf(uxn_temp_strbuf, "\tSTH2kr STA2 ");
|
||||||
printf(";%.*s STA2 ", sym->name_length, sym->name);
|
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sprintf(uxn_temp_strbuf, ";%.*s STA2 ", sym->name_length, sym->name);
|
||||||
|
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_write()
|
uxn_emit_write(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_read()
|
uxn_emit_read(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_open()
|
uxn_emit_open(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_close()
|
uxn_emit_close(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_stat()
|
uxn_emit_stat(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_end_statement()
|
uxn_emit_end_statement(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("\n");
|
StrBuf_append(a, out, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_set_value()
|
uxn_emit_set_value(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_plex_def()
|
uxn_emit_plex_def(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_cast_int_to_nat()
|
uxn_emit_cast_int_to_nat(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("int_to_nat_ ");
|
StrBuf_append(a, out, "int_to_nat_ ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_cast_int_to_real()
|
uxn_emit_cast_int_to_real(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("int_to_real_ ");
|
StrBuf_append(a, out, "int_to_real_ ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_cast_int_to_str()
|
uxn_emit_cast_int_to_str(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("int_to_str_ ");
|
StrBuf_append(a, out, "int_to_str_ ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_cast_nat_to_int()
|
uxn_emit_cast_nat_to_int(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("nat_to_int_ ");
|
StrBuf_append(a, out, "nat_to_int_ ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_cast_nat_to_real()
|
uxn_emit_cast_nat_to_real(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("nat_to_real_ ");
|
StrBuf_append(a, out, "nat_to_real_ ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_cast_nat_to_str()
|
uxn_emit_cast_nat_to_str(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("nat_to_str_ ");
|
StrBuf_append(a, out, "nat_to_str_ ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_cast_real_to_int()
|
uxn_emit_cast_real_to_int(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("real_to_int_ ");
|
StrBuf_append(a, out, "real_to_int_ ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_cast_real_to_nat()
|
uxn_emit_cast_real_to_nat(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("real_to_nat_ ");
|
StrBuf_append(a, out, "real_to_nat_ ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_cast_real_to_str()
|
uxn_emit_cast_real_to_str(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("real_to_str_ ");
|
StrBuf_append(a, out, "real_to_str_ ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_strbuf_init()
|
uxn_emit_strbuf_init(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_strbuf_append()
|
uxn_emit_strbuf_append(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_strbuf_to_str()
|
uxn_emit_strbuf_to_str(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_arena_fn_return_plex()
|
uxn_emit_arena_fn_return_plex(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_arena_fn_return_array()
|
uxn_emit_arena_fn_return_array(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_arena_fn_return_strbuf()
|
uxn_emit_arena_fn_return_strbuf(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_cast_str_to_int()
|
uxn_emit_cast_str_to_int(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
uxn_emit_cast_str_to_nat()
|
uxn_emit_cast_str_to_nat(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
uxn_emit_cast_str_to_real()
|
uxn_emit_cast_str_to_real(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
|
USED(a);
|
||||||
|
USED(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_sll()
|
uxn_emit_sll(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("#40 SFT SFT ");
|
StrBuf_append(a, out, "#40 SFT SFT ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_srl()
|
uxn_emit_srl(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("SFT ");
|
StrBuf_append(a, out, "SFT ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_xor()
|
uxn_emit_xor(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("EOR2 ");
|
StrBuf_append(a, out, "EOR2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_mod()
|
uxn_emit_mod(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("DIV2k MUL2 SUB2 ");
|
StrBuf_append(a, out, "DIV2k MUL2 SUB2 ");
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
uxn_emit_or()
|
uxn_emit_or(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("ORA2 ");
|
StrBuf_append(a, out, "ORA2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_and()
|
uxn_emit_and(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("AND2 ");
|
StrBuf_append(a, out, "AND2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_print()
|
uxn_emit_print(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("str/<print> ");
|
StrBuf_append(a, out, "str/<print> ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_if()
|
uxn_emit_if(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("#03 JCN !{ \n");
|
StrBuf_append(a, out, "#03 JCN !{ \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_patch_if(i32 local_ifs)
|
uxn_emit_patch_if(Arena *a, List *out, i32 local_ifs)
|
||||||
{
|
{
|
||||||
printf("!&if_end.%d } ", local_ifs);
|
sprintf(uxn_temp_strbuf, "!&if_end.%d } ", local_ifs);
|
||||||
|
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_patch_if_done(i32 local_ifs)
|
uxn_emit_patch_if_done(Arena *a, List *out, i32 local_ifs)
|
||||||
{
|
{
|
||||||
printf("&if_end.%d \n", local_ifs);
|
sprintf(uxn_temp_strbuf, "&if_end.%d \n", local_ifs);
|
||||||
|
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_while(i32 local_whiles)
|
uxn_emit_while(Arena *a, List *out, i32 local_whiles)
|
||||||
{
|
{
|
||||||
printf("&while.%d ", local_whiles);
|
sprintf(uxn_temp_strbuf, "&while.%d ", local_whiles);
|
||||||
|
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_while_postfix()
|
uxn_emit_while_postfix(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("#03 JCN !{ \n");
|
StrBuf_append(a, out, "#03 JCN !{ \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_patch_while(i32 local_whiles)
|
uxn_emit_patch_while(Arena *a, List *out, i32 local_whiles)
|
||||||
{
|
{
|
||||||
printf("!&while.%d } \n", local_whiles);
|
sprintf(uxn_temp_strbuf, "!&while.%d } \n", local_whiles);
|
||||||
|
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_early_return()
|
uxn_emit_early_return(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("!&return ");
|
StrBuf_append(a, out, "!&return ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_halt()
|
uxn_emit_halt(Arena *a, List *out)
|
||||||
{
|
{
|
||||||
printf("POP2r BRK ");
|
StrBuf_append(a, out, "POP2r BRK ");
|
||||||
}
|
}
|
||||||
|
|
||||||
Emitter
|
Emitter
|
||||||
|
|
|
||||||
13
list.c
13
list.c
|
|
@ -59,6 +59,19 @@ List_map(List *list, list_iter_fn func)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
List_map_out(Arena *a, List *out, List *list, list_iter_out_fn func)
|
||||||
|
{
|
||||||
|
Node *curr;
|
||||||
|
if(!list || !func) return;
|
||||||
|
|
||||||
|
curr = list->head;
|
||||||
|
while(curr) {
|
||||||
|
if(!func(a, out, node_value(curr))) break;
|
||||||
|
curr = curr->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
List_get(List *list, u32 index)
|
List_get(List *list, u32 index)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
2
list.h
2
list.h
|
|
@ -18,11 +18,13 @@ struct list_s {
|
||||||
|
|
||||||
typedef bool (*compare_fn)(void *data, void *target);
|
typedef bool (*compare_fn)(void *data, void *target);
|
||||||
typedef bool (*list_iter_fn)(void *data);
|
typedef bool (*list_iter_fn)(void *data);
|
||||||
|
typedef bool (*list_iter_out_fn)(Arena *a, List *out, void *data);
|
||||||
|
|
||||||
List *List_init(Arena *arena);
|
List *List_init(Arena *arena);
|
||||||
void *node_value(Node *n);
|
void *node_value(Node *n);
|
||||||
void *List_push(Arena *arena, List *list, void *data, u32 data_size);
|
void *List_push(Arena *arena, List *list, void *data, u32 data_size);
|
||||||
void List_map(List *list, list_iter_fn func);
|
void List_map(List *list, list_iter_fn func);
|
||||||
|
void List_map_out(Arena *a, List *out, List *list, list_iter_out_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);
|
||||||
|
|
|
||||||
16
strbuf.c
16
strbuf.c
|
|
@ -1,9 +1,9 @@
|
||||||
#include "strbuf.h"
|
#include "strbuf.h"
|
||||||
|
|
||||||
StrBuf *
|
List *
|
||||||
StrBuf_init(Arena *a)
|
StrBuf_init(Arena *a)
|
||||||
{
|
{
|
||||||
StrBuf *l = (StrBuf*)aalloc(a, sizeof(StrBuf));
|
List *l = (List*)aalloc(a, sizeof(List));
|
||||||
if (!l) return nil;
|
if (!l) return nil;
|
||||||
|
|
||||||
l->head = nil;
|
l->head = nil;
|
||||||
|
|
@ -14,10 +14,8 @@ StrBuf_init(Arena *a)
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
StrBuf_append(Arena *a, StrBuf *buf, char *str)
|
StrBuf_append_exactly(Arena *a, List *buf, char *str, u32 length)
|
||||||
{
|
{
|
||||||
u32 length = slen(str);
|
|
||||||
|
|
||||||
void *dest;
|
void *dest;
|
||||||
void *ptr = aalloc(a, sizeof(Node) + length);
|
void *ptr = aalloc(a, sizeof(Node) + length);
|
||||||
Node *node = (Node *)ptr;
|
Node *node = (Node *)ptr;
|
||||||
|
|
@ -44,8 +42,14 @@ StrBuf_append(Arena *a, StrBuf *buf, char *str)
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
StrBuf_append(Arena *a, List *buf, char *str)
|
||||||
|
{
|
||||||
|
return StrBuf_append_exactly(a, buf, str, slen(str));
|
||||||
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
StrBuf_toS(Arena *a, StrBuf *buf, u32 *out_length)
|
StrBuf_toS(Arena *a, List *buf, u32 *out_length)
|
||||||
{
|
{
|
||||||
Node *curr;
|
Node *curr;
|
||||||
char *tmp_str;
|
char *tmp_str;
|
||||||
|
|
|
||||||
14
strbuf.h
14
strbuf.h
|
|
@ -3,15 +3,9 @@
|
||||||
|
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
|
|
||||||
typedef struct strbuf_s StrBuf;
|
List *StrBuf_init(Arena *a);
|
||||||
struct strbuf_s {
|
void *StrBuf_append(Arena *a, List *buf, char *str);
|
||||||
Node *head;
|
void *StrBuf_append_exactly(Arena *a, List *buf, char *str, u32 length);
|
||||||
Node *tail;
|
char *StrBuf_toS(Arena *a, List *buf, u32 *out_length);
|
||||||
u32 count;
|
|
||||||
};
|
|
||||||
|
|
||||||
StrBuf *StrBuf_init(Arena *a);
|
|
||||||
void *StrBuf_append(Arena *a, StrBuf *buf, char *str);
|
|
||||||
char *StrBuf_toS(Arena *a, StrBuf *buf, u32 *out_length);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
Loading…
Reference in New Issue