Fix everything except for casting
This commit is contained in:
parent
bb764a3017
commit
99675eb6d3
80
compiler.c
80
compiler.c
|
|
@ -10,26 +10,51 @@ Arena *arena;
|
|||
/****************************************************
|
||||
* Scope
|
||||
***************************************************/
|
||||
|
||||
void
|
||||
scope_push()
|
||||
scopes_init()
|
||||
{
|
||||
Scope *child = aalloc(arena, sizeof(Scope));
|
||||
child->symbols = List_init(arena);
|
||||
child->parent = parser.current_scope;
|
||||
child->locals_offset = 0;
|
||||
Scope *current;
|
||||
Scope child = {0};
|
||||
child.symbols = List_init(arena);
|
||||
child.locals_offset = 0;
|
||||
|
||||
parser.current_scope = child;
|
||||
current = (Scope*)List_push(arena, parser.scopes, &child, sizeof(Scope));
|
||||
parser.current_scope = current;
|
||||
}
|
||||
|
||||
Scope*
|
||||
scope_new()
|
||||
{
|
||||
Scope *current;
|
||||
Scope child = {0};
|
||||
child.symbols = List_init(arena);
|
||||
child.parent = parser.current_scope;
|
||||
child.locals_offset = 0;
|
||||
|
||||
current = (Scope*)List_push(arena, parser.scopes, &child, sizeof(Scope));
|
||||
parser.current_scope = current;
|
||||
parser.scope_idx++;
|
||||
parser.depth++;
|
||||
return current;
|
||||
}
|
||||
|
||||
void
|
||||
scope_pop()
|
||||
{
|
||||
Scope *prev = parser.current_scope->parent;
|
||||
parser.current_scope = prev;
|
||||
if (parser.current_scope) {
|
||||
parser.current_scope = parser.current_scope->parent;
|
||||
parser.depth--;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
scope_push()
|
||||
{
|
||||
Scope *scope = List_get(parser.scopes, parser.scope_idx);
|
||||
parser.current_scope = scope;
|
||||
parser.depth++;
|
||||
parser.scope_idx++;
|
||||
}
|
||||
|
||||
Symbol *
|
||||
scope_get_symbol(Scope *scope, const char *name, u32 name_length)
|
||||
|
|
@ -49,6 +74,7 @@ scope_get_symbol(Scope *scope, const char *name, u32 name_length)
|
|||
Symbol *
|
||||
scope_add_symbol(const char *name, u32 name_length, SymbolType type, u32 size)
|
||||
{
|
||||
Symbol new_sym = {0};
|
||||
Symbol *sym = scope_get_symbol(parser.current_scope, name, name_length);
|
||||
if(sym != nil) {
|
||||
if(parser.pass)
|
||||
|
|
@ -57,25 +83,22 @@ scope_add_symbol(const char *name, u32 name_length, SymbolType type, u32 size)
|
|||
emitter.error("duplicate found", 14, parser.previous.line);
|
||||
}
|
||||
|
||||
sym = aalloc(arena, sizeof(Symbol));
|
||||
scpy(sym->name, name, name_length);
|
||||
sym->name_length = name_length;
|
||||
sym->type = type;
|
||||
sym->secondary_type = SYMBOL_VOID;
|
||||
sym->size = size;
|
||||
sym->ref = parser.current_scope->locals_offset;
|
||||
scpy(new_sym.name, name, name_length);
|
||||
new_sym.name_length = name_length;
|
||||
new_sym.type = type;
|
||||
new_sym.secondary_type = SYMBOL_VOID;
|
||||
new_sym.size = size;
|
||||
new_sym.ref = parser.current_scope->locals_offset;
|
||||
parser.current_scope->locals_offset += size;
|
||||
if(type == SYMBOL_PLEX || type == SYMBOL_METHOD || type == SYMBOL_TRAIT ||
|
||||
type == SYMBOL_FUNCTION) {
|
||||
sym->args = List_init(arena);
|
||||
new_sym.args = List_init(arena);
|
||||
}
|
||||
|
||||
if(type == SYMBOL_PLEX || type == SYMBOL_METHOD || type == SYMBOL_TRAIT)
|
||||
sym->fields = List_init(arena);
|
||||
new_sym.fields = List_init(arena);
|
||||
|
||||
List_push(arena, parser.current_scope->symbols, sym, sizeof(Symbol));
|
||||
|
||||
return sym;
|
||||
return List_push(arena, parser.current_scope->symbols, &new_sym, sizeof(Symbol));
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -194,7 +217,7 @@ define_function()
|
|||
|
||||
/* need to push scope early because the variables need to be a part of the fn
|
||||
* scope */
|
||||
scope_push();
|
||||
scope_new();
|
||||
|
||||
expect(TOKEN_LPAREN);
|
||||
advance();
|
||||
|
|
@ -229,12 +252,12 @@ build_symbol_table(char *source)
|
|||
{
|
||||
init_lexer(source);
|
||||
advance();
|
||||
scope_push();
|
||||
scopes_init();
|
||||
|
||||
while(!match(TOKEN_EOF)) {
|
||||
|
||||
if(match(TOKEN_LBRACE)) {
|
||||
scope_push();
|
||||
scope_new();
|
||||
} else if(match(TOKEN_RBRACE)) {
|
||||
scope_pop();
|
||||
} else if(match(TOKEN_KEYWORD_FN)) {
|
||||
|
|
@ -502,7 +525,7 @@ variable_declaration(Symbol *def)
|
|||
void
|
||||
declaration()
|
||||
{
|
||||
if(is_type()) {
|
||||
if(is_type() && parser.current.type == TOKEN_IDENTIFIER) {
|
||||
variable_declaration(nil);
|
||||
}else{
|
||||
statement();
|
||||
|
|
@ -580,9 +603,12 @@ function()
|
|||
Symbol *sym = scope_get_symbol(parser.current_scope, parser.previous.start,
|
||||
parser.previous.length);
|
||||
emitter.emit_function(sym);
|
||||
while(!check(TOKEN_LBRACE)) {
|
||||
scope_push();
|
||||
while(!check(TOKEN_RPAREN)) {
|
||||
advance();
|
||||
}
|
||||
consume(TOKEN_RPAREN);
|
||||
consume(TOKEN_LBRACE);
|
||||
block();
|
||||
emitter.emit_arena_fn_return();
|
||||
}
|
||||
|
|
@ -795,9 +821,11 @@ compile(Arena *a, Emitter e, char *source)
|
|||
{
|
||||
arena = a;
|
||||
emitter = e;
|
||||
parser.scopes = List_init(arena);
|
||||
|
||||
build_symbol_table(source);
|
||||
parser.pass++;
|
||||
parser.scope_idx = 0;
|
||||
emit_program(source);
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ 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;
|
||||
};
|
||||
|
|
@ -41,12 +42,13 @@ 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;
|
||||
bool main_found;
|
||||
};
|
||||
|
||||
bool compile(Arena *a, Emitter e, char *source);
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ uxn_mem(u32 a)
|
|||
void
|
||||
uxn_prolog()
|
||||
{
|
||||
printf("|100\n\tLIT2r 0000 main POP2r BRK\n\n");
|
||||
printf("|100\n\tLIT2r 0000 main_ POP2r BRK\n\n");
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -478,7 +478,8 @@ uxn_emit_function(Symbol *sym)
|
|||
sym->secondary_type != SYMBOL_VOID)
|
||||
printf(" res ");
|
||||
printf(")\n");
|
||||
printf("\tOVR2r LIT2r #%04x SUB2r\n", sym->size);
|
||||
if (sym->size > 0)
|
||||
printf("\tOVR2r LIT2r %04x SUB2r\n", sym->size);
|
||||
List_map(sym->args, fn_loop_emit_args);
|
||||
printf("\n");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
|100
|
||||
LIT2r 0000 main POP2r BRK
|
||||
LIT2r 0000 main_ POP2r BRK
|
||||
|
||||
@main_ ( -- )
|
||||
|
||||
@main ( -- )
|
||||
#0001 #0001 add_ nat_to_str_ str/<println>
|
||||
|
||||
&return
|
||||
POP2r JMP2r
|
||||
|
||||
|
|
@ -12,7 +12,9 @@
|
|||
STH2kr STA2
|
||||
STH2kr #0002 ADD2 STA2
|
||||
|
||||
STH2kr LDA2 STH2kr #0002 ADD2 LDA2 ADD2
|
||||
STH2kr LDA2
|
||||
STH2kr #0002 ADD2 LDA2
|
||||
ADD2
|
||||
|
||||
&return
|
||||
POP2r JMP2r
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
|
||||
function main() {
|
||||
print(add(1, 1) as str);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
49
test/str.ul
49
test/str.ul
|
|
@ -2,20 +2,15 @@
|
|||
* Constants
|
||||
*/
|
||||
const str nl = "\n";
|
||||
const str terminal_namespace = "/dev/term/0";
|
||||
|
||||
plex Terminal {
|
||||
nat handle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print with a newline
|
||||
*/
|
||||
function pln(str string) {
|
||||
Terminal term = open(terminal_namespace, 0);
|
||||
write(term, string, string.length);
|
||||
write(term, nl, nl.length);
|
||||
// implied return because it is a void function.
|
||||
for (byte c in string) {
|
||||
putchar(c);
|
||||
}
|
||||
putchar(nl);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -23,10 +18,8 @@ function pln(str string) {
|
|||
*/
|
||||
function concat(str src1, str src2) str {
|
||||
str result = malloc(src1.length + src2.length);
|
||||
// note result[0].ref is much different than result.ref[0] !
|
||||
// result[0].ref means the pointer at char 0 (pointer to first char)
|
||||
memcpy(result[0].ref, src1.ref);
|
||||
memcpy(result[src1.length].ref, src2.ref);
|
||||
memcpy(result[0].ptr, src1.ptr);
|
||||
memcpy(result[src1.length].ptr, src2.ptr);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -36,6 +29,7 @@ function concat(str src1, str src2) str {
|
|||
function str_index_of(str haystack, byte needle) int {
|
||||
int i = -1;
|
||||
for (byte c in haystack) {
|
||||
i = i + 1;
|
||||
if (c == needle) {
|
||||
break;
|
||||
}
|
||||
|
|
@ -48,7 +42,7 @@ function str_index_of(str haystack, byte needle) int {
|
|||
*/
|
||||
function str_eq(str src1, str src2) bool {
|
||||
if (src1.length != src2.length) return false;
|
||||
do (int i=0; src1.length; i++) {
|
||||
for (int i=0; src1.length; i++) {
|
||||
if (src1[i] != src2[i]) return false;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -60,7 +54,7 @@ function str_eq(str src1, str src2) bool {
|
|||
function str_slice(str src, int start, int stop) str {
|
||||
int len = stop - start;
|
||||
str result = malloc(len);
|
||||
do (int i=start; i<stop; i++) {
|
||||
for (int i=start; i<stop; i++) {
|
||||
result[i] = src[i];
|
||||
}
|
||||
return result;
|
||||
|
|
@ -70,14 +64,39 @@ function str_slice(str src, int start, int stop) str {
|
|||
* int to string
|
||||
*/
|
||||
function itos(int src) str {
|
||||
byte buffer[6];
|
||||
nat i = 6;
|
||||
bool neg = n < 0;
|
||||
|
||||
if (neg) n = -n;
|
||||
|
||||
do {
|
||||
buffer[--i] = '0' + n % 10;
|
||||
n /= 10;
|
||||
} while(n > 0);
|
||||
|
||||
if(neg) buffer[--i] = '-';
|
||||
|
||||
str result = malloc(6 - i);
|
||||
memcpy(result, buffer[0].ptr + i, 6 - i);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* nat to string
|
||||
*/
|
||||
function ntos(nat src) str {
|
||||
byte buffer[5];
|
||||
nat i = 5;
|
||||
|
||||
do {
|
||||
buffer[--i] = '0' + n % 10;
|
||||
n /= 10;
|
||||
} while(n > 0);
|
||||
|
||||
str result = malloc(5 - i);
|
||||
memcpy(result, buffer[0].ptr + i, 5 - i);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in New Issue