Add and, or, xor, mod, sll, srl, locals, putchar, getchar, simple if (WIP)
This commit is contained in:
parent
38585bf105
commit
cf1f665e56
106
compiler.c
106
compiler.c
|
|
@ -1,9 +1,10 @@
|
||||||
#include "compiler.h"
|
#include "compiler.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "emit.h"
|
#include "emit.h"
|
||||||
|
#include "lexer.h"
|
||||||
|
|
||||||
Emitter emitter;
|
Emitter emitter = {0};
|
||||||
Parser parser;
|
Parser parser = {0};
|
||||||
Arena *arena;
|
Arena *arena;
|
||||||
|
|
||||||
/****************************************************
|
/****************************************************
|
||||||
|
|
@ -141,7 +142,7 @@ binary()
|
||||||
emitter.emit_eq();
|
emitter.emit_eq();
|
||||||
break;
|
break;
|
||||||
case TOKEN_GT:
|
case TOKEN_GT:
|
||||||
emitter.emit_ge();
|
emitter.emit_gt();
|
||||||
break;
|
break;
|
||||||
case TOKEN_GTE:
|
case TOKEN_GTE:
|
||||||
emitter.emit_ge();
|
emitter.emit_ge();
|
||||||
|
|
@ -164,6 +165,24 @@ binary()
|
||||||
case TOKEN_SLASH:
|
case TOKEN_SLASH:
|
||||||
emitter.emit_div();
|
emitter.emit_div();
|
||||||
break;
|
break;
|
||||||
|
case TOKEN_OPERATOR_AND:
|
||||||
|
emitter.emit_and();
|
||||||
|
break;
|
||||||
|
case TOKEN_OPERATOR_OR:
|
||||||
|
emitter.emit_or();
|
||||||
|
break;
|
||||||
|
case TOKEN_OPERATOR_XOR:
|
||||||
|
emitter.emit_xor();
|
||||||
|
break;
|
||||||
|
case TOKEN_OPERATOR_MOD:
|
||||||
|
emitter.emit_mod();
|
||||||
|
break;
|
||||||
|
case TOKEN_SLL:
|
||||||
|
emitter.emit_sll();
|
||||||
|
break;
|
||||||
|
case TOKEN_SRL:
|
||||||
|
emitter.emit_srl();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -204,7 +223,7 @@ variable()
|
||||||
}
|
}
|
||||||
|
|
||||||
parser.current_type = sym->type;
|
parser.current_type = sym->type;
|
||||||
emitter.emit_variable(sym);
|
emitter.emit_variable(sym, parser.depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -233,7 +252,7 @@ cast_type()
|
||||||
emitter.error("Not castable to this type", 26, parser.previous.line);
|
emitter.error("Not castable to this type", 26, parser.previous.line);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TOKEN_TYPE_NAT:{
|
case TOKEN_TYPE_NAT:{
|
||||||
switch(st) {
|
switch(st) {
|
||||||
|
|
@ -313,77 +332,77 @@ variable_declaration()
|
||||||
|
|
||||||
switch(tt) {
|
switch(tt) {
|
||||||
case TOKEN_TYPE_INT: {
|
case TOKEN_TYPE_INT: {
|
||||||
size = emitter.emit_int_type(parser.current.start, parser.current.length);
|
size = emitter.emit_int_type(parser.current.start, parser.current.length, parser.depth);
|
||||||
scope_add_symbol(parser.current.start, parser.current.length, SYMBOL_INT,
|
scope_add_symbol(parser.current.start, parser.current.length, SYMBOL_INT,
|
||||||
size);
|
size);
|
||||||
parser.current_type = SYMBOL_INT;
|
parser.current_type = SYMBOL_INT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TOKEN_TYPE_NAT: {
|
case TOKEN_TYPE_NAT: {
|
||||||
size = emitter.emit_nat_type(parser.current.start, parser.current.length);
|
size = emitter.emit_nat_type(parser.current.start, parser.current.length, parser.depth);
|
||||||
scope_add_symbol(parser.current.start, parser.current.length, SYMBOL_NAT,
|
scope_add_symbol(parser.current.start, parser.current.length, SYMBOL_NAT,
|
||||||
size);
|
size);
|
||||||
parser.current_type = SYMBOL_NAT;
|
parser.current_type = SYMBOL_NAT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TOKEN_TYPE_REAL: {
|
case TOKEN_TYPE_REAL: {
|
||||||
size = emitter.emit_real_type(parser.current.start, parser.current.length);
|
size = emitter.emit_real_type(parser.current.start, parser.current.length, parser.depth);
|
||||||
scope_add_symbol(parser.current.start, parser.current.length, SYMBOL_REAL,
|
scope_add_symbol(parser.current.start, parser.current.length, SYMBOL_REAL,
|
||||||
size);
|
size);
|
||||||
parser.current_type = SYMBOL_REAL;
|
parser.current_type = SYMBOL_REAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TOKEN_TYPE_STR: {
|
case TOKEN_TYPE_STR: {
|
||||||
size = emitter.emit_str_type(parser.current.start, parser.current.length);
|
size = emitter.emit_str_type(parser.current.start, parser.current.length, parser.depth);
|
||||||
scope_add_symbol(parser.current.start, parser.current.length, SYMBOL_STR,
|
scope_add_symbol(parser.current.start, parser.current.length, SYMBOL_STR,
|
||||||
size);
|
size);
|
||||||
parser.current_type = SYMBOL_STR;
|
parser.current_type = SYMBOL_STR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TOKEN_TYPE_BOOL: {
|
case TOKEN_TYPE_BOOL: {
|
||||||
size = emitter.emit_bool_type(parser.current.start, parser.current.length);
|
size = emitter.emit_bool_type(parser.current.start, parser.current.length, parser.depth);
|
||||||
scope_add_symbol(parser.current.start, parser.current.length, SYMBOL_BOOL,
|
scope_add_symbol(parser.current.start, parser.current.length, SYMBOL_BOOL,
|
||||||
size);
|
size);
|
||||||
parser.current_type = SYMBOL_BOOL;
|
parser.current_type = SYMBOL_BOOL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TOKEN_TYPE_BYTE: {
|
case TOKEN_TYPE_BYTE: {
|
||||||
size = emitter.emit_byte_type(parser.current.start, parser.current.length);
|
size = emitter.emit_byte_type(parser.current.start, parser.current.length, parser.depth);
|
||||||
scope_add_symbol(parser.current.start, parser.current.length, SYMBOL_U8,
|
scope_add_symbol(parser.current.start, parser.current.length, SYMBOL_U8,
|
||||||
size);
|
size);
|
||||||
parser.current_type = SYMBOL_BYTE;
|
parser.current_type = SYMBOL_BYTE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TOKEN_TYPE_U8: {
|
case TOKEN_TYPE_U8: {
|
||||||
size = emitter.emit_u8_type(parser.current.start, parser.current.length);
|
size = emitter.emit_u8_type(parser.current.start, parser.current.length, parser.depth);
|
||||||
scope_add_symbol(parser.current.start, parser.current.length, SYMBOL_U8,
|
scope_add_symbol(parser.current.start, parser.current.length, SYMBOL_U8,
|
||||||
size);
|
size);
|
||||||
parser.current_type = SYMBOL_U8;
|
parser.current_type = SYMBOL_U8;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TOKEN_TYPE_I8: {
|
case TOKEN_TYPE_I8: {
|
||||||
size = emitter.emit_i8_type(parser.current.start, parser.current.length);
|
size = emitter.emit_i8_type(parser.current.start, parser.current.length, parser.depth);
|
||||||
scope_add_symbol(parser.current.start, parser.current.length, SYMBOL_I8,
|
scope_add_symbol(parser.current.start, parser.current.length, SYMBOL_I8,
|
||||||
size);
|
size);
|
||||||
parser.current_type = SYMBOL_I8;
|
parser.current_type = SYMBOL_I8;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TOKEN_TYPE_U16: {
|
case TOKEN_TYPE_U16: {
|
||||||
size = emitter.emit_u16_type(parser.current.start, parser.current.length);
|
size = emitter.emit_u16_type(parser.current.start, parser.current.length, parser.depth);
|
||||||
scope_add_symbol(parser.current.start, parser.current.length, SYMBOL_U16,
|
scope_add_symbol(parser.current.start, parser.current.length, SYMBOL_U16,
|
||||||
size);
|
size);
|
||||||
parser.current_type = SYMBOL_U16;
|
parser.current_type = SYMBOL_U16;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TOKEN_TYPE_I16: {
|
case TOKEN_TYPE_I16: {
|
||||||
size = emitter.emit_i16_type(parser.current.start, parser.current.length);
|
size = emitter.emit_i16_type(parser.current.start, parser.current.length, parser.depth);
|
||||||
scope_add_symbol(parser.current.start, parser.current.length, SYMBOL_I16,
|
scope_add_symbol(parser.current.start, parser.current.length, SYMBOL_I16,
|
||||||
size);
|
size);
|
||||||
parser.current_type = SYMBOL_I16;
|
parser.current_type = SYMBOL_I16;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
/* probably a variable */
|
/* probably a plex */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -393,7 +412,7 @@ variable_declaration()
|
||||||
if(match(TOKEN_EQ)) {
|
if(match(TOKEN_EQ)) {
|
||||||
emitter.emit_set_value();
|
emitter.emit_set_value();
|
||||||
expression();
|
expression();
|
||||||
emitter.emit_constant(var.start, var.length);
|
emitter.emit_constant(var.start, var.length, parser.depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
consume(TOKEN_SEMICOLON);
|
consume(TOKEN_SEMICOLON);
|
||||||
|
|
@ -425,6 +444,35 @@ print_statement()
|
||||||
emitter.emit_print();
|
emitter.emit_print();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
putchar_statement()
|
||||||
|
{
|
||||||
|
expression();
|
||||||
|
consume(TOKEN_SEMICOLON);
|
||||||
|
emitter.emit_end_statement();
|
||||||
|
emitter.emit_putchar();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
getchar_statement()
|
||||||
|
{
|
||||||
|
expression();
|
||||||
|
consume(TOKEN_SEMICOLON);
|
||||||
|
emitter.emit_end_statement();
|
||||||
|
emitter.emit_putchar();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
if_statement()
|
||||||
|
{
|
||||||
|
consume(TOKEN_LPAREN);
|
||||||
|
expression();
|
||||||
|
consume(TOKEN_RPAREN);
|
||||||
|
emitter.emit_jump();
|
||||||
|
statement();
|
||||||
|
emitter.emit_patch_jump();
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
block()
|
block()
|
||||||
{
|
{
|
||||||
|
|
@ -440,8 +488,14 @@ statement()
|
||||||
scope_push();
|
scope_push();
|
||||||
block();
|
block();
|
||||||
scope_pop();
|
scope_pop();
|
||||||
|
} else if(match(TOKEN_KEYWORD_IF)) {
|
||||||
|
if_statement();
|
||||||
} else if(match(TOKEN_KEYWORD_PRINT)) {
|
} else if(match(TOKEN_KEYWORD_PRINT)) {
|
||||||
print_statement();
|
print_statement();
|
||||||
|
} else if(match(TOKEN_KEYWORD_PUTCHAR)) {
|
||||||
|
putchar_statement();
|
||||||
|
} else if(match(TOKEN_KEYWORD_GETCHAR)) {
|
||||||
|
getchar_statement();
|
||||||
} else {
|
} else {
|
||||||
expression();
|
expression();
|
||||||
}
|
}
|
||||||
|
|
@ -521,7 +575,6 @@ ParseRule rules[] = {
|
||||||
/* TOKEN_KEYWORD_USE */ {nil, nil, PREC_NONE},
|
/* TOKEN_KEYWORD_USE */ {nil, nil, PREC_NONE},
|
||||||
/* TOKEN_KEYWORD_INIT */ {nil, nil, PREC_NONE},
|
/* TOKEN_KEYWORD_INIT */ {nil, nil, PREC_NONE},
|
||||||
/* TOKEN_KEYWORD_THIS */ {nil, nil, PREC_NONE},
|
/* TOKEN_KEYWORD_THIS */ {nil, nil, PREC_NONE},
|
||||||
/* TOKEN_KEYWORD_GLOBAL */ {nil, nil, PREC_NONE},
|
|
||||||
/* TOKEN_KEYWORD_OPEN */ {nil, nil, PREC_NONE},
|
/* TOKEN_KEYWORD_OPEN */ {nil, nil, PREC_NONE},
|
||||||
/* TOKEN_KEYWORD_READ */ {nil, nil, PREC_NONE},
|
/* TOKEN_KEYWORD_READ */ {nil, nil, PREC_NONE},
|
||||||
/* TOKEN_KEYWORD_WRITE */ {nil, nil, PREC_NONE},
|
/* TOKEN_KEYWORD_WRITE */ {nil, nil, PREC_NONE},
|
||||||
|
|
@ -532,10 +585,12 @@ ParseRule rules[] = {
|
||||||
/* TOKEN_KEYWORD_NIL */ {literal, nil, PREC_NONE},
|
/* TOKEN_KEYWORD_NIL */ {literal, nil, PREC_NONE},
|
||||||
/* TOKEN_KEYWORD_TRUE */ {literal, nil, PREC_NONE},
|
/* TOKEN_KEYWORD_TRUE */ {literal, nil, PREC_NONE},
|
||||||
/* TOKEN_KEYWORD_FALSE */ {literal, nil, PREC_NONE},
|
/* TOKEN_KEYWORD_FALSE */ {literal, nil, PREC_NONE},
|
||||||
/* TOKEN_KEYWORD_PRINT */ {nil, nil, PREC_NONE},
|
/* TOKEN_KEYWORD_PUTCHAR */ {nil, nil, PREC_NONE},
|
||||||
/* TOKEN_OPERATOR_NOT */ {nil, nil, PREC_NONE},
|
/* TOKEN_KEYWORD_GETCHAR */ {nil, nil, PREC_NONE},
|
||||||
/* TOKEN_OPERATOR_AND */ {nil, nil, PREC_NONE},
|
/* TOKEN_OPERATOR_AND */ {nil, binary, PREC_NONE},
|
||||||
/* TOKEN_OPERATOR_OR */ {nil, nil, PREC_NONE},
|
/* TOKEN_OPERATOR_OR */ {nil, binary, PREC_NONE},
|
||||||
|
/* TOKEN_OPERATOR_XOR */ {nil, binary, PREC_NONE},
|
||||||
|
/* TOKEN_OPERATOR_MOD */ {nil, binary, PREC_NONE},
|
||||||
/* TOKEN_BANG */ {unary, nil, PREC_NONE},
|
/* TOKEN_BANG */ {unary, nil, PREC_NONE},
|
||||||
/* TOKEN_BANG_EQ */ {nil, binary, PREC_EQUALITY},
|
/* TOKEN_BANG_EQ */ {nil, binary, PREC_EQUALITY},
|
||||||
/* TOKEN_EQ */ {nil, nil, PREC_NONE},
|
/* TOKEN_EQ */ {nil, nil, PREC_NONE},
|
||||||
|
|
@ -567,7 +622,10 @@ ParseRule rules[] = {
|
||||||
/* TOKEN_RBRACE */ {nil, nil, PREC_NONE},
|
/* TOKEN_RBRACE */ {nil, nil, PREC_NONE},
|
||||||
/* TOKEN_LBRACKET */ {nil, nil, PREC_NONE},
|
/* TOKEN_LBRACKET */ {nil, nil, PREC_NONE},
|
||||||
/* TOKEN_RBRACKET */ {nil, nil, PREC_NONE},
|
/* TOKEN_RBRACKET */ {nil, nil, PREC_NONE},
|
||||||
/* TOKEN_ARROW_RIGHT */ {nil, nil, PREC_NONE}};
|
/* TOKEN_ARROW_RIGHT */ {nil, nil, PREC_NONE},
|
||||||
|
/* TOKEN_SLL */ {nil, binary, PREC_NONE},
|
||||||
|
/* TOKEN_SRL */ {nil, binary, PREC_NONE},
|
||||||
|
/*TOKEN_KEYWORD_PRINT*/{nil, binary, PREC_NONE} };
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parse_precedence(Precedence precedence)
|
parse_precedence(Precedence precedence)
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ struct parser_s {
|
||||||
Token current;
|
Token current;
|
||||||
Token previous;
|
Token previous;
|
||||||
SymbolType current_type;
|
SymbolType current_type;
|
||||||
|
u32 depth;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool compile(Arena *a, Emitter e, char *source);
|
bool compile(Arena *a, Emitter e, char *source);
|
||||||
|
|
|
||||||
18
emit.h
18
emit.h
|
|
@ -8,7 +8,9 @@ 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 (*VoidArgEmit)();
|
||||||
typedef void (*StrArgEmit)(const char *str, i32 length);
|
typedef void (*StrArgEmit)(const char *str, i32 length);
|
||||||
typedef i32 (*TypeVariableEmit)(const char *str, i32 length);
|
typedef i32 (*TypeVariableEmit)(const char *str, i32 length, bool local);
|
||||||
|
typedef void (*ConstEmit)(const char *str, i32 length, bool local);
|
||||||
|
typedef void (*VarEmit)(Symbol *sym, bool local);
|
||||||
|
|
||||||
typedef struct emitter_s Emitter;
|
typedef struct emitter_s Emitter;
|
||||||
struct emitter_s {
|
struct emitter_s {
|
||||||
|
|
@ -54,12 +56,14 @@ struct emitter_s {
|
||||||
VoidArgEmit emit_trait;
|
VoidArgEmit emit_trait;
|
||||||
VoidArgEmit emit_const;
|
VoidArgEmit emit_const;
|
||||||
VoidArgEmit emit_print;
|
VoidArgEmit emit_print;
|
||||||
|
VoidArgEmit emit_putchar;
|
||||||
|
VoidArgEmit emit_getchar;
|
||||||
VoidArgEmit emit_neg;
|
VoidArgEmit emit_neg;
|
||||||
VoidArgEmit emit_not;
|
VoidArgEmit emit_not;
|
||||||
VoidArgEmit emit_open_paren;
|
VoidArgEmit emit_open_paren;
|
||||||
VoidArgEmit emit_close_paren;
|
VoidArgEmit emit_close_paren;
|
||||||
StrArgEmit emit_constant;
|
ConstEmit emit_constant;
|
||||||
SymbolEmit emit_variable;
|
VarEmit emit_variable;
|
||||||
VoidArgEmit emit_write;
|
VoidArgEmit emit_write;
|
||||||
VoidArgEmit emit_read;
|
VoidArgEmit emit_read;
|
||||||
VoidArgEmit emit_open;
|
VoidArgEmit emit_open;
|
||||||
|
|
@ -87,6 +91,14 @@ struct emitter_s {
|
||||||
VoidArgEmit emit_cast_str_to_int;
|
VoidArgEmit emit_cast_str_to_int;
|
||||||
VoidArgEmit emit_cast_str_to_nat;
|
VoidArgEmit emit_cast_str_to_nat;
|
||||||
VoidArgEmit emit_cast_str_to_real;
|
VoidArgEmit emit_cast_str_to_real;
|
||||||
|
VoidArgEmit emit_sll;
|
||||||
|
VoidArgEmit emit_srl;
|
||||||
|
VoidArgEmit emit_xor;
|
||||||
|
VoidArgEmit emit_mod;
|
||||||
|
VoidArgEmit emit_and;
|
||||||
|
VoidArgEmit emit_or;
|
||||||
|
VoidArgEmit emit_jump;
|
||||||
|
VoidArgEmit emit_patch_jump;
|
||||||
};
|
};
|
||||||
|
|
||||||
Emitter rer_emitter();
|
Emitter rer_emitter();
|
||||||
|
|
|
||||||
229
emit/rer/emit.c
229
emit/rer/emit.c
|
|
@ -2,6 +2,25 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define RER_OP_2 (1 << 5)
|
||||||
|
#define RER_OP_R (1 << 6)
|
||||||
|
#define RER_OP_K (1 << 7)
|
||||||
|
|
||||||
|
enum rer_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,
|
||||||
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_error(const char *str, i32 length, i32 line)
|
rer_emit_error(const char *str, i32 length, i32 line)
|
||||||
{
|
{
|
||||||
|
|
@ -18,87 +37,106 @@ rer_mem(u32 a)
|
||||||
void
|
void
|
||||||
rer_prolog()
|
rer_prolog()
|
||||||
{
|
{
|
||||||
|
printf("|100\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_epilogue()
|
rer_epilogue()
|
||||||
{
|
{
|
||||||
|
printf("\n\n@str/<print> ( str* -- )\n\
|
||||||
|
LDAk DUP ?{ POP POP2 JMP2r }\n\
|
||||||
|
#18 DEO\n\
|
||||||
|
INC2 !/<print>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_add()
|
rer_emit_add()
|
||||||
{
|
{
|
||||||
|
printf("ADD2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_sub()
|
rer_emit_sub()
|
||||||
{
|
{
|
||||||
|
printf("SUB2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_mul()
|
rer_emit_mul()
|
||||||
{
|
{
|
||||||
|
printf("MUL2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_div()
|
rer_emit_div()
|
||||||
{
|
{
|
||||||
|
printf("DIV2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_lt()
|
rer_emit_lt()
|
||||||
{
|
{
|
||||||
|
printf("LTH2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_le()
|
rer_emit_le()
|
||||||
{
|
{
|
||||||
|
printf("ROT SWP LTH ?{ LTH #00 EQU JMPr } GTH JMPr ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_gt()
|
rer_emit_gt()
|
||||||
{
|
{
|
||||||
|
printf("GTH2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_ge()
|
rer_emit_ge()
|
||||||
{
|
{
|
||||||
|
printf("ROT SWP GTH ?{ GTH #00 EQU JMPr } LTH JMPr ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_ne()
|
rer_emit_ne()
|
||||||
{
|
{
|
||||||
|
printf("NEQ2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_eq()
|
rer_emit_eq()
|
||||||
{
|
{
|
||||||
|
printf("EQU2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_false()
|
rer_emit_false()
|
||||||
{
|
{
|
||||||
|
printf("#0000 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_true()
|
rer_emit_true()
|
||||||
{
|
{
|
||||||
|
printf("#0001 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_nil()
|
rer_emit_nil()
|
||||||
{
|
{
|
||||||
|
printf("#0000 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_neg()
|
rer_emit_neg()
|
||||||
{
|
{
|
||||||
|
printf("#0000 SUB2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_not()
|
rer_emit_not()
|
||||||
{
|
{
|
||||||
|
printf("#FFFF EOR2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -107,93 +145,133 @@ rer_emit_void()
|
||||||
}
|
}
|
||||||
|
|
||||||
i32
|
i32
|
||||||
rer_emit_bool_type(const char *str, i32 length)
|
rer_emit_bool_type(const char *str, i32 length, bool local)
|
||||||
{
|
{
|
||||||
USED(str);USED(length);
|
if(local)
|
||||||
|
printf("!{ &%.*s $1 } ", length, str);
|
||||||
|
else
|
||||||
|
printf("!{ @%.*s $1 } ", length, str);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
i32
|
i32
|
||||||
rer_emit_byte_type(const char *str, i32 length)
|
rer_emit_byte_type(const char *str, i32 length, bool local)
|
||||||
{
|
{
|
||||||
USED(str);USED(length);
|
if(local)
|
||||||
|
printf("!{ &%.*s $1 } ", length, str);
|
||||||
|
else
|
||||||
|
printf("!{ @%.*s $1 } ", length, str);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
i32
|
i32
|
||||||
rer_emit_int_type(const char *str, i32 length)
|
rer_emit_int_type(const char *str, i32 length, bool local)
|
||||||
{
|
{
|
||||||
USED(str);USED(length);
|
if(local)
|
||||||
|
printf("!{ &%.*s $2 } ", length, str);
|
||||||
|
else
|
||||||
|
printf("!{ @%.*s $2 } ", length, str);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
i32
|
i32
|
||||||
rer_emit_nat_type(const char *str, i32 length)
|
rer_emit_nat_type(const char *str, i32 length, bool local)
|
||||||
{
|
{
|
||||||
USED(str);USED(length);
|
if(local)
|
||||||
|
printf("!{ &%.*s $2 } ", length, str);
|
||||||
|
else
|
||||||
|
printf("!{ @%.*s $2 } ", length, str);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
i32
|
i32
|
||||||
rer_emit_real_type(const char *str, i32 length)
|
rer_emit_real_type(const char *str, i32 length, bool local)
|
||||||
{
|
{
|
||||||
USED(str);USED(length);
|
if(local)
|
||||||
|
printf("!{ &%.*s $2 } ", length, str);
|
||||||
|
else
|
||||||
|
printf("!{ @%.*s $2 } ", length, str);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
i32
|
i32
|
||||||
rer_emit_str_type(const char *str, i32 length)
|
rer_emit_str_type(const char *str, i32 length, bool local)
|
||||||
{
|
{
|
||||||
USED(str);USED(length);
|
if(local)
|
||||||
|
printf("!{ &%.*s $2 } ", length, str);
|
||||||
|
else
|
||||||
|
printf("!{ @%.*s $2 } ", length, str);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
i32
|
i32
|
||||||
rer_emit_u8_type(const char *str, i32 length)
|
rer_emit_u8_type(const char *str, i32 length, bool local)
|
||||||
{
|
{
|
||||||
USED(str);USED(length);
|
if(local)
|
||||||
|
printf("!{ &%.*s $1 } ", length, str);
|
||||||
|
else
|
||||||
|
printf("!{ @%.*s $1 } ", length, str);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
i32
|
i32
|
||||||
rer_emit_i8_type(const char *str, i32 length)
|
rer_emit_i8_type(const char *str, i32 length, bool local)
|
||||||
{
|
{
|
||||||
USED(str);USED(length);
|
if(local)
|
||||||
|
printf("!{ &%.*s $1 } ", length, str);
|
||||||
|
else
|
||||||
|
printf("!{ @%.*s $1 } ", length, str);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
i32
|
i32
|
||||||
rer_emit_i16_type(const char *str, i32 length)
|
rer_emit_i16_type(const char *str, i32 length, bool local)
|
||||||
{
|
{
|
||||||
USED(str);USED(length);
|
if(local)
|
||||||
|
printf("!{ &%.*s $2 } ", length, str);
|
||||||
|
else
|
||||||
|
printf("!{ @%.*s $2 } ", length, str);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
i32
|
i32
|
||||||
rer_emit_u16_type(const char *str, i32 length)
|
rer_emit_u16_type(const char *str, i32 length, bool local)
|
||||||
{
|
{
|
||||||
USED(str);USED(length);
|
if(local)
|
||||||
|
printf("!{ &%.*s $2 } ", length, str);
|
||||||
|
else
|
||||||
|
printf("!{ @%.*s $2 } ", length, str);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
i32
|
i32
|
||||||
rer_emit_i32_type(const char *str, i32 length)
|
rer_emit_i32_type(const char *str, i32 length, bool local)
|
||||||
{
|
{
|
||||||
USED(str);USED(length);
|
if(local)
|
||||||
|
printf("!{ &%.*s $4 } ", length, str);
|
||||||
|
else
|
||||||
|
printf("!{ @%.*s $4 } ", length, str);
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
i32
|
i32
|
||||||
rer_emit_u32_type(const char *str, i32 length)
|
rer_emit_u32_type(const char *str, i32 length, bool local)
|
||||||
{
|
{
|
||||||
USED(str);USED(length);
|
if(local)
|
||||||
|
printf("!{ &%.*s $4 } ", length, str);
|
||||||
|
else
|
||||||
|
printf("!{ @%.*s $4 } ", length, str);
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
i32
|
i32
|
||||||
rer_emit_f32_type(const char *str, i32 length)
|
rer_emit_f32_type(const char *str, i32 length, bool local)
|
||||||
{
|
{
|
||||||
USED(str);USED(length);
|
if(local)
|
||||||
|
printf("!{ &%.*s $4 } ", length, str);
|
||||||
|
else
|
||||||
|
printf("!{ @%.*s $4 } ", length, str);
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -232,13 +310,23 @@ rer_emit_byte(const char *str, i32 length)
|
||||||
void
|
void
|
||||||
rer_emit_str(const char *str, i32 length)
|
rer_emit_str(const char *str, i32 length)
|
||||||
{
|
{
|
||||||
printf("\"%.*s ", length, str);
|
/* 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
|
void
|
||||||
rer_emit_constant(const char *str, i32 length)
|
rer_emit_constant(const char *str, i32 length, bool local)
|
||||||
{
|
{
|
||||||
printf(";%.*s STA2 ", length, str);
|
if(local)
|
||||||
|
printf(",/%.*s STR2 ", length, str);
|
||||||
|
else
|
||||||
|
printf(";%.*s STA2 ", length, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -272,9 +360,15 @@ rer_emit_const()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_print()
|
rer_emit_putchar()
|
||||||
{
|
{
|
||||||
printf("print ");
|
printf("#18 DEO ");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rer_emit_getchar()
|
||||||
|
{
|
||||||
|
printf("#12 DEI ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -288,9 +382,12 @@ rer_emit_close_paren()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_variable(Symbol *sym)
|
rer_emit_variable(Symbol *sym, bool local)
|
||||||
{
|
{
|
||||||
printf(";%.*s LDA2 ", sym->name_length, sym->name);
|
if(local)
|
||||||
|
printf(",/%.*s LDR2 ", sym->name_length, sym->name);
|
||||||
|
else
|
||||||
|
printf(";%.*s LDA2 ", sym->name_length, sym->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -426,6 +523,60 @@ 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/<print> ");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
rer_emit_jump()
|
||||||
|
{
|
||||||
|
printf("?{ ");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rer_emit_patch_jump()
|
||||||
|
{
|
||||||
|
printf("} ");
|
||||||
|
}
|
||||||
|
|
||||||
Emitter
|
Emitter
|
||||||
rer_emitter()
|
rer_emitter()
|
||||||
{
|
{
|
||||||
|
|
@ -472,6 +623,8 @@ rer_emitter()
|
||||||
rer_emit_trait,
|
rer_emit_trait,
|
||||||
rer_emit_const,
|
rer_emit_const,
|
||||||
rer_emit_print,
|
rer_emit_print,
|
||||||
|
rer_emit_putchar,
|
||||||
|
rer_emit_getchar,
|
||||||
rer_emit_neg,
|
rer_emit_neg,
|
||||||
rer_emit_not,
|
rer_emit_not,
|
||||||
rer_emit_open_paren,
|
rer_emit_open_paren,
|
||||||
|
|
@ -505,5 +658,13 @@ rer_emitter()
|
||||||
rer_emit_cast_str_to_int,
|
rer_emit_cast_str_to_int,
|
||||||
rer_emit_cast_str_to_nat,
|
rer_emit_cast_str_to_nat,
|
||||||
rer_emit_cast_str_to_real,
|
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_jump,
|
||||||
|
rer_emit_patch_jump,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
316
emit/uxn/emit.c
316
emit/uxn/emit.c
|
|
@ -7,60 +7,20 @@
|
||||||
#define UXN_OP_K (1 << 7)
|
#define UXN_OP_K (1 << 7)
|
||||||
|
|
||||||
enum uxn_opcode {
|
enum uxn_opcode {
|
||||||
/* Stack I */ /* Logic */ /* Memory I */ /* Arithmetic*/
|
/* Stack I */ /* Logic */ /* Memory I */ /* Arithmetic*/
|
||||||
BRK = 0x00,
|
BRK = 0x00, EQU = 0x08, LDZ = 0x10, ADD = 0x18,
|
||||||
EQU = 0x08,
|
INC = 0x01, NEQ = 0x09, STZ = 0x11, SUB = 0x19,
|
||||||
LDZ = 0x10,
|
POP = 0x02, GTH = 0x0A, LDR = 0x12, MUL = 0x1A,
|
||||||
ADD = 0x18,
|
NIP = 0x03, LTH = 0x0B, STR = 0x13, DIV = 0x1B,
|
||||||
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 */
|
/* Stack II */ /* Stash */ /* Memory II */ /* Bitwise */
|
||||||
SWP = 0x04,
|
SWP = 0x04, JMP = 0x0C, LDA = 0x14, AND = 0x1C,
|
||||||
JMP = 0x0C,
|
ROT = 0x05, JCN = 0x0D, STA = 0x15, ORA = 0x1D,
|
||||||
LDA = 0x14,
|
DUP = 0x06, JSR = 0x0E, DEI = 0x16, EOR = 0x1E,
|
||||||
AND = 0x1C,
|
OVR = 0x07, STH = 0x0F, DEO = 0x17, SFT = 0x1F,
|
||||||
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,
|
LIT = 0x80, JCI = 0x20, JMI = 0x40, JSI = 0x60,
|
||||||
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
|
void
|
||||||
uxn_emit_error(const char *str, i32 length, i32 line)
|
uxn_emit_error(const char *str, i32 length, i32 line)
|
||||||
{
|
{
|
||||||
|
|
@ -77,21 +37,16 @@ uxn_mem(u32 a)
|
||||||
void
|
void
|
||||||
uxn_prolog()
|
uxn_prolog()
|
||||||
{
|
{
|
||||||
printf("|100 @main ( -> )\n");
|
printf("|100\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_epilogue()
|
uxn_epilogue()
|
||||||
{
|
{
|
||||||
/* https://wiki.xxiivv.com/etc/lib.math.tal.txt */
|
printf("BRK\n\n@str/<print> ( str* -- )\n\
|
||||||
|
LDAk DUP ?{ POP POP2 JMP2r }\n\
|
||||||
printf("\n@nat-to-str ( -- ) \n\
|
#18 DEO\n\
|
||||||
&>wp \n\
|
INC2 !/<print>\n");
|
||||||
LDAk DUP ?{ POP POP2 JMP2r } \n\
|
|
||||||
#18 DEO \n\
|
|
||||||
INC2 !&>wp\n\n");
|
|
||||||
printf("@num-to-string $12\n");
|
|
||||||
printf("@heap\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -181,7 +136,7 @@ uxn_emit_neg()
|
||||||
void
|
void
|
||||||
uxn_emit_not()
|
uxn_emit_not()
|
||||||
{
|
{
|
||||||
printf("#FFFF EOR2 ");
|
printf("#ffff EOR2 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -190,93 +145,133 @@ uxn_emit_void()
|
||||||
}
|
}
|
||||||
|
|
||||||
i32
|
i32
|
||||||
uxn_emit_bool_type(const char *str, i32 length)
|
uxn_emit_bool_type(const char *str, i32 length, bool local)
|
||||||
{
|
{
|
||||||
printf("!{ @%.*s $1 } ", length, str);
|
if(local)
|
||||||
|
printf("!{ &%.*s $2 } ", length, str);
|
||||||
|
else
|
||||||
|
printf("!{ @%.*s $2 } ", length, str);
|
||||||
|
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
i32
|
||||||
|
uxn_emit_byte_type(const char *str, i32 length, bool local)
|
||||||
|
{
|
||||||
|
if(local)
|
||||||
|
printf("!{ &%.*s $1 } ", length, str);
|
||||||
|
else
|
||||||
|
printf("!{ @%.*s $1 } ", length, str);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
i32
|
i32
|
||||||
uxn_emit_byte_type(const char *str, i32 length)
|
uxn_emit_int_type(const char *str, i32 length, bool local)
|
||||||
{
|
{
|
||||||
printf("!{ @%.*s $1 } ", length, str);
|
if(local)
|
||||||
|
printf("!{ &%.*s $2 } ", length, str);
|
||||||
|
else
|
||||||
|
printf("!{ @%.*s $2 } ", length, str);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
i32
|
||||||
|
uxn_emit_nat_type(const char *str, i32 length, bool local)
|
||||||
|
{
|
||||||
|
if(local)
|
||||||
|
printf("!{ &%.*s $2 } ", length, str);
|
||||||
|
else
|
||||||
|
printf("!{ @%.*s $2 } ", length, str);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
i32
|
||||||
|
uxn_emit_real_type(const char *str, i32 length, bool local)
|
||||||
|
{
|
||||||
|
if(local)
|
||||||
|
printf("!{ &%.*s $2 } ", length, str);
|
||||||
|
else
|
||||||
|
printf("!{ @%.*s $2 } ", length, str);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
i32
|
||||||
|
uxn_emit_str_type(const char *str, i32 length, bool local)
|
||||||
|
{
|
||||||
|
if(local)
|
||||||
|
printf("!{ &%.*s $2 } ", length, str);
|
||||||
|
else
|
||||||
|
printf("!{ @%.*s $2 } ", length, str);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
i32
|
||||||
|
uxn_emit_u8_type(const char *str, i32 length, bool local)
|
||||||
|
{
|
||||||
|
if(local)
|
||||||
|
printf("!{ &%.*s $1 } ", length, str);
|
||||||
|
else
|
||||||
|
printf("!{ @%.*s $1 } ", length, str);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
i32
|
i32
|
||||||
uxn_emit_int_type(const char *str, i32 length)
|
uxn_emit_i8_type(const char *str, i32 length, bool local)
|
||||||
{
|
{
|
||||||
printf("!{ @%.*s $2 } ", length, str);
|
if(local)
|
||||||
return 2;
|
printf("!{ &%.*s $1 } ", length, str);
|
||||||
}
|
else
|
||||||
|
printf("!{ @%.*s $1 } ", length, str);
|
||||||
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
i32
|
i32
|
||||||
uxn_emit_i8_type(const char *str, i32 length)
|
uxn_emit_i16_type(const char *str, i32 length, bool local)
|
||||||
{
|
{
|
||||||
printf("!{ @%.*s $1 } ", length, str);
|
if(local)
|
||||||
return 1;
|
printf("!{ &%.*s $2 } ", length, str);
|
||||||
}
|
else
|
||||||
|
printf("!{ @%.*s $2 } ", length, str);
|
||||||
i32
|
|
||||||
uxn_emit_i16_type(const char *str, i32 length)
|
|
||||||
{
|
|
||||||
printf("!{ @%.*s $2 } ", length, str);
|
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
i32
|
i32
|
||||||
uxn_emit_u16_type(const char *str, i32 length)
|
uxn_emit_u16_type(const char *str, i32 length, bool local)
|
||||||
{
|
{
|
||||||
printf("!{ @%.*s $2 } ", length, str);
|
if(local)
|
||||||
|
printf("!{ &%.*s $2 } ", length, str);
|
||||||
|
else
|
||||||
|
printf("!{ @%.*s $2 } ", length, str);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
i32
|
i32
|
||||||
uxn_emit_i32_type(const char *str, i32 length)
|
uxn_emit_i32_type(const char *str, i32 length, bool local)
|
||||||
{
|
{
|
||||||
printf("!{ @%.*s $4 } ", length, str);
|
if(local)
|
||||||
|
printf("!{ &%.*s $4 } ", length, str);
|
||||||
|
else
|
||||||
|
printf("!{ @%.*s $4 } ", length, str);
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
i32
|
i32
|
||||||
uxn_emit_u32_type(const char *str, i32 length)
|
uxn_emit_u32_type(const char *str, i32 length, bool local)
|
||||||
{
|
{
|
||||||
printf("!{ @%.*s $4 } ", length, str);
|
if(local)
|
||||||
|
printf("!{ &%.*s $4 } ", length, str);
|
||||||
|
else
|
||||||
|
printf("!{ @%.*s $4 } ", length, str);
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
i32
|
i32
|
||||||
uxn_emit_f32_type(const char *str, i32 length)
|
uxn_emit_f32_type(const char *str, i32 length, bool local)
|
||||||
{
|
{
|
||||||
printf("!{ @%.*s $4 } ", length, str);
|
if(local)
|
||||||
|
printf("!{ &%.*s $4 } ", length, str);
|
||||||
|
else
|
||||||
|
printf("!{ @%.*s $4 } ", length, str);
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -315,13 +310,23 @@ uxn_emit_byte(const char *str, i32 length)
|
||||||
void
|
void
|
||||||
uxn_emit_str(const char *str, i32 length)
|
uxn_emit_str(const char *str, i32 length)
|
||||||
{
|
{
|
||||||
printf("\"%.*s ", length, str);
|
/* 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
|
void
|
||||||
uxn_emit_constant(const char *str, i32 length)
|
uxn_emit_constant(const char *str, i32 length, bool local)
|
||||||
{
|
{
|
||||||
printf(";%.*s STA2 ", length, str);
|
if(local)
|
||||||
|
printf(",/%.*s STR2 ", length, str);
|
||||||
|
else
|
||||||
|
printf(";%.*s STA2 ", length, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -355,9 +360,15 @@ uxn_emit_const()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_print()
|
uxn_emit_putchar()
|
||||||
{
|
{
|
||||||
printf("print ");
|
printf("#18 DEO ");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
uxn_emit_getchar()
|
||||||
|
{
|
||||||
|
printf("#12 DEI ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -371,9 +382,12 @@ uxn_emit_close_paren()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_variable(Symbol *sym)
|
uxn_emit_variable(Symbol *sym, bool local)
|
||||||
{
|
{
|
||||||
printf(";%.*s LDA2 ", sym->name_length, sym->name);
|
if(local)
|
||||||
|
printf(",/%.*s LDR2 ", sym->name_length, sym->name);
|
||||||
|
else
|
||||||
|
printf(";%.*s LDA2 ", sym->name_length, sym->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -509,6 +523,60 @@ uxn_emit_cast_str_to_real()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
uxn_emit_sll()
|
||||||
|
{
|
||||||
|
printf("#40 SFT SFT ");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
uxn_emit_srl()
|
||||||
|
{
|
||||||
|
printf("SFT ");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
uxn_emit_xor()
|
||||||
|
{
|
||||||
|
printf("EOR2 ");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
uxn_emit_mod()
|
||||||
|
{
|
||||||
|
printf("DIV2k MUL2 SUB2 ");
|
||||||
|
}
|
||||||
|
void
|
||||||
|
uxn_emit_or()
|
||||||
|
{
|
||||||
|
printf("ORA2 ");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
uxn_emit_and()
|
||||||
|
{
|
||||||
|
printf("AND2 ");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
uxn_emit_print()
|
||||||
|
{
|
||||||
|
printf("str/<print> ");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
uxn_emit_jump()
|
||||||
|
{
|
||||||
|
printf("?{ ");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
uxn_emit_patch_jump()
|
||||||
|
{
|
||||||
|
printf("} ");
|
||||||
|
}
|
||||||
|
|
||||||
Emitter
|
Emitter
|
||||||
uxn_emitter()
|
uxn_emitter()
|
||||||
{
|
{
|
||||||
|
|
@ -555,6 +623,8 @@ uxn_emitter()
|
||||||
uxn_emit_trait,
|
uxn_emit_trait,
|
||||||
uxn_emit_const,
|
uxn_emit_const,
|
||||||
uxn_emit_print,
|
uxn_emit_print,
|
||||||
|
uxn_emit_putchar,
|
||||||
|
uxn_emit_getchar,
|
||||||
uxn_emit_neg,
|
uxn_emit_neg,
|
||||||
uxn_emit_not,
|
uxn_emit_not,
|
||||||
uxn_emit_open_paren,
|
uxn_emit_open_paren,
|
||||||
|
|
@ -588,5 +658,13 @@ uxn_emitter()
|
||||||
uxn_emit_cast_str_to_int,
|
uxn_emit_cast_str_to_int,
|
||||||
uxn_emit_cast_str_to_nat,
|
uxn_emit_cast_str_to_nat,
|
||||||
uxn_emit_cast_str_to_real,
|
uxn_emit_cast_str_to_real,
|
||||||
|
uxn_emit_sll,
|
||||||
|
uxn_emit_srl,
|
||||||
|
uxn_emit_xor,
|
||||||
|
uxn_emit_mod,
|
||||||
|
uxn_emit_and,
|
||||||
|
uxn_emit_or,
|
||||||
|
uxn_emit_jump,
|
||||||
|
uxn_emit_patch_jump,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
20
lexer.c
20
lexer.c
|
|
@ -233,8 +233,10 @@ identifierType()
|
||||||
return check_keyword(2, 1, "r", TOKEN_TYPE_PTR);
|
return check_keyword(2, 1, "r", TOKEN_TYPE_PTR);
|
||||||
case 'l':
|
case 'l':
|
||||||
return check_keyword(2, 2, "ex", TOKEN_KEYWORD_PLEX);
|
return check_keyword(2, 2, "ex", TOKEN_KEYWORD_PLEX);
|
||||||
|
case 'u':
|
||||||
|
return check_keyword(2, 5, "tchar", TOKEN_KEYWORD_PUTCHAR);
|
||||||
case 'r':
|
case 'r':
|
||||||
return check_keyword(2, 3, "int", TOKEN_KEYWORD_PRINT);
|
return check_keyword(2, 3, "int", TOKEN_KEYWORD_PRINT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -321,13 +323,17 @@ identifierType()
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'g':
|
case 'g':
|
||||||
return check_keyword(1, 5, "lobal", TOKEN_KEYWORD_GLOBAL);
|
return check_keyword(1, 6, "etchar", TOKEN_KEYWORD_GETCHAR);
|
||||||
case 'l':
|
case 'l':
|
||||||
return check_keyword(1, 3, "oop", TOKEN_KEYWORD_LOOP);
|
return check_keyword(1, 3, "oop", TOKEN_KEYWORD_LOOP);
|
||||||
case 'd':
|
case 'd':
|
||||||
return check_keyword(1, 1, "o", TOKEN_KEYWORD_DO);
|
return check_keyword(1, 1, "o", TOKEN_KEYWORD_DO);
|
||||||
case 'v':
|
case 'v':
|
||||||
return check_keyword(1, 3, "oid", TOKEN_TYPE_VOID);
|
return check_keyword(1, 3, "oid", TOKEN_TYPE_VOID);
|
||||||
|
case 'x':
|
||||||
|
return check_keyword(1, 2, "or", TOKEN_OPERATOR_XOR);
|
||||||
|
case 'm':
|
||||||
|
return check_keyword(1, 2, "od", TOKEN_OPERATOR_MOD);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TOKEN_IDENTIFIER;
|
return TOKEN_IDENTIFIER;
|
||||||
|
|
@ -426,9 +432,9 @@ next_token()
|
||||||
case '=':
|
case '=':
|
||||||
return make_token(match('=') ? TOKEN_EQ_EQ : TOKEN_EQ);
|
return make_token(match('=') ? TOKEN_EQ_EQ : TOKEN_EQ);
|
||||||
case '<':
|
case '<':
|
||||||
return make_token(match('=') ? TOKEN_LTE : TOKEN_LT);
|
return make_token(match('=') ? TOKEN_LTE : match('<') ? TOKEN_SLL : TOKEN_LT);
|
||||||
case '>':
|
case '>':
|
||||||
return make_token(match('=') ? TOKEN_GTE : TOKEN_GT);
|
return make_token(match('=') ? TOKEN_GTE : match('>') ? TOKEN_SRL : TOKEN_GT);
|
||||||
case '"':
|
case '"':
|
||||||
return string();
|
return string();
|
||||||
}
|
}
|
||||||
|
|
@ -504,10 +510,8 @@ token_type_to_string(TokenType type)
|
||||||
return "KEYWORD_TRUE";
|
return "KEYWORD_TRUE";
|
||||||
case TOKEN_KEYWORD_FALSE:
|
case TOKEN_KEYWORD_FALSE:
|
||||||
return "KEYWORD_FALSE";
|
return "KEYWORD_FALSE";
|
||||||
case TOKEN_KEYWORD_GLOBAL:
|
case TOKEN_KEYWORD_GETCHAR:
|
||||||
return "KEYWORD_GLOBAL";
|
return "KEYWORD_GETCHAR";
|
||||||
case TOKEN_OPERATOR_NOT:
|
|
||||||
return "OPERATOR_NOT";
|
|
||||||
case TOKEN_OPERATOR_AND:
|
case TOKEN_OPERATOR_AND:
|
||||||
return "OPERATOR_AND";
|
return "OPERATOR_AND";
|
||||||
case TOKEN_OPERATOR_OR:
|
case TOKEN_OPERATOR_OR:
|
||||||
|
|
|
||||||
12
lexer.h
12
lexer.h
|
|
@ -36,7 +36,6 @@ typedef enum {
|
||||||
TOKEN_KEYWORD_USE,
|
TOKEN_KEYWORD_USE,
|
||||||
TOKEN_KEYWORD_INIT,
|
TOKEN_KEYWORD_INIT,
|
||||||
TOKEN_KEYWORD_THIS,
|
TOKEN_KEYWORD_THIS,
|
||||||
TOKEN_KEYWORD_GLOBAL,
|
|
||||||
TOKEN_KEYWORD_OPEN,
|
TOKEN_KEYWORD_OPEN,
|
||||||
TOKEN_KEYWORD_READ,
|
TOKEN_KEYWORD_READ,
|
||||||
TOKEN_KEYWORD_WRITE,
|
TOKEN_KEYWORD_WRITE,
|
||||||
|
|
@ -47,10 +46,12 @@ typedef enum {
|
||||||
TOKEN_KEYWORD_NIL,
|
TOKEN_KEYWORD_NIL,
|
||||||
TOKEN_KEYWORD_TRUE,
|
TOKEN_KEYWORD_TRUE,
|
||||||
TOKEN_KEYWORD_FALSE,
|
TOKEN_KEYWORD_FALSE,
|
||||||
TOKEN_KEYWORD_PRINT,
|
TOKEN_KEYWORD_PUTCHAR,
|
||||||
TOKEN_OPERATOR_NOT,
|
TOKEN_KEYWORD_GETCHAR,
|
||||||
TOKEN_OPERATOR_AND,
|
TOKEN_OPERATOR_AND,
|
||||||
TOKEN_OPERATOR_OR,
|
TOKEN_OPERATOR_OR,
|
||||||
|
TOKEN_OPERATOR_XOR,
|
||||||
|
TOKEN_OPERATOR_MOD,
|
||||||
TOKEN_BANG,
|
TOKEN_BANG,
|
||||||
TOKEN_BANG_EQ,
|
TOKEN_BANG_EQ,
|
||||||
TOKEN_EQ,
|
TOKEN_EQ,
|
||||||
|
|
@ -82,7 +83,10 @@ typedef enum {
|
||||||
TOKEN_RBRACE,
|
TOKEN_RBRACE,
|
||||||
TOKEN_LBRACKET,
|
TOKEN_LBRACKET,
|
||||||
TOKEN_RBRACKET,
|
TOKEN_RBRACKET,
|
||||||
TOKEN_ARROW_RIGHT
|
TOKEN_ARROW_RIGHT,
|
||||||
|
TOKEN_SLL,
|
||||||
|
TOKEN_SRL,
|
||||||
|
TOKEN_KEYWORD_PRINT
|
||||||
} TokenType;
|
} TokenType;
|
||||||
|
|
||||||
typedef struct token_s Token;
|
typedef struct token_s Token;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,3 @@
|
||||||
int i = 122;
|
int i = 122;
|
||||||
int j = 32;
|
int j = 32;
|
||||||
|
putchar((i - j));
|
||||||
//function main() {
|
|
||||||
print((i - j) as str);
|
|
||||||
//}
|
|
||||||
|
|
|
||||||
|
|
@ -2,5 +2,5 @@ function main() {
|
||||||
int i = 122;
|
int i = 122;
|
||||||
int j = 32;
|
int j = 32;
|
||||||
|
|
||||||
print((i - j)); // prints ascii `Z`
|
putchar((i - j)); // prints ascii `Z`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue