Accessing constant values in structs
This commit is contained in:
26
ccodegen.cpp
26
ccodegen.cpp
@@ -78,7 +78,20 @@ function void
|
||||
gen_expr(Ast_Expr *ast){
|
||||
switch(ast->kind){
|
||||
CASE(IDENT, Atom){
|
||||
gen("%s", node->intern_val.str);
|
||||
Sym *sym = resolved_get(node);
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -305,13 +318,10 @@ gen_ast(Ast *ast){
|
||||
}
|
||||
}
|
||||
else if(sym->type == type_int){
|
||||
gen("enum { %s = %lld };", node->name.str, sym->int_val);
|
||||
gen("// constant int %s = %lld;", node->name.str, sym->int_val);
|
||||
}
|
||||
else if(sym->type == type_string){
|
||||
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);
|
||||
gen("// String %s = LIT(\"%s\");", node->name.str, sym->intern_val.str);
|
||||
}
|
||||
else if(sym->type == type_type){
|
||||
if(sym->type_val->kind == TYPE_STRUCT){
|
||||
@@ -339,7 +349,7 @@ gen_ast(Ast *ast){
|
||||
Ast_Enum *enu = (Ast_Enum *)sym->type_val->ast;
|
||||
assert(enu->kind == AST_ENUM);
|
||||
if(node->value->kind == AST_ENUM){
|
||||
gen("enum %s{", node->name.str);
|
||||
gen("/*enum %s{", node->name.str);
|
||||
// @todo add typespec
|
||||
global_indent++;
|
||||
For(enu->members){
|
||||
@@ -350,7 +360,7 @@ gen_ast(Ast *ast){
|
||||
gen(",");
|
||||
}
|
||||
global_indent--;
|
||||
genln("};");
|
||||
genln("};*/");
|
||||
}
|
||||
else{
|
||||
// Type alias
|
||||
|
||||
9
enums.kl
9
enums.kl
@@ -2,9 +2,16 @@
|
||||
Thing :: struct
|
||||
len: int
|
||||
|
||||
|
||||
Constant :: 10
|
||||
Thing_Kind :: enum
|
||||
None
|
||||
Thing_Not
|
||||
|
||||
thing: Thing
|
||||
access := thing.len
|
||||
|
||||
test := Thing.Thing_Kind.Thing_Not
|
||||
test_const := Thing.Constant
|
||||
|
||||
Allocator_Kind :: enum
|
||||
Null
|
||||
|
||||
12
new_type.cpp
12
new_type.cpp
@@ -83,6 +83,18 @@ global Ast_Resolved_Type *type_string = &type__string;
|
||||
global Ast_Resolved_Type *type_bool = &type__bool;
|
||||
global Ast_Resolved_Type *type_null = &type__null;
|
||||
|
||||
function B32
|
||||
is_string(Ast_Resolved_Type *type){
|
||||
B32 result = type->kind == TYPE_STRING;
|
||||
return result;
|
||||
}
|
||||
|
||||
function B32
|
||||
is_int(Ast_Resolved_Type *type){
|
||||
B32 result = type->kind == TYPE_INT;
|
||||
return result;
|
||||
}
|
||||
|
||||
function B32
|
||||
is_struct(Ast_Resolved_Type *type){
|
||||
B32 result = type->kind == TYPE_STRUCT;
|
||||
|
||||
@@ -603,6 +603,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){
|
||||
CASE(BINARY, Binary){
|
||||
Operand result = {};
|
||||
if(node->op == TK_Dot){
|
||||
B32 required_to_be_const = false;
|
||||
// @note: resolve first chunk which involves querying global map
|
||||
// second part requires searching through a struct
|
||||
// resolve.x.y
|
||||
@@ -610,6 +611,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){
|
||||
Ast_Resolved_Type *type = resolved_ident.type;
|
||||
if(type == type_type){
|
||||
type = resolved_ident.type_val;
|
||||
required_to_be_const = true;
|
||||
}
|
||||
// @copy_paste
|
||||
if(is_pointer(type)){
|
||||
@@ -634,16 +636,21 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){
|
||||
// @copy_paste
|
||||
if(query){
|
||||
Sym *sym = resolved_get(query);
|
||||
if(required_to_be_const && sym->kind != SYM_CONST) parsing_error(ident->pos, "Required to be constant");
|
||||
type = sym->type;
|
||||
if(type == type_type){
|
||||
required_to_be_const = true;
|
||||
type = sym->type_val;
|
||||
}
|
||||
if(is_pointer(type)){
|
||||
type = type->base;
|
||||
}
|
||||
type_complete(type);
|
||||
if(!is_struct(type)){
|
||||
parsing_error(node->pos, "Trying to access inside a value that is not a struct");
|
||||
if(!(is_struct(type) || is_enum(type))){
|
||||
parsing_error(node->pos, "Trying to access inside a value that is not a struct or enum");
|
||||
}
|
||||
sym_new_resolved(SYM_VAR, {}, sym->type, {}, ident);
|
||||
|
||||
sym_new_resolved(sym->kind, {}, sym->type, sym->value, ident);
|
||||
} else parsing_error(ident->pos, "No such member in struct");
|
||||
}
|
||||
|
||||
@@ -656,8 +663,9 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){
|
||||
Ast_Enum_Member *query = query_enum(enu, ident->intern_val);
|
||||
if(query){
|
||||
Sym *resolved = resolved_get(query);
|
||||
|
||||
assert(resolved);
|
||||
// @warning: rewrite into a constant
|
||||
// @warning: rewrite entire node into a constant
|
||||
{
|
||||
sym_new_resolved(SYM_CONST, {}, resolved->type, resolved->value, node->left);
|
||||
node->right = 0;
|
||||
@@ -670,13 +678,25 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){
|
||||
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);
|
||||
assert(sym);
|
||||
// @note: warning rewriting nodes with constant values
|
||||
if(sym->kind == SYM_CONST){
|
||||
sym_new_resolved(sym->kind, {}, sym->type, sym->value, node->left);
|
||||
node->right = 0;
|
||||
}
|
||||
else{
|
||||
sym_new_resolved(sym->kind, {}, sym->type, sym->value, 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]");
|
||||
|
||||
if(result.is_const == false && required_to_be_const){
|
||||
invalid_codepath;
|
||||
}
|
||||
|
||||
}
|
||||
else{
|
||||
Operand left = resolve_expr(node->left);
|
||||
|
||||
Reference in New Issue
Block a user