feat: preparation for arrays

This commit is contained in:
overflowerror 2024-04-27 11:09:17 +02:00
parent 764450a442
commit 863d2f2e02
7 changed files with 70 additions and 10 deletions

View file

@ -111,6 +111,28 @@ struct expression* literal_expression_str_new(char* s) {
return expr;
}
struct expression* literal_expression_array_new(size_t length, struct expression** values) {
if (values == NULL) {
values = safe_malloc(length * sizeof(struct expression*));
for (size_t i = 0; i < length; i++) {
values[i] = literal_expression_num_new(0);
}
}
_new(expr, expression);
expr->kind = LITERAL;
expr->type = UNKNOWN_TYPE;
expr->literal = (struct literal_expression) {
.kind = ARRAY_LITERAL,
.array = (struct array_literal) {
.length = length,
.values = values,
}
};
return expr;
}
struct expression* variable_expression_new(char* id) {
_new(expr, expression);
expr->kind = VARIABLE;

View file

@ -7,6 +7,7 @@ enum literal_kind {
NUMBER_LITERAL,
CHAR_LITERAL,
STRING_LITERAL,
ARRAY_LITERAL,
};
enum expression_kind {
@ -32,12 +33,18 @@ enum statement_kind {
WHILE_STATEMENT,
};
struct array_literal {
size_t length;
struct expression** values;
};
struct literal_expression {
enum literal_kind kind;
union {
long long number;
char ch;
char* str;
char* str;
struct array_literal array;
};
};
@ -138,6 +145,7 @@ struct statement* while_statement_new(struct expression*, struct block*);
struct expression* literal_expression_char_new(char);
struct expression* literal_expression_str_new(char*);
struct expression* literal_expression_num_new(long long);
struct expression* literal_expression_array_new(size_t, struct expression**);
struct expression* variable_expression_new(char*);
struct expression* macro_expression_new(char*, char*);
struct expression* builtin_call_expression_new(void);

View file

@ -23,7 +23,7 @@ void _move_to(FILE* out, scope_t* scope, size_t target) {
}
}
void _copy(FILE* out, scope_t* scope, region_t* source, region_t* target) {
void _copy(FILE* out, scope_t* scope, region_t* source, size_t source_offset, region_t* target, size_t target_offset) {
size_t size = source->size;
if (target->size < size) {
size = target->size;
@ -33,12 +33,12 @@ void _copy(FILE* out, scope_t* scope, region_t* source, region_t* target) {
move_to(tmp); reset();
for (size_t i = 0; i < size; i++) {
move_offset(source, i);
move_offset(source, source_offset + i);
loop({
dec();
move_offset(target, i); inc();
move_offset(target, target_offset + i); inc();
move_offset(tmp, i); inc();
move_offset(source, i);
move_offset(source, source_offset + i);
});
}
@ -46,7 +46,7 @@ void _copy(FILE* out, scope_t* scope, region_t* source, region_t* target) {
move_offset(tmp, i);
loop({
dec();
move_offset(source, i); inc();
move_offset(source, source_offset + i); inc();
move_offset(tmp, i);
});
}

View file

@ -23,7 +23,7 @@
#define move_to(r) move(r->start)
#define move_offset(r, o) move(r->start + o)
#define copy(s, t) _copy(out, scope, s, t)
#define copy(s, t) _copy(out, scope, s, 0, t, 0)
#define clone(s) _clone(out, scope, s)
#define reset_region(r) _reset_region(out, scope, r)
@ -31,7 +31,7 @@
#define region_used(region) if (region->is_temp) { scope_remove(scope, region); }
void _move_to(FILE*, scope_t*, size_t);
void _copy(FILE*, scope_t*, region_t*, region_t*);
void _copy(FILE*, scope_t*, region_t*, size_t, region_t*, size_t);
region_t* _clone(FILE*, scope_t*, region_t*);
void _reset_region(FILE*, scope_t*, region_t*);

View file

@ -41,6 +41,19 @@ static region_t* codegen_literal_expr(FILE* out, scope_t* scope, struct literal_
}
break;
}
case ARRAY_LITERAL:
region = scope_add_tmp(scope, expr.array.length);
for (size_t i = 0; i < expr.array.length; i++) {
region_t* tmp = codegen_expr(out, scope, expr.array.values[i]);
if (tmp->size > 1) {
panic("arrays can only contain scalar values");
}
_copy(out, scope, tmp, 0, region, i);
if (tmp->is_temp) {
scope_remove(scope, tmp);
}
}
break;
default:
fprintf(stderr, "literal kind: %d\n", expr.kind);
panic("unknown literal kind");

View file

@ -5,7 +5,6 @@ oct "0"[0-9]+
hex "0x"[0-9a-fA-F]+
bin "0b"[01]+
print "print"
var "var"
if "if"
else "else"
@ -92,6 +91,8 @@ strbuf_t strbuf = NULL;
<INITIAL>")" { return CLOSING_BRACKETS; }
<INITIAL>"{" { return OPENING_BRACES; }
<INITIAL>"}" { return CLOSING_BRACES; }
<INITIAL>"[" { return OPENING_SQ_BRACKETS; }
<INITIAL>"]" { return CLOSING_SQ_BRACKETS; }
<INITIAL>"," { return COMMA; }
<INITIAL>"$(" { BEGIN MACRO; strbuf_clear(strbuf); }

View file

@ -34,7 +34,7 @@ extern struct block* program;
%type <block> stats optelse block
%type <statement> stat definition assignment exprstat if while
%type <expr> expr literal variable macroexpr builtincall calcexpr argumentlist
%type <expr> expr literal variable macroexpr builtincall calcexpr argumentlist arrayliteral
%type <op> op
%token <number> NUM
@ -64,6 +64,8 @@ extern struct block* program;
%token CLOSING_BRACKETS
%token OPENING_BRACES
%token CLOSING_BRACES
%token OPENING_SQ_BRACKETS
%token CLOSING_SQ_BRACKETS
%token COMMA
%token VAR
@ -255,6 +257,20 @@ literal: NUM
| STR {
$$ = literal_expression_str_new($1);
}
| arrayliteral
;
arrayliteral: OPENING_SQ_BRACKETS NUM CLOSING_SQ_BRACKETS
{
$$ = literal_expression_array_new($2, NULL);
}
| OPENING_SQ_BRACKETS CLOSING_SQ_BRACKETS OPENING_BRACES argumentlist CLOSING_BRACES
{
$$ = literal_expression_array_new(
$4->builtin_call.argument_number,
$4->builtin_call.arguments
);
}
;
variable: ID