From 173ef843df925014d2700d0d4893aa6ee396cdce Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Thu, 2 Jun 2022 22:17:28 +0200 Subject: [PATCH] New types, Value rework, Sym cleanup --- ccodegen.cpp | 6 +- enums.kl | 2 +- globals.kl | 42 ++++----- lambdas.kl | 22 ++--- lexer.kl | 2 +- new_ast.cpp | 26 ++++-- new_types.kl | 6 ++ order1.kl | 2 +- order2.kl | 26 +++--- typecheck.cpp | 47 +++++----- typecheck.h | 238 +++++++++++++++++++++++++++++++++++++------------- 11 files changed, 270 insertions(+), 149 deletions(-) create mode 100644 new_types.kl diff --git a/ccodegen.cpp b/ccodegen.cpp index 8b4daba..7ed2b2f 100644 --- a/ccodegen.cpp +++ b/ccodegen.cpp @@ -20,9 +20,9 @@ gen_indent(){ function void gen_simple_decl_prefix(Ast_Resolved_Type *ast){ switch(ast->kind){ - case TYPE_INT: gen("int "); break; + case TYPE_INT: gen("Int "); break; case TYPE_BOOL: gen("bool "); break; - case TYPE_UNSIGNED: gen("unsigned "); break; + case TYPE_UINT: gen("UInt "); break; case TYPE_STRING: gen("String "); break; case TYPE_VOID: gen("void "); break; case TYPE_POINTER:{gen_simple_decl_prefix(ast->base); gen("*");} break; @@ -43,7 +43,7 @@ gen_simple_decl_postfix(Ast_Resolved_Type *ast){ switch(ast->kind){ case TYPE_INT: break; case TYPE_BOOL: break; - case TYPE_UNSIGNED: break; + case TYPE_UINT: break; case TYPE_STRING: break; case TYPE_VOID: break; case TYPE_POINTER: gen_simple_decl_postfix(ast->base); break; diff --git a/enums.kl b/enums.kl index 5d9cb81..fc3c4d5 100644 --- a/enums.kl +++ b/enums.kl @@ -1,6 +1,6 @@ Thing :: struct - len: int + len: Int Constant_String :: "Test" Constant :: 10 diff --git a/globals.kl b/globals.kl index f10a8b4..ee0ccf0 100644 --- a/globals.kl +++ b/globals.kl @@ -1,58 +1,58 @@ //----------------------------------------------------------------------------- // Function types //----------------------------------------------------------------------------- -test_function :: (thing: int): *int +test_function :: (thing: Int): *Int function_type: test_function const_function_alias :: test_function -// null_function: (t: int): *int = null +// null_function: (t: Int): *Int = null //----------------------------------------------------------------------------- // Booleans //----------------------------------------------------------------------------- -boolean: bool = true -value_of_bool: int = cast(boolean: int) +Boolean: Bool = true +value_of_Bool: Int = cast(Boolean: Int) //----------------------------------------------------------------------------- // Nulls //----------------------------------------------------------------------------- -// int_null: int = null +// Int_null: Int = null // str_null: String = null -// bool_null: bool = null +// Bool_null: Bool = null //----------------------------------------------------------------------------- // Compound expressions //----------------------------------------------------------------------------- -array1: [4]int = [4]int(1,2,3,4) -array2 := [32]int(1,2,3,4) -array3 := [32]int( +array1: [4]Int = [4]Int(1,2,3,4) +array2 := [32]Int(1,2,3,4) +array3 := [32]Int( [0] = 0, [1] = 1, [2] = 2, [31] = 31, ) array_item := array1[0] -array_item_imp: int = array2[2] +array_item_imp: Int = array2[2] //----------------------------------------------------------------------------- -// Pointers +// PoInters //----------------------------------------------------------------------------- -pointer_decl : *int -variable_from_deref: int = *pointer_decl -pointer_from_var : *int = &variable_from_deref -boolean_pointer := &boolean +poInter_decl : *Int +variable_from_deref: Int = *poInter_decl +poInter_from_var : *Int = &variable_from_deref +Boolean_poInter := &Boolean //----------------------------------------------------------------------------- // Implicit type //----------------------------------------------------------------------------- -implicit_int :: 10 +implicit_Int :: 10 implicit_str :: "Hello world" //----------------------------------------------------------------------------- -// Pointers +// PoInters //----------------------------------------------------------------------------- -// pointer1: *int = 0 -// pointer2: *int = pointer1 -// pointer3: **int = 0 +// poInter1: *Int = 0 +// poInter2: *Int = poInter1 +// poInter3: **Int = 0 //----------------------------------------------------------------------------- // String types @@ -61,7 +61,7 @@ string1 :: "Test" string2 :: string1 //----------------------------------------------------------------------------- -// Constant int variables +// Constant Int variables //----------------------------------------------------------------------------- thing0 :: 10 thing1 :: thing0 + 11 diff --git a/lambdas.kl b/lambdas.kl index 055cd7b..614bea0 100644 --- a/lambdas.kl +++ b/lambdas.kl @@ -1,8 +1,8 @@ -a_type :: int -pointer_type :: *int -// null_pointer: pointer_type = null +a_type :: Int +poInter_type :: *Int +// null_poInter: poInter_type = null -if_stmt :: (cond: int): type +if_stmt :: (cond: Int): type CONSTANT :: 10 thing := 10 if i := thing + cond, cond + CONSTANT @@ -17,11 +17,11 @@ for_stmt :: () for i := 0, i + 10, i+=1 pass -add_10 :: (size: int): int - add_20 :: (new_size: int): int +add_10 :: (size: Int): Int + add_20 :: (new_size: Int): Int return 20 - add :: (a: int, b: int = 10): int + add :: (a: Int, b: Int = 10): Int return a + b constant :: 20; result := constant + 10 @@ -38,13 +38,13 @@ add_10 :: (size: int): int return v4 -return_constant :: (): int +return_constant :: (): Int constant :: 10 return constant -returning_void :: (insert: int) - val1: int = return_constant() - val2: int = add_10(val1) +returning_Void :: (insert: Int) + val1: Int = return_constant() + val2: Int = add_10(val1) return diff --git a/lexer.kl b/lexer.kl index ce29feb..28b1f0d 100644 --- a/lexer.kl +++ b/lexer.kl @@ -1,7 +1,7 @@ /* Lex_Stream :: struct stream: String - offset: int + offset: Int lexc :: (s: *Lex_Stream): String // @todo U8 U S return s.stream + s.offset // s.offset @todo Actual string support diff --git a/new_ast.cpp b/new_ast.cpp index 8f7a867..5513502 100644 --- a/new_ast.cpp +++ b/new_ast.cpp @@ -18,7 +18,7 @@ Intern_String keyword_enum; Intern_String intern_void; Intern_String intern_int; Intern_String intern_str; -Intern_String intern_unsigned; +Intern_String intern_uint; struct Ast_Package; struct Sym; @@ -67,10 +67,10 @@ struct Parse_Ctx:Lexer{ interns.first_keyword = keyword_struct.str; interns.last_keyword = keyword_enum.str; - intern_void = intern_string(&interns, "void"_s); - intern_int = intern_string(&interns, "int"_s); + intern_void = intern_string(&interns, "Void"_s); + intern_int = intern_string(&interns, "Int"_s); intern_str = intern_string(&interns, "String"_s); - intern_unsigned = intern_string(&interns, "unsigned"_s); + intern_uint = intern_string(&interns, "UInt"_s); } }; @@ -133,11 +133,21 @@ struct Ast{ struct Ast_Resolved_Type; struct Ast_Expr:Ast{}; +#define VALUE_FIELDS \ +Ast_Resolved_Type *type; \ +union{ \ + bool bool_val; \ + F64 f64_val; \ + F32 f32_val; \ + S64 int_val; \ + Intern_String intern_val; \ + Ast_Resolved_Type *type_val; \ +}; +#define INLINE_VALUE_FIELDS union{Value value; struct{VALUE_FIELDS};} +struct Value{VALUE_FIELDS}; + struct Ast_Atom: Ast_Expr{ - union{ - Intern_String intern_val; - U64 int_val; - }; + INLINE_VALUE_FIELDS; }; struct Ast_Call_Item: Ast_Expr{ diff --git a/new_types.kl b/new_types.kl new file mode 100644 index 0000000..ba9c236 --- /dev/null +++ b/new_types.kl @@ -0,0 +1,6 @@ + +main :: (argc: S64, argv: **U8) + some_constant :: true + thing: Bool = some_constant + + diff --git a/order1.kl b/order1.kl index 86b6518..71c6b38 100644 --- a/order1.kl +++ b/order1.kl @@ -2,7 +2,7 @@ other_func :: () a_val := recursive_lambda -recursive_lambda :: (thing: int) +recursive_lambda :: (thing: Int) in_val := recursive_lambda some_value := thing + const_in_lambda diff --git a/order2.kl b/order2.kl index 6745deb..c162daa 100644 --- a/order2.kl +++ b/order2.kl @@ -1,5 +1,5 @@ Str16 :: String16 -// arena_pointer: *Arena = null +// arena_poInter: *Arena = null thing: Arena no_type := thing constant_access := Arena.constant_inside @@ -11,22 +11,22 @@ arena := Arena( cap = 1000, ) -// lambda_value := (val: int) // @todo +// lambda_value := (val: Int) // @todo // return Arena :: struct // arena: Arena next: *Arena - data: *int - len : int - cap : int + data: *Int + len : Int + cap : Int Sub :: struct - len: int + len: Int Sub_Sub :: struct - len: int + len: Int - get_len :: (s: *Arena): int // @todo + get_len :: (s: *Arena): Int // @todo return s.next.len constant_inside :: 10000 @@ -35,12 +35,12 @@ Arena :: struct string16: Str16 String16 :: struct - data: *void - len : int + data: *Void + len : Int with_type: Arena = thing -pointer := &with_type -deref := *pointer +poInter := &with_type +deref := *poInter test_assignments :: () @@ -59,7 +59,7 @@ test_assignments :: () i = i > 2 CONST :: 23 == 23 - j: *int + j: *Int *j = 1 /* invalid 8 = 32 diff --git a/typecheck.cpp b/typecheck.cpp index 91af031..dd95da8 100644 --- a/typecheck.cpp +++ b/typecheck.cpp @@ -5,7 +5,7 @@ function Ast_Resolved_Type * resolve_typespec(Ast_Expr *ast, B32 ast_can_be_null){ if(ast_can_be_null && ast == 0) return 0; Operand resolved = resolve_expr(ast); - if(resolved.type != type_type) parsing_error(ast->pos, "Expected [Type] got instead %s", resolved.type->kind); + if(resolved.type != type_type) parsing_error(ast->pos, "Expected [Type] got instead %s", type_names[resolved.type->kind]); return resolved.type_val; } @@ -55,34 +55,18 @@ resolve_stmt(Ast *ast, Ast_Resolved_Type *ret){ CASE(VAR, Var){ Operand op = resolve_binding(node); - Sym *sym = sym_new_resolved(SYM_VAR, node->name, op.type, op.value, node); - sym_insert(sym); + sym_var(node->name, op, node, INSERT_INTO_SCOPE); BREAK(); } CASE(CONST, Const){ Operand op = resolve_binding(node); - Sym *sym = sym_new_resolved(SYM_CONST, node->name, op.type, op.value, node); - sym_insert(sym); + sym_const(node->name, op, node, INSERT_INTO_SCOPE); BREAK(); } CASE(BINARY, Binary){ - if(node->op == TK_ColonAssign){ - // Operand left = resolve_expr(node->left); // needs to be lvalue - Operand right = resolve_expr(node->right); - assert(node->left->kind == AST_IDENT); - Ast_Atom *atom = (Ast_Atom *)node->left; // @todo use left operand - Sym *sym = sym_new_resolved(SYM_VAR, atom->intern_val, right.type, right.value, node); - sym_insert(sym); - } - else if(token_is_assign(node->op)){ - Operand left = resolve_expr(node->left); - if(!left.is_lvalue) parsing_error(node->pos, "Assigning to rvalue"); - Operand right = resolve_expr(node->right); - if(left.type != right.type) parsing_error(node->pos, "Different types"); - } - else invalid_codepath; + resolve_expr(node); BREAK(); } @@ -156,7 +140,7 @@ resolve_lambda(Ast_Lambda *lambda, Sym *sym = 0){ } lambda_type = type_lambda(lambda, ret_type, args); - sym_type(lambda, lambda_type); + sym_type(lambda_type, lambda); Operand result = operand_type(lambda_type); // @note: top level lambda needs to get marked as resolved @@ -173,7 +157,7 @@ resolve_lambda(Ast_Lambda *lambda, Sym *sym = 0){ For(lambda->args){ S64 i = lambda->args.get_index(&it); Ast_Resolved_Type *type = args[i]; - sym_insert(SYM_VAR, it->name, type, {}, it); + sym_var(it->name, type, it, INSERT_INTO_SCOPE); } For(lambda->block->stmts){ resolve_stmt(it, ret_type); @@ -218,7 +202,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res Operand expr = require_const_int(node->expr, AST_CANT_BE_NULL); Ast_Resolved_Type *resolved = type_array(type.type_val, expr.int_val); - sym_type(node, resolved); + sym_type(resolved, node); return operand_type(resolved); BREAK(); } @@ -385,7 +369,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res if(value.type->kind == TYPE_POINTER){return operand_lvalue(value.type->base);} else if(value.type->kind == TYPE_TYPE){ Ast_Resolved_Type *type = type_pointer(value.type_val); - sym_new_resolved_type(type, node); + sym_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 {}; } @@ -406,9 +390,18 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res Operand right = resolve_expr(node->right); Ast_Atom *atom = (Ast_Atom *)node->left; - sym_insert(SYM_VAR, atom->intern_val, right.type, right.value, node); + sym_var(atom->intern_val, right, node, INSERT_INTO_SCOPE); } + //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- + else if(token_is_assign(node->op)){ + assert(is_flag_set(node->flags, AST_STMT)); + Operand left = resolve_expr(node->left); + if(!left.is_lvalue) parsing_error(node->pos, "Assigning to rvalue"); + Operand right = resolve_expr(node->right); + if(left.type != right.type) parsing_error(node->pos, "Different types"); + } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- @@ -427,7 +420,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res if(is_pointer(type)) type = type->base; type_complete(type); if(!(is_struct(type) || is_enum(type))) parsing_error(node->pos, "Trying to access inside a value that is not a struct or enum"); - sym_new_resolved(SYM_VAR, {}, resolved_ident.type, {}, node->left); + sym_var({}, resolved_ident.type, node->left); // This happens only on binary nodes which further chain with dots and require lookups // This part cant happen on enums @@ -568,7 +561,7 @@ resolve_const(Ast_Expr *ast, Sym *sym){ op.int_val = value++; } - sym_insert(SYM_CONST, it->name, op.type, op.value, it); + sym_const(it->name, op, it, INSERT_INTO_SCOPE); } scope_close(scope_index); return operand_type(type); diff --git a/typecheck.h b/typecheck.h index 5474329..e4aae22 100644 --- a/typecheck.h +++ b/typecheck.h @@ -3,17 +3,31 @@ //----------------------------------------------------------------------------- enum Ast_Resolved_Type_Kind{ TYPE_NONE, - TYPE_NULL, TYPE_COMPLETING, TYPE_INCOMPLETE, - TYPE_UNTYPED_BOOL, + + TYPE_UNTYPED_BOOL, // FIRST_TYPED_NUMERIC, FIRST_NUMERIC TYPE_UNTYPED_INT, - TYPE_UNTYPED_STRING, - TYPE_INT, - TYPE_BOOL, - TYPE_UNSIGNED, + 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, @@ -21,19 +35,40 @@ enum Ast_Resolved_Type_Kind{ 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]", - "[Null]", "[Completing]", "[Incomplete]", + "[Untyped_Bool]", "[Untyped_Int]", + "[Untyped_Float]", "[Untyped_String]", + "[Int]", + "[S64]", + "[S32]", + "[S16]", + "[S8]", + "[UInt]", + "[U64]", + "[U32]", + "[U16]", + "[U8]", + "[Float32]", + "[Float64]", "[Bool]", - "[Unsigned]", "[String]", "[Void]", "[Pointer]", @@ -73,30 +108,81 @@ struct Ast_Resolved_Type{ }; }; +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__int = {TYPE_INT, sizeof(int), __alignof(int)}; 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_type = &type__type; -global Ast_Resolved_Type *type_void = &type__void; -global Ast_Resolved_Type *type_int = &type__int; -global Ast_Resolved_Type *type_string = &type__string; -global Ast_Resolved_Type *type_bool = &type__bool; +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 @@ -113,35 +199,18 @@ enum Sym_State{ SYM_RESOLVED, }; -#define VALUE_FIELDS \ - bool bool_val; \ - S64 int_val; \ - Intern_String intern_val; \ - Ast_Resolved_Type *type_val; -#define INLINE_VALUE_FIELDS union{Value value; union{VALUE_FIELDS};} -union Value{VALUE_FIELDS}; - struct Sym{ Intern_String name; Sym_Kind kind; Sym_State state; Ast *ast; - - Ast_Resolved_Type *type; INLINE_VALUE_FIELDS; }; struct Operand{ - Ast_Resolved_Type *type; + INLINE_VALUE_FIELDS; bool is_const: 1; bool is_lvalue: 1; - INLINE_VALUE_FIELDS; -}; - -struct Typecheck_Ctx{ // @todo - Ast_Resolved_Type *required_type; - Sym *const_sym; - B32 expr_can_be_null; }; enum{AST_CANT_BE_NULL = 0, AST_CAN_BE_NULL = 1}; @@ -208,19 +277,36 @@ sym_new(Sym_Kind kind, Intern_String name, Ast *ast, B32 associate = true){ } function Sym * -sym_new_resolved(Sym_Kind kind, Intern_String name, Ast_Resolved_Type *type, Value value, Ast *ast, B32 associate = true){ +sym_new_resolved(Sym_Kind kind, Intern_String name, Value value, Ast *ast, B32 associate = true){ Sym *result = sym_new(kind, name, ast, associate); - result->type = type; result->state = SYM_RESOLVED; result->value = value; return result; } +const B32 INSERT_INTO_SCOPE = true; + function Sym * -sym_new_resolved_type(Ast_Resolved_Type *type, Ast *ast){ +sym_var(Intern_String name, Ast_Resolved_Type *type, Ast *ast, B32 insert_into_scope = false){ Value value; - value.type_val = type; - return sym_new_resolved(SYM_CONST, {}, type_type, value, ast); + value.type = type; + Sym *sym = sym_new_resolved(SYM_VAR, name, value, ast); + if(insert_into_scope) sym_insert(sym); + return sym; +} + +function Sym * +sym_var(Intern_String name, Operand op, Ast *ast, B32 insert_into_scope = false){ + Sym *sym = sym_new_resolved(SYM_VAR, name, op.value, ast); + if(insert_into_scope) sym_insert(sym); + return sym; +} + +function Sym * +sym_const(Intern_String name, Operand op, Ast *ast, B32 insert_into_scope = false){ + Sym *sym = sym_new_resolved(SYM_CONST, name, op.value, ast); + if(insert_into_scope) sym_insert(sym); + return sym; } function Sym * @@ -239,15 +325,17 @@ resolved_type_get(Ast_Expr *ast){ } function Sym * -sym_type(Ast *ast, Ast_Resolved_Type *type, Intern_String name = {}, B32 associate = true){ - Value value; value.type_val = type; - Sym *result = sym_new_resolved(SYM_CONST, name, type_type, value, ast, associate); +sym_type(Ast_Resolved_Type *type, Ast *ast, Intern_String name = {}, B32 associate = true){ + Value value; + value.type = type_type; + value.type_val = type; + Sym *result = sym_new_resolved(SYM_CONST, name, value, ast, associate); return result; } function Sym * -sym_insert(Sym_Kind kind, Intern_String name, Ast_Resolved_Type *type, Value value, Ast *ast){ - Sym *sym = sym_new_resolved(kind, name, type, value, ast); +sym_insert(Sym_Kind kind, Intern_String name, Value value, Ast *ast){ + Sym *sym = sym_new_resolved(kind, name, value, ast); sym_insert(sym); return sym; } @@ -255,28 +343,32 @@ sym_insert(Sym_Kind kind, Intern_String name, Ast_Resolved_Type *type, Value val function void sym_insert_builtin_type(String name, Ast_Resolved_Type *type){ Intern_String string = intern_string(&pctx->interns, name); - Sym *sym = sym_type(&empty_decl, type, string, false); + Sym *sym = sym_type(type, &empty_decl, string, false); sym_insert(sym); } 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); { Intern_String string = intern_string(&pctx->interns, "true"_s); - Value val; val.int_val = 1; - Sym *sym = sym_new_resolved(SYM_CONST, string, type_bool, val, &empty_decl, false); + Value val; + val.type = type_bool; + val.bool_val = 1; + Sym *sym = sym_new_resolved(SYM_CONST, string, val, &empty_decl, false); sym_insert(sym); } { Intern_String string = intern_string(&pctx->interns, "false"_s); - Value val; val.int_val = 0; - Sym *sym = sym_new_resolved(SYM_CONST, string, type_bool, val, &empty_decl, false); + Value val; + val.type = type_bool; + val.bool_val = 0; + Sym *sym = sym_new_resolved(SYM_CONST, string, val, &empty_decl, false); sym_insert(sym); } } @@ -296,7 +388,8 @@ operand(Sym *sym){ function Operand operand_type(Ast_Resolved_Type *type){ - Operand result = {type_type}; + Operand result = {}; + result.type = type_type; result.is_const = true; result.is_lvalue = false; result.type_val = type; @@ -305,7 +398,8 @@ operand_type(Ast_Resolved_Type *type){ function Operand operand_int(S64 int_val){ - Operand result = {type_int}; + Operand result = {}; + result.type = type_int; result.int_val = int_val; result.is_const = true; result.is_lvalue = false; @@ -314,7 +408,8 @@ operand_int(S64 int_val){ function Operand operand_str(Intern_String intern_val){ - Operand result = {type_string}; + Operand result = {}; + result.type = type_string; result.intern_val = intern_val; result.is_const = true; result.is_lvalue = false; @@ -332,7 +427,8 @@ operand_lambda(Ast_Resolved_Type *type){ function Operand operand_lvalue(Ast_Resolved_Type *type){ - Operand result = {type}; + Operand result = {}; + result.type = type; result.is_const = false; result.is_lvalue = true; return result; @@ -340,7 +436,8 @@ operand_lvalue(Ast_Resolved_Type *type){ function Operand operand_rvalue(Ast_Resolved_Type *type){ - Operand result = {type}; + Operand result = {}; + result.type = type; result.is_const = false; result.is_lvalue = false; return result; @@ -349,12 +446,27 @@ operand_rvalue(Ast_Resolved_Type *type){ //----------------------------------------------------------------------------- // Type constructors and utillities //----------------------------------------------------------------------------- -force_inline B32 is_string(Ast_Resolved_Type *type){return type->kind == TYPE_STRING;} -force_inline B32 is_int(Ast_Resolved_Type *type){return type->kind == TYPE_INT;} -force_inline B32 is_struct(Ast_Resolved_Type *type){return type->kind == TYPE_STRUCT;} -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;} +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){ @@ -465,7 +577,7 @@ type_struct_complete(Ast_Resolved_Type *type, Ast_Struct *node){ For(node->members){ Operand op = resolve_binding(it); Intern_String name = ast_get_name(it); - sym_new_resolved(SYM_VAR, name, op.type, {}, it); + sym_var(name, op, it); members.add({op.type, name}); } type->agg.members = members.tight_copy(pctx->perm); @@ -481,7 +593,7 @@ type_struct_complete(Ast_Resolved_Type *type, Ast_Struct *node){ For(node->const_members){ Operand op = resolve_binding(it); Intern_String name = ast_get_name(it); - sym_new_resolved(SYM_CONST, name, op.type, op.value, it); + sym_const(name, op, it); } }