New types, Value rework, Sym cleanup

This commit is contained in:
Krzosa Karol
2022-06-02 22:17:28 +02:00
parent 9a58e407a4
commit 173ef843df
11 changed files with 270 additions and 149 deletions

View File

@@ -20,9 +20,9 @@ gen_indent(){
function void function void
gen_simple_decl_prefix(Ast_Resolved_Type *ast){ gen_simple_decl_prefix(Ast_Resolved_Type *ast){
switch(ast->kind){ switch(ast->kind){
case TYPE_INT: gen("int "); break; case TYPE_INT: gen("Int "); break;
case TYPE_BOOL: gen("bool "); 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_STRING: gen("String "); break;
case TYPE_VOID: gen("void "); break; case TYPE_VOID: gen("void "); break;
case TYPE_POINTER:{gen_simple_decl_prefix(ast->base); gen("*");} 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){ switch(ast->kind){
case TYPE_INT: break; case TYPE_INT: break;
case TYPE_BOOL: break; case TYPE_BOOL: break;
case TYPE_UNSIGNED: break; case TYPE_UINT: break;
case TYPE_STRING: break; case TYPE_STRING: break;
case TYPE_VOID: break; case TYPE_VOID: break;
case TYPE_POINTER: gen_simple_decl_postfix(ast->base); break; case TYPE_POINTER: gen_simple_decl_postfix(ast->base); break;

View File

@@ -1,6 +1,6 @@
Thing :: struct Thing :: struct
len: int len: Int
Constant_String :: "Test" Constant_String :: "Test"
Constant :: 10 Constant :: 10

View File

@@ -1,58 +1,58 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Function types // Function types
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
test_function :: (thing: int): *int test_function :: (thing: Int): *Int
function_type: test_function function_type: test_function
const_function_alias :: test_function const_function_alias :: test_function
// null_function: (t: int): *int = null // null_function: (t: Int): *Int = null
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Booleans // Booleans
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
boolean: bool = true Boolean: Bool = true
value_of_bool: int = cast(boolean: int) value_of_Bool: Int = cast(Boolean: Int)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Nulls // Nulls
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// int_null: int = null // Int_null: Int = null
// str_null: String = null // str_null: String = null
// bool_null: bool = null // Bool_null: Bool = null
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Compound expressions // Compound expressions
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
array1: [4]int = [4]int(1,2,3,4) array1: [4]Int = [4]Int(1,2,3,4)
array2 := [32]int(1,2,3,4) array2 := [32]Int(1,2,3,4)
array3 := [32]int( array3 := [32]Int(
[0] = 0, [0] = 0,
[1] = 1, [1] = 1,
[2] = 2, [2] = 2,
[31] = 31, [31] = 31,
) )
array_item := array1[0] array_item := array1[0]
array_item_imp: int = array2[2] array_item_imp: Int = array2[2]
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Pointers // PoInters
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
pointer_decl : *int poInter_decl : *Int
variable_from_deref: int = *pointer_decl variable_from_deref: Int = *poInter_decl
pointer_from_var : *int = &variable_from_deref poInter_from_var : *Int = &variable_from_deref
boolean_pointer := &boolean Boolean_poInter := &Boolean
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Implicit type // Implicit type
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
implicit_int :: 10 implicit_Int :: 10
implicit_str :: "Hello world" implicit_str :: "Hello world"
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Pointers // PoInters
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// pointer1: *int = 0 // poInter1: *Int = 0
// pointer2: *int = pointer1 // poInter2: *Int = poInter1
// pointer3: **int = 0 // poInter3: **Int = 0
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// String types // String types
@@ -61,7 +61,7 @@ string1 :: "Test"
string2 :: string1 string2 :: string1
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Constant int variables // Constant Int variables
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
thing0 :: 10 thing0 :: 10
thing1 :: thing0 + 11 thing1 :: thing0 + 11

View File

@@ -1,8 +1,8 @@
a_type :: int a_type :: Int
pointer_type :: *int poInter_type :: *Int
// null_pointer: pointer_type = null // null_poInter: poInter_type = null
if_stmt :: (cond: int): type if_stmt :: (cond: Int): type
CONSTANT :: 10 CONSTANT :: 10
thing := 10 thing := 10
if i := thing + cond, cond + CONSTANT if i := thing + cond, cond + CONSTANT
@@ -17,11 +17,11 @@ for_stmt :: ()
for i := 0, i + 10, i+=1 for i := 0, i + 10, i+=1
pass pass
add_10 :: (size: int): int add_10 :: (size: Int): Int
add_20 :: (new_size: int): int add_20 :: (new_size: Int): Int
return 20 return 20
add :: (a: int, b: int = 10): int add :: (a: Int, b: Int = 10): Int
return a + b return a + b
constant :: 20; result := constant + 10 constant :: 20; result := constant + 10
@@ -38,13 +38,13 @@ add_10 :: (size: int): int
return v4 return v4
return_constant :: (): int return_constant :: (): Int
constant :: 10 constant :: 10
return constant return constant
returning_void :: (insert: int) returning_Void :: (insert: Int)
val1: int = return_constant() val1: Int = return_constant()
val2: int = add_10(val1) val2: Int = add_10(val1)
return return

View File

@@ -1,7 +1,7 @@
/* /*
Lex_Stream :: struct Lex_Stream :: struct
stream: String stream: String
offset: int offset: Int
lexc :: (s: *Lex_Stream): String // @todo U8 U S lexc :: (s: *Lex_Stream): String // @todo U8 U S
return s.stream + s.offset // s.offset @todo Actual string support return s.stream + s.offset // s.offset @todo Actual string support

View File

@@ -18,7 +18,7 @@ Intern_String keyword_enum;
Intern_String intern_void; Intern_String intern_void;
Intern_String intern_int; Intern_String intern_int;
Intern_String intern_str; Intern_String intern_str;
Intern_String intern_unsigned; Intern_String intern_uint;
struct Ast_Package; struct Ast_Package;
struct Sym; struct Sym;
@@ -67,10 +67,10 @@ struct Parse_Ctx:Lexer{
interns.first_keyword = keyword_struct.str; interns.first_keyword = keyword_struct.str;
interns.last_keyword = keyword_enum.str; interns.last_keyword = keyword_enum.str;
intern_void = intern_string(&interns, "void"_s); intern_void = intern_string(&interns, "Void"_s);
intern_int = intern_string(&interns, "int"_s); intern_int = intern_string(&interns, "Int"_s);
intern_str = intern_string(&interns, "String"_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_Resolved_Type;
struct Ast_Expr:Ast{}; struct Ast_Expr:Ast{};
struct Ast_Atom: Ast_Expr{ #define VALUE_FIELDS \
union{ Ast_Resolved_Type *type; \
Intern_String intern_val; union{ \
U64 int_val; 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{
INLINE_VALUE_FIELDS;
}; };
struct Ast_Call_Item: Ast_Expr{ struct Ast_Call_Item: Ast_Expr{

6
new_types.kl Normal file
View File

@@ -0,0 +1,6 @@
main :: (argc: S64, argv: **U8)
some_constant :: true
thing: Bool = some_constant

View File

@@ -2,7 +2,7 @@
other_func :: () other_func :: ()
a_val := recursive_lambda a_val := recursive_lambda
recursive_lambda :: (thing: int) recursive_lambda :: (thing: Int)
in_val := recursive_lambda in_val := recursive_lambda
some_value := thing + const_in_lambda some_value := thing + const_in_lambda

View File

@@ -1,5 +1,5 @@
Str16 :: String16 Str16 :: String16
// arena_pointer: *Arena = null // arena_poInter: *Arena = null
thing: Arena thing: Arena
no_type := thing no_type := thing
constant_access := Arena.constant_inside constant_access := Arena.constant_inside
@@ -11,22 +11,22 @@ arena := Arena(
cap = 1000, cap = 1000,
) )
// lambda_value := (val: int) // @todo // lambda_value := (val: Int) // @todo
// return // return
Arena :: struct Arena :: struct
// arena: Arena // arena: Arena
next: *Arena next: *Arena
data: *int data: *Int
len : int len : Int
cap : int cap : Int
Sub :: struct Sub :: struct
len: int len: Int
Sub_Sub :: struct Sub_Sub :: struct
len: int len: Int
get_len :: (s: *Arena): int // @todo get_len :: (s: *Arena): Int // @todo
return s.next.len return s.next.len
constant_inside :: 10000 constant_inside :: 10000
@@ -35,12 +35,12 @@ Arena :: struct
string16: Str16 string16: Str16
String16 :: struct String16 :: struct
data: *void data: *Void
len : int len : Int
with_type: Arena = thing with_type: Arena = thing
pointer := &with_type poInter := &with_type
deref := *pointer deref := *poInter
test_assignments :: () test_assignments :: ()
@@ -59,7 +59,7 @@ test_assignments :: ()
i = i > 2 i = i > 2
CONST :: 23 == 23 CONST :: 23 == 23
j: *int j: *Int
*j = 1 *j = 1
/* invalid /* invalid
8 = 32 8 = 32

View File

@@ -5,7 +5,7 @@ function Ast_Resolved_Type *
resolve_typespec(Ast_Expr *ast, B32 ast_can_be_null){ resolve_typespec(Ast_Expr *ast, B32 ast_can_be_null){
if(ast_can_be_null && ast == 0) return 0; if(ast_can_be_null && ast == 0) return 0;
Operand resolved = resolve_expr(ast); 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; return resolved.type_val;
} }
@@ -55,34 +55,18 @@ resolve_stmt(Ast *ast, Ast_Resolved_Type *ret){
CASE(VAR, Var){ CASE(VAR, Var){
Operand op = resolve_binding(node); Operand op = resolve_binding(node);
Sym *sym = sym_new_resolved(SYM_VAR, node->name, op.type, op.value, node); sym_var(node->name, op, node, INSERT_INTO_SCOPE);
sym_insert(sym);
BREAK(); BREAK();
} }
CASE(CONST, Const){ CASE(CONST, Const){
Operand op = resolve_binding(node); Operand op = resolve_binding(node);
Sym *sym = sym_new_resolved(SYM_CONST, node->name, op.type, op.value, node); sym_const(node->name, op, node, INSERT_INTO_SCOPE);
sym_insert(sym);
BREAK(); BREAK();
} }
CASE(BINARY, Binary){ CASE(BINARY, Binary){
if(node->op == TK_ColonAssign){ resolve_expr(node);
// 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;
BREAK(); BREAK();
} }
@@ -156,7 +140,7 @@ resolve_lambda(Ast_Lambda *lambda, Sym *sym = 0){
} }
lambda_type = type_lambda(lambda, ret_type, args); lambda_type = type_lambda(lambda, ret_type, args);
sym_type(lambda, lambda_type); sym_type(lambda_type, lambda);
Operand result = operand_type(lambda_type); Operand result = operand_type(lambda_type);
// @note: top level lambda needs to get marked as resolved // @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){ For(lambda->args){
S64 i = lambda->args.get_index(&it); S64 i = lambda->args.get_index(&it);
Ast_Resolved_Type *type = args[i]; 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){ For(lambda->block->stmts){
resolve_stmt(it, ret_type); 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); Operand expr = require_const_int(node->expr, AST_CANT_BE_NULL);
Ast_Resolved_Type *resolved = type_array(type.type_val, expr.int_val); Ast_Resolved_Type *resolved = type_array(type.type_val, expr.int_val);
sym_type(node, resolved); sym_type(resolved, node);
return operand_type(resolved); return operand_type(resolved);
BREAK(); 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);} if(value.type->kind == TYPE_POINTER){return operand_lvalue(value.type->base);}
else if(value.type->kind == TYPE_TYPE){ else if(value.type->kind == TYPE_TYPE){
Ast_Resolved_Type *type = type_pointer(value.type_val); Ast_Resolved_Type *type = type_pointer(value.type_val);
sym_new_resolved_type(type, node); sym_type(type, node);
return operand_type(type); 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 {}; } 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); Operand right = resolve_expr(node->right);
Ast_Atom *atom = (Ast_Atom *)node->left; 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; if(is_pointer(type)) type = type->base;
type_complete(type); 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"); 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 happens only on binary nodes which further chain with dots and require lookups
// This part cant happen on enums // This part cant happen on enums
@@ -568,7 +561,7 @@ resolve_const(Ast_Expr *ast, Sym *sym){
op.int_val = value++; 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); scope_close(scope_index);
return operand_type(type); return operand_type(type);

View File

@@ -3,17 +3,31 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
enum Ast_Resolved_Type_Kind{ enum Ast_Resolved_Type_Kind{
TYPE_NONE, TYPE_NONE,
TYPE_NULL,
TYPE_COMPLETING, TYPE_COMPLETING,
TYPE_INCOMPLETE, TYPE_INCOMPLETE,
TYPE_UNTYPED_BOOL,
TYPE_UNTYPED_BOOL, // FIRST_TYPED_NUMERIC, FIRST_NUMERIC
TYPE_UNTYPED_INT, TYPE_UNTYPED_INT,
TYPE_UNTYPED_STRING, TYPE_UNTYPED_FLOAT, // LAST_TYPED_NUMERIC
TYPE_INT, TYPE_UNTYPED_STRING, // LAST_NUMERIC
TYPE_BOOL,
TYPE_UNSIGNED, 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_STRING,
TYPE_VOID, TYPE_VOID,
TYPE_POINTER, TYPE_POINTER,
TYPE_ARRAY, TYPE_ARRAY,
TYPE_LAMBDA, TYPE_LAMBDA,
@@ -21,19 +35,40 @@ enum Ast_Resolved_Type_Kind{
TYPE_UNION, TYPE_UNION,
TYPE_ENUM, TYPE_ENUM,
TYPE_TYPE, 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[] = { const char *type_names[] = {
"[Invalid Ast_Resolved_Type]", "[Invalid Ast_Resolved_Type]",
"[Null]",
"[Completing]", "[Completing]",
"[Incomplete]", "[Incomplete]",
"[Untyped_Bool]", "[Untyped_Bool]",
"[Untyped_Int]", "[Untyped_Int]",
"[Untyped_Float]",
"[Untyped_String]", "[Untyped_String]",
"[Int]", "[Int]",
"[S64]",
"[S32]",
"[S16]",
"[S8]",
"[UInt]",
"[U64]",
"[U32]",
"[U16]",
"[U8]",
"[Float32]",
"[Float64]",
"[Bool]", "[Bool]",
"[Unsigned]",
"[String]", "[String]",
"[Void]", "[Void]",
"[Pointer]", "[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 "<unknown_type>";
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Type globals // Type globals
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
const SizeU pointer_size = sizeof(SizeU); const SizeU pointer_size = sizeof(SizeU);
const SizeU pointer_align = __alignof(SizeU); const SizeU pointer_align = __alignof(SizeU);
global Ast_Resolved_Type type__void = {TYPE_VOID}; 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__string = {TYPE_STRING, sizeof(String), __alignof(String)};
global Ast_Resolved_Type type__bool = {TYPE_BOOL, sizeof(bool), __alignof(bool)}; 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_type = &type__type; global Ast_Resolved_Type type__f32 = {TYPE_F32, sizeof(F32), __alignof(F32)};
global Ast_Resolved_Type *type_void = &type__void; global Ast_Resolved_Type type__f64 = {TYPE_F64, sizeof(F64), __alignof(F64)};
global Ast_Resolved_Type *type_int = &type__int;
global Ast_Resolved_Type *type_string = &type__string; global Ast_Resolved_Type type__int = {TYPE_INT, sizeof(S64), __alignof(S64)};
global Ast_Resolved_Type *type_bool = &type__bool; 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_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_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_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_string = &type__untyped_string;
global Ast_Resolved_Type *untyped_bool = &type__untyped_bool; global Ast_Resolved_Type *untyped_bool = &type__untyped_bool;
global Ast_Resolved_Type *untyped_int = &type__untyped_int; global Ast_Resolved_Type *untyped_int = &type__untyped_int;
global Ast_Resolved_Type *untyped_float = &type__untyped_float;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Symbols // Symbols
@@ -113,35 +199,18 @@ enum Sym_State{
SYM_RESOLVED, 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{ struct Sym{
Intern_String name; Intern_String name;
Sym_Kind kind; Sym_Kind kind;
Sym_State state; Sym_State state;
Ast *ast; Ast *ast;
Ast_Resolved_Type *type;
INLINE_VALUE_FIELDS; INLINE_VALUE_FIELDS;
}; };
struct Operand{ struct Operand{
Ast_Resolved_Type *type; INLINE_VALUE_FIELDS;
bool is_const: 1; bool is_const: 1;
bool is_lvalue: 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}; 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 * 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); Sym *result = sym_new(kind, name, ast, associate);
result->type = type;
result->state = SYM_RESOLVED; result->state = SYM_RESOLVED;
result->value = value; result->value = value;
return result; return result;
} }
const B32 INSERT_INTO_SCOPE = true;
function Sym * 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 value;
value.type_val = type; value.type = type;
return sym_new_resolved(SYM_CONST, {}, type_type, value, ast); 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 * function Sym *
@@ -239,15 +325,17 @@ resolved_type_get(Ast_Expr *ast){
} }
function Sym * function Sym *
sym_type(Ast *ast, Ast_Resolved_Type *type, Intern_String name = {}, B32 associate = true){ sym_type(Ast_Resolved_Type *type, Ast *ast, Intern_String name = {}, B32 associate = true){
Value value; value.type_val = type; Value value;
Sym *result = sym_new_resolved(SYM_CONST, name, type_type, value, ast, associate); value.type = type_type;
value.type_val = type;
Sym *result = sym_new_resolved(SYM_CONST, name, value, ast, associate);
return result; return result;
} }
function Sym * function Sym *
sym_insert(Sym_Kind kind, Intern_String name, Ast_Resolved_Type *type, Value value, Ast *ast){ sym_insert(Sym_Kind kind, Intern_String name, Value value, Ast *ast){
Sym *sym = sym_new_resolved(kind, name, type, value, ast); Sym *sym = sym_new_resolved(kind, name, value, ast);
sym_insert(sym); sym_insert(sym);
return sym; return sym;
} }
@@ -255,28 +343,32 @@ sym_insert(Sym_Kind kind, Intern_String name, Ast_Resolved_Type *type, Value val
function void function void
sym_insert_builtin_type(String name, Ast_Resolved_Type *type){ sym_insert_builtin_type(String name, Ast_Resolved_Type *type){
Intern_String string = intern_string(&pctx->interns, name); 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); sym_insert(sym);
} }
function void function void
sym_insert_builtins(){ sym_insert_builtins(){
sym_insert_builtin_type("void"_s, type_void); sym_insert_builtin_type("Void"_s, type_void);
sym_insert_builtin_type("bool"_s, type_bool); sym_insert_builtin_type("Bool"_s, type_bool);
sym_insert_builtin_type("int"_s, type_int); sym_insert_builtin_type("Int"_s, type_int);
sym_insert_builtin_type("String"_s, type_string); sym_insert_builtin_type("String"_s, type_string);
{ {
Intern_String string = intern_string(&pctx->interns, "true"_s); Intern_String string = intern_string(&pctx->interns, "true"_s);
Value val; val.int_val = 1; Value val;
Sym *sym = sym_new_resolved(SYM_CONST, string, type_bool, val, &empty_decl, false); val.type = type_bool;
val.bool_val = 1;
Sym *sym = sym_new_resolved(SYM_CONST, string, val, &empty_decl, false);
sym_insert(sym); sym_insert(sym);
} }
{ {
Intern_String string = intern_string(&pctx->interns, "false"_s); Intern_String string = intern_string(&pctx->interns, "false"_s);
Value val; val.int_val = 0; Value val;
Sym *sym = sym_new_resolved(SYM_CONST, string, type_bool, val, &empty_decl, false); val.type = type_bool;
val.bool_val = 0;
Sym *sym = sym_new_resolved(SYM_CONST, string, val, &empty_decl, false);
sym_insert(sym); sym_insert(sym);
} }
} }
@@ -296,7 +388,8 @@ operand(Sym *sym){
function Operand function Operand
operand_type(Ast_Resolved_Type *type){ operand_type(Ast_Resolved_Type *type){
Operand result = {type_type}; Operand result = {};
result.type = type_type;
result.is_const = true; result.is_const = true;
result.is_lvalue = false; result.is_lvalue = false;
result.type_val = type; result.type_val = type;
@@ -305,7 +398,8 @@ operand_type(Ast_Resolved_Type *type){
function Operand function Operand
operand_int(S64 int_val){ operand_int(S64 int_val){
Operand result = {type_int}; Operand result = {};
result.type = type_int;
result.int_val = int_val; result.int_val = int_val;
result.is_const = true; result.is_const = true;
result.is_lvalue = false; result.is_lvalue = false;
@@ -314,7 +408,8 @@ operand_int(S64 int_val){
function Operand function Operand
operand_str(Intern_String intern_val){ operand_str(Intern_String intern_val){
Operand result = {type_string}; Operand result = {};
result.type = type_string;
result.intern_val = intern_val; result.intern_val = intern_val;
result.is_const = true; result.is_const = true;
result.is_lvalue = false; result.is_lvalue = false;
@@ -332,7 +427,8 @@ operand_lambda(Ast_Resolved_Type *type){
function Operand function Operand
operand_lvalue(Ast_Resolved_Type *type){ operand_lvalue(Ast_Resolved_Type *type){
Operand result = {type}; Operand result = {};
result.type = type;
result.is_const = false; result.is_const = false;
result.is_lvalue = true; result.is_lvalue = true;
return result; return result;
@@ -340,7 +436,8 @@ operand_lvalue(Ast_Resolved_Type *type){
function Operand function Operand
operand_rvalue(Ast_Resolved_Type *type){ operand_rvalue(Ast_Resolved_Type *type){
Operand result = {type}; Operand result = {};
result.type = type;
result.is_const = false; result.is_const = false;
result.is_lvalue = false; result.is_lvalue = false;
return result; return result;
@@ -349,12 +446,27 @@ operand_rvalue(Ast_Resolved_Type *type){
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Type constructors and utillities // Type constructors and utillities
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
force_inline B32 is_string(Ast_Resolved_Type *type){return type->kind == TYPE_STRING;} force_inline B32 is_struct(Ast_Resolved_Type *a){return a->kind == TYPE_STRUCT;}
force_inline B32 is_int(Ast_Resolved_Type *type){return type->kind == TYPE_INT;} force_inline B32 is_array(Ast_Resolved_Type *a){return a->kind == TYPE_ARRAY;}
force_inline B32 is_struct(Ast_Resolved_Type *type){return type->kind == TYPE_STRUCT;} force_inline B32 is_enum(Ast_Resolved_Type *a){return a->kind == TYPE_ENUM;}
force_inline B32 is_array(Ast_Resolved_Type *type){return type->kind == TYPE_ARRAY;} force_inline B32 is_pointer(Ast_Resolved_Type *a){return a->kind == TYPE_POINTER;}
force_inline B32 is_enum(Ast_Resolved_Type *type){return type->kind == TYPE_ENUM;} force_inline B32 is_string(Ast_Resolved_Type *a){return a->kind == TYPE_STRING || a->kind == TYPE_UNTYPED_STRING;}
force_inline B32 is_pointer(Ast_Resolved_Type *type){return type->kind == TYPE_POINTER;} 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 * function Ast_Resolved_Type *
type_new(Allocator *allocator, Ast_Resolved_Type_Kind kind, SizeU size, SizeU align){ 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){ For(node->members){
Operand op = resolve_binding(it); Operand op = resolve_binding(it);
Intern_String name = ast_get_name(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}); members.add({op.type, name});
} }
type->agg.members = members.tight_copy(pctx->perm); 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){ For(node->const_members){
Operand op = resolve_binding(it); Operand op = resolve_binding(it);
Intern_String name = ast_get_name(it); Intern_String name = ast_get_name(it);
sym_new_resolved(SYM_CONST, name, op.type, op.value, it); sym_const(name, op, it);
} }
} }