422 lines
5.3 KiB
C
422 lines
5.3 KiB
C
#include "../../emit.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#define UXN_OP_2 (1 << 5)
|
|
#define UXN_OP_R (1 << 6)
|
|
#define UXN_OP_K (1 << 7)
|
|
|
|
enum uxn_opcode {
|
|
/* Stack I */ /* Logic */ /* Memory I */ /* Arithmetic*/
|
|
BRK = 0x00,
|
|
EQU = 0x08,
|
|
LDZ = 0x10,
|
|
ADD = 0x18,
|
|
INC = 0x01,
|
|
NEQ = 0x09,
|
|
STZ = 0x11,
|
|
SUB = 0x19,
|
|
POP = 0x02,
|
|
GTH = 0x0A,
|
|
LDR = 0x12,
|
|
MUL = 0x1A,
|
|
NIP = 0x03,
|
|
LTH = 0x0B,
|
|
STR = 0x13,
|
|
DIV = 0x1B,
|
|
/* Stack II */ /* Stash */ /* Memory II */ /* Bitwise */
|
|
SWP = 0x04,
|
|
JMP = 0x0C,
|
|
LDA = 0x14,
|
|
AND = 0x1C,
|
|
ROT = 0x05,
|
|
JCN = 0x0D,
|
|
STA = 0x15,
|
|
ORA = 0x1D,
|
|
DUP = 0x06,
|
|
JSR = 0x0E,
|
|
DEI = 0x16,
|
|
EOR = 0x1E,
|
|
OVR = 0x07,
|
|
STH = 0x0F,
|
|
DEO = 0x17,
|
|
SFT = 0x1F,
|
|
|
|
LIT = 0x80,
|
|
JCI = 0x20,
|
|
JMI = 0x40,
|
|
JSI = 0x60,
|
|
};
|
|
|
|
/*
|
|
https://rosettacode.org/wiki/Bitwise_operations#Uxntal
|
|
|
|
%not { #ff EOR }
|
|
%and { AND }
|
|
%or { ORA }
|
|
%xor { EOR }
|
|
%shl { #40 SFT SFT }
|
|
%shr { SFT }
|
|
%rol { #40 SFT #00 ROT ROT SFT2 ORA }
|
|
%ror { SWP #00 ROT SFT2 ORA }
|
|
*/
|
|
|
|
void
|
|
uxn_emit_error(const char *str, i32 length, i32 line)
|
|
{
|
|
printf("Error at line: %d > %.*s\n ", line, length, str);
|
|
exit(1);
|
|
}
|
|
|
|
void
|
|
uxn_prolog()
|
|
{
|
|
/* essentially the "main" function */
|
|
printf("|100 @on-reset ( -> )\n");
|
|
}
|
|
|
|
void
|
|
uxn_epilogue()
|
|
{
|
|
}
|
|
|
|
void
|
|
uxn_emit_add()
|
|
{
|
|
printf("ADD2 ");
|
|
}
|
|
|
|
void
|
|
uxn_emit_sub()
|
|
{
|
|
printf("SUB2 ");
|
|
}
|
|
|
|
void
|
|
uxn_emit_mul()
|
|
{
|
|
printf("MUL2 ");
|
|
}
|
|
|
|
void
|
|
uxn_emit_div()
|
|
{
|
|
printf("DIV2 ");
|
|
}
|
|
|
|
void
|
|
uxn_emit_lt()
|
|
{
|
|
printf("LTH2 ");
|
|
}
|
|
|
|
void
|
|
uxn_emit_le()
|
|
{
|
|
printf("ROT SWP LTH ?{ LTH #00 EQU JMPr } GTH JMPr ");
|
|
}
|
|
|
|
void
|
|
uxn_emit_gt()
|
|
{
|
|
printf("GTH2 ");
|
|
}
|
|
|
|
void
|
|
uxn_emit_ge()
|
|
{
|
|
printf("ROT SWP GTH ?{ GTH #00 EQU JMPr } LTH JMPr ");
|
|
}
|
|
|
|
void
|
|
uxn_emit_ne()
|
|
{
|
|
printf("NEQ2 ");
|
|
}
|
|
|
|
void
|
|
uxn_emit_eq()
|
|
{
|
|
printf("EQU2 ");
|
|
}
|
|
|
|
void
|
|
uxn_emit_false()
|
|
{
|
|
printf("#0000 ");
|
|
}
|
|
|
|
void
|
|
uxn_emit_true()
|
|
{
|
|
printf("#0001 ");
|
|
}
|
|
|
|
void
|
|
uxn_emit_nil()
|
|
{
|
|
printf("#0000 ");
|
|
}
|
|
|
|
void
|
|
uxn_emit_neg()
|
|
{
|
|
printf("#0000 SUB2 ");
|
|
}
|
|
|
|
void
|
|
uxn_emit_not()
|
|
{
|
|
printf("#FFFF EOR2 ");
|
|
}
|
|
|
|
void
|
|
uxn_emit_void()
|
|
{
|
|
}
|
|
|
|
/* @global $size */
|
|
/* &local $size */
|
|
|
|
i32
|
|
uxn_emit_bool_type(const char *str, i32 length)
|
|
{
|
|
printf("!{ @%.*s $1 } ", length, str);
|
|
return 1;
|
|
}
|
|
|
|
i32
|
|
uxn_emit_byte_type(const char *str, i32 length)
|
|
{
|
|
printf("!{ @%.*s $1 } ", length, str);
|
|
return 1;
|
|
}
|
|
|
|
i32
|
|
uxn_emit_int_type(const char *str, i32 length)
|
|
{
|
|
printf("!{ @%.*s $2 } ", length, str);
|
|
return 2;
|
|
}
|
|
|
|
i32
|
|
uxn_emit_nat_type(const char *str, i32 length)
|
|
{
|
|
printf("!{ @%.*s $2 } ", length, str);
|
|
return 2;
|
|
}
|
|
|
|
i32
|
|
uxn_emit_real_type(const char *str, i32 length)
|
|
{
|
|
printf("!{ @%.*s $2 } ", length, str);
|
|
return 2;
|
|
}
|
|
|
|
i32
|
|
uxn_emit_str_type(const char *str, i32 length)
|
|
{
|
|
printf("!{ @%.*s $2 } ", length, str);
|
|
return 2;
|
|
}
|
|
|
|
i32
|
|
uxn_emit_u8_type(const char *str, i32 length)
|
|
{
|
|
printf("!{ @%.*s $1 } ", length, str);
|
|
return 1;
|
|
}
|
|
|
|
i32
|
|
uxn_emit_i8_type(const char *str, i32 length)
|
|
{
|
|
printf("!{ @%.*s $1 } ", length, str);
|
|
return 1;
|
|
}
|
|
|
|
i32
|
|
uxn_emit_i16_type(const char *str, i32 length)
|
|
{
|
|
printf("!{ @%.*s $2 } ", length, str);
|
|
return 2;
|
|
}
|
|
|
|
i32
|
|
uxn_emit_u16_type(const char *str, i32 length)
|
|
{
|
|
printf("!{ @%.*s $2 } ", length, str);
|
|
return 2;
|
|
}
|
|
|
|
i32
|
|
uxn_emit_i32_type(const char *str, i32 length)
|
|
{
|
|
printf("!{ @%.*s $4 } ", length, str);
|
|
return 4;
|
|
}
|
|
|
|
i32
|
|
uxn_emit_u32_type(const char *str, i32 length)
|
|
{
|
|
printf("!{ @%.*s $4 } ", length, str);
|
|
return 4;
|
|
}
|
|
|
|
i32
|
|
uxn_emit_f32_type(const char *str, i32 length)
|
|
{
|
|
printf("!{ @%.*s $4 } ", length, str);
|
|
return 4;
|
|
}
|
|
|
|
void
|
|
uxn_emit_int(const char *str, i32 length)
|
|
{
|
|
i32 i = (i32)strtol(str, nil, 10);
|
|
printf("#%04x ", i);
|
|
USED(length);
|
|
}
|
|
|
|
void
|
|
uxn_emit_nat(const char *str, i32 length)
|
|
{
|
|
u32 i = (u32)strtol(str, nil, 10);
|
|
printf("#%04x ", i);
|
|
USED(length);
|
|
}
|
|
|
|
void
|
|
uxn_emit_real(const char *str, i32 length)
|
|
{
|
|
USED(str);
|
|
USED(length);
|
|
/// TODO: implement this
|
|
}
|
|
|
|
void
|
|
uxn_emit_byte(const char *str, i32 length)
|
|
{
|
|
u8 i = (u8)strtol(str, nil, 10);
|
|
printf("#%04x ", i);
|
|
USED(length);
|
|
}
|
|
|
|
void
|
|
uxn_emit_str(const char *str, i32 length)
|
|
{
|
|
printf("\"%.*s ", length, str);
|
|
}
|
|
|
|
void
|
|
uxn_emit_constant(const char *str, i32 length)
|
|
{
|
|
printf(";%.*s STA2 ", length, str);
|
|
}
|
|
|
|
void
|
|
uxn_emit_array()
|
|
{
|
|
}
|
|
|
|
void
|
|
uxn_emit_function()
|
|
{
|
|
}
|
|
|
|
void
|
|
uxn_emit_plex()
|
|
{
|
|
}
|
|
|
|
void
|
|
uxn_emit_method()
|
|
{
|
|
}
|
|
|
|
void
|
|
uxn_emit_trait()
|
|
{
|
|
}
|
|
|
|
void
|
|
uxn_emit_const()
|
|
{
|
|
}
|
|
|
|
void
|
|
uxn_emit_print()
|
|
{
|
|
printf("#18 DEO ");
|
|
}
|
|
|
|
void
|
|
uxn_emit_open_paren()
|
|
{
|
|
}
|
|
void
|
|
uxn_emit_close_paren()
|
|
{
|
|
}
|
|
|
|
void
|
|
uxn_emit_variable(Symbol *sym) {
|
|
printf(";%.*s LDA2 ", sym->name_length, sym->name);
|
|
}
|
|
|
|
Emitter
|
|
uxn_emitter()
|
|
{
|
|
return (Emitter){
|
|
POSTFIX,
|
|
BINARY,
|
|
uxn_emit_error,
|
|
uxn_prolog,
|
|
uxn_epilogue,
|
|
uxn_emit_add,
|
|
uxn_emit_sub,
|
|
uxn_emit_mul,
|
|
uxn_emit_div,
|
|
uxn_emit_lt,
|
|
uxn_emit_le,
|
|
uxn_emit_gt,
|
|
uxn_emit_ge,
|
|
uxn_emit_ne,
|
|
uxn_emit_eq,
|
|
uxn_emit_false,
|
|
uxn_emit_true,
|
|
uxn_emit_nil,
|
|
uxn_emit_void,
|
|
uxn_emit_int,
|
|
uxn_emit_nat,
|
|
uxn_emit_real,
|
|
uxn_emit_byte,
|
|
uxn_emit_str,
|
|
uxn_emit_bool_type,
|
|
uxn_emit_byte_type,
|
|
uxn_emit_int_type,
|
|
uxn_emit_nat_type,
|
|
uxn_emit_real_type,
|
|
uxn_emit_str_type,
|
|
uxn_emit_u8_type,
|
|
uxn_emit_i8_type,
|
|
uxn_emit_i16_type,
|
|
uxn_emit_u16_type,
|
|
uxn_emit_i32_type,
|
|
uxn_emit_u32_type,
|
|
uxn_emit_f32_type,
|
|
uxn_emit_array,
|
|
uxn_emit_function,
|
|
uxn_emit_plex,
|
|
uxn_emit_method,
|
|
uxn_emit_trait,
|
|
uxn_emit_const,
|
|
uxn_emit_print,
|
|
uxn_emit_neg,
|
|
uxn_emit_not,
|
|
uxn_emit_open_paren,
|
|
uxn_emit_close_paren,
|
|
uxn_emit_constant,
|
|
uxn_emit_variable,
|
|
};
|
|
}
|