Compare commits

..

2 Commits

Author SHA1 Message Date
zongor f8008e81d5 WIP more array stuff 2026-06-28 15:09:48 -07:00
zongor 974d282d7a Change to output a string buffer instead of raw printf 2026-06-28 14:01:13 -07:00
10 changed files with 1404 additions and 1040 deletions

View File

@ -1,6 +1,7 @@
#include "../../compiler.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static char *
readFile(const char *path)
@ -39,7 +40,7 @@ print_help()
"output, currently Uxn tal code and Reality Engine rom.\n\n");
}
#define MEM_SIZE 64000
#define MEM_SIZE (1 << 16)
int
main(int argc, char **argv)
@ -67,10 +68,28 @@ main(int argc, char **argv)
u8 tape[MEM_SIZE];
Arena a = {tape, 0, MEM_SIZE};
List *code = List_init(&a);
List *memory = List_init(&a);
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);
printf("\n");
return EXIT_SUCCESS;
}

View File

@ -8,6 +8,8 @@
Emitter emitter = {0};
Parser parser = {0};
Arena *arena;
List *code;
List *memory;
/****************************************************
* Scope
@ -359,6 +361,20 @@ ParseRule *get_rule(TokenType type);
void parse_precedence(Precedence precedence);
/**
FIXME: we need to move the string to be on the heap instead of the stack
so we need special handling in variable_dec
During the first pass we need to append the string label @variable
and then the hexed out literal.
every time we reference the string we should reference the global ptr.
If the string gets appended then we should copy and use the local varaiable
but for string conts or array conts we should use the global ref '@'
*/
u32
variable_declaration(Symbol *def)
{
@ -366,11 +382,33 @@ variable_declaration(Symbol *def)
TokenType tt = parser.previous.type;
SymbolType st = token_type_to_sym_type(tt);
Symbol *variable;
List *array_literal;
if (parser.current.type == TOKEN_LBRACE) {
while(!check(TOKEN_RBRACKET)) {
advance();
}
variable = scope_get_symbol(parser.current_scope,
parser.previous.start,
parser.previous.length);
if (match(TOKEN_EQ)) {
expect(TOKEN_LBRACKET);
while (!match(TOKEN_RBRACKET)) {
StrBuf_append_exactly(arena, array_literal,
(char*)parser.previous.start,
parser.previous.length);
if(match(TOKEN_RBRACKET)) break;
expect(TOKEN_COMMA);
}
}
expect(TOKEN_SEMICOLON);
emitter.emit_array(arena, memory, variable, array_literal);
return variable->size;
}
if(st != SYMBOL_UNDEFINED) {
@ -383,7 +421,7 @@ variable_declaration(Symbol *def)
if(def) {
List_push(arena, def->args, variable, sizeof(Symbol));
} else {
emitter.emit_type(variable, parser.depth);
emitter.emit_type(arena, code, variable, parser.depth);
parser.current_type = st;
}
} else {
@ -400,13 +438,13 @@ variable_declaration(Symbol *def)
if(parser.pass == 0) return size;
if(match(TOKEN_EQ)) {
emitter.emit_set_value();
emitter.emit_set_value(arena, code);
expression();
emitter.emit_constant(variable, parser.depth);
emitter.emit_constant(arena, code, variable, parser.depth);
}
consume(TOKEN_SEMICOLON);
emitter.emit_end_statement();
emitter.emit_end_statement(arena, code);
parser.current_type = SYMBOL_UNDEFINED;
return size;
}
@ -421,52 +459,52 @@ binary()
switch(operatorType) {
case TOKEN_BANG_EQ:
emitter.emit_ne();
emitter.emit_ne(arena, code);
break;
case TOKEN_EQ_EQ:
emitter.emit_eq();
emitter.emit_eq(arena, code);
break;
case TOKEN_GT:
emitter.emit_gt();
emitter.emit_gt(arena, code);
break;
case TOKEN_GTE:
emitter.emit_ge();
emitter.emit_ge(arena, code);
break;
case TOKEN_LT:
emitter.emit_lt();
emitter.emit_lt(arena, code);
break;
case TOKEN_LTE:
emitter.emit_le();
emitter.emit_le(arena, code);
break;
case TOKEN_PLUS:
emitter.emit_add();
emitter.emit_add(arena, code);
break;
case TOKEN_MINUS:
emitter.emit_sub();
emitter.emit_sub(arena, code);
break;
case TOKEN_STAR:
emitter.emit_mul();
emitter.emit_mul(arena, code);
break;
case TOKEN_SLASH:
emitter.emit_div();
emitter.emit_div(arena, code);
break;
case TOKEN_OPERATOR_AND:
emitter.emit_and();
emitter.emit_and(arena, code);
break;
case TOKEN_OPERATOR_OR:
emitter.emit_or();
emitter.emit_or(arena, code);
break;
case TOKEN_OPERATOR_XOR:
emitter.emit_xor();
emitter.emit_xor(arena, code);
break;
case TOKEN_OPERATOR_MOD:
emitter.emit_mod();
emitter.emit_mod(arena, code);
break;
case TOKEN_SLL:
emitter.emit_sll();
emitter.emit_sll(arena, code);
break;
case TOKEN_SRL:
emitter.emit_srl();
emitter.emit_srl(arena, code);
break;
default:
return;
@ -478,13 +516,13 @@ literal()
{
switch(parser.previous.type) {
case TOKEN_KEYWORD_FALSE:
emitter.emit_false();
emitter.emit_false(arena, code);
break;
case TOKEN_KEYWORD_TRUE:
emitter.emit_true();
emitter.emit_true(arena, code);
break;
case TOKEN_KEYWORD_NIL:
emitter.emit_nil();
emitter.emit_nil(arena, code);
break;
default:
return;
@ -515,9 +553,9 @@ variable()
parser.current_type = sym->type;
if(match(TOKEN_EQ)) {
expression();
emitter.emit_set_variable(sym, sym->scope);
emitter.emit_set_variable(arena, code, sym, sym->scope);
} else {
emitter.emit_variable(sym, sym->scope);
emitter.emit_variable(arena, code, sym, sym->scope);
}
}
@ -539,15 +577,15 @@ cast_type()
case SYMBOL_INT: {
switch(cast_type) {
case TOKEN_TYPE_NAT: {
emitter.emit_cast_int_to_nat();
emitter.emit_cast_int_to_nat(arena, code);
break;
}
case TOKEN_TYPE_REAL: {
emitter.emit_cast_int_to_real();
emitter.emit_cast_int_to_real(arena, code);
break;
}
case TOKEN_TYPE_STR: {
emitter.emit_cast_int_to_str();
emitter.emit_cast_int_to_str(arena, code);
break;
}
default:
@ -559,15 +597,15 @@ cast_type()
case SYMBOL_NAT: {
switch(cast_type) {
case TOKEN_TYPE_INT: {
emitter.emit_cast_nat_to_int();
emitter.emit_cast_nat_to_int(arena, code);
break;
}
case TOKEN_TYPE_REAL: {
emitter.emit_cast_nat_to_real();
emitter.emit_cast_nat_to_real(arena, code);
break;
}
case TOKEN_TYPE_STR: {
emitter.emit_cast_nat_to_str();
emitter.emit_cast_nat_to_str(arena, code);
break;
}
default:
@ -578,15 +616,15 @@ cast_type()
case SYMBOL_REAL: {
switch(cast_type) {
case TOKEN_TYPE_NAT: {
emitter.emit_cast_real_to_nat();
emitter.emit_cast_real_to_nat(arena, code);
break;
}
case TOKEN_TYPE_INT: {
emitter.emit_cast_real_to_int();
emitter.emit_cast_real_to_int(arena, code);
break;
}
case TOKEN_TYPE_STR: {
emitter.emit_cast_real_to_str();
emitter.emit_cast_real_to_str(arena, code);
break;
}
default:
@ -597,15 +635,15 @@ cast_type()
case SYMBOL_STR: {
switch(cast_type) {
case TOKEN_TYPE_NAT: {
emitter.emit_cast_str_to_nat();
emitter.emit_cast_str_to_nat(arena, code);
break;
}
case TOKEN_TYPE_REAL: {
emitter.emit_cast_str_to_real();
emitter.emit_cast_str_to_real(arena, code);
break;
}
case TOKEN_TYPE_INT: {
emitter.emit_cast_str_to_int();
emitter.emit_cast_str_to_int(arena, code);
break;
}
default:
@ -632,8 +670,8 @@ print_statement()
{
expression();
consume(TOKEN_SEMICOLON);
emitter.emit_print();
emitter.emit_end_statement();
emitter.emit_print(arena, code);
emitter.emit_end_statement(arena, code);
}
void
@ -642,28 +680,28 @@ if_statement()
consume(TOKEN_LPAREN);
expression();
consume(TOKEN_RPAREN);
emitter.emit_if();
emitter.emit_if(arena, code);
statement();
emitter.emit_patch_if(emitter.ifs);
emitter.emit_patch_if(arena, code, emitter.ifs);
if(match(TOKEN_KEYWORD_ELSE)) {
emitter.else_if_depth++;
statement();
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
while_statement()
{
emitter.emit_while(emitter.loops);
emitter.emit_while(arena, code, emitter.loops);
consume(TOKEN_LPAREN);
expression();
consume(TOKEN_RPAREN);
emitter.emit_while_postfix();
emitter.emit_while_postfix(arena, code);
statement();
emitter.emit_patch_while(emitter.loops++);
emitter.emit_patch_while(arena, code, emitter.loops++);
}
void
@ -679,13 +717,13 @@ function()
{
Symbol *sym = scope_get_symbol(parser.current_scope, parser.previous.start,
parser.previous.length);
emitter.emit_function(sym);
emitter.emit_function(arena, code, sym);
scope_push();
while(!check(TOKEN_RPAREN)) advance();
consume(TOKEN_RPAREN);
consume(TOKEN_LBRACE);
block();
emitter.emit_arena_fn_return();
emitter.emit_arena_fn_return(arena, code);
}
void
@ -698,7 +736,7 @@ call()
}
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;
return;
}
@ -707,11 +745,11 @@ void
return_statement()
{
if(match(TOKEN_SEMICOLON)) {
emitter.emit_early_return();
emitter.emit_early_return(arena, code);
} else {
expression();
consume(TOKEN_SEMICOLON);
emitter.emit_early_return();
emitter.emit_early_return(arena, code);
}
}
@ -734,7 +772,7 @@ statement()
} else if(match(TOKEN_KEYWORD_PRINT)) {
print_statement();
} else if(match(TOKEN_KEYWORD_HALT)) {
emitter.emit_halt();
emitter.emit_halt(arena, code);
} else {
expression();
}
@ -743,24 +781,24 @@ statement()
void
grouping()
{
emitter.emit_open_paren();
emitter.emit_open_paren(arena, code);
expression();
emitter.emit_close_paren();
emitter.emit_close_paren(arena, code);
consume(TOKEN_RPAREN);
}
void
number()
{
emitter.emit_int(parser.previous.start, parser.previous.length);
emitter.emit_int(arena, code, parser.previous.start, parser.previous.length);
}
void
string()
{
emitter.emit_str(parser.previous.start, parser.previous.length);
emitter.emit_str(arena, code, parser.previous.start, parser.previous.length);
}
void
@ -771,10 +809,10 @@ unary()
switch(operatorType) {
case TOKEN_MINUS:
emitter.emit_neg();
emitter.emit_neg(arena, code);
break;
case TOKEN_BANG:
emitter.emit_not();
emitter.emit_not(arena, code);
break;
default:
return;
@ -895,18 +933,19 @@ emit_program(char *source)
init_lexer(source);
advance();
emitter.prolog();
emitter.prolog(arena, code);
emitter.epilogue(arena, memory);
while(!match(TOKEN_EOF)) declaration();
emitter.epilogue();
}
bool
compile(Arena *a, Emitter e, char *source)
compile(Arena *a, List *c, List* m, Emitter e, char *source)
{
arena = a;
emitter = e;
code = c;
memory = m;
parser.scopes = List_init(arena);
build_symbol_table(source);

View File

@ -40,17 +40,17 @@ struct parse_rule_s {
};
struct parser_s {
Symbol *call_fn;
Scope *current_scope;
u32 scope_idx;
List *scopes;
Token current;
Token previous;
SymbolType current_type;
u32 depth;
u8 pass;
Symbol *call_fn;
Scope *current_scope;
List *scopes;
Token current;
Token previous;
SymbolType current_type;
u32 scope_idx;
u32 depth;
u8 pass;
};
bool compile(Arena *a, Emitter e, char *source);
bool compile(Arena *a, List *c, List *m, Emitter e, char *source);
#endif

14
emit.h
View File

@ -2,15 +2,17 @@
#define UNDAR_EMIT_H
#include "common.h"
#include "strbuf.h"
#include "libc.h"
typedef u32 (*SymbolSize)(SymbolType t);
typedef void (*SymbolEmit)(Symbol *sym);
typedef void (*ErrorMsg)(const char *str, i32 length, i32 line);
typedef void (*VoidArgEmit)();
typedef void (*StrArgEmit)(const char *str, i32 length);
typedef void (*VarEmit)(Symbol *sym, bool local);
typedef void (*I32ArgEmit)(i32 val);
typedef void (*SymbolEmit)(Arena *a, List *out, Symbol *sym);
typedef void (*VoidArgEmit)(Arena *a, List *out);
typedef void (*StrArgEmit)(Arena *a, List *out, const char *str, i32 length);
typedef void (*VarEmit)(Arena *a, List *out, Symbol *sym, bool local);
typedef void (*MultipleEmit)(Arena *a, List *out, Symbol *sym, List* in);
typedef void (*I32ArgEmit)(Arena *a, List *out, i32 val);
typedef struct emitter_s Emitter;
struct emitter_s {
@ -42,7 +44,7 @@ struct emitter_s {
StrArgEmit emit_byte;
StrArgEmit emit_str;
VarEmit emit_type;
VoidArgEmit emit_array;
MultipleEmit emit_array;
SymbolEmit emit_function;
VoidArgEmit emit_plex;
VoidArgEmit emit_method;

View File

@ -2,11 +2,12 @@
#include <stdio.h>
#include <stdlib.h>
char rer_temp_strbuf[256];
void
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);
}
@ -17,110 +18,114 @@ rer_mem(u32 a)
}
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
rer_epilogue()
rer_epilogue(Arena *a, List *out)
{
printf("BRK\n\n");
USED(a);
USED(out);
}
void
rer_emit_add()
rer_emit_add(Arena *a, List *out)
{
printf("ADD2 ");
StrBuf_append(a, out, "ADD2 ");
}
void
rer_emit_sub()
rer_emit_sub(Arena *a, List *out)
{
printf("SUB2 ");
StrBuf_append(a, out, "SUB2 ");
}
void
rer_emit_mul()
rer_emit_mul(Arena *a, List *out)
{
printf("MUL2 ");
StrBuf_append(a, out, "MUL2 ");
}
void
rer_emit_div()
rer_emit_div(Arena *a, List *out)
{
printf("DIV2 ");
StrBuf_append(a, out, "DIV2 ");
}
void
rer_emit_lt()
rer_emit_lt(Arena *a, List *out)
{
printf("LTH2 ");
StrBuf_append(a, out, "LTH2 ");
}
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
rer_emit_gt()
rer_emit_gt(Arena *a, List *out)
{
printf("GTH2 ");
StrBuf_append(a, out, "GTH2 ");
}
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
rer_emit_ne()
rer_emit_ne(Arena *a, List *out)
{
printf("NEQ2 ");
StrBuf_append(a, out, "NEQ2 ");
}
void
rer_emit_eq()
rer_emit_eq(Arena *a, List *out)
{
printf("EQU2 ");
StrBuf_append(a, out, "EQU2 ");
}
void
rer_emit_false()
rer_emit_false(Arena *a, List *out)
{
printf("#0000 ");
StrBuf_append(a, out, "#0000 ");
}
void
rer_emit_true()
rer_emit_true(Arena *a, List *out)
{
printf("#0001 ");
StrBuf_append(a, out, "#0001 ");
}
void
rer_emit_nil()
rer_emit_nil(Arena *a, List *out)
{
printf("#0000 ");
StrBuf_append(a, out, "#0000 ");
}
void
rer_emit_neg()
rer_emit_neg(Arena *a, List *out)
{
printf("#0000 SUB2 ");
StrBuf_append(a, out, "#0000 SUB2 ");
}
void
rer_emit_not()
rer_emit_not(Arena *a, List *out)
{
printf("#0000 EQU2 ");
StrBuf_append(a, out, "#0000 EQU2 ");
}
void
rer_emit_void()
rer_emit_void(Arena *a, List *out)
{
USED(a);
USED(out);
}
u32
@ -161,434 +166,517 @@ rer_get_size(SymbolType t)
}
void
rer_emit_primitive_type(Symbol *sym, bool local)
rer_emit_type(Arena *a, List *out, Symbol *sym, bool local)
{
if(local)
if(sym->ref)
printf("STH2kr #%04x ADD2 STA2\n", sym->ref);
else
printf("STH2kr STA2\n");
else
switch(sym->type) {
case SYMBOL_BOOL: {
printf("!{ @%.*s $2 } ", sym->name_length, sym->name);
break;
}
case SYMBOL_BYTE: {
printf("!{ @%.*s $1 } ", sym->name_length, sym->name);
break;
}
case SYMBOL_INT: {
printf("!{ @%.*s $2 } ", sym->name_length, sym->name);
break;
}
case SYMBOL_NAT: {
printf("!{ @%.*s $2 } ", sym->name_length, sym->name);
break;
}
case SYMBOL_REAL: {
printf("!{ @%.*s $2 } ", sym->name_length, sym->name);
break;
}
case SYMBOL_STR: {
printf("!{ @%.*s $2 } ", sym->name_length, sym->name);
break;
}
case SYMBOL_U8: {
printf("!{ @%.*s $1 } ", sym->name_length, sym->name);
break;
}
case SYMBOL_I8: {
printf("!{ @%.*s $1 } ", sym->name_length, sym->name);
break;
}
case SYMBOL_I16: {
printf("!{ @%.*s $2 } ", sym->name_length, sym->name);
break;
}
case SYMBOL_U16: {
printf("!{ @%.*s $2 } ", sym->name_length, sym->name);
break;
}
case SYMBOL_I32: {
printf("!{ @%.*s $4 } ", sym->name_length, sym->name);
break;
}
case SYMBOL_U32: {
printf("!{ @%.*s $4 } ", sym->name_length, sym->name);
break;
}
case SYMBOL_F32: {
printf("!{ @%.*s $4 } ", sym->name_length, sym->name);
break;
}
default:
break;
if(local) {
if(sym->ref) {
sprintf(rer_temp_strbuf, "\tSTH2kr #%04x ADD2 LDA2\n", sym->ref);
StrBuf_append(a, out, rer_temp_strbuf);
} else {
sprintf(rer_temp_strbuf, "\tSTH2kr LDA2\n");
StrBuf_append(a, out, rer_temp_strbuf);
}
} else {
sprintf(rer_temp_strbuf, "!{ @%.*s $%d } ", sym->name_length, sym->name,
rer_get_size(sym->type));
StrBuf_append(a, out, rer_temp_strbuf);
}
}
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);
printf("#%04x ", i);
sprintf(rer_temp_strbuf, "#%04x ", i);
StrBuf_append(a, out, rer_temp_strbuf);
USED(length);
}
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);
printf("#%04x ", i);
sprintf(rer_temp_strbuf, "#%04x ", i);
StrBuf_append(a, out, rer_temp_strbuf);
USED(length);
}
void
rer_emit_real(const char *str, i32 length)
rer_emit_real(Arena *a, List *out, const char *str, i32 length)
{
USED(str);
USED(length);
USED(a);
USED(out);
/// TODO: implement this
}
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);
printf("#%04x ", i);
sprintf(rer_temp_strbuf, "#%04x ", i);
StrBuf_append(a, out, rer_temp_strbuf);
USED(length);
}
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 */
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
rer_emit_constant(Symbol *sym, bool local)
rer_emit_constant(Arena *a, List *out, Symbol *sym, bool local)
{
if(local)
if(sym->ref)
printf("\tSTH2kr #%04x ADD2 LDA2\n", sym->ref);
else
printf("\tSTH2kr LDA2\n");
else
printf(";%.*s STA2 ", sym->name_length, sym->name);
if(local) {
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);
}
} else {
sprintf(rer_temp_strbuf, ";%.*s STA2 ", sym->name_length, sym->name);
StrBuf_append(a, out, rer_temp_strbuf);
}
}
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
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
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
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
rer_emit_plex()
rer_emit_plex(Arena *a, List *out)
{
USED(a);
USED(out);
}
void
rer_emit_method()
rer_emit_method(Arena *a, List *out)
{
USED(a);
USED(out);
}
void
rer_emit_trait()
rer_emit_trait(Arena *a, List *out)
{
USED(a);
USED(out);
}
void
rer_emit_const()
rer_emit_const(Arena *a, List *out)
{
USED(a);
USED(out);
}
void
rer_emit_putchar()
rer_emit_open_paren(Arena *a, List *out)
{
printf("#18 DEO ");
USED(a);
USED(out);
}
void
rer_emit_getchar()
rer_emit_close_paren(Arena *a, List *out)
{
printf("#12 DEI ");
USED(a);
USED(out);
}
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
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
rer_emit_variable(Symbol *sym, bool local)
rer_emit_write(Arena *a, List *out)
{
if(local)
if(sym->ref)
printf("STH2kr #%04x ADD2 LDA2 ", sym->ref);
else
printf("STH2kr LDA2 ");
else
printf(";%.*s LDA2 ", sym->name_length, sym->name);
USED(a);
USED(out);
}
void
rer_emit_set_variable(Symbol *sym, bool local)
rer_emit_read(Arena *a, List *out)
{
if(local)
if(sym->ref)
printf("STH2kr #%04x ADD2 STA2 ", sym->ref);
else
printf("STH2kr STA2 ");
else
printf(";%.*s STA2 ", sym->name_length, sym->name);
USED(a);
USED(out);
}
void
rer_emit_write()
rer_emit_open(Arena *a, List *out)
{
USED(a);
USED(out);
}
void
rer_emit_read()
rer_emit_close(Arena *a, List *out)
{
USED(a);
USED(out);
}
void
rer_emit_open()
rer_emit_stat(Arena *a, List *out)
{
USED(a);
USED(out);
}
void
rer_emit_close()
rer_emit_end_statement(Arena *a, List *out)
{
StrBuf_append(a, out, "\n");
}
void
rer_emit_stat()
rer_emit_set_value(Arena *a, List *out)
{
USED(a);
USED(out);
}
void
rer_emit_end_statement()
rer_emit_plex_def(Arena *a, List *out)
{
printf("\n");
USED(a);
USED(out);
}
void
rer_emit_set_value()
rer_emit_cast_int_to_nat(Arena *a, List *out)
{
StrBuf_append(a, out, "int_to_nat_ ");
}
void
rer_emit_plex_def()
rer_emit_cast_int_to_real(Arena *a, List *out)
{
StrBuf_append(a, out, "int_to_real_ ");
}
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
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
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
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
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
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
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
rer_emit_cast_real_to_nat()
rer_emit_strbuf_init(Arena *a, List *out)
{
printf("real_to_nat_ ");
USED(a);
USED(out);
}
void
rer_emit_cast_real_to_str()
rer_emit_strbuf_append(Arena *a, List *out)
{
printf("real_to_str_ ");
USED(a);
USED(out);
}
void
rer_emit_strbuf_init()
rer_emit_strbuf_to_str(Arena *a, List *out)
{
USED(a);
USED(out);
}
void
rer_emit_strbuf_append()
rer_emit_arena_fn_return_plex(Arena *a, List *out)
{
USED(a);
USED(out);
}
void
rer_emit_strbuf_to_str()
rer_emit_arena_fn_return_array(Arena *a, List *out)
{
USED(a);
USED(out);
}
void
rer_emit_arena_fn_return_plex()
rer_emit_arena_fn_return_strbuf(Arena *a, List *out)
{
USED(a);
USED(out);
}
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
rer_emit_arena_fn_return_strbuf()
rer_emit_sll(Arena *a, List *out)
{
StrBuf_append(a, out, "#40 SFT SFT ");
}
void
rer_emit_cast_str_to_int()
{
}
void
rer_emit_cast_str_to_nat()
{
}
void
rer_emit_cast_str_to_real()
rer_emit_srl(Arena *a, List *out)
{
StrBuf_append(a, out, "SFT ");
}
void
rer_emit_sll()
rer_emit_xor(Arena *a, List *out)
{
printf("#40 SFT SFT ");
StrBuf_append(a, out, "EOR2 ");
}
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
rer_emit_xor()
rer_emit_and(Arena *a, List *out)
{
printf("EOR2 ");
StrBuf_append(a, out, "AND2 ");
}
void
rer_emit_mod()
rer_emit_print(Arena *a, List *out)
{
printf("DIV2k MUL2 SUB2 ");
}
void
rer_emit_or()
{
printf("ORA2 ");
StrBuf_append(a, out, "str/<print> ");
}
void
rer_emit_and()
rer_emit_if(Arena *a, List *out)
{
printf("AND2 ");
StrBuf_append(a, out, "#03 JCN !{ \n");
}
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
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
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
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
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
rer_emit_while_postfix()
rer_emit_early_return(Arena *a, List *out)
{
printf("#03 JCN !{ \n");
StrBuf_append(a, out, "!&return ");
}
void
rer_emit_patch_while(i32 local_whiles)
rer_emit_halt(Arena *a, List *out)
{
printf("!&while.%d } \n", local_whiles);
}
void
rer_emit_halt()
{
printf("POP2r BRK ");
StrBuf_append(a, out, "POP2r BRK ");
}
Emitter
@ -622,7 +710,7 @@ rer_emitter()
rer_emit_real,
rer_emit_byte,
rer_emit_str,
rer_emit_primitive_type,
rer_emit_type,
rer_emit_array,
rer_emit_function,
rer_emit_plex,
@ -677,7 +765,7 @@ rer_emitter()
rer_emit_while,
rer_emit_while_postfix,
rer_emit_patch_while,
rer_emit_arena_fn_return,
rer_emit_early_return,
rer_emit_halt,
};
}

