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