diff --git a/main.cpp b/main.cpp index 9e4d852..1114c49 100644 --- a/main.cpp +++ b/main.cpp @@ -46,7 +46,8 @@ For now I don't thing it should be overloadable. [ ] - Add single line lambda expressions @ideas -[ ] - Using keyword that brings in the struct enviroment into current scope etc. +[ ] - [Using] keyword that brings in the struct enviroment into current scope etc. +[ ] - Constant arrays that evaluate fully at compile time @donzo [x] - Access through struct names to constants Arena.CONSTANT diff --git a/typecheck.cpp b/typecheck.cpp index e21168f..f3e6247 100644 --- a/typecheck.cpp +++ b/typecheck.cpp @@ -177,7 +177,8 @@ resolve_lambda(Ast_Lambda *lambda, Sym *sym = 0){ resolve_stmt(it, ret_type); } scope_close(scope_index); - result.type = lambda_type; + + result = operand_lambda(lambda_type); } return result; @@ -194,7 +195,6 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res CASE(IDENT, Atom){ Sym *sym = resolve_name(node->pos, node->intern_val); - // @note: check if null and rewrite the expression to match the expected type if(sym->type->kind == TYPE_NULL){ if(!expected_type) parsing_error(node->pos, "Couldn't infer type of null"); return operand_null(expected_type); @@ -212,14 +212,16 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res BREAK(); } + // Typespec array [32]int CASE(ARRAY, Array){ + // @todo: Arrays of inferred size [] Operand type = resolve_expr(node->base); if(type.type != type_type) parsing_error(node->pos, "Prefix array operator is only allowed on types"); - Operand expr = require_const_int(node->expr, AST_CANT_BE_NULL); // @todo: + Operand expr = require_const_int(node->expr, AST_CANT_BE_NULL); - type.type_val = type_array(type.type_val, expr.int_val); - sym_type(node, type.type_val); - return type; + Ast_Resolved_Type *resolved = type_array(type.type_val, expr.int_val); + sym_type(node, resolved); + return operand_type(resolved); BREAK(); } @@ -233,8 +235,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res Operand index = resolve_expr(node->index); if(left.type->kind != TYPE_ARRAY) parsing_error(node->pos, "Indexing variable that is not an array"); if(index.type != type_int) parsing_error(node->pos, "Trying to index the array with invalid type, expected int"); - Operand result = {left.type->arr.base}; - return result; + return operand_lvalue(left.type->arr.base); BREAK(); } @@ -363,8 +364,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res } else parsing_error(node->pos, "Invalid function call type"); - Operand result = {type, false}; - return result; + return operand_rvalue(type); BREAK(); } @@ -372,23 +372,12 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res Operand expr = resolve_expr(node->expr); Ast_Resolved_Type *type = resolve_typespec(node->typespec); - if(type == expr.type) return expr; - - else if(expr.type == type_int && type == type_bool){ - expr.type = type_bool; - return expr; - } - else if(expr.type == type_bool && type == type_int){ - expr.type = type_int; - return expr; - } - else if(expr.type == type_null){ - expr.type = type; - return expr; - } - + if(type == expr.type); + else if(expr.type == type_int && type == type_bool) type = type_bool; + else if(expr.type == type_bool && type == type_int) type = type_int; + else if(expr.type == type_null); else parsing_error(node->pos, "Failed to cast, incompatible types"); - + return operand_rvalue(type); BREAK(); } @@ -396,22 +385,15 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res Operand value = resolve_expr(node->expr); switch(node->op){ case TK_Pointer:{ - if(value.type->kind == TYPE_POINTER){ - Operand result = {value.type->base}; - return result; - } + if(value.type->kind == TYPE_POINTER){return operand_lvalue(value.type->base);} else if(value.type->kind == TYPE_TYPE){ - Operand result = {type_type, true}; - result.type_val = type_pointer(value.type_val); - sym_new_resolved(SYM_CONST, {}, type_type, result.value, node); - return result; + Ast_Resolved_Type *type = type_pointer(value.type_val); + sym_new_resolved_type(type, node); + return operand_type(type); } else{ parsing_error(node->pos, "Dereferencing expression %s that is not a [Pointer] or [Type]", type_names[value.type->kind]); return {}; } }break; - case TK_Dereference:{ - Operand result = {type_pointer(value.type)}; - return result; - }break; + case TK_Dereference:{return operand_lvalue(type_pointer(value.type));}break; invalid_default_case; return {}; } diff --git a/typecheck.h b/typecheck.h index 1b34455..76388f1 100644 --- a/typecheck.h +++ b/typecheck.h @@ -205,6 +205,13 @@ sym_new_resolved(Sym_Kind kind, Intern_String name, Ast_Resolved_Type *type, Val return result; } +function Sym * +sym_new_resolved_type(Ast_Resolved_Type *type, Ast *ast){ + Value value; + value.type_val = type; + return sym_new_resolved(SYM_CONST, {}, type_type, value, ast); +} + function Sym * resolved_get(Ast *ast){ Sym *result = (Sym *)map_get(&pctx->resolved, ast); @@ -278,21 +285,23 @@ operand(Sym *sym){ Operand result = {}; result.type = sym->type; result.is_const = sym->kind == SYM_CONST ? true : false; + result.is_lvalue= sym->kind == SYM_CONST ? false : true; // Cant assign to const values result.value = sym->value; return result; } function Operand operand_type(Ast_Resolved_Type *type){ - Operand result = {type_type, true}; + Operand result = {type_type}; + result.is_const = true; + result.is_lvalue = false; result.type_val = type; return result; } function Operand operand_int(S64 int_val){ - Operand result = {}; - result.type = type_int; + Operand result = {type_int}; result.int_val = int_val; result.is_const = true; result.is_lvalue = false; @@ -301,8 +310,7 @@ operand_int(S64 int_val){ function Operand operand_str(Intern_String intern_val){ - Operand result = {}; - result.type = type_string; + Operand result = {type_string}; result.intern_val = intern_val; result.is_const = true; result.is_lvalue = false; @@ -311,9 +319,34 @@ operand_str(Intern_String intern_val){ function Operand operand_null(Ast_Resolved_Type *type){ + Operand result = {type}; + result.is_const = true; + result.is_lvalue = false; + return result; +} + +function Operand +operand_lambda(Ast_Resolved_Type *type){ Operand result = {}; result.type = type; - result.is_const = true; + result.is_const = true; + result.is_lvalue = false; + return result; +} + +function Operand +operand_lvalue(Ast_Resolved_Type *type){ + Operand result = {type}; + result.is_const = false; + result.is_lvalue = true; + return result; +} + +function Operand +operand_rvalue(Ast_Resolved_Type *type){ + Operand result = {type}; + result.is_const = false; + result.is_lvalue = false; return result; }