diff --git a/ccodegen.cpp b/ccodegen.cpp index 7ed2b2f..bec2efd 100644 --- a/ccodegen.cpp +++ b/ccodegen.cpp @@ -82,13 +82,11 @@ gen_expr(Ast_Expr *ast){ BREAK(); } - CASE(INT, Atom){ - gen("%lld", node->int_val); - BREAK(); - } - - CASE(STR, Atom){ - gen("LIT(\"%s\")", node->intern_val.str); + CASE(VALUE, Atom){ + 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 invalid_codepath; BREAK(); } diff --git a/main.cpp b/main.cpp index 14fe87e..03f1772 100644 --- a/main.cpp +++ b/main.cpp @@ -80,6 +80,7 @@ For now I don't thing it should be overloadable. #include "base.cpp" #include "base_unicode.cpp" #include "new_lex.cpp" +#include "types.h" #include "new_ast.cpp" #include "new_parse.cpp" #include "typecheck.h" diff --git a/new_ast.cpp b/new_ast.cpp index 5513502..17a2109 100644 --- a/new_ast.cpp +++ b/new_ast.cpp @@ -83,8 +83,7 @@ enum Ast_Kind: U32{ AST_PACKAGE, - AST_STR, - AST_INT, + AST_VALUE, AST_CAST, AST_IDENT, AST_INDEX, @@ -116,9 +115,9 @@ enum{ AST_STMT = 2, AST_BINDING = 4, AST_AGGREGATE = 8, - AST_ATOM = 16, - AST_AGGREGATE_CHILD = 32, - AST_ITEM_INCLUDED = 64, + AST_AGGREGATE_CHILD = 16, + AST_ITEM_INCLUDED = 32, + AST_ATOM = 64, }; struct Ast{ @@ -140,6 +139,7 @@ union{ \ F64 f64_val; \ F32 f32_val; \ S64 int_val; \ + U64 uint_val; \ Intern_String intern_val; \ Ast_Resolved_Type *type_val; \ }; @@ -282,21 +282,23 @@ struct Ast_Package:Ast{ function Ast_Atom * ast_str(Token *pos, Intern_String string){ - AST_NEW(Atom, STR, pos, AST_ATOM | AST_EXPR); + AST_NEW(Atom, VALUE, pos, AST_EXPR | AST_ATOM); + result->type = type_string; // @todo untyped result->intern_val = string; return result; } function Ast_Atom * ast_ident(Token *pos, Intern_String string){ - AST_NEW(Atom, IDENT, pos, AST_ATOM | AST_EXPR); + AST_NEW(Atom, IDENT, pos, AST_EXPR | AST_ATOM); result->intern_val = string; return result; } function Ast_Atom * ast_int(Token *pos, S64 integer){ - AST_NEW(Atom, INT, pos, AST_ATOM | AST_EXPR); + AST_NEW(Atom, VALUE, pos, AST_EXPR | AST_ATOM); + result->type = type_int; // @todo untyped result->int_val = integer; return result; } diff --git a/typecheck.cpp b/typecheck.cpp index dd95da8..cc9a5a9 100644 --- a/typecheck.cpp +++ b/typecheck.cpp @@ -112,16 +112,8 @@ 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; + ast->kind = AST_VALUE; + ast->value = sym->value; } #define rewrite_into_const(ast,T,sym) _rewrite_into_const(ast,sizeof(T),sym) @@ -176,8 +168,10 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res assert(is_flag_set(ast->flags, AST_EXPR)); switch(ast->kind){ - CASE(INT, Atom){return operand_int(node->int_val); BREAK();} - CASE(STR, Atom){return operand_str(node->intern_val); BREAK();} + CASE(VALUE, Atom){ + return operand_rvalue(node->value); + BREAK(); + } CASE(IDENT, Atom){ Sym *sym = resolve_name(node->pos, node->intern_val); diff --git a/typecheck.h b/typecheck.h index e4aae22..241c24a 100644 --- a/typecheck.h +++ b/typecheck.h @@ -1,188 +1,3 @@ -//----------------------------------------------------------------------------- -// Resolved Types -//----------------------------------------------------------------------------- -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, - TYPE_S16, - TYPE_S8 , - TYPE_UINT, - TYPE_U64, - TYPE_U32, - TYPE_U16, - TYPE_U8 , - TYPE_F32, - TYPE_F64, - TYPE_BOOL, // LAST_NUMERIC - - TYPE_STRING, - TYPE_VOID, - - TYPE_POINTER, - TYPE_ARRAY, - TYPE_LAMBDA, - TYPE_STRUCT, - TYPE_UNION, - TYPE_ENUM, - TYPE_TYPE, - - TYPE_UNTYPED_FIRST = TYPE_UNTYPED_BOOL, - TYPE_UNTYPED_LAST = TYPE_UNTYPED_STRING, - - TYPE_UNTYPED_FIRST_NUMERIC = TYPE_UNTYPED_BOOL, - TYPE_UNTYPED_LAST_NUMERIC = TYPE_UNTYPED_FLOAT, - - TYPE_FIRST_NUMERIC = TYPE_INT, - TYPE_LAST_NUMERIC = TYPE_BOOL, -}; - -const char *type_names[] = { - "[Invalid Ast_Resolved_Type]", - "[Completing]", - "[Incomplete]", - - "[Untyped_Bool]", - "[Untyped_Int]", - "[Untyped_Float]", - "[Untyped_String]", - - "[Int]", - "[S64]", - "[S32]", - "[S16]", - "[S8]", - "[UInt]", - "[U64]", - "[U32]", - "[U16]", - "[U8]", - "[Float32]", - "[Float64]", - "[Bool]", - "[String]", - "[Void]", - "[Pointer]", - "[Array]", - "[Lambda]", - "[Struct]", - "[Union]", - "[Enum]", - "[Type]", -}; - -struct Ast_Resolved_Member{ - Ast_Resolved_Type *type; - Intern_String name; - U64 offset; -}; - -struct Ast_Resolved_Type{ - Ast_Resolved_Type_Kind kind; - SizeU size; - SizeU align; - - Ast *ast; - union{ - Ast_Resolved_Type *base; - struct{ - Ast_Resolved_Type *base; - SizeU size; - }arr; - struct{ - Array members; - }agg; - struct{ - Ast_Resolved_Type *ret; - Array args; - }func; - }; -}; - -function const char * -name(Ast_Resolved_Type *type){ - switch(type->kind){ - case TYPE_VOID: return "void"; - case TYPE_INT: return "Int"; - case TYPE_UINT: return "UInt"; - case TYPE_BOOL: return "bool"; - case TYPE_STRING: return "String"; - case TYPE_S8: return "S8"; - case TYPE_S16: return "S16"; - case TYPE_S32: return "S32"; - case TYPE_S64: return "S64"; - case TYPE_U8: return "U8"; - case TYPE_U16: return "U16"; - case TYPE_U32: return "U32"; - case TYPE_U64: return "U64"; - invalid_default_case; - } - return ""; -} - -//----------------------------------------------------------------------------- -// Type globals -//----------------------------------------------------------------------------- -const SizeU pointer_size = sizeof(SizeU); -const SizeU pointer_align = __alignof(SizeU); -global Ast_Resolved_Type type__void = {TYPE_VOID}; -global Ast_Resolved_Type type__string = {TYPE_STRING, sizeof(String), __alignof(String)}; -global Ast_Resolved_Type type__bool = {TYPE_BOOL, sizeof(bool), __alignof(bool)}; -global Ast_Resolved_Type type__type = {TYPE_TYPE}; - -global Ast_Resolved_Type type__f32 = {TYPE_F32, sizeof(F32), __alignof(F32)}; -global Ast_Resolved_Type type__f64 = {TYPE_F64, sizeof(F64), __alignof(F64)}; - -global Ast_Resolved_Type type__int = {TYPE_INT, sizeof(S64), __alignof(S64)}; -global Ast_Resolved_Type type__s8 = {TYPE_S8, sizeof(S8), __alignof(S8)}; -global Ast_Resolved_Type type__s16 = {TYPE_S16, sizeof(S16), __alignof(S16)}; -global Ast_Resolved_Type type__s32 = {TYPE_S32, sizeof(S32), __alignof(S32)}; -global Ast_Resolved_Type type__s64 = {TYPE_S64, sizeof(S64), __alignof(S64)}; - -global Ast_Resolved_Type type__uint = {TYPE_UINT, sizeof(SizeU), __alignof(SizeU)}; -global Ast_Resolved_Type type__u8 = {TYPE_U8, sizeof(U8), __alignof(U8)}; -global Ast_Resolved_Type type__u16 = {TYPE_U16, sizeof(U16), __alignof(U16)}; -global Ast_Resolved_Type type__u32 = {TYPE_U32, sizeof(U32), __alignof(U32)}; -global Ast_Resolved_Type type__u64 = {TYPE_U64, sizeof(U64), __alignof(U64)}; - -global Ast_Resolved_Type type__untyped_bool = {TYPE_UNTYPED_BOOL, sizeof(bool), __alignof(bool)}; -global Ast_Resolved_Type type__untyped_int = {TYPE_UNTYPED_INT, sizeof(S64), __alignof(S64)}; -global Ast_Resolved_Type type__untyped_string = {TYPE_UNTYPED_STRING, sizeof(String), __alignof(String)}; -global Ast_Resolved_Type type__untyped_float = {TYPE_UNTYPED_FLOAT, sizeof(double), __alignof(double)}; - -global Ast_Resolved_Type *type_type = &type__type; -global Ast_Resolved_Type *type_void = &type__void; -global Ast_Resolved_Type *type_string = &type__string; -global Ast_Resolved_Type *type_bool = &type__bool; - -global Ast_Resolved_Type *type_f32 = &type__f32; -global Ast_Resolved_Type *type_f64 = &type__f64; - -global Ast_Resolved_Type *type_int = &type__int; -global Ast_Resolved_Type *type_s8 = &type__s8 ; -global Ast_Resolved_Type *type_s16 = &type__s16; -global Ast_Resolved_Type *type_s32 = &type__s32; -global Ast_Resolved_Type *type_s64 = &type__s64; - -global Ast_Resolved_Type *type_uint = &type__uint; -global Ast_Resolved_Type *type_u8 = &type__u8 ; -global Ast_Resolved_Type *type_u16 = &type__u16; -global Ast_Resolved_Type *type_u32 = &type__u32; -global Ast_Resolved_Type *type_u64 = &type__u64; - -global Ast_Resolved_Type *untyped_string = &type__untyped_string; -global Ast_Resolved_Type *untyped_bool = &type__untyped_bool; -global Ast_Resolved_Type *untyped_int = &type__untyped_int; -global Ast_Resolved_Type *untyped_float = &type__untyped_float; //----------------------------------------------------------------------------- // Symbols @@ -349,10 +164,21 @@ sym_insert_builtin_type(String name, Ast_Resolved_Type *type){ function void sym_insert_builtins(){ - sym_insert_builtin_type("Void"_s, type_void); - sym_insert_builtin_type("Bool"_s, type_bool); - sym_insert_builtin_type("Int"_s, type_int); + sym_insert_builtin_type("Void"_s , type_void); + sym_insert_builtin_type("Bool"_s , type_bool); + sym_insert_builtin_type("Int"_s , type_int); sym_insert_builtin_type("String"_s, type_string); + sym_insert_builtin_type("S8"_s, type_s8); + sym_insert_builtin_type("S16"_s, type_s16); + sym_insert_builtin_type("S32"_s, type_s32); + sym_insert_builtin_type("S64"_s, type_s64); + sym_insert_builtin_type("U8"_s, type_u8); + sym_insert_builtin_type("U16"_s, type_u16); + sym_insert_builtin_type("U32"_s, type_u32); + sym_insert_builtin_type("U64"_s, type_u64); + sym_insert_builtin_type("F32"_s, type_f32); + sym_insert_builtin_type("F64"_s, type_f64); + { Intern_String string = intern_string(&pctx->interns, "true"_s); @@ -425,6 +251,14 @@ operand_lambda(Ast_Resolved_Type *type){ return result; } +function Operand +operand_rvalue(Value value){ + Operand result = {}; + result.is_const = true; + result.value = value; + return result; +} + function Operand operand_lvalue(Ast_Resolved_Type *type){ Operand result = {}; @@ -444,30 +278,8 @@ operand_rvalue(Ast_Resolved_Type *type){ } //----------------------------------------------------------------------------- -// Type constructors and utillities +// Hash consed types //----------------------------------------------------------------------------- -force_inline B32 is_struct(Ast_Resolved_Type *a){return a->kind == TYPE_STRUCT;} -force_inline B32 is_array(Ast_Resolved_Type *a){return a->kind == TYPE_ARRAY;} -force_inline B32 is_enum(Ast_Resolved_Type *a){return a->kind == TYPE_ENUM;} -force_inline B32 is_pointer(Ast_Resolved_Type *a){return a->kind == TYPE_POINTER;} -force_inline B32 is_string(Ast_Resolved_Type *a){return a->kind == TYPE_STRING || a->kind == TYPE_UNTYPED_STRING;} -force_inline B32 is_untyped_int(Ast_Resolved_Type *a){return a->kind == TYPE_UNTYPED_INT;} -force_inline B32 is_typed_int(Ast_Resolved_Type *a){return (a->kind >= TYPE_INT && a->kind <= TYPE_U8);} -force_inline B32 is_int(Ast_Resolved_Type *a){return (a->kind >= TYPE_INT && a->kind <= TYPE_U8) || a->kind == TYPE_UNTYPED_INT;} -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_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);} - - -force_inline B32 -is_numeric(Ast_Resolved_Type *type){ - return (type->kind >= TYPE_UNTYPED_FIRST_NUMERIC && type->kind <= TYPE_UNTYPED_LAST_NUMERIC) || - (type->kind >= TYPE_FIRST_NUMERIC && type->kind <= TYPE_LAST_NUMERIC); -} - function Ast_Resolved_Type * type_new(Allocator *allocator, Ast_Resolved_Type_Kind kind, SizeU size, SizeU align){ Ast_Resolved_Type *result = exp_alloc_type(allocator, Ast_Resolved_Type, AF_ZeroMemory); diff --git a/types.h b/types.h new file mode 100644 index 0000000..99eb06f --- /dev/null +++ b/types.h @@ -0,0 +1,215 @@ +//----------------------------------------------------------------------------- +// Resolved Types +//----------------------------------------------------------------------------- +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, + TYPE_S16, + TYPE_S8 , + TYPE_UINT, + TYPE_U64, + TYPE_U32, + TYPE_U16, + TYPE_U8 , + TYPE_F32, + TYPE_F64, + TYPE_BOOL, // LAST_NUMERIC + + TYPE_STRING, + TYPE_VOID, + + TYPE_POINTER, + TYPE_ARRAY, + TYPE_LAMBDA, + TYPE_STRUCT, + TYPE_UNION, + TYPE_ENUM, + TYPE_TYPE, + + TYPE_UNTYPED_FIRST = TYPE_UNTYPED_BOOL, + TYPE_UNTYPED_LAST = TYPE_UNTYPED_STRING, + + TYPE_UNTYPED_FIRST_NUMERIC = TYPE_UNTYPED_BOOL, + TYPE_UNTYPED_LAST_NUMERIC = TYPE_UNTYPED_FLOAT, + + TYPE_FIRST_NUMERIC = TYPE_INT, + TYPE_LAST_NUMERIC = TYPE_BOOL, +}; + +const char *type_names[] = { + "[Invalid Ast_Resolved_Type]", + "[Completing]", + "[Incomplete]", + + "[Untyped_Bool]", + "[Untyped_Int]", + "[Untyped_Float]", + "[Untyped_String]", + + "[Int]", + "[S64]", + "[S32]", + "[S16]", + "[S8]", + "[UInt]", + "[U64]", + "[U32]", + "[U16]", + "[U8]", + "[Float32]", + "[Float64]", + "[Bool]", + "[String]", + "[Void]", + "[Pointer]", + "[Array]", + "[Lambda]", + "[Struct]", + "[Union]", + "[Enum]", + "[Type]", +}; + +struct Ast; +struct Ast_Resolved_Type; +struct Ast_Resolved_Member{ + Ast_Resolved_Type *type; + Intern_String name; + U64 offset; +}; + +struct Ast_Resolved_Type{ + Ast_Resolved_Type_Kind kind; + SizeU size; + SizeU align; + + Ast *ast; + union{ + Ast_Resolved_Type *base; + struct{ + Ast_Resolved_Type *base; + SizeU size; + }arr; + struct{ + Array members; + }agg; + struct{ + Ast_Resolved_Type *ret; + Array args; + }func; + }; +}; + +function const char * +name(Ast_Resolved_Type *type){ + switch(type->kind){ + case TYPE_VOID: return "Void"; + case TYPE_INT: return "Int"; + case TYPE_UINT: return "UInt"; + case TYPE_BOOL: return "Bool"; + case TYPE_STRING: return "String"; + + case TYPE_F32: return "F32"; + case TYPE_F64: return "F64"; + case TYPE_S8: return "S8"; + case TYPE_S16: return "S16"; + case TYPE_S32: return "S32"; + case TYPE_S64: return "S64"; + case TYPE_U8: return "U8"; + case TYPE_U16: return "U16"; + case TYPE_U32: return "U32"; + case TYPE_U64: return "U64"; + invalid_default_case; + } + return ""; +} + +//----------------------------------------------------------------------------- +// Type globals +//----------------------------------------------------------------------------- +const SizeU pointer_size = sizeof(SizeU); +const SizeU pointer_align = __alignof(SizeU); +global Ast_Resolved_Type type__void = {TYPE_VOID}; +global Ast_Resolved_Type type__string = {TYPE_STRING, sizeof(String), __alignof(String)}; +global Ast_Resolved_Type type__bool = {TYPE_BOOL, sizeof(bool), __alignof(bool)}; +global Ast_Resolved_Type type__type = {TYPE_TYPE}; + +global Ast_Resolved_Type type__f32 = {TYPE_F32, sizeof(F32), __alignof(F32)}; +global Ast_Resolved_Type type__f64 = {TYPE_F64, sizeof(F64), __alignof(F64)}; + +global Ast_Resolved_Type type__int = {TYPE_INT, sizeof(S64), __alignof(S64)}; +global Ast_Resolved_Type type__s8 = {TYPE_S8, sizeof(S8), __alignof(S8)}; +global Ast_Resolved_Type type__s16 = {TYPE_S16, sizeof(S16), __alignof(S16)}; +global Ast_Resolved_Type type__s32 = {TYPE_S32, sizeof(S32), __alignof(S32)}; +global Ast_Resolved_Type type__s64 = {TYPE_S64, sizeof(S64), __alignof(S64)}; + +global Ast_Resolved_Type type__uint = {TYPE_UINT, sizeof(SizeU), __alignof(SizeU)}; +global Ast_Resolved_Type type__u8 = {TYPE_U8, sizeof(U8), __alignof(U8)}; +global Ast_Resolved_Type type__u16 = {TYPE_U16, sizeof(U16), __alignof(U16)}; +global Ast_Resolved_Type type__u32 = {TYPE_U32, sizeof(U32), __alignof(U32)}; +global Ast_Resolved_Type type__u64 = {TYPE_U64, sizeof(U64), __alignof(U64)}; + +global Ast_Resolved_Type type__untyped_bool = {TYPE_UNTYPED_BOOL, sizeof(bool), __alignof(bool)}; +global Ast_Resolved_Type type__untyped_int = {TYPE_UNTYPED_INT, sizeof(S64), __alignof(S64)}; +global Ast_Resolved_Type type__untyped_string = {TYPE_UNTYPED_STRING, sizeof(String), __alignof(String)}; +global Ast_Resolved_Type type__untyped_float = {TYPE_UNTYPED_FLOAT, sizeof(double), __alignof(double)}; + +global Ast_Resolved_Type *type_type = &type__type; +global Ast_Resolved_Type *type_void = &type__void; +global Ast_Resolved_Type *type_string = &type__string; +global Ast_Resolved_Type *type_bool = &type__bool; + +global Ast_Resolved_Type *type_f32 = &type__f32; +global Ast_Resolved_Type *type_f64 = &type__f64; + +global Ast_Resolved_Type *type_int = &type__int; +global Ast_Resolved_Type *type_s8 = &type__s8 ; +global Ast_Resolved_Type *type_s16 = &type__s16; +global Ast_Resolved_Type *type_s32 = &type__s32; +global Ast_Resolved_Type *type_s64 = &type__s64; + +global Ast_Resolved_Type *type_uint = &type__uint; +global Ast_Resolved_Type *type_u8 = &type__u8 ; +global Ast_Resolved_Type *type_u16 = &type__u16; +global Ast_Resolved_Type *type_u32 = &type__u32; +global Ast_Resolved_Type *type_u64 = &type__u64; + +global Ast_Resolved_Type *untyped_string = &type__untyped_string; +global Ast_Resolved_Type *untyped_bool = &type__untyped_bool; +global Ast_Resolved_Type *untyped_int = &type__untyped_int; +global Ast_Resolved_Type *untyped_float = &type__untyped_float; + +//----------------------------------------------------------------------------- +// Type constructors and utillities +//----------------------------------------------------------------------------- +force_inline B32 is_struct(Ast_Resolved_Type *a){return a->kind == TYPE_STRUCT;} +force_inline B32 is_array(Ast_Resolved_Type *a){return a->kind == TYPE_ARRAY;} +force_inline B32 is_enum(Ast_Resolved_Type *a){return a->kind == TYPE_ENUM;} +force_inline B32 is_pointer(Ast_Resolved_Type *a){return a->kind == TYPE_POINTER;} +force_inline B32 is_string(Ast_Resolved_Type *a){return a->kind == TYPE_STRING || a->kind == TYPE_UNTYPED_STRING;} +force_inline B32 is_untyped_int(Ast_Resolved_Type *a){return a->kind == TYPE_UNTYPED_INT;} +force_inline B32 is_typed_int(Ast_Resolved_Type *a){return (a->kind >= TYPE_INT && a->kind <= TYPE_U8);} +force_inline B32 is_int(Ast_Resolved_Type *a){return (a->kind >= TYPE_INT && a->kind <= TYPE_U8) || a->kind == TYPE_UNTYPED_INT;} +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_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);} + + +force_inline B32 +is_numeric(Ast_Resolved_Type *type){ + return (type->kind >= TYPE_UNTYPED_FIRST_NUMERIC && type->kind <= TYPE_UNTYPED_LAST_NUMERIC) || + (type->kind >= TYPE_FIRST_NUMERIC && type->kind <= TYPE_LAST_NUMERIC); +}