wip string and array indexing, need to do setting index array yet
This commit is contained in:
parent
b8899d8bc9
commit
23bb9f73e7
|
|
@ -3,7 +3,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static char *
|
||||
char *
|
||||
readFile(const char *path)
|
||||
{
|
||||
FILE *file = fopen(path, "rb");
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@
|
|||
|
||||
#define MEM_SIZE (1 << 16)
|
||||
|
||||
static size_t List_size(List *list) {
|
||||
size_t
|
||||
List_size(List *list)
|
||||
{
|
||||
size_t total = 0;
|
||||
Node *curr = list->head;
|
||||
while(curr) {
|
||||
|
|
@ -16,7 +18,9 @@ static size_t List_size(List *list) {
|
|||
return total;
|
||||
}
|
||||
|
||||
static void list2buffer(List *list, char *buffer, size_t *offset) {
|
||||
void
|
||||
list2buffer(List *list, char *buffer, size_t *offset)
|
||||
{
|
||||
Node *curr = list->head;
|
||||
while(curr) {
|
||||
char *tmp_str = node_value(curr);
|
||||
|
|
@ -27,16 +31,21 @@ static void list2buffer(List *list, char *buffer, size_t *offset) {
|
|||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE
|
||||
char *undar_compile(int emitter_type, char *source) {
|
||||
char *
|
||||
undar_compile(int emitter_type, char *source)
|
||||
{
|
||||
u8 tape[MEM_SIZE];
|
||||
Arena a = {tape, 0, MEM_SIZE};
|
||||
|
||||
Emitter e;
|
||||
if (emitter_type == 0) {
|
||||
switch(emitter_type) {
|
||||
case 0:
|
||||
e = rer_emitter();
|
||||
} else if (emitter_type == 1) {
|
||||
break;
|
||||
case 1:
|
||||
e = uxn_emitter();
|
||||
} else {
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
128
compiler.c
128
compiler.c
|
|
@ -158,6 +158,7 @@ token_type_to_sym_type(TokenType t)
|
|||
bool
|
||||
advance(void)
|
||||
{
|
||||
parser->before = parser->previous;
|
||||
parser->previous = parser->current;
|
||||
|
||||
for(;;) {
|
||||
|
|
@ -241,11 +242,9 @@ define_function(void)
|
|||
advance();
|
||||
|
||||
/* parse the args */
|
||||
while(!check(TOKEN_LBRACE)) {
|
||||
while(!match(TOKEN_RPAREN)) {
|
||||
size += variable_declaration(fn);
|
||||
advance();
|
||||
if(check(TOKEN_LBRACE)) break;
|
||||
advance();
|
||||
if(match(TOKEN_RPAREN)) break;
|
||||
}
|
||||
|
||||
if(is_type()) {
|
||||
|
|
@ -332,6 +331,14 @@ define_array(void)
|
|||
array->fields = strides;
|
||||
}
|
||||
|
||||
void
|
||||
define_string(void)
|
||||
{
|
||||
scope_add_symbol(parser->current.start,
|
||||
parser->current.length,
|
||||
SYMBOL_STR, 0);
|
||||
}
|
||||
|
||||
void
|
||||
build_symbol_table(char *source)
|
||||
{
|
||||
|
|
@ -351,6 +358,8 @@ build_symbol_table(char *source)
|
|||
define_plex();
|
||||
} else if(match(TOKEN_KEYWORD_TRAIT)) {
|
||||
define_trait();
|
||||
} else if (parser->previous.type != TOKEN_KEYWORD_AS && match(TOKEN_TYPE_STR)) {
|
||||
define_string();
|
||||
} else if (parser->current.type >= TOKEN_TYPE_I8 &&
|
||||
parser->current.type <= TOKEN_TYPE_PTR) {
|
||||
advance();
|
||||
|
|
@ -380,6 +389,28 @@ variable_declaration(Symbol *def)
|
|||
Symbol *variable;
|
||||
List *array_literal;
|
||||
|
||||
|
||||
if (tt == TOKEN_TYPE_STR) {
|
||||
variable = scope_get_symbol(parser->current_scope,
|
||||
parser->current.start,
|
||||
parser->current.length);
|
||||
if (!variable) {
|
||||
emitter->error("cannot find str symbol", 23, parser->current.line);
|
||||
return 0;
|
||||
}
|
||||
advance();
|
||||
|
||||
if (match(TOKEN_EQ)) {
|
||||
expect(TOKEN_LITERAL_STR);
|
||||
variable->size = parser->previous.length - 2;
|
||||
emitter->emit_str(arena, memory, variable, parser->previous.start, parser->previous.length);
|
||||
expect(TOKEN_SEMICOLON);
|
||||
}
|
||||
|
||||
parser->current_type = st;
|
||||
return emitter->get_size(st);
|
||||
}
|
||||
|
||||
if (parser->current.type == TOKEN_LBRACKET) {
|
||||
while(!check(TOKEN_RBRACKET)) {
|
||||
advance();
|
||||
|
|
@ -390,7 +421,7 @@ variable_declaration(Symbol *def)
|
|||
parser->current.start,
|
||||
parser->current.length);
|
||||
if (!variable) {
|
||||
emitter->error("cannot find array symbol", 24, parser->current.line);
|
||||
emitter->error("cannot find array symbol", 25, parser->current.line);
|
||||
return 0;
|
||||
}
|
||||
advance();
|
||||
|
|
@ -417,7 +448,8 @@ variable_declaration(Symbol *def)
|
|||
emitter->emit_zero_block(arena, memory, variable->size * emitter->get_size(variable->secondary_type));
|
||||
}
|
||||
|
||||
return variable->size;
|
||||
parser->current_type = st;
|
||||
return emitter->get_size(st);
|
||||
}
|
||||
|
||||
if(st != SYMBOL_UNDEFINED) {
|
||||
|
|
@ -468,34 +500,34 @@ binary(void)
|
|||
|
||||
switch(operatorType) {
|
||||
case TOKEN_BANG_EQ:
|
||||
emitter->emit_ne(arena, code);
|
||||
emitter->emit_ne(arena, code, emitter->get_size(parser->current_type));
|
||||
break;
|
||||
case TOKEN_EQ_EQ:
|
||||
emitter->emit_eq(arena, code);
|
||||
emitter->emit_eq(arena, code, emitter->get_size(parser->current_type));
|
||||
break;
|
||||
case TOKEN_GT:
|
||||
emitter->emit_gt(arena, code);
|
||||
emitter->emit_gt(arena, code, emitter->get_size(parser->current_type));
|
||||
break;
|
||||
case TOKEN_GTE:
|
||||
emitter->emit_ge(arena, code);
|
||||
emitter->emit_ge(arena, code, emitter->get_size(parser->current_type));
|
||||
break;
|
||||
case TOKEN_LT:
|
||||
emitter->emit_lt(arena, code);
|
||||
emitter->emit_lt(arena, code, emitter->get_size(parser->current_type));
|
||||
break;
|
||||
case TOKEN_LTE:
|
||||
emitter->emit_le(arena, code);
|
||||
emitter->emit_le(arena, code, emitter->get_size(parser->current_type));
|
||||
break;
|
||||
case TOKEN_PLUS:
|
||||
emitter->emit_add(arena, code);
|
||||
emitter->emit_add(arena, code, emitter->get_size(parser->current_type));
|
||||
break;
|
||||
case TOKEN_MINUS:
|
||||
emitter->emit_sub(arena, code);
|
||||
emitter->emit_sub(arena, code, emitter->get_size(parser->current_type));
|
||||
break;
|
||||
case TOKEN_STAR:
|
||||
emitter->emit_mul(arena, code);
|
||||
emitter->emit_mul(arena, code, emitter->get_size(parser->current_type));
|
||||
break;
|
||||
case TOKEN_SLASH:
|
||||
emitter->emit_div(arena, code);
|
||||
emitter->emit_div(arena, code, emitter->get_size(parser->current_type));
|
||||
break;
|
||||
case TOKEN_OPERATOR_AND:
|
||||
emitter->emit_and(arena, code);
|
||||
|
|
@ -544,12 +576,24 @@ expression(void)
|
|||
parse_precedence(PREC_ASSIGNMENT);
|
||||
}
|
||||
|
||||
void
|
||||
dot(void)
|
||||
{
|
||||
Symbol *sym = scope_get_symbol(parser->current_scope, parser->before.start,
|
||||
parser->before.length);
|
||||
if(sym == nil) {
|
||||
emitter->error(parser->current.start, parser->current.length,
|
||||
parser->current.line);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
variable(void)
|
||||
{
|
||||
Symbol *sym = scope_get_symbol(parser->current_scope, parser->previous.start,
|
||||
parser->previous.length);
|
||||
if(sym == nil) {
|
||||
return;
|
||||
emitter->error(parser->previous.start, parser->previous.length,
|
||||
parser->previous.line);
|
||||
}
|
||||
|
|
@ -559,26 +603,59 @@ variable(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (sym->type == SYMBOL_STR) {
|
||||
emitter->emit_deref_prolog(arena, code, sym);
|
||||
|
||||
if (match(TOKEN_LBRACKET)) {
|
||||
/* add offset of "length"*/
|
||||
emitter->emit_nat(arena, code, "2", 1);
|
||||
emitter->emit_add(arena, code, 2);
|
||||
expression();
|
||||
emitter->emit_add(arena, code, 2);
|
||||
emitter->emit_deref(arena, code, 1);
|
||||
while (!match(TOKEN_RBRACKET)) {
|
||||
}
|
||||
parser->current_type = SYMBOL_BYTE;
|
||||
} else if (match(TOKEN_DOT)) {
|
||||
if (sleq("length", parser->current.start, parser->current.length)) {
|
||||
emitter->emit_deref(arena, code, 2);
|
||||
} else {
|
||||
emitter->error("arrays currently can only get their length, don't do anything fancy yet...", 75, parser->current.line);
|
||||
}
|
||||
parser->current_type = SYMBOL_NAT;
|
||||
advance();
|
||||
} else {
|
||||
emitter->emit_nat(arena, code, "2", 1);
|
||||
emitter->emit_add(arena, code, 2);
|
||||
/* emitter->emit_deref(arena, code); */
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (sym->type == SYMBOL_ARRAY) {
|
||||
u32 size = emitter->get_size(sym->secondary_type);
|
||||
emitter->emit_deref_prolog(arena, code, sym);
|
||||
|
||||
if (match(TOKEN_LBRACKET)) {
|
||||
expression();
|
||||
emitter->emit_address(arena, code, emitter->get_size(sym->secondary_type));
|
||||
emitter->emit_mul(arena, code);
|
||||
emitter->emit_add(arena, code);
|
||||
emitter->emit_address(arena, code, size);
|
||||
emitter->emit_mul(arena, code, size);
|
||||
emitter->emit_add(arena, code, size);
|
||||
/* add offset of "length"*/
|
||||
emitter->emit_nat(arena, code, "2", 1);
|
||||
emitter->emit_add(arena, code);
|
||||
emitter->emit_deref(arena, code);
|
||||
emitter->emit_add(arena, code, size);
|
||||
emitter->emit_deref(arena, code, size);
|
||||
parser->current_type = sym->secondary_type;
|
||||
while (!match(TOKEN_RBRACKET)) {
|
||||
}
|
||||
} else if (match(TOKEN_DOT)) {
|
||||
if (sleq("length", parser->current.start, parser->current.length)) {
|
||||
emitter->emit_deref(arena, code);
|
||||
emitter->emit_deref(arena, code, size);
|
||||
} else {
|
||||
emitter->error("arrays currently can only get their length, don't do anything fancy yet...", 75, parser->current.line);
|
||||
}
|
||||
parser->current_type = SYMBOL_NAT;
|
||||
advance();
|
||||
}
|
||||
return;
|
||||
|
|
@ -833,7 +910,7 @@ number(void)
|
|||
void
|
||||
string(void)
|
||||
{
|
||||
emitter->emit_str(arena, code, parser->previous.start, parser->previous.length);
|
||||
emitter->emit_inline_str(arena, code, parser->previous.start, parser->previous.length);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -884,6 +961,7 @@ ParseRule rules[] = {
|
|||
/* TOKEN_RBRACE */ {nil, nil, PREC_NONE},
|
||||
/* TOKEN_LBRACKET */ {nil, nil, PREC_NONE},
|
||||
/* TOKEN_RBRACKET */ {nil, nil, PREC_NONE},
|
||||
/* TOKEN_DOT */ {nil, dot, PREC_CALL},
|
||||
/* TOKEN_IDENTIFIER */ {variable, nil, PREC_NONE},
|
||||
/* TOKEN_LITERAL_INT */ {number, nil, PREC_NONE},
|
||||
/* TOKEN_LITERAL_NAT */ {number, nil, PREC_NONE},
|
||||
|
|
@ -948,7 +1026,6 @@ ParseRule rules[] = {
|
|||
/* TOKEN_LT */ {nil, binary, PREC_COMPARISON},
|
||||
/* TOKEN_GTE */ {nil, binary, PREC_COMPARISON},
|
||||
/* TOKEN_LTE */ {nil, binary, PREC_COMPARISON},
|
||||
/* TOKEN_DOT */ {nil, nil, PREC_NONE},
|
||||
/* TOKEN_COMMA */ {nil, nil, PREC_NONE},
|
||||
/* TOKEN_COLON */ {nil, nil, PREC_NONE},
|
||||
/* TOKEN_CARET */ {nil, nil, PREC_NONE},
|
||||
|
|
@ -1015,7 +1092,8 @@ compile(Arena *a, List *c, List* m, Emitter *e, char *source)
|
|||
|
||||
build_symbol_table(source);
|
||||
parser->pass++;
|
||||
parser->scope_idx = 0;
|
||||
parser->depth = 0;
|
||||
parser->scope_idx = 1;
|
||||
emit_program(source);
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ typedef struct parse_rule_s ParseRule;
|
|||
|
||||
struct scope_s {
|
||||
Scope *parent; /* pointer to this scopes parent to "bubble up"*/
|
||||
Scope *child; /* pointer to this scopes parent to "bubble up"*/
|
||||
List *symbols; /* list of symbols that live in this scope */
|
||||
u32 locals_offset;
|
||||
};
|
||||
|
|
@ -45,6 +44,7 @@ struct parser_s {
|
|||
List *scopes;
|
||||
Token current;
|
||||
Token previous;
|
||||
Token before;
|
||||
SymbolType current_type;
|
||||
u32 scope_idx;
|
||||
u32 depth;
|
||||
|
|
|
|||
26
emit.h
26
emit.h
|
|
@ -14,6 +14,7 @@ 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 void (*U32ArgEmit)(Arena *a, List *out, u32 ptr);
|
||||
typedef void (*RawEmit)(Arena *a, List *out, Symbol *sym, const char *str, u32 length);
|
||||
|
||||
typedef struct emitter_s Emitter;
|
||||
struct emitter_s {
|
||||
|
|
@ -25,16 +26,16 @@ struct emitter_s {
|
|||
SymbolSize get_size;
|
||||
VoidArgEmit prolog;
|
||||
VoidArgEmit epilogue;
|
||||
VoidArgEmit emit_add;
|
||||
VoidArgEmit emit_sub;
|
||||
VoidArgEmit emit_mul;
|
||||
VoidArgEmit emit_div;
|
||||
VoidArgEmit emit_lt;
|
||||
VoidArgEmit emit_le;
|
||||
VoidArgEmit emit_gt;
|
||||
VoidArgEmit emit_ge;
|
||||
VoidArgEmit emit_ne;
|
||||
VoidArgEmit emit_eq;
|
||||
U32ArgEmit emit_add;
|
||||
U32ArgEmit emit_sub;
|
||||
U32ArgEmit emit_mul;
|
||||
U32ArgEmit emit_div;
|
||||
U32ArgEmit emit_lt;
|
||||
U32ArgEmit emit_le;
|
||||
U32ArgEmit emit_gt;
|
||||
U32ArgEmit emit_ge;
|
||||
U32ArgEmit emit_ne;
|
||||
U32ArgEmit emit_eq;
|
||||
VoidArgEmit emit_false;
|
||||
VoidArgEmit emit_true;
|
||||
VoidArgEmit emit_nil;
|
||||
|
|
@ -43,7 +44,7 @@ struct emitter_s {
|
|||
StrArgEmit emit_nat;
|
||||
StrArgEmit emit_real;
|
||||
StrArgEmit emit_byte;
|
||||
StrArgEmit emit_str;
|
||||
RawEmit emit_str;
|
||||
VarEmit emit_type;
|
||||
MultipleEmit emit_array;
|
||||
SymbolEmit emit_function;
|
||||
|
|
@ -102,11 +103,12 @@ struct emitter_s {
|
|||
VoidArgEmit emit_early_return;
|
||||
VoidArgEmit emit_halt;
|
||||
SymbolEmit emit_deref_prolog;
|
||||
VoidArgEmit emit_deref;
|
||||
U32ArgEmit emit_deref;
|
||||
VoidArgEmit emit_ref;
|
||||
U32ArgEmit emit_address;
|
||||
U32ArgEmit emit_zero_block;
|
||||
StrArgEmit emit_char;
|
||||
StrArgEmit emit_inline_str;
|
||||
};
|
||||
|
||||
Emitter rer_emitter(void);
|
||||
|
|
|
|||
161
emit/rer/emit.c
161
emit/rer/emit.c
|
|
@ -689,86 +689,87 @@ rer_emitter()
|
|||
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_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_early_return,
|
||||
rer_emit_halt,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
|
|
|
|||
161
emit/uxn/emit.c
161
emit/uxn/emit.c
|
|
@ -595,63 +595,89 @@ uxn_epilogue(Arena *a, List *out)
|
|||
}
|
||||
|
||||
void
|
||||
uxn_emit_add(Arena *a, List *out)
|
||||
uxn_emit_add(Arena *a, List *out, u32 size)
|
||||
{
|
||||
if (size > 1)
|
||||
StrBuf_append(a, out, "ADD2 ");
|
||||
else
|
||||
StrBuf_append(a, out, "ADD ");
|
||||
}
|
||||
|
||||
void
|
||||
uxn_emit_sub(Arena *a, List *out)
|
||||
uxn_emit_sub(Arena *a, List *out, u32 size)
|
||||
{
|
||||
if (size > 1)
|
||||
StrBuf_append(a, out, "SUB2 ");
|
||||
else
|
||||
StrBuf_append(a, out, "SUB ");
|
||||
}
|
||||
|
||||
void
|
||||
uxn_emit_mul(Arena *a, List *out)
|
||||
uxn_emit_mul(Arena *a, List *out, u32 size)
|
||||
{
|
||||
if (size > 1)
|
||||
StrBuf_append(a, out, "MUL2 ");
|
||||
else
|
||||
StrBuf_append(a, out, "MUL ");
|
||||
}
|
||||
|
||||
void
|
||||
uxn_emit_div(Arena *a, List *out)
|
||||
uxn_emit_div(Arena *a, List *out, u32 size)
|
||||
{
|
||||
if (size > 1)
|
||||
StrBuf_append(a, out, "DIV2 ");
|
||||
else
|
||||
StrBuf_append(a, out, "DIV ");
|
||||
}
|
||||
|
||||
void
|
||||
uxn_emit_lt(Arena *a, List *out)
|
||||
uxn_emit_lt(Arena *a, List *out, u32 size)
|
||||
{
|
||||
if (size > 1)
|
||||
StrBuf_append(a, out, "LTH2 ");
|
||||
else
|
||||
StrBuf_append(a, out, "LTH ");
|
||||
}
|
||||
|
||||
void
|
||||
uxn_emit_le(Arena *a, List *out)
|
||||
uxn_emit_le(Arena *a, List *out, u32 size)
|
||||
{
|
||||
USED(size);
|
||||
StrBuf_append(a, out, "ROT SWP LTH ?{ LTH #00 EQU JMPr } GTH JMPr ");
|
||||
}
|
||||
|
||||
void
|
||||
uxn_emit_gt(Arena *a, List *out)
|
||||
uxn_emit_gt(Arena *a, List *out, u32 size)
|
||||
{
|
||||
if (size > 1)
|
||||
StrBuf_append(a, out, "GTH2 ");
|
||||
else
|
||||
StrBuf_append(a, out, "GTH ");
|
||||
}
|
||||
|
||||
void
|
||||
uxn_emit_ge(Arena *a, List *out)
|
||||
uxn_emit_ge(Arena *a, List *out, u32 size)
|
||||
{
|
||||
USED(size);
|
||||
StrBuf_append(a, out, "ROT SWP GTH ?{ GTH #00 EQU JMPr } LTH JMPr ");
|
||||
}
|
||||
|
||||
void
|
||||
uxn_emit_ne(Arena *a, List *out)
|
||||
uxn_emit_ne(Arena *a, List *out, u32 size)
|
||||
{
|
||||
if (size > 1)
|
||||
StrBuf_append(a, out, "NEQ2 ");
|
||||
else
|
||||
StrBuf_append(a, out, "NEQ ");
|
||||
}
|
||||
|
||||
void
|
||||
uxn_emit_eq(Arena *a, List *out)
|
||||
uxn_emit_eq(Arena *a, List *out, u32 size)
|
||||
{
|
||||
if (size > 1)
|
||||
StrBuf_append(a, out, "EQU2 ");
|
||||
else
|
||||
StrBuf_append(a, out, "EQU ");
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -786,46 +812,11 @@ uxn_emit_byte(Arena *a, List *out, const char *str, i32 length)
|
|||
void
|
||||
uxn_emit_char(Arena *a, List *out, const char *str, i32 length)
|
||||
{
|
||||
sprintf(uxn_temp_strbuf, "#%04x ", (char)str[0]);
|
||||
sprintf(uxn_temp_strbuf, "#%02x ", (char)str[1]);
|
||||
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||
USED(length);
|
||||
}
|
||||
|
||||
void
|
||||
uxn_emit_str(Arena *a, List *out, const char *str, i32 length)
|
||||
{
|
||||
/* set a pointer to the string literal and then jump over it */
|
||||
StrBuf_append(a, out, ";{ #0002 ADD2 } !{ ");
|
||||
|
||||
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(uxn_temp_strbuf, "%02x ", c);
|
||||
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||
}
|
||||
|
||||
StrBuf_append(a, out, "00 } ");
|
||||
}
|
||||
|
||||
void
|
||||
uxn_emit_constant(Arena *a, List *out, Symbol *sym, bool local)
|
||||
{
|
||||
|
|
@ -955,6 +946,77 @@ uxn_emit_array(Arena *a, List *out, Symbol *sym, List *in)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
uxn_emit_inline_str(Arena *a, List *out, const char *str, i32 length)
|
||||
{
|
||||
/* set a pointer to the string literal and then jump over it */
|
||||
StrBuf_append(a, out, ";{ #0002 ADD2 } !{ ");
|
||||
|
||||
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(uxn_temp_strbuf, "%02x ", c);
|
||||
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||
}
|
||||
|
||||
StrBuf_append(a, out, "00 } ");
|
||||
}
|
||||
|
||||
void
|
||||
uxn_emit_str(Arena *a, List *out, Symbol *sym, const char *str, u32 length)
|
||||
{
|
||||
sprintf(uxn_temp_strbuf, "@%.*s %04x ", sym->name_length, sym->name, length - 2);
|
||||
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||
|
||||
u32 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(uxn_temp_strbuf, "%02x ", c);
|
||||
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||
}
|
||||
|
||||
StrBuf_append(a, out, "00 ");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
uxn_emit_deref_prolog(Arena *a, List *out, Symbol *sym)
|
||||
{
|
||||
|
|
@ -963,9 +1025,13 @@ uxn_emit_deref_prolog(Arena *a, List *out, Symbol *sym)
|
|||
}
|
||||
|
||||
void
|
||||
uxn_emit_deref(Arena *a, List *out)
|
||||
uxn_emit_deref(Arena *a, List *out, u32 size)
|
||||
{
|
||||
if (size > 1)
|
||||
StrBuf_append(a, out, "LDA2 ");
|
||||
else
|
||||
StrBuf_append(a, out, "LDA ");
|
||||
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -1474,5 +1540,6 @@ uxn_emitter()
|
|||
uxn_emit_address,
|
||||
uxn_emit_zero_block,
|
||||
uxn_emit_char,
|
||||
uxn_emit_inline_str,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
2
lexer.h
2
lexer.h
|
|
@ -12,6 +12,7 @@ typedef enum {
|
|||
TOKEN_RBRACE,
|
||||
TOKEN_LBRACKET,
|
||||
TOKEN_RBRACKET,
|
||||
TOKEN_DOT,
|
||||
TOKEN_IDENTIFIER,
|
||||
TOKEN_LITERAL_INT,
|
||||
TOKEN_LITERAL_NAT,
|
||||
|
|
@ -76,7 +77,6 @@ typedef enum {
|
|||
TOKEN_LT,
|
||||
TOKEN_GTE,
|
||||
TOKEN_LTE,
|
||||
TOKEN_DOT,
|
||||
TOKEN_COMMA,
|
||||
TOKEN_COLON,
|
||||
TOKEN_CARET,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
str msg = " damage inflicted!\n"
|
||||
str msg = " damage inflicted!\n";
|
||||
nat AT = 14;
|
||||
nat accuracy = 150;
|
||||
|
||||
|
|
|
|||
|
|
@ -23,10 +23,8 @@ function bf(str code)
|
|||
{
|
||||
nat mp; // memory pointer
|
||||
nat ip = 0; // instruction pointer
|
||||
// while (ip < code.length) {
|
||||
// if (ip > code.length) { return; }
|
||||
while (ip < 106) {
|
||||
if (ip < 0 or ip > 106) { return; }
|
||||
while (ip < code.length) {
|
||||
if (ip > code.length) { return; }
|
||||
if (mp > memory.length) { return; }
|
||||
if (code[ip] == '>') {
|
||||
mp = mp + 1;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
str msg = " damage inflicted!\n";
|
||||
|
||||
if (msg[1] == 'd') {
|
||||
print("yes\n");
|
||||
}
|
||||
|
||||
print(msg.length as str);
|
||||
print(msg);
|
||||
halt;
|
||||
Loading…
Reference in New Issue