mirror of
https://github.com/sigmasternchen/macrofuck
synced 2025-03-15 07:08:56 +00:00
feat: preparation for arrays
This commit is contained in:
parent
764450a442
commit
863d2f2e02
7 changed files with 70 additions and 10 deletions
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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*);
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue