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){
|
gen_expr(Ast_Expr *ast){
|
||||||
switch(ast->kind){
|
switch(ast->kind){
|
||||||
CASE(IDENT, Atom){
|
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();
|
BREAK();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,13 +318,10 @@ gen_ast(Ast *ast){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(sym->type == type_int){
|
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){
|
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){
|
||||||
@@ -339,7 +349,7 @@ gen_ast(Ast *ast){
|
|||||||
Ast_Enum *enu = (Ast_Enum *)sym->type_val->ast;
|
Ast_Enum *enu = (Ast_Enum *)sym->type_val->ast;
|
||||||
assert(enu->kind == AST_ENUM);
|
assert(enu->kind == AST_ENUM);
|
||||||
if(node->value->kind == AST_ENUM){
|
if(node->value->kind == AST_ENUM){
|
||||||
gen("enum %s{", node->name.str);
|
gen("/*enum %s{", node->name.str);
|
||||||
// @todo add typespec
|
// @todo add typespec
|
||||||
global_indent++;
|
global_indent++;
|
||||||
For(enu->members){
|
For(enu->members){
|
||||||
@@ -350,7 +360,7 @@ gen_ast(Ast *ast){
|
|||||||
gen(",");
|
gen(",");
|
||||||
}
|
}
|
||||||
global_indent--;
|
global_indent--;
|
||||||
genln("};");
|
genln("};*/");
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
// Type alias
|
// Type alias
|
||||||
|
|||||||
9
enums.kl
9
enums.kl
@@ -2,9 +2,16 @@
|
|||||||
Thing :: struct
|
Thing :: struct
|
||||||
len: int
|
len: int
|
||||||
|
|
||||||
|
|
||||||
|
Constant :: 10
|
||||||
|
Thing_Kind :: enum
|
||||||
|
None
|
||||||
|
Thing_Not
|
||||||
|
|
||||||
thing: Thing
|
thing: Thing
|
||||||
access := thing.len
|
access := thing.len
|
||||||
|
test := Thing.Thing_Kind.Thing_Not
|
||||||
|
test_const := Thing.Constant
|
||||||
|
|
||||||
Allocator_Kind :: enum
|
Allocator_Kind :: enum
|
||||||
Null
|
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_bool = &type__bool;
|
||||||
global Ast_Resolved_Type *type_null = &type__null;
|
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
|
function B32
|
||||||
is_struct(Ast_Resolved_Type *type){
|
is_struct(Ast_Resolved_Type *type){
|
||||||
B32 result = type->kind == TYPE_STRUCT;
|
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){
|
CASE(BINARY, Binary){
|
||||||
Operand result = {};
|
Operand result = {};
|
||||||
if(node->op == TK_Dot){
|
if(node->op == TK_Dot){
|
||||||
|
B32 required_to_be_const = false;
|
||||||
// @note: resolve first chunk which involves querying global map
|
// @note: resolve first chunk which involves querying global map
|
||||||
// second part requires searching through a struct
|
// second part requires searching through a struct
|
||||||
// resolve.x.y
|
// 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;
|
Ast_Resolved_Type *type = resolved_ident.type;
|
||||||
if(type == type_type){
|
if(type == type_type){
|
||||||
type = resolved_ident.type_val;
|
type = resolved_ident.type_val;
|
||||||
|
required_to_be_const = true;
|
||||||
}
|
}
|
||||||
// @copy_paste
|
// @copy_paste
|
||||||
if(is_pointer(type)){
|
if(is_pointer(type)){
|
||||||
@@ -634,16 +636,21 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){
|
|||||||
// @copy_paste
|
// @copy_paste
|
||||||
if(query){
|
if(query){
|
||||||
Sym *sym = resolved_get(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;
|
type = sym->type;
|
||||||
|
if(type == type_type){
|
||||||
|
required_to_be_const = true;
|
||||||
|
type = sym->type_val;
|
||||||
|
}
|
||||||
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, {}, sym->type, {}, ident);
|
|
||||||
|
|
||||||
|
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, "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);
|
Ast_Enum_Member *query = query_enum(enu, ident->intern_val);
|
||||||
if(query){
|
if(query){
|
||||||
Sym *resolved = resolved_get(query);
|
Sym *resolved = resolved_get(query);
|
||||||
|
|
||||||
assert(resolved);
|
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);
|
sym_new_resolved(SYM_CONST, {}, resolved->type, resolved->value, node->left);
|
||||||
node->right = 0;
|
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);
|
Ast *query = query_struct(agg, ident->intern_val);
|
||||||
if(query){
|
if(query){
|
||||||
Sym *sym = resolved_get(query);
|
Sym *sym = resolved_get(query);
|
||||||
assert(sym);
|
|
||||||
result = operand(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, "No such member in struct");
|
||||||
}
|
}
|
||||||
else parsing_error(ident->pos, "Trying to [.] access a value that is not [Enum] or [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{
|
else{
|
||||||
Operand left = resolve_expr(node->left);
|
Operand left = resolve_expr(node->left);
|
||||||
|
|||||||
Reference in New Issue
Block a user