Change to output a string buffer instead of raw printf

This commit is contained in:
zongor 2026-06-28 14:01:13 -07:00
parent 1ec9f7a2d1
commit 974d282d7a
10 changed files with 1270 additions and 1038 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)
@ -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
@ -371,6 +373,20 @@ variable_declaration(Symbol *def)
while(!check(TOKEN_RBRACKET)) {
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) {
@ -383,7 +399,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 +416,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 +437,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 +494,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 +531,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 +555,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 +575,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 +594,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 +613,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 +648,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 +658,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 +695,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 +714,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 +723,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 +750,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 +759,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 +787,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 +911,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

11
emit.h
View File

@ -2,15 +2,16 @@
#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 (*I32ArgEmit)(Arena *a, List *out, i32 val);
typedef struct emitter_s Emitter;
struct emitter_s {

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