New types, Value rework, Sym cleanup
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
2
enums.kl
2
enums.kl
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
Thing :: struct
|
Thing :: struct
|
||||||
len: int
|
len: Int
|
||||||
|
|
||||||
Constant_String :: "Test"
|
Constant_String :: "Test"
|
||||||
Constant :: 10
|
Constant :: 10
|
||||||
|
|||||||
42
globals.kl
42
globals.kl
@@ -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
|
||||||
|
|||||||
22
lambdas.kl
22
lambdas.kl
@@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
2
lexer.kl
2
lexer.kl
@@ -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
|
||||||
|
|||||||
26
new_ast.cpp
26
new_ast.cpp
@@ -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
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 :: ()
|
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
|
||||||
|
|
||||||
|
|||||||
26
order2.kl
26
order2.kl
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
238
typecheck.h
238
typecheck.h
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user