Fix regression, constant variables now get properly rewritten

This commit is contained in:
Krzosa Karol
2022-05-31 14:01:18 +02:00
parent 369418b042
commit 04d38511a9
7 changed files with 49 additions and 68 deletions

View File

@@ -147,7 +147,7 @@ gen_expr(Ast_Expr *ast){
CASE(CALL, Call){ CASE(CALL, Call){
// @todo: Reach into map instead of direct lookup // @todo: Reach into map instead of direct lookup
if(node->type->kind == TYPE_STRUCT){ // @todo: Should this be type_type maybe??? if(is_struct(node->type) || is_array(node->type)){ // @todo: Should this be type_type maybe???
gen("("); gen("(");
gen_simple_decl(node->type, {}); gen_simple_decl(node->type, {});
gen(")"); gen(")");

View File

@@ -4,6 +4,7 @@ Thing :: struct
Constant_String :: "Test" Constant_String :: "Test"
Constant :: 10 Constant :: 10
Thing_Kind :: enum Thing_Kind :: enum
None None
Thing_Not Thing_Not
@@ -19,6 +20,5 @@ Allocator_Kind :: enum
Arena Arena
Heap Heap
kind := Allocator_Kind.Heap kind := Allocator_Kind.Heap

View File

@@ -40,19 +40,24 @@ For now I don't thing it should be overloadable.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
@todo @todo
[ ] - Enums
[ ] - Enum . access to values
[ ] - Fixing access to constants, in C we cant have constants inside of structs / functions so we need to rewrite the tree [ ] - Fixing access to constants, in C we cant have constants inside of structs / functions so we need to rewrite the tree
[ ] - Access through struct names to constants Arena.CONSTANT
[ ] - Default values in structs??? Should compound stmts bring values from default values?? Maybe not? Whats the alternative [ ] - Default values in structs??? Should compound stmts bring values from default values?? Maybe not? Whats the alternative
[ ] - Write up on order independent declarations [ ] - Write up on order independent declarations
[ ] - Init statements
[ ] - lvalue, rvalue concept so we cant assign value to some arbitrary weird expression
[ ] - For loop [ ] - For loop
[ ] - Switch [ ] - Switch
[ ] - More basic types
[ ] - Lexer: Need to insert scope endings when hitting End of file [ ] - Lexer: Need to insert scope endings when hitting End of file
[ ] - Add single line lambda expressions [ ] - Add single line lambda expressions
@ideas
@donzo @donzo
[x] - Access through struct names to constants Arena.CONSTANT
[x] - Enums
[x] - Enum . access to values
[x] - Struct calls [x] - Struct calls
[x] - Default values in calls [x] - Default values in calls
[x] - Resolving calls with default values [x] - Resolving calls with default values
@@ -81,11 +86,11 @@ int main(){
lex_test(); lex_test();
String result = {}; String result = {};
// result = compile_file("order1.kl"_s); result = compile_file("globals.kl"_s);
// result = compile_file("lambdas.kl"_s);
// result = compile_file("order2.kl"_s);
result = compile_file("enums.kl"_s); result = compile_file("enums.kl"_s);
// result = compile_file("globals.kl"_s); result = compile_file("order2.kl"_s);
result = compile_file("lambdas.kl"_s);
result = compile_file("order1.kl"_s);
printf("%s", result.str); printf("%s", result.str);
__debugbreak(); __debugbreak();

View File

@@ -83,35 +83,12 @@ 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 force_inline B32 is_string(Ast_Resolved_Type *type){return type->kind == TYPE_STRING;}
is_string(Ast_Resolved_Type *type){ force_inline B32 is_int(Ast_Resolved_Type *type){return type->kind == TYPE_INT;}
B32 result = type->kind == TYPE_STRING; force_inline B32 is_struct(Ast_Resolved_Type *type){return type->kind == TYPE_STRUCT;}
return result; force_inline B32 is_array(Ast_Resolved_Type *type){return type->kind == TYPE_ARRAY;}
} force_inline B32 is_enum(Ast_Resolved_Type *type){return type->kind == TYPE_ENUM;}
force_inline B32 is_pointer(Ast_Resolved_Type *type){return type->kind == TYPE_POINTER;}
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;
return result;
}
function B32
is_enum(Ast_Resolved_Type *type){
B32 result = type->kind == TYPE_ENUM;
return result;
}
function B32
is_pointer(Ast_Resolved_Type *type){
B32 result = type->kind == TYPE_POINTER;
return result;
}
function Ast_Resolved_Type * function Ast_Resolved_Type *
type_new(Allocator *allocator, Ast_Resolved_Type_Kind kind, SizeU size, SizeU align){ type_new(Allocator *allocator, Ast_Resolved_Type_Kind kind, SizeU size, SizeU align){

View File

@@ -9,7 +9,7 @@ recursive_lambda :: (thing: int)
const_in_lambda :: 10 const_in_lambda :: 10
not_const := val + 10 not_const := val + 10
val := 10 val := CONSTANT_VAL
DEPENDENCE :: CONSTANT_VAL DEPENDENCE :: CONSTANT_VAL
CONSTANT_VAL :: 10 CONSTANT_VAL :: 10

View File

@@ -2,13 +2,13 @@ Str16 :: String16
arena_pointer: *Arena = null arena_pointer: *Arena = null
thing: Arena thing: Arena
no_type := thing no_type := thing
constant_access := Arena.constant_inside
arena := Arena( arena := Arena(
next = null, next = null,
data = null, data = null,
len = 1000, len = 1000,
cap = 1000, cap = 1000,
// constant_inside = 10,
) )
// lambda_value := (val: int) // What to do with this??? // lambda_value := (val: int) // What to do with this???

View File

@@ -198,7 +198,7 @@ resolve_stmt(Ast *ast, Ast_Resolved_Type *ret){
CASE(RETURN, Return){ // @todo: need to check if all paths return a value CASE(RETURN, Return){ // @todo: need to check if all paths return a value
Operand op = {}; Operand op = {};
if(node->expr) op = resolve_expr(node->expr); if(node->expr) op = resolve_expr(node->expr);
if(!op.type && ret != type_void) parsing_error(node->pos, "Function expects a void return value but the returned value is [x]"); if(!op.type && ret != type_void) parsing_error(node->pos, "Function expects a void return value but the returned value is [%s]", type_names[op.type->kind]);
if(op.type && op.type != ret) parsing_error(node->pos, "Return statement has different type then returned value"); if(op.type && op.type != ret) parsing_error(node->pos, "Return statement has different type then returned value");
BREAK(); BREAK();
@@ -277,6 +277,23 @@ require_const_int(Ast_Expr *expr, B32 ast_can_be_null){
return op; return op;
} }
#define rewrite_into_const(ast,T,sym) _rewrite_into_const(ast,sizeof(T),sym)
function void
_rewrite_into_const(Ast *node, U64 ast_size, Sym *sym){
auto ast = (Ast_Atom *)node;
assert(ast_size >= sizeof(Ast_Atom));
if(sym->type == type_int){
ast->kind = AST_INT;
ast->int_val = sym->int_val;
} else if(sym->type == type_string){
ast->kind = AST_STR;
ast->intern_val = sym->intern_val;
} else if(sym->type == type_bool){
ast->kind = AST_INT;
ast->int_val = sym->int_val;
} else invalid_codepath;
}
function Operand function Operand
resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){
if(!ast) return {}; // @todo: add option for better error prevention if(!ast) return {}; // @todo: add option for better error prevention
@@ -298,8 +315,6 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){
CASE(IDENT, Atom){ CASE(IDENT, Atom){
Sym *sym = resolve_name(node->pos, node->intern_val); Sym *sym = resolve_name(node->pos, node->intern_val);
// @cleanup: due to Value being a union this portion probably can get cleaned
// @note: check if null and rewrite the expression to match the expected type // @note: check if null and rewrite the expression to match the expected type
Operand result = {}; Operand result = {};
if(sym->type->kind == TYPE_NULL){ if(sym->type->kind == TYPE_NULL){
@@ -307,9 +322,13 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){
result.type = expected_type; result.type = expected_type;
result.is_const = true; result.is_const = true;
} }
else if(sym->kind == SYM_CONST || sym->kind == SYM_VAR){ else if(sym->kind == SYM_CONST && sym->type != type_type && sym->type->kind != TYPE_LAMBDA){
result = operand(sym); result = operand(sym);
sym_new_resolved(SYM_CONST, sym->name, sym->type, sym->value, node); rewrite_into_const(node, Ast_Atom, sym);
}
else if(sym->kind == SYM_VAR || sym->kind == SYM_CONST){
result = operand(sym);
sym_new_resolved(sym->kind, sym->name, sym->type, sym->value, node);
} }
else invalid_codepath; else invalid_codepath;
@@ -663,20 +682,8 @@ 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 entire node into a constant rewrite_into_const(node, Ast_Binary, resolved);
{
Ast_Atom *rewrite = (Ast_Atom *)node;
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);
} }
} }
@@ -689,15 +696,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){
assert(sym); assert(sym);
// @warning rewriting nodes with constant values // @warning rewriting nodes with constant values
if(sym->kind == SYM_CONST){ if(sym->kind == SYM_CONST){
Ast_Atom *rewrite = (Ast_Atom *)node; rewrite_into_const(node, Ast_Binary, sym);
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);