fix local variables, wip: globals
This commit is contained in:
parent
28598e354a
commit
251101ecb8
1
common.h
1
common.h
|
|
@ -37,6 +37,7 @@ struct symbol_s {
|
||||||
SymbolType secondary_type; /* return type for functions/methods, or const if type/plex */
|
SymbolType secondary_type; /* return type for functions/methods, or const if type/plex */
|
||||||
u32 ref; /* either constant value or pointer to other thing */
|
u32 ref; /* either constant value or pointer to other thing */
|
||||||
u32 size; /* either size of the plex or length of the array/list/etc. */
|
u32 size; /* either size of the plex or length of the array/list/etc. */
|
||||||
|
u32 scope; /* scope ref */
|
||||||
List *args; /* function params or plex constructor args */
|
List *args; /* function params or plex constructor args */
|
||||||
List *fields; /* either plex variable fields, or method signatures */
|
List *fields; /* either plex variable fields, or method signatures */
|
||||||
};
|
};
|
||||||
|
|
|
||||||
99
compiler.c
99
compiler.c
|
|
@ -89,6 +89,7 @@ scope_add_symbol(const char *name, u32 name_length, SymbolType type, u32 size)
|
||||||
new_sym.secondary_type = SYMBOL_VOID;
|
new_sym.secondary_type = SYMBOL_VOID;
|
||||||
new_sym.size = size;
|
new_sym.size = size;
|
||||||
new_sym.ref = parser.current_scope->locals_offset;
|
new_sym.ref = parser.current_scope->locals_offset;
|
||||||
|
new_sym.scope = parser.scope_idx;
|
||||||
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) {
|
||||||
|
|
@ -245,7 +246,7 @@ define_function()
|
||||||
scope_pop();
|
scope_pop();
|
||||||
continue;
|
continue;
|
||||||
} else if(is_type() && parser.current.type == TOKEN_IDENTIFIER)
|
} else if(is_type() && parser.current.type == TOKEN_IDENTIFIER)
|
||||||
size += variable_declaration(fn);
|
size += variable_declaration(nil);
|
||||||
advance();
|
advance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -274,6 +275,7 @@ build_symbol_table(char *source)
|
||||||
} else {
|
} else {
|
||||||
/* in binary bytecode output mode we need to count the bytes here */
|
/* in binary bytecode output mode we need to count the bytes here */
|
||||||
/* otherwise ignore everything */
|
/* otherwise ignore everything */
|
||||||
|
advance();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -284,6 +286,54 @@ void declaration();
|
||||||
ParseRule *get_rule(TokenType type);
|
ParseRule *get_rule(TokenType type);
|
||||||
void parse_precedence(Precedence precedence);
|
void parse_precedence(Precedence precedence);
|
||||||
|
|
||||||
|
u32
|
||||||
|
variable_declaration(Symbol *def)
|
||||||
|
{
|
||||||
|
i32 size = 0;
|
||||||
|
TokenType tt = parser.previous.type;
|
||||||
|
SymbolType st = token_type_to_sym_type(tt);
|
||||||
|
Symbol *variable;
|
||||||
|
|
||||||
|
if(st != SYMBOL_UNDEFINED) {
|
||||||
|
size = emitter.get_size(st);
|
||||||
|
|
||||||
|
variable =
|
||||||
|
scope_add_symbol(parser.current.start, parser.current.length, st, size);
|
||||||
|
if (!def && (parser.pass == 0)) {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(def) {
|
||||||
|
List_push(arena, def->args, variable, sizeof(Symbol));
|
||||||
|
} else {
|
||||||
|
emitter.emit_type(variable, parser.depth);
|
||||||
|
parser.current_type = st;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* we need to look up the type */
|
||||||
|
emitter.error("Not implemented", 16, parser.previous.line);
|
||||||
|
}
|
||||||
|
|
||||||
|
advance();
|
||||||
|
|
||||||
|
if(def && (check(TOKEN_COMMA) || check(TOKEN_RPAREN))) return size;
|
||||||
|
if(def)
|
||||||
|
emitter.error(parser.previous.start, parser.previous.length,
|
||||||
|
parser.previous.line);
|
||||||
|
if (parser.pass == 0) return size;
|
||||||
|
|
||||||
|
if(match(TOKEN_EQ)) {
|
||||||
|
emitter.emit_set_value();
|
||||||
|
expression();
|
||||||
|
emitter.emit_constant(variable, parser.depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
consume(TOKEN_SEMICOLON);
|
||||||
|
emitter.emit_end_statement();
|
||||||
|
parser.current_type = SYMBOL_UNDEFINED;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
binary()
|
binary()
|
||||||
{
|
{
|
||||||
|
|
@ -388,9 +438,9 @@ variable()
|
||||||
parser.current_type = sym->type;
|
parser.current_type = sym->type;
|
||||||
if(match(TOKEN_EQ)) {
|
if(match(TOKEN_EQ)) {
|
||||||
expression();
|
expression();
|
||||||
emitter.emit_set_variable(sym, parser.depth);
|
emitter.emit_set_variable(sym, sym->scope);
|
||||||
} else {
|
} else {
|
||||||
emitter.emit_variable(sym, parser.depth);
|
emitter.emit_variable(sym, sym->scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -484,49 +534,6 @@ cast_type()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u32
|
|
||||||
variable_declaration(Symbol *def)
|
|
||||||
{
|
|
||||||
i32 size = 0;
|
|
||||||
TokenType tt = parser.previous.type;
|
|
||||||
Token var = parser.current;
|
|
||||||
SymbolType st = token_type_to_sym_type(tt);
|
|
||||||
Symbol *variable;
|
|
||||||
|
|
||||||
if(st != SYMBOL_UNDEFINED) {
|
|
||||||
size = emitter.get_size(st);
|
|
||||||
variable =
|
|
||||||
scope_add_symbol(parser.current.start, parser.current.length, st, size);
|
|
||||||
if(def) {
|
|
||||||
List_push(arena, def->args, variable, sizeof(Symbol));
|
|
||||||
} else {
|
|
||||||
emitter.emit_type(variable, parser.depth);
|
|
||||||
parser.current_type = st;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* we need to look up the type */
|
|
||||||
emitter.error("Not implemented", 16, parser.previous.line);
|
|
||||||
}
|
|
||||||
|
|
||||||
advance();
|
|
||||||
|
|
||||||
if(def && (check(TOKEN_COMMA) || check(TOKEN_RPAREN))) return size;
|
|
||||||
if(def)
|
|
||||||
emitter.error(parser.previous.start, parser.previous.length,
|
|
||||||
parser.previous.line);
|
|
||||||
|
|
||||||
if(match(TOKEN_EQ)) {
|
|
||||||
emitter.emit_set_value();
|
|
||||||
expression();
|
|
||||||
emitter.emit_constant(var.start, var.length, parser.depth);
|
|
||||||
}
|
|
||||||
|
|
||||||
consume(TOKEN_SEMICOLON);
|
|
||||||
emitter.emit_end_statement();
|
|
||||||
parser.current_type = SYMBOL_UNDEFINED;
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
declaration()
|
declaration()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
3
emit.h
3
emit.h
|
|
@ -9,7 +9,6 @@ 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 void (*ConstEmit)(const char *str, i32 length, bool local);
|
|
||||||
typedef void (*VarEmit)(Symbol *sym, bool local);
|
typedef void (*VarEmit)(Symbol *sym, bool local);
|
||||||
typedef void (*I32ArgEmit)(i32 val);
|
typedef void (*I32ArgEmit)(i32 val);
|
||||||
|
|
||||||
|
|
@ -56,7 +55,7 @@ struct emitter_s {
|
||||||
VoidArgEmit emit_not;
|
VoidArgEmit emit_not;
|
||||||
VoidArgEmit emit_open_paren;
|
VoidArgEmit emit_open_paren;
|
||||||
VoidArgEmit emit_close_paren;
|
VoidArgEmit emit_close_paren;
|
||||||
ConstEmit emit_constant;
|
VarEmit emit_constant;
|
||||||
VarEmit emit_variable;
|
VarEmit emit_variable;
|
||||||
VarEmit emit_set_variable;
|
VarEmit emit_set_variable;
|
||||||
VoidArgEmit emit_write;
|
VoidArgEmit emit_write;
|
||||||
|
|
|
||||||
|
|
@ -270,12 +270,15 @@ rer_emit_str(const char *str, i32 length)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rer_emit_constant(const char *str, i32 length, bool local)
|
rer_emit_constant(Symbol *sym, bool local)
|
||||||
{
|
{
|
||||||
if(local)
|
if(local)
|
||||||
printf(",/%.*s STR2 ", length, str);
|
if(sym->ref)
|
||||||
|
printf("\tSTH2kr #%04x ADD2 LDA2\n", sym->ref);
|
||||||
|
else
|
||||||
|
printf("\tSTH2kr LDA2\n");
|
||||||
else
|
else
|
||||||
printf(";%.*s STA2 ", length, str);
|
printf(";%.*s STA2 ", sym->name_length, sym->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -435,12 +435,15 @@ uxn_emit_str(const char *str, i32 length)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uxn_emit_constant(const char *str, i32 length, bool local)
|
uxn_emit_constant(Symbol *sym, bool local)
|
||||||
{
|
{
|
||||||
if(local)
|
if(local)
|
||||||
printf(",/%.*s STR2 ", length, str);
|
if(sym->ref)
|
||||||
|
printf("\tSTH2kr #%04x ADD2 STA2\n", sym->ref);
|
||||||
|
else
|
||||||
|
printf("\tSTH2kr STA2\n");
|
||||||
else
|
else
|
||||||
printf(";%.*s STA2 ", length, str);
|
printf(";%.*s STA2 ", sym->name_length, sym->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@ str msg = " damage inflicted!\n"
|
||||||
nat AT = 14;
|
nat AT = 14;
|
||||||
nat accuracy = 150;
|
nat accuracy = 150;
|
||||||
|
|
||||||
nat dmg = ((AT * accuracy) / 20) - 3;
|
function main() {
|
||||||
|
nat dmg = ((AT * accuracy) / 20) - 3;
|
||||||
|
|
||||||
print(dmg as str);
|
print(dmg as str);
|
||||||
print(msg);
|
print(msg);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,82 @@
|
||||||
|
|100
|
||||||
|
LIT2r 0000 main_ POP2r BRK
|
||||||
|
|
||||||
|
@main_ ( -- )
|
||||||
|
|
||||||
|
#0017 fib_ nat_to_str_ str/<print>
|
||||||
|
&return
|
||||||
|
POP2r JMP2r
|
||||||
|
|
||||||
|
@fib_ ( n -- res )
|
||||||
|
OVR2r LIT2r 0002 SUB2r
|
||||||
|
STH2kr STA2
|
||||||
|
|
||||||
|
STH2kr LDA2 #0002 LTH2 #03 JCN !{
|
||||||
|
STH2kr LDA2 !&return !&if_end.0 } &if_end.0
|
||||||
|
STH2kr LDA2 #0002 SUB2 fib_ STH2kr LDA2 #0001 SUB2 fib_ ADD2 !&return &return
|
||||||
|
POP2r JMP2r
|
||||||
|
|
||||||
|
@sext
|
||||||
|
#80 ANDk EQU #ff MUL SWP JMP2r
|
||||||
|
|
||||||
|
@aalloc_ ( size* -- result* )
|
||||||
|
OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2
|
||||||
|
;mem_length_ LDA2 STH2kr STA2
|
||||||
|
;mem_length_ LDA2k STH2kr INC2 INC2 LDA2 ADD2 SWP2 STA2
|
||||||
|
;mem_ STH2kr LDA2 ADD2 !&return
|
||||||
|
#0000
|
||||||
|
|
||||||
|
&return
|
||||||
|
POP2r JMP2r
|
||||||
|
|
||||||
|
@amcpy_ ( length* from* -- result* )
|
||||||
|
OVR2r LIT2r 0008 SUB2r STH2kr #0006 ADD2 STA2
|
||||||
|
STH2kr #0004 ADD2 STA2
|
||||||
|
STH2kr #0004 ADD2 LDA2 aalloc_
|
||||||
|
STH2kr INC2 INC2 STA2
|
||||||
|
#0000 STH2kr STA2
|
||||||
|
|
||||||
|
&begin.1
|
||||||
|
STH2kr LDA2 STH2kr #0004 ADD2 LDA2 LTH2 #00 EQU ?&break.1
|
||||||
|
STH2kr #0006 ADD2 LDA2 STH2kr LDA2 ADD2 LDA sext
|
||||||
|
STH2kr INC2 INC2 LDA2 STH2kr LDA2 ADD2 STA
|
||||||
|
POP
|
||||||
|
|
||||||
|
&continue.1
|
||||||
|
STH2kr LDA2k INC2k ROT2 STA2
|
||||||
|
POP2 !&begin.1
|
||||||
|
|
||||||
|
&break.1
|
||||||
|
STH2kr INC2 INC2 LDA2 !&return
|
||||||
|
#0000
|
||||||
|
|
||||||
|
&return
|
||||||
|
POP2r JMP2r
|
||||||
|
|
||||||
|
@nat_to_str_ ( n* -- result* )
|
||||||
|
OVR2r LIT2r 000a SUB2r STH2kr #0008 ADD2 STA2
|
||||||
|
#0005 STH2kr STA2
|
||||||
|
|
||||||
|
&begin.1
|
||||||
|
STH2kr #0008 ADD2 LDA2 #000a OVR2 OVR2 DIV2 MUL2 SUB2 #0030 ADD2 STH2kr INC2 INC2 STH2kr LDA2k #0001 SUB2 SWP2 STA2k
|
||||||
|
POP2 ADD2 STA
|
||||||
|
POP STH2kr #0008 ADD2 LDA2k #000a DIV2 SWP2 STA2
|
||||||
|
|
||||||
|
&continue.1
|
||||||
|
#0000 STH2kr #0008 ADD2 LDA2 LTH2 ?&begin.1
|
||||||
|
|
||||||
|
&break.1
|
||||||
|
#0005 STH2kr LDA2 SUB2 STH2kr INC2 INC2 STH2kr LDA2 ADD2 amcpy_
|
||||||
|
!&return
|
||||||
|
#0000
|
||||||
|
|
||||||
|
&return
|
||||||
|
POP2r JMP2r
|
||||||
|
|
||||||
|
@str/<print> ( str* -- )
|
||||||
|
LDAk DUP ?{ POP POP2 JMP2r }
|
||||||
|
#18 DEO
|
||||||
|
INC2 !/<print>
|
||||||
|
|
||||||
|
@mem_length_ #0000
|
||||||
|
@mem_
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
int i = 122;
|
int i = 122;
|
||||||
int j = 32;
|
int j = 32;
|
||||||
putchar((i - j));
|
|
||||||
|
function main() {
|
||||||
|
putchar((i - j));
|
||||||
|
}
|
||||||
|
|
|
||||||
18
test/if.ul
18
test/if.ul
|
|
@ -1,9 +1,11 @@
|
||||||
nat x = 20;
|
function main() {
|
||||||
|
nat x = 20;
|
||||||
|
|
||||||
if (x == 10) {
|
if (x == 10) {
|
||||||
print("x is 10");
|
print("x is 10");
|
||||||
} else if (x == 20) {
|
} else if (x == 20) {
|
||||||
print("x is 20");
|
print("x is 20");
|
||||||
} else {
|
} else {
|
||||||
print("x is something else");
|
print("x is something else");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue