Folding constant enum access into constant int value
This commit is contained in:
16
ccodegen.cpp
16
ccodegen.cpp
@@ -103,10 +103,15 @@ 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);
|
||||||
gen_expr(node->left);
|
if(sym->kind == SYM_CONST){
|
||||||
if(sym->type->kind == TYPE_POINTER) gen("->");
|
gen("%lld", sym->int_val);
|
||||||
else gen(".");
|
}
|
||||||
gen_expr(node->right);
|
else{
|
||||||
|
gen_expr(node->left);
|
||||||
|
if(sym->type->kind == TYPE_POINTER) gen("->");
|
||||||
|
else gen(".");
|
||||||
|
gen_expr(node->right);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
gen("(");
|
gen("(");
|
||||||
@@ -305,6 +310,9 @@ gen_ast(Ast *ast){
|
|||||||
else if(sym->type == type_string){
|
else if(sym->type == type_string){
|
||||||
gen("String %s = LIT(\"%s\");", node->name.str, sym->intern_val.str);
|
gen("String %s = LIT(\"%s\");", node->name.str, sym->intern_val.str);
|
||||||
}
|
}
|
||||||
|
else if(sym->type->kind == TYPE_ENUM){
|
||||||
|
gen("enum { %s = %lld };", node->name.str, sym->int_val);
|
||||||
|
}
|
||||||
else if(sym->type == type_type){
|
else if(sym->type == type_type){
|
||||||
if(sym->type_val->kind == TYPE_STRUCT){
|
if(sym->type_val->kind == TYPE_STRUCT){
|
||||||
Ast_Struct *agg = (Ast_Struct *)sym->type_val->ast;
|
Ast_Struct *agg = (Ast_Struct *)sym->type_val->ast;
|
||||||
|
|||||||
12
enums.kl
12
enums.kl
@@ -1,5 +1,15 @@
|
|||||||
|
|
||||||
|
Thing :: struct
|
||||||
|
len: int
|
||||||
|
|
||||||
|
thing: Thing
|
||||||
|
access := thing.len
|
||||||
|
|
||||||
|
|
||||||
Allocator_Kind :: enum
|
Allocator_Kind :: enum
|
||||||
Null
|
Null
|
||||||
Arena
|
Arena
|
||||||
Heap = Arena
|
Heap
|
||||||
|
|
||||||
|
|
||||||
|
kind := Allocator_Kind.Heap
|
||||||
10
new_ast.cpp
10
new_ast.cpp
@@ -593,4 +593,14 @@ query_struct(Ast_Struct *agg, Intern_String string){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Ast_Enum_Member *
|
||||||
|
query_enum(Ast_Enum *enu, Intern_String string){
|
||||||
|
For(enu->members){
|
||||||
|
if(it->name == string){
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -89,6 +89,12 @@ is_struct(Ast_Resolved_Type *type){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function B32
|
||||||
|
is_enum(Ast_Resolved_Type *type){
|
||||||
|
B32 result = type->kind == TYPE_ENUM;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
function B32
|
function B32
|
||||||
is_pointer(Ast_Resolved_Type *type){
|
is_pointer(Ast_Resolved_Type *type){
|
||||||
B32 result = type->kind == TYPE_POINTER;
|
B32 result = type->kind == TYPE_POINTER;
|
||||||
@@ -183,7 +189,6 @@ type_incomplete(Ast *ast){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Array<Ast_Resolved_Member> members
|
|
||||||
function void
|
function void
|
||||||
type_complete(Ast_Resolved_Type *type){
|
type_complete(Ast_Resolved_Type *type){
|
||||||
if(type->kind == TYPE_COMPLETING){
|
if(type->kind == TYPE_COMPLETING){
|
||||||
|
|||||||
@@ -607,21 +607,24 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){
|
|||||||
// second part requires searching through a struct
|
// second part requires searching through a struct
|
||||||
// resolve.x.y
|
// resolve.x.y
|
||||||
Operand resolved_ident = resolve_expr(node->left);
|
Operand resolved_ident = resolve_expr(node->left);
|
||||||
// @copy_paste
|
|
||||||
Ast_Resolved_Type *type = resolved_ident.type;
|
Ast_Resolved_Type *type = resolved_ident.type;
|
||||||
|
if(type == type_type){
|
||||||
|
type = resolved_ident.type_val;
|
||||||
|
}
|
||||||
|
// @copy_paste
|
||||||
if(is_pointer(type)){
|
if(is_pointer(type)){
|
||||||
type = type->base;
|
type = type->base;
|
||||||
}
|
}
|
||||||
type_complete(type);
|
type_complete(type);
|
||||||
if(!is_struct(type)){
|
if(!(is_struct(type) || is_enum(type))){
|
||||||
parsing_error(node->pos, "Trying to access inside a value that is not a struct");
|
parsing_error(node->pos, "Trying to access inside a value that is not a struct or enum");
|
||||||
}
|
}
|
||||||
sym_new_resolved(SYM_VAR, {}, resolved_ident.type, {}, node->left);
|
sym_new_resolved(SYM_VAR, {}, resolved_ident.type, {}, node->left);
|
||||||
|
|
||||||
// This happens only on binary nodes which further chain with dots and require lookups
|
// This happens only on binary nodes which further chain with dots and require lookups
|
||||||
// x.resolve.y
|
// x.resolve.y
|
||||||
Ast_Binary *binary = (Ast_Binary *)node->right;
|
Ast_Binary *binary = (Ast_Binary *)node->right;
|
||||||
for(; !is_ident(binary); binary=(Ast_Binary *)binary->right){
|
for(;!is_ident(binary); binary=(Ast_Binary *)binary->right){
|
||||||
assert(is_ident(binary->left));
|
assert(is_ident(binary->left));
|
||||||
Ast_Atom *ident = (Ast_Atom *)binary->left;
|
Ast_Atom *ident = (Ast_Atom *)binary->left;
|
||||||
assert(is_binary(binary));
|
assert(is_binary(binary));
|
||||||
@@ -648,13 +651,31 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){
|
|||||||
// x.y.resolve
|
// x.y.resolve
|
||||||
// @copy_paste
|
// @copy_paste
|
||||||
Ast_Atom *ident = (Ast_Atom *)binary;
|
Ast_Atom *ident = (Ast_Atom *)binary;
|
||||||
Ast_Struct *agg = (Ast_Struct *)type->ast;
|
if(is_enum(type)){
|
||||||
Ast *query = query_struct(agg, ident->intern_val);
|
Ast_Enum *enu = (Ast_Enum *)type->ast;
|
||||||
if(query){
|
Ast_Enum_Member *query = query_enum(enu, ident->intern_val);
|
||||||
Sym *sym = resolved_get(query);
|
if(query){
|
||||||
result = operand(sym);
|
Sym *resolved = resolved_get(query);
|
||||||
sym_new_resolved(SYM_VAR, {}, sym->type, {}, ident);
|
assert(resolved);
|
||||||
} else parsing_error(ident->pos, "No such member in struct");
|
// @warning: rewrite into a constant
|
||||||
|
{
|
||||||
|
sym_new_resolved(SYM_CONST, {}, resolved->type, resolved->value, node->left);
|
||||||
|
node->right = 0;
|
||||||
|
}
|
||||||
|
result = operand(resolved);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(is_struct(type)){
|
||||||
|
Ast_Struct *agg = (Ast_Struct *)type->ast;
|
||||||
|
Ast *query = query_struct(agg, ident->intern_val);
|
||||||
|
if(query){
|
||||||
|
Sym *sym = resolved_get(query);
|
||||||
|
assert(sym);
|
||||||
|
result = operand(sym);
|
||||||
|
sym_new_resolved(SYM_VAR, {}, sym->type, {}, ident);
|
||||||
|
} else parsing_error(ident->pos, "No such member in struct");
|
||||||
|
}
|
||||||
|
else parsing_error(ident->pos, "Trying to [.] access a value that is not [Enum] or [Struct]");
|
||||||
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
|||||||
Reference in New Issue
Block a user