New types, Value rework, Sym cleanup
This commit is contained in:
@@ -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;
|
||||
|
||||
2
enums.kl
2
enums.kl
@@ -1,6 +1,6 @@
|
||||
|
||||
Thing :: struct
|
||||
len: int
|
||||
len: Int
|
||||
|
||||
Constant_String :: "Test"
|
||||
Constant :: 10
|
||||
|
||||
42
globals.kl
42
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
|
||||
|
||||
22
lambdas.kl
22
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
|
||||
|
||||
|
||||
|
||||
2
lexer.kl
2
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
|
||||
|
||||
26
new_ast.cpp
26
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{
|
||||
|
||||
6
new_types.kl
Normal file
6
new_types.kl
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
main :: (argc: S64, argv: **U8)
|
||||
some_constant :: true
|
||||
thing: Bool = some_constant
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
26
order2.kl
26
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
|
||||
|
||||
@@ -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);
|
||||
|
||||
238
typecheck.h
238
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 "<unknown_type>";
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user