WIP array fixes
This commit is contained in:
parent
0ab7ef872b
commit
9c746ad15b
151
compiler.c
151
compiler.c
|
|
@ -209,7 +209,7 @@ expect(TokenType type)
|
|||
{
|
||||
if(!consume(type)) {
|
||||
emitter->error(parser->previous.start, parser->previous.length,
|
||||
parser->previous.line);
|
||||
parser->previous.line);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -278,7 +278,7 @@ calculate_strides(List *dims, List *strides)
|
|||
u32 num_dims = dims->count;
|
||||
u32 current_stride = 1;
|
||||
|
||||
if (num_dims == 1) {
|
||||
if(num_dims == 1) {
|
||||
List_push(arena, strides, ¤t_stride, sizeof(u32));
|
||||
return;
|
||||
}
|
||||
|
|
@ -287,11 +287,12 @@ calculate_strides(List *dims, List *strides)
|
|||
List_push(arena, strides, ¤t_stride, sizeof(u32));
|
||||
|
||||
/* this is very slow but for small numbers of dimensions its fine */
|
||||
num = (u32*)List_get(dims, i);
|
||||
if (num){
|
||||
num = (u32 *)List_get(dims, i);
|
||||
if(num) {
|
||||
current_stride *= (*num);
|
||||
} else {
|
||||
emitter->error("Tried to get a dimension that did not exist", 43, parser->previous.line);
|
||||
emitter->error("Tried to get a dimension that did not exist", 43,
|
||||
parser->previous.line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -324,7 +325,7 @@ define_array(void)
|
|||
size = emitter->get_size(st) * flat_array_length;
|
||||
|
||||
array = scope_add_symbol(parser->current.start, parser->current.length,
|
||||
SYMBOL_ARRAY, size);
|
||||
SYMBOL_ARRAY, size);
|
||||
array->secondary_type = st;
|
||||
calculate_strides(dims, strides);
|
||||
array->args = dims;
|
||||
|
|
@ -334,9 +335,8 @@ define_array(void)
|
|||
void
|
||||
define_string(void)
|
||||
{
|
||||
scope_add_symbol(parser->current.start,
|
||||
parser->current.length,
|
||||
SYMBOL_STR, 0);
|
||||
scope_add_symbol(parser->current.start, parser->current.length, SYMBOL_STR,
|
||||
0);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -358,14 +358,13 @@ 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)) {
|
||||
} 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) {
|
||||
} else if(parser->current.type >= TOKEN_TYPE_I8 &&
|
||||
parser->current.type <= TOKEN_TYPE_PTR) {
|
||||
advance();
|
||||
if (check(TOKEN_LBRACKET)) {
|
||||
define_array();
|
||||
}
|
||||
if(check(TOKEN_LBRACKET)) define_array();
|
||||
} else {
|
||||
/* in binary bytecode output mode we need to count the bytes here */
|
||||
/* otherwise ignore everything */
|
||||
|
|
@ -389,51 +388,47 @@ 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) {
|
||||
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)) {
|
||||
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);
|
||||
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();
|
||||
}
|
||||
if(parser->current.type == TOKEN_LBRACKET) {
|
||||
while(!check(TOKEN_RBRACKET)) advance();
|
||||
advance();
|
||||
|
||||
variable = scope_get_symbol(parser->current_scope,
|
||||
parser->current.start,
|
||||
parser->current.length);
|
||||
if (!variable) {
|
||||
variable = scope_get_symbol(parser->current_scope, parser->current.start,
|
||||
parser->current.length);
|
||||
if(!variable) {
|
||||
emitter->error("cannot find array symbol", 25, parser->current.line);
|
||||
return 0;
|
||||
}
|
||||
advance();
|
||||
|
||||
if (match(TOKEN_EQ)) {
|
||||
if(match(TOKEN_EQ)) {
|
||||
expect(TOKEN_LBRACKET);
|
||||
array_literal = List_init(arena);
|
||||
|
||||
while (!match(TOKEN_RBRACKET)) {
|
||||
while(!match(TOKEN_RBRACKET)) {
|
||||
StrBuf_append_exactly(arena, array_literal,
|
||||
(char*)parser->current.start,
|
||||
parser->current.length);
|
||||
(char *)parser->current.start,
|
||||
parser->current.length);
|
||||
advance();
|
||||
if(match(TOKEN_RBRACKET)) break;
|
||||
expect(TOKEN_COMMA);
|
||||
|
|
@ -445,7 +440,9 @@ variable_declaration(Symbol *def)
|
|||
expect(TOKEN_SEMICOLON);
|
||||
|
||||
emitter->emit_array(arena, memory, variable, nil);
|
||||
emitter->emit_zero_block(arena, memory, variable->size * emitter->get_size(variable->secondary_type));
|
||||
emitter->emit_zero_block(arena, memory,
|
||||
variable->size *
|
||||
emitter->get_size(variable->secondary_type));
|
||||
}
|
||||
|
||||
parser->current_type = st;
|
||||
|
|
@ -455,7 +452,8 @@ variable_declaration(Symbol *def)
|
|||
if(st != SYMBOL_UNDEFINED) {
|
||||
size = emitter->get_size(st);
|
||||
|
||||
variable = scope_add_symbol(parser->current.start, parser->current.length, st, size);
|
||||
variable = scope_add_symbol(parser->current.start, parser->current.length,
|
||||
st, size);
|
||||
|
||||
if(!def && (parser->pass == 0)) return size;
|
||||
|
||||
|
|
@ -475,7 +473,7 @@ variable_declaration(Symbol *def)
|
|||
if(def && (check(TOKEN_COMMA) || check(TOKEN_RPAREN))) return size;
|
||||
if(def)
|
||||
emitter->error(parser->previous.start, parser->previous.length,
|
||||
parser->previous.line);
|
||||
parser->previous.line);
|
||||
if(parser->pass == 0) return size;
|
||||
|
||||
if(match(TOKEN_EQ)) {
|
||||
|
|
@ -583,7 +581,7 @@ dot(void)
|
|||
parser->before.length);
|
||||
if(sym == nil) {
|
||||
emitter->error(parser->current.start, parser->current.length,
|
||||
parser->current.line);
|
||||
parser->current.line);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -595,7 +593,7 @@ variable(void)
|
|||
if(sym == nil) {
|
||||
return;
|
||||
emitter->error(parser->previous.start, parser->previous.length,
|
||||
parser->previous.line);
|
||||
parser->previous.line);
|
||||
}
|
||||
|
||||
if(sym->type == SYMBOL_FUNCTION) {
|
||||
|
|
@ -603,19 +601,19 @@ variable(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (sym->type == SYMBOL_STR) {
|
||||
if(sym->type == SYMBOL_STR) {
|
||||
emitter->emit_deref_prolog(arena, code, sym);
|
||||
|
||||
if (match(TOKEN_LBRACKET)) {
|
||||
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);
|
||||
while (!match(TOKEN_RBRACKET)) {
|
||||
while(!match(TOKEN_RBRACKET)) {
|
||||
}
|
||||
|
||||
if (match(TOKEN_EQ)) {
|
||||
if(match(TOKEN_EQ)) {
|
||||
expression();
|
||||
|
||||
emitter->emit_stack_rot(arena, code, 1);
|
||||
|
|
@ -626,11 +624,13 @@ variable(void)
|
|||
}
|
||||
|
||||
parser->current_type = SYMBOL_BYTE;
|
||||
} else if (match(TOKEN_DOT)) {
|
||||
if (sleq("length", parser->current.start, parser->current.length)) {
|
||||
} 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);
|
||||
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();
|
||||
|
|
@ -643,10 +643,10 @@ variable(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (sym->type == SYMBOL_ARRAY) {
|
||||
if(sym->type == SYMBOL_ARRAY) {
|
||||
u32 size = emitter->get_size(sym->secondary_type);
|
||||
|
||||
if (match(TOKEN_LBRACKET)) {
|
||||
if(match(TOKEN_LBRACKET)) {
|
||||
emitter->emit_deref_prolog(arena, code, sym);
|
||||
expression();
|
||||
emitter->emit_address(arena, code, 2);
|
||||
|
|
@ -656,13 +656,13 @@ variable(void)
|
|||
emitter->emit_nat(arena, code, "2", 1);
|
||||
emitter->emit_add(arena, code, 2);
|
||||
|
||||
while (!match(TOKEN_RBRACKET)) {
|
||||
while(!match(TOKEN_RBRACKET)) {
|
||||
/* eventually do something with multidimensional arrays */
|
||||
}
|
||||
|
||||
if (match(TOKEN_EQ)) {
|
||||
if(match(TOKEN_EQ)) {
|
||||
expression();
|
||||
if (size == 1) {
|
||||
if(size == 1) {
|
||||
emitter->emit_stack_rot(arena, code, 1);
|
||||
emitter->emit_stack_rot(arena, code, 1);
|
||||
} else {
|
||||
|
|
@ -674,12 +674,14 @@ variable(void)
|
|||
}
|
||||
parser->current_type = sym->secondary_type;
|
||||
|
||||
} else if (match(TOKEN_DOT)) {
|
||||
} else if(match(TOKEN_DOT)) {
|
||||
emitter->emit_deref_prolog(arena, code, sym);
|
||||
if (sleq("length", parser->current.start, parser->current.length)) {
|
||||
if(sleq("length", parser->current.start, parser->current.length)) {
|
||||
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);
|
||||
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();
|
||||
|
|
@ -789,14 +791,16 @@ cast_type(void)
|
|||
break;
|
||||
}
|
||||
default:
|
||||
emitter->error("Type cast not implemented for this type (oops)", 46, parser->previous.line);
|
||||
emitter->error("Type cast not implemented for this type (oops)", 46,
|
||||
parser->previous.line);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
declaration(void)
|
||||
{
|
||||
if(is_type() && (parser->current.type == TOKEN_IDENTIFIER || parser->current.type == TOKEN_LBRACKET) )
|
||||
if(is_type() && (parser->current.type == TOKEN_IDENTIFIER ||
|
||||
parser->current.type == TOKEN_LBRACKET))
|
||||
variable_declaration(nil);
|
||||
else
|
||||
statement();
|
||||
|
|
@ -826,7 +830,8 @@ if_statement(void)
|
|||
statement();
|
||||
emitter->else_if_depth--;
|
||||
}
|
||||
if(emitter->else_if_depth == 0) emitter->emit_patch_if_done(arena, code, emitter->ifs++);
|
||||
if(emitter->else_if_depth == 0)
|
||||
emitter->emit_patch_if_done(arena, code, emitter->ifs++);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -930,19 +935,33 @@ grouping(void)
|
|||
void
|
||||
number(void)
|
||||
{
|
||||
emitter->emit_int(arena, code, parser->previous.start, parser->previous.length);
|
||||
switch(parser->current_type) {
|
||||
case SYMBOL_BOOL:
|
||||
case SYMBOL_BYTE:
|
||||
case SYMBOL_U8:
|
||||
case SYMBOL_I8:
|
||||
emitter->emit_char(arena, code, parser->previous.start,
|
||||
parser->previous.length);
|
||||
break;
|
||||
default:
|
||||
emitter->emit_nat(arena, code, parser->previous.start,
|
||||
parser->previous.length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
string(void)
|
||||
{
|
||||
emitter->emit_inline_str(arena, code, parser->previous.start, parser->previous.length);
|
||||
emitter->emit_inline_str(arena, code, parser->previous.start,
|
||||
parser->previous.length);
|
||||
}
|
||||
|
||||
void
|
||||
character(void)
|
||||
{
|
||||
emitter->emit_char(arena, code, parser->previous.start, parser->previous.length);
|
||||
emitter->emit_char(arena, code, parser->previous.start,
|
||||
parser->previous.length);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -992,7 +1011,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_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},
|
||||
|
|
@ -1025,7 +1044,7 @@ ParseRule rules[] = {
|
|||
/* TOKEN_KEYWORD_THIS */ {nil, nil, PREC_NONE},
|
||||
/* TOKEN_KEYWORD_OPEN */ {nil, nil, PREC_NONE},
|
||||
/* TOKEN_KEYWORD_READ */ {read, nil, PREC_NONE},
|
||||
/* TOKEN_KEYWORD_WRITE */ { write, nil, PREC_NONE},
|
||||
/* TOKEN_KEYWORD_WRITE */ {write, nil, PREC_NONE},
|
||||
/* TOKEN_KEYWORD_STAT */ {nil, nil, PREC_NONE},
|
||||
/* TOKEN_KEYWORD_CLOSE */ {nil, nil, PREC_NONE},
|
||||
/* TOKEN_KEYWORD_LOOP */ {nil, nil, PREC_NONE},
|
||||
|
|
@ -1070,7 +1089,7 @@ ParseRule rules[] = {
|
|||
/* TOKEN_KEYWORD_DEVMAP*/ {nil, nil, PREC_NONE},
|
||||
/* TOKEN_KEYWORD_BYTE*/ {nil, nil, PREC_NONE},
|
||||
/* TOKEN_KEYWORD_CHAR*/ {character, nil, PREC_NONE},
|
||||
};
|
||||
};
|
||||
|
||||
void
|
||||
parse_precedence(Precedence precedence)
|
||||
|
|
@ -1111,7 +1130,7 @@ emit_program(char *source)
|
|||
}
|
||||
|
||||
bool
|
||||
compile(Arena *a, List *c, List* m, Emitter *e, char *source)
|
||||
compile(Arena *a, List *c, List *m, Emitter *e, char *source)
|
||||
{
|
||||
Parser p = {0};
|
||||
arena = a;
|
||||
|
|
|
|||
Loading…
Reference in New Issue