Adding Unary [-] [+] to new type system
This commit is contained in:
@@ -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();
|
||||
|
||||
15
new_types.kl
15
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)
|
||||
|
||||
@@ -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));
|
||||
|
||||
43
types.h
43
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 "<Unknown_Type>";
|
||||
}
|
||||
|
||||
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);}
|
||||
|
||||
Reference in New Issue
Block a user