Rewriting field.accesses that evaluate to constants

This commit is contained in:
Krzosa Karol
2022-05-31 13:39:34 +02:00
parent 1168965ba4
commit 369418b042
3 changed files with 28 additions and 30 deletions

View File

@@ -78,20 +78,7 @@ function void
gen_expr(Ast_Expr *ast){ gen_expr(Ast_Expr *ast){
switch(ast->kind){ switch(ast->kind){
CASE(IDENT, Atom){ CASE(IDENT, Atom){
Sym *sym = resolved_get(node); gen("%s", node->intern_val.str);
if(sym){
if(sym->kind == SYM_CONST){
if(sym->type == type_int){
gen("%lld", sym->int_val);
}
else if(sym->type == type_string){
gen("LIT(\"%s\")", sym->intern_val.str);
}
else gen("%s", node->intern_val.str);
}
else gen("%s", node->intern_val.str);
}
else gen("%s", node->intern_val.str);
BREAK(); BREAK();
} }
@@ -116,15 +103,10 @@ gen_expr(Ast_Expr *ast){
CASE(BINARY, Binary){ CASE(BINARY, Binary){
if(node->op == TK_Dot){ if(node->op == TK_Dot){
Sym *sym = resolved_get(node->left); Sym *sym = resolved_get(node->left);
if(sym->kind == SYM_CONST){ gen_expr(node->left);
gen("%lld", sym->int_val); if(sym->type->kind == TYPE_POINTER) gen("->");
} else gen(".");
else{ gen_expr(node->right);
gen_expr(node->left);
if(sym->type->kind == TYPE_POINTER) gen("->");
else gen(".");
gen_expr(node->right);
}
} }
else{ else{
gen("("); gen("(");

View File

@@ -2,12 +2,13 @@
Thing :: struct Thing :: struct
len: int len: int
Constant_String :: "Test"
Constant :: 10 Constant :: 10
Thing_Kind :: enum Thing_Kind :: enum
None None
Thing_Not Thing_Not
test_string := Thing.Constant_String
thing: Thing thing: Thing
access := thing.len access := thing.len
test := Thing.Thing_Kind.Thing_Not test := Thing.Thing_Kind.Thing_Not
@@ -19,4 +20,5 @@ Allocator_Kind :: enum
Heap Heap
kind := Allocator_Kind.Heap kind := Allocator_Kind.Heap

View File

@@ -667,8 +667,15 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){
assert(resolved); assert(resolved);
// @warning: rewrite entire node into a constant // @warning: rewrite entire node into a constant
{ {
sym_new_resolved(SYM_CONST, {}, resolved->type, resolved->value, node->left); Ast_Atom *rewrite = (Ast_Atom *)node;
node->right = 0; static_assert(sizeof(Ast_Binary) > sizeof(Ast_Atom), "This wont work");
if(resolved->type == type_int){
rewrite->kind = AST_INT;
rewrite->int_val = resolved->int_val;
} else if(resolved->type == type_string){
rewrite->kind = AST_STR;
rewrite->intern_val = resolved->intern_val;
} else invalid_codepath;
} }
result = operand(resolved); result = operand(resolved);
} }
@@ -680,10 +687,17 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){
Sym *sym = resolved_get(query); Sym *sym = resolved_get(query);
result = operand(sym); result = operand(sym);
assert(sym); assert(sym);
// @note: warning rewriting nodes with constant values // @warning rewriting nodes with constant values
if(sym->kind == SYM_CONST){ if(sym->kind == SYM_CONST){
sym_new_resolved(sym->kind, {}, sym->type, sym->value, node->left); Ast_Atom *rewrite = (Ast_Atom *)node;
node->right = 0; static_assert(sizeof(Ast_Binary) > sizeof(Ast_Atom), "This wont work");
if(sym->type == type_int){
rewrite->kind = AST_INT;
rewrite->int_val = sym->int_val;
} else if(sym->type == type_string){
rewrite->kind = AST_STR;
rewrite->intern_val = sym->intern_val;
} else invalid_codepath;
} }
else{ else{
sym_new_resolved(sym->kind, {}, sym->type, sym->value, ident); sym_new_resolved(sym->kind, {}, sym->type, sym->value, ident);