#include "../../emit.h" #include #include void rer_emit_error(const char *str, i32 length, i32 line) { fprintf(stderr, "\n===\nError at line: %d > %.*s\n===\n", line, length, str); exit(1); } void rer_mem(u32 a) { USED(a); } void rer_prolog() { printf("|100\n"); } void rer_epilogue() { printf("BRK\n\n"); } void rer_emit_add() { printf("ADD2 "); } void rer_emit_sub() { printf("SUB2 "); } void rer_emit_mul() { printf("MUL2 "); } void rer_emit_div() { printf("DIV2 "); } void rer_emit_lt() { printf("LTH2 "); } void rer_emit_le() { printf("ROT SWP LTH ?{ LTH #00 EQU JMPr } GTH JMPr "); } void rer_emit_gt() { printf("GTH2 "); } void rer_emit_ge() { printf("ROT SWP GTH ?{ GTH #00 EQU JMPr } LTH JMPr "); } void rer_emit_ne() { printf("NEQ2 "); } void rer_emit_eq() { printf("EQU2 "); } void rer_emit_false() { printf("#0000 "); } void rer_emit_true() { printf("#0001 "); } void rer_emit_nil() { printf("#0000 "); } void rer_emit_neg() { printf("#0000 SUB2 "); } void rer_emit_not() { printf("#0000 EQU2 "); } void rer_emit_void() { } u32 rer_get_size(SymbolType t) { switch(t) { case SYMBOL_BOOL: return 1; case SYMBOL_BYTE: return 1; case SYMBOL_INT: return 2; case SYMBOL_NAT: return 2; case SYMBOL_REAL: return 2; case SYMBOL_STR: return 2; case SYMBOL_U8: return 1; case SYMBOL_I8: return 1; case SYMBOL_I16: return 2; case SYMBOL_U16: return 2; case SYMBOL_I32: return 4; case SYMBOL_U32: return 4; case SYMBOL_F32: return 4; default: break; } return 0; } void rer_emit_primitive_type(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; } } void rer_emit_int(const char *str, i32 length) { i32 i = (i32)strtol(str, nil, 10); printf("#%04x ", i); USED(length); } void rer_emit_nat(const char *str, i32 length) { u32 i = (u32)strtol(str, nil, 10); printf("#%04x ", i); USED(length); } void rer_emit_real(const char *str, i32 length) { USED(str); USED(length); /// TODO: implement this } void rer_emit_byte(const char *str, i32 length) { u8 i = (u8)strtol(str, nil, 10); printf("#%04x ", i); USED(length); } void rer_emit_str(const char *str, i32 length) { /* set a pointer to the string literal and then jump over it */ printf(";{ #0002 ADD2 } !{ "); for(i32 i = 1; i < length - 1; i++) printf("%02x ", str[i]); printf("00 } "); } void rer_emit_constant(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); } void rer_emit_array() { } void rer_emit_function(Symbol *sym) { USED(sym); } void rer_emit_arena_fn_return() { printf("&return\n\t\tPOP2r JMP2r\n\n"); } void rer_emit_arena_fn_call(Symbol *sym) { USED(sym); } void rer_emit_plex() { } void rer_emit_method() { } void rer_emit_trait() { } void rer_emit_const() { } void rer_emit_putchar() { printf("#18 DEO "); } void rer_emit_getchar() { printf("#12 DEI "); } void rer_emit_open_paren() { } void rer_emit_close_paren() { } void rer_emit_variable(Symbol *sym, bool local) { 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); } void rer_emit_set_variable(Symbol *sym, bool local) { 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); } void rer_emit_write() { } void rer_emit_read() { } void rer_emit_open() { } void rer_emit_close() { } void rer_emit_stat() { } void rer_emit_end_statement() { printf("\n"); } void rer_emit_set_value() { } void rer_emit_plex_def() { } void rer_emit_cast_int_to_nat() { printf("int_to_nat_ "); } void rer_emit_cast_int_to_real() { printf("int_to_real_ "); } void rer_emit_cast_int_to_str() { printf("int_to_str_ "); } void rer_emit_cast_nat_to_int() { printf("nat_to_int_ "); } void rer_emit_cast_nat_to_real() { printf("nat_to_real_ "); } void rer_emit_cast_nat_to_str() { printf("nat_to_str_ "); } void rer_emit_cast_real_to_int() { printf("real_to_int_ "); } void rer_emit_cast_real_to_nat() { printf("real_to_nat_ "); } void rer_emit_cast_real_to_str() { printf("real_to_str_ "); } void rer_emit_strbuf_init() { } void rer_emit_strbuf_append() { } void rer_emit_strbuf_to_str() { } void rer_emit_arena_fn_return_plex() { } void rer_emit_arena_fn_return_array() { } void rer_emit_arena_fn_return_strbuf() { } void rer_emit_cast_str_to_int() { } void rer_emit_cast_str_to_nat() { } void rer_emit_cast_str_to_real() { } void rer_emit_sll() { printf("#40 SFT SFT "); } void rer_emit_srl() { printf("SFT "); } void rer_emit_xor() { printf("EOR2 "); } void rer_emit_mod() { printf("DIV2k MUL2 SUB2 "); } void rer_emit_or() { printf("ORA2 "); } void rer_emit_and() { printf("AND2 "); } void rer_emit_print() { printf("str/ "); } void rer_emit_if() { printf("#03 JCN !{ \n"); } void rer_emit_patch_if(i32 local_ifs) { printf("!&if_end.%d } ", local_ifs); } void rer_emit_patch_if_done(i32 local_ifs) { printf("&if_end.%d \n", local_ifs); } void rer_emit_while(i32 local_whiles) { printf("&while.%d ", local_whiles); } void rer_emit_while_postfix() { printf("#03 JCN !{ \n"); } void rer_emit_patch_while(i32 local_whiles) { printf("!&while.%d } \n", local_whiles); } void rer_emit_halt() { printf("POP2r BRK "); } Emitter rer_emitter() { return (Emitter){ 0, 0, 0, 0, rer_emit_error, rer_get_size, rer_prolog, rer_epilogue, rer_emit_add, rer_emit_sub, rer_emit_mul, rer_emit_div, rer_emit_lt, rer_emit_le, rer_emit_gt, rer_emit_ge, rer_emit_ne, rer_emit_eq, rer_emit_false, rer_emit_true, rer_emit_nil, rer_emit_void, rer_emit_int, rer_emit_nat, rer_emit_real, rer_emit_byte, rer_emit_str, rer_emit_primitive_type, rer_emit_array, rer_emit_function, rer_emit_plex, rer_emit_method, rer_emit_trait, rer_emit_const, rer_emit_print, rer_emit_neg, rer_emit_not, rer_emit_open_paren, rer_emit_close_paren, rer_emit_constant, rer_emit_variable, rer_emit_set_variable, rer_emit_write, rer_emit_read, rer_emit_open, rer_emit_close, rer_emit_stat, rer_emit_end_statement, rer_emit_set_value, rer_emit_plex_def, rer_emit_cast_int_to_nat, rer_emit_cast_int_to_real, rer_emit_cast_int_to_str, rer_emit_cast_nat_to_int, rer_emit_cast_nat_to_real, rer_emit_cast_nat_to_str, rer_emit_cast_real_to_int, rer_emit_cast_real_to_nat, rer_emit_cast_real_to_str, rer_emit_strbuf_init, rer_emit_strbuf_append, rer_emit_strbuf_to_str, rer_emit_arena_fn_call, rer_emit_arena_fn_return, rer_emit_arena_fn_return_plex, rer_emit_arena_fn_return_array, rer_emit_arena_fn_return_strbuf, rer_emit_cast_str_to_int, rer_emit_cast_str_to_nat, rer_emit_cast_str_to_real, rer_emit_sll, rer_emit_srl, rer_emit_xor, rer_emit_mod, rer_emit_and, rer_emit_or, rer_emit_if, rer_emit_patch_if, rer_emit_patch_if_done, rer_emit_while, rer_emit_while_postfix, rer_emit_patch_while, rer_emit_arena_fn_return, rer_emit_halt, }; }