diff --git a/ccodegen.cpp b/ccodegen.cpp index 30aad02..bdd308b 100644 --- a/ccodegen.cpp +++ b/ccodegen.cpp @@ -76,7 +76,7 @@ gen_expr(Ast_Expr *ast){ if(is_int(node->type)) gen("%lld", node->int_val); else if(is_string(node->type)) gen("LIT(\"%s\")", node->intern_val.str); else if(is_bool(node->type)) node->bool_val ? gen("true"):gen("false"); - else if(node->type == type_f32) gen("%f", node->f32_val); + else if(is_f32(node->type)) gen("%f", node->f32_val); else if(is_float(node->type)) gen("%f", node->f64_val); else invalid_codepath; BREAK(); diff --git a/new_types.kl b/new_types.kl index 507b447..a95217f 100644 --- a/new_types.kl +++ b/new_types.kl @@ -1,14 +1,19 @@ -main :: (argc: S64, argv: **U8) +basic_type_assignment :: () + custom_data: Custom_Data some_constant :: true thing: Bool = some_constant - - - float_val :: 325.42 float_var := float_val int_val :: 1251525 int_var: Int = int_val - conversion: F64 = int_val + conversion: F64 = +int_val + unsigned: Int = ++-int_val + +Custom_Data :: struct + thing: S32 + +// compounds :: () +// custom_data := Custom_Data(23) diff --git a/typecheck.cpp b/typecheck.cpp index f918b28..3901340 100644 --- a/typecheck.cpp +++ b/typecheck.cpp @@ -276,7 +276,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res found->flags = set_flag(found->flags, AST_ITEM_INCLUDED); Operand op = resolve_expr(expr->item, found_type->type); - if(found_type->type != op.type) parsing_error(expr->pos, "Invalid type of compound constructor item"); + if(found_type->type != op.type) parsing_error(expr->pos, "Invalid type of compound constructor item, expected %s got instead %s", type_names[op.type->kind], type_names[found_type->type->kind]); } // @note: cleanup, required? @@ -370,9 +370,44 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res }break; case TK_Dereference:{return operand_lvalue(type_pointer(value.type));}break; case TK_Sub:{ + Operand op = resolve_expr(node->expr); + if(!is_numeric(op.type)) parsing_error(node->pos, "Unary [-] cant be applied to value of type %s", docname(op.type)); + if(op.is_const){ + switch(op.type->kind){ + case TYPE_UNTYPED_INT: op.int_val = -op.int_val;break; + case TYPE_UNTYPED_FLOAT: op.f64_val = -op.f64_val;break; + case TYPE_INT: op.int_val = -op.int_val;break; + case TYPE_S64: op.int_val = -op.int_val;break; // @todo Check bounds + case TYPE_S32: op.int_val = -op.int_val;break; + case TYPE_S16: op.int_val = -op.int_val;break; + case TYPE_S8: op.int_val = -op.int_val;break; + case TYPE_F32: op.f32_val = -op.f32_val;break; + case TYPE_F64: op.f64_val = -op.f64_val;break; + case TYPE_U64: + case TYPE_U32: + case TYPE_U16: + case TYPE_U8: + case TYPE_UINT: parsing_error(node->pos, "Application of unary [-] on type %s results in overflow", docname(op.type));break; + default: parsing_error(node->pos, "Constant application of unary [-] on type of %s is unsupported", docname(op.type));break; + } + auto atom = (Ast_Atom *)node; + atom->kind = AST_VALUE; + atom->flags |= AST_ATOM; + atom->value = op.value; + } + return op; }break; case TK_Add:{ + Operand op = resolve_expr(node->expr); + if(!is_numeric(op.type)) parsing_error(node->pos, "Unary [+] cant be applied to value of type %s", docname(op.type)); + if(op.is_const){ + auto atom = (Ast_Atom *)node; + atom->kind = AST_VALUE; + atom->flags |= AST_ATOM; + atom->value = op.value; + } + return op; }break; invalid_default_case; return {}; } @@ -589,8 +624,11 @@ resolve_binding(Ast *ast, Sym *sym){ CASE(VAR, Var){ Ast_Resolved_Type *type = resolve_typespec(node->typespec, AST_CAN_BE_NULL); Operand expr = resolve_expr(node->expr, type); + if(!type) expr.type = if_untyped_get_default_conversion(expr.type); - if(is_untyped(expr.type)){ + else if(!expr.type) expr.type = type; + else if(type == expr.type); + else if(is_untyped(expr.type)){ Ast_Resolved_Type *untyped = expr.type; if(is_int(type) && is_int(untyped)){ switch(type->kind){ @@ -614,8 +652,8 @@ resolve_binding(Ast *ast, Sym *sym){ invalid_default_case; } } - else if(type->kind == TYPE_F32 && is_float(untyped)){ - expr.f32_val = expr.f64_val; + else if(is_float(type) && is_float(untyped)){ + if(type == type_f32) expr.f32_val = expr.f64_val; } else if(is_bool(type) && is_bool(untyped)); else if(is_string(type) && is_string(untyped)); diff --git a/types.h b/types.h index 98691a5..f924cc0 100644 --- a/types.h +++ b/types.h @@ -9,12 +9,10 @@ enum Ast_Resolved_Type_Kind{ TYPE_NONE, TYPE_COMPLETING, TYPE_INCOMPLETE, - TYPE_UNTYPED_BOOL, // FIRST_TYPED_NUMERIC, FIRST_NUMERIC TYPE_UNTYPED_INT, TYPE_UNTYPED_FLOAT, // LAST_TYPED_NUMERIC TYPE_UNTYPED_STRING, // LAST_NUMERIC - TYPE_INT, // FIRST_NUMERIC TYPE_S64, TYPE_S32, @@ -28,10 +26,8 @@ enum Ast_Resolved_Type_Kind{ TYPE_F32, TYPE_F64, TYPE_BOOL, // LAST_NUMERIC - TYPE_STRING, TYPE_VOID, - TYPE_POINTER, TYPE_ARRAY, TYPE_LAMBDA, @@ -114,6 +110,43 @@ struct Ast_Resolved_Type{ }; }; +function const char * +docname(Ast_Resolved_Type *type){ + switch(type->kind){ + case TYPE_NONE: return "[Invalid Ast_Resolved_Type]"; + case TYPE_COMPLETING: return "[Completing]"; + case TYPE_INCOMPLETE: return "[Incomplete]"; + case TYPE_UNTYPED_BOOL: return "[Untyped_Bool]"; + case TYPE_UNTYPED_INT: return "[Untyped_Int]"; + case TYPE_UNTYPED_FLOAT: return "[Untyped_Float]"; + case TYPE_UNTYPED_STRING: return "[Untyped_String]"; + case TYPE_INT: return "[Int]"; + case TYPE_S64: return "[S64]"; + case TYPE_S32: return "[S32]"; + case TYPE_S16: return "[S16]"; + case TYPE_S8: return "[S8]"; + case TYPE_UINT: return "[UInt]"; + case TYPE_U64: return "[U64]"; + case TYPE_U32: return "[U32]"; + case TYPE_U16: return "[U16]"; + case TYPE_U8: return "[U8]"; + case TYPE_F32: return "[Float32]"; + case TYPE_F64: return "[Float64]"; + case TYPE_BOOL: return "[Bool]"; + case TYPE_STRING: return "[String]"; + case TYPE_VOID: return "[Void]"; + case TYPE_POINTER: return "[Pointer]"; + case TYPE_ARRAY: return "[Array]"; + case TYPE_LAMBDA: return "[Lambda]"; + case TYPE_STRUCT: return "[Struct]"; + case TYPE_UNION: return "[Union]"; + case TYPE_ENUM: return "[Enum]"; + case TYPE_TYPE: return "[Type]"; + invalid_default_case; + } + return ""; +} + function const char * name(Ast_Resolved_Type *type){ switch(type->kind){ @@ -207,6 +240,8 @@ force_inline B32 is_int(Ast_Resolved_Type *a){return (a->kind >= TYPE_INT && a-> force_inline B32 is_signed_int(Ast_Resolved_Type *a){return a->kind >= TYPE_INT && a->kind <= TYPE_S8;} force_inline B32 is_unsigned_int(Ast_Resolved_Type *a){return a->kind >= TYPE_UINT && a->kind <= TYPE_U8;} force_inline B32 is_float(Ast_Resolved_Type *a){return a->kind == TYPE_F32 || a->kind == TYPE_F64 || a->kind == TYPE_UNTYPED_FLOAT;} +force_inline B32 is_f32(Ast_Resolved_Type *a){return a->kind == TYPE_F32;} +force_inline B32 is_f64(Ast_Resolved_Type *a){return a->kind == TYPE_F64;} force_inline B32 is_bool(Ast_Resolved_Type *a){return a->kind == TYPE_BOOL || a->kind == TYPE_UNTYPED_BOOL;} force_inline B32 is_untyped(Ast_Resolved_Type *a){return a->kind >= TYPE_UNTYPED_FIRST && a->kind <= TYPE_UNTYPED_LAST;} force_inline B32 is_typed(Ast_Resolved_Type *a){return !is_untyped(a);}