File diff suppressed because it is too large Load Diff

13
list.c
View File

@ -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 *
List_get(List *list, u32 index)
{

2
list.h
View File

@ -18,11 +18,13 @@ struct list_s {
typedef bool (*compare_fn)(void *data, void *target);
typedef bool (*list_iter_fn)(void *data);
typedef bool (*list_iter_out_fn)(Arena *a, List *out, void *data);
List *List_init(Arena *arena);
void *node_value(Node *n);
void *List_push(Arena *arena, List *list, void *data, u32 data_size);
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_get(List *list, u32 index);
void List_set(List *list, u32 index, void *data, u32 size);

View File

@ -1,9 +1,9 @@
#include "strbuf.h"
StrBuf *
List *
StrBuf_init(Arena *a)
{
StrBuf *l = (StrBuf*)aalloc(a, sizeof(StrBuf));
List *l = (List*)aalloc(a, sizeof(List));
if (!l) return nil;
l->head = nil;
@ -14,10 +14,8 @@ StrBuf_init(Arena *a)
}
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 *ptr = aalloc(a, sizeof(Node) + length);
Node *node = (Node *)ptr;
@ -44,8 +42,14 @@ StrBuf_append(Arena *a, StrBuf *buf, char *str)
return dest;
}
void *
StrBuf_append(Arena *a, List *buf, char *str)
{
return StrBuf_append_exactly(a, buf, str, slen(str));
}
char *
StrBuf_toS(Arena *a, StrBuf *buf, u32 *out_length)
StrBuf_toS(Arena *a, List *buf, u32 *out_length)
{
Node *curr;
char *tmp_str;

View File

@ -3,15 +3,9 @@
#include "list.h"
typedef struct strbuf_s StrBuf;
struct strbuf_s {
Node *head;
Node *tail;
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);
List *StrBuf_init(Arena *a);
void *StrBuf_append(Arena *a, List *buf, char *str);
void *StrBuf_append_exactly(Arena *a, List *buf, char *str, u32 length);
char *StrBuf_toS(Arena *a, List *buf, u32 *out_length);
#endif