Any type initially working
This commit is contained in:
36
ccodegen.cpp
36
ccodegen.cpp
@@ -255,6 +255,13 @@ gen_lambda(Intern_String name, Ast_Lambda *lambda, B32 generate_block = true){
|
||||
|
||||
function bool
|
||||
gen_expr(Ast_Expr *ast, Ast_Type *type_of_var){
|
||||
if(is_any(type_of_var)){
|
||||
gen("(Any){&");
|
||||
gen_expr(ast);
|
||||
gen(", %d}", ast->resolved_type->type_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
switch(ast->kind){
|
||||
CASE(IDENT, Atom){
|
||||
if(node->resolved_decl->kind == AST_MODULE_NAMESPACE || node->resolved_decl->kind == AST_FILE_NAMESPACE)
|
||||
@@ -373,7 +380,7 @@ gen_expr(Ast_Expr *ast, Ast_Type *type_of_var){
|
||||
gen_expr(node->name);
|
||||
gen("(");
|
||||
For(node->exprs){
|
||||
gen_expr(it->item);
|
||||
gen_expr(it->item, it->resolved_type);
|
||||
if(!node->exprs.is_last(&it)) gen(", ");
|
||||
}
|
||||
gen(")");
|
||||
@@ -700,22 +707,23 @@ insert_builtin_into_scope(Ast_Scope *p, String name, Ast_Type *type){
|
||||
|
||||
function void
|
||||
insert_builtin_types_into_scope(Ast_Scope *p){
|
||||
insert_builtin_into_scope(p, "S64"_s, type_s64);
|
||||
insert_builtin_into_scope(p, "S32"_s, type_s32);
|
||||
insert_builtin_into_scope(p, "S16"_s, type_s16);
|
||||
insert_builtin_into_scope(p, "S8"_s, type_s8);
|
||||
insert_builtin_into_scope(p, "int"_s, type_int);
|
||||
insert_builtin_into_scope(p, "char"_s, type_char);
|
||||
insert_builtin_into_scope(p, "U64"_s, type_u64);
|
||||
insert_builtin_into_scope(p, "U32"_s, type_u32);
|
||||
insert_builtin_into_scope(p, "U16"_s, type_u16);
|
||||
insert_builtin_into_scope(p, "U8"_s, type_u8);
|
||||
insert_builtin_into_scope(p, "F64"_s, type_f64);
|
||||
insert_builtin_into_scope(p, "F32"_s, type_f32);
|
||||
|
||||
insert_builtin_into_scope(p, "void"_s , type_void);
|
||||
insert_builtin_into_scope(p, "Bool"_s , type_bool);
|
||||
insert_builtin_into_scope(p, "String"_s, type_string);
|
||||
insert_builtin_into_scope(p, "char"_s, type_char);
|
||||
insert_builtin_into_scope(p, "int"_s, type_int);
|
||||
insert_builtin_into_scope(p, "S8"_s, type_s8);
|
||||
insert_builtin_into_scope(p, "S16"_s, type_s16);
|
||||
insert_builtin_into_scope(p, "S32"_s, type_s32);
|
||||
insert_builtin_into_scope(p, "S64"_s, type_s64);
|
||||
insert_builtin_into_scope(p, "U8"_s, type_u8);
|
||||
insert_builtin_into_scope(p, "U16"_s, type_u16);
|
||||
insert_builtin_into_scope(p, "U32"_s, type_u32);
|
||||
insert_builtin_into_scope(p, "U64"_s, type_u64);
|
||||
insert_builtin_into_scope(p, "F32"_s, type_f32);
|
||||
insert_builtin_into_scope(p, "F64"_s, type_f64);
|
||||
insert_builtin_into_scope(p, "Any"_s, type_any);
|
||||
// insert_builtin_into_scope(p, "Any"_s, type_any);
|
||||
insert_builtin_into_scope(p, "Type"_s, type_type);
|
||||
}
|
||||
|
||||
|
||||
13
main.cpp
13
main.cpp
@@ -41,10 +41,9 @@ want to export all the symbols, we can namespace them optionally.
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
@todo
|
||||
[ ] - Probably need to give Ast_Expr a Value field, then I can express Type nicely
|
||||
[ ] - I would love for String, slice, Any etc. to have their struct declarations in source files, I also would want for stuff like string.str to work without weird special cases
|
||||
[ ] - Implementing type Any
|
||||
[ ] - Runtime TypeInfo
|
||||
[ ] - Proper type Type support
|
||||
|
||||
[ ] - #test construct that would gather all tests and run them on start of program or something
|
||||
[ ] - Foreign import that would link library
|
||||
@@ -54,7 +53,6 @@ want to export all the symbols, we can namespace them optionally.
|
||||
[ ] - Mixing loads and imports leads to code duplication, is that what we want???
|
||||
[ ] - Fix field access, cant cast, cant index
|
||||
[ ] - Add parent_scope to Ast_Type, Add name to Ast_Type?
|
||||
[ ] - Switch
|
||||
[ ] - Some way to take slice of data
|
||||
[ ] - Optional function renaming in codegen
|
||||
[ ] - Using in structs to embed members, then casting offsets to that embedded member
|
||||
@@ -83,6 +81,9 @@ want to export all the symbols, we can namespace them optionally.
|
||||
[ ] - Polymorphism - create declaration of a polymorphic thing, when it's called just copy it, replace types and typecheck normally, when someone calls again you just search for the instantiation again
|
||||
|
||||
@donzo
|
||||
[x] - Runtime TypeInfo
|
||||
[x] - Proper type Type support
|
||||
[x] - Switch
|
||||
[x] - Type aliases :: should probably be strictly typed, but assigning constant values should work
|
||||
[x] - Array of inferred size
|
||||
[x] - Casting pointers to and from void should be implicit
|
||||
@@ -188,7 +189,13 @@ int main(int argument_count, char **arguments){
|
||||
pctx->language_base_module = module;
|
||||
parse_all_modules();
|
||||
resolve_everything_in_module(module);
|
||||
|
||||
// @note: language stuff needs to be declared before type_info data
|
||||
// so we mark where it ends
|
||||
pctx->base_language_ordered_decl_len = pctx->ordered_decls.len;
|
||||
Ast_Decl *any_decl = search_for_decl(module, pctx->intern("Any"_s));
|
||||
assert(any_decl->type == type_type);
|
||||
type_any = any_decl->type_val;
|
||||
}
|
||||
|
||||
Ast_Module *module = add_module(0, pctx->intern(program_name));
|
||||
|
||||
@@ -8,15 +8,14 @@ Slice :: struct
|
||||
data: *void
|
||||
len : S64
|
||||
|
||||
Any :: struct
|
||||
data: *void
|
||||
type: Type_ID
|
||||
|
||||
*/
|
||||
|
||||
Any :: struct
|
||||
data: *void
|
||||
type: Type
|
||||
|
||||
Type_Info_Kind :: enum
|
||||
NONE
|
||||
S64 :: 7 // FIRST_NUMERIC
|
||||
S64 // FIRST_NUMERIC
|
||||
S32
|
||||
S16
|
||||
S8
|
||||
@@ -40,7 +39,6 @@ Type_Info_Kind :: enum
|
||||
TYPE
|
||||
SLICE
|
||||
TUPLE
|
||||
ANY
|
||||
|
||||
Type_Info_Struct_Member :: struct
|
||||
name: String
|
||||
|
||||
@@ -41,24 +41,50 @@ create_bitmap :: (size: Vec2I, bottom_up: Bool = true): Windows_Bitmap
|
||||
result.hdc = CreateCompatibleDC(hdc)
|
||||
return result
|
||||
|
||||
print :: (type: Type)
|
||||
type_info := get_type_info(type)
|
||||
_gcvt :: #foreign (value: F64, digits: int, buffer: *char): *char
|
||||
print_float :: (value: F64)
|
||||
buff: [100]char
|
||||
_gcvt(value, 10, &buff[0])
|
||||
OutputDebugStringA(&buff[0])
|
||||
|
||||
print_type :: (t: Type)
|
||||
type_info := get_type_info(t)
|
||||
if !type_info
|
||||
return
|
||||
|
||||
switch type_info.kind
|
||||
S64, S32, S16, S8, int
|
||||
Type_Info_Kind.S64, Type_Info_Kind.S32, Type_Info_Kind.S16, Type_Info_Kind.S8, Type_Info_Kind.INT
|
||||
OutputDebugStringA("Integer")
|
||||
U64, U32, U16, U8
|
||||
Type_Info_Kind.U64, Type_Info_Kind.U32, Type_Info_Kind.U16, Type_Info_Kind.U8
|
||||
OutputDebugStringA("Unsigned")
|
||||
Type_Info_Kind.F64, Type_Info_Kind.F32
|
||||
OutputDebugStringA("Float")
|
||||
Type_Info_Kind.POINTER
|
||||
OutputDebugStringA("*")
|
||||
print(type_info.base_type)
|
||||
Type_Info_Kind.SLICE
|
||||
OutputDebugStringA("[]")
|
||||
print(type_info.base_type)
|
||||
print_type(type_info.base_type)
|
||||
default;; OutputDebugStringA("Unknown")
|
||||
|
||||
print :: (a: Any)
|
||||
type_info := get_type_info(a.type)
|
||||
if !type_info
|
||||
return
|
||||
|
||||
print_type(a.type)
|
||||
OutputDebugStringA(" - ")
|
||||
// @todo check for types here
|
||||
switch type_info.kind
|
||||
Type_Info_Kind.S64, Type_Info_Kind.S32, Type_Info_Kind.S16, Type_Info_Kind.S8, Type_Info_Kind.INT
|
||||
OutputDebugStringA("Integer")
|
||||
Type_Info_Kind.U64, Type_Info_Kind.U32, Type_Info_Kind.U16, Type_Info_Kind.U8
|
||||
OutputDebugStringA("Unsigned")
|
||||
Type_Info_Kind.F64
|
||||
data := a.data->*F64
|
||||
print_float(*data)
|
||||
Type_Info_Kind.POINTER
|
||||
OutputDebugStringA("Pointer")
|
||||
default;; OutputDebugStringA("Unknown")
|
||||
|
||||
|
||||
app_is_running := true
|
||||
window_procedure :: (hwnd: HWND, msg: UINT, wparam: WPARAM, lparam: LPARAM): LRESULT
|
||||
if msg == WM_DESTROY
|
||||
@@ -67,19 +93,15 @@ window_procedure :: (hwnd: HWND, msg: UINT, wparam: WPARAM, lparam: LPARAM): LRE
|
||||
return 0
|
||||
else;; return DefWindowProcW(hwnd, msg, wparam, lparam)
|
||||
|
||||
_gcvt :: #foreign (value: F64, digits: int, buffer: *char): *char
|
||||
print_float :: (value: F64)
|
||||
buff: [100]char
|
||||
_gcvt(value, 10, &buff[0])
|
||||
OutputDebugStringA("\n")
|
||||
OutputDebugStringA(&buff[0])
|
||||
|
||||
WinMain :: (hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: LPSTR, nShowCmd: int): int
|
||||
if good_scheduling := false, timeBeginPeriod(1) == TIMERR_NOERROR
|
||||
good_scheduling = true
|
||||
|
||||
print([]**S64)
|
||||
char_info := get_type_info(char)
|
||||
val := 4232.23
|
||||
thing: Any = val
|
||||
print(val)
|
||||
|
||||
assert(char_info.kind == Type_Info_Kind.CHAR)
|
||||
#assert(int == int)
|
||||
#assert(int != char)
|
||||
|
||||
@@ -362,6 +362,9 @@ make_sure_value_is_compatible_with_type(Token *pos, Operand *expr, Ast_Type *typ
|
||||
assert(type);
|
||||
expr->type = type;
|
||||
}
|
||||
else if(is_any(type)){
|
||||
expr->type = type;
|
||||
}
|
||||
else if(is_void_pointer(type) && is_pointer(expr->type)){
|
||||
expr->type = type;
|
||||
}
|
||||
@@ -788,8 +791,9 @@ resolve_compound_struct(Ast_Call *node, Ast_Type *type){
|
||||
m->visited = true;
|
||||
|
||||
// @copy_paste
|
||||
if(m->type == type_type)
|
||||
if(m->type == type_type && m->type_val){
|
||||
item_type = m->type_val;
|
||||
}
|
||||
else item_type = m->type;
|
||||
|
||||
default_counter+=1;
|
||||
|
||||
27
types.h
27
types.h
@@ -3,13 +3,7 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
enum Ast_Type_Kind{
|
||||
TYPE_NONE,
|
||||
TYPE_COMPLETING,
|
||||
TYPE_INCOMPLETE,
|
||||
TYPE_UNTYPED_BOOL, // FIRST_TYPED_NUMERIC, FIRST_NUMERIC
|
||||
TYPE_UNTYPED_INT,
|
||||
TYPE_UNTYPED_FLOAT, // LAST_TYPED_NUMERIC
|
||||
TYPE_UNTYPED_STRING,
|
||||
TYPE_S64 = 7, // FIRST_NUMERIC
|
||||
TYPE_S64, // FIRST_NUMERIC
|
||||
TYPE_S32,
|
||||
TYPE_S16,
|
||||
TYPE_S8 ,
|
||||
@@ -33,7 +27,13 @@ enum Ast_Type_Kind{
|
||||
TYPE_TYPE,
|
||||
TYPE_SLICE,
|
||||
TYPE_TUPLE,
|
||||
TYPE_ANY,
|
||||
|
||||
TYPE_COMPLETING,
|
||||
TYPE_INCOMPLETE,
|
||||
TYPE_UNTYPED_BOOL, // FIRST_TYPED_NUMERIC, FIRST_NUMERIC
|
||||
TYPE_UNTYPED_INT,
|
||||
TYPE_UNTYPED_FLOAT, // LAST_TYPED_NUMERIC
|
||||
TYPE_UNTYPED_STRING,
|
||||
|
||||
TYPE_UNTYPED_FIRST = TYPE_UNTYPED_BOOL,
|
||||
TYPE_UNTYPED_LAST = TYPE_UNTYPED_STRING,
|
||||
@@ -122,7 +122,6 @@ name(Ast_Type *type){
|
||||
case TYPE_U16: return "U16";
|
||||
case TYPE_U32: return "U32";
|
||||
case TYPE_U64: return "U64";
|
||||
case TYPE_ANY: return "Any";
|
||||
case TYPE_TUPLE: return "Tuple";
|
||||
case TYPE_TYPE: return "Type";
|
||||
invalid_default_case;
|
||||
@@ -139,7 +138,6 @@ global Ast_Type type__void = {TYPE_VOID};
|
||||
global Ast_Type type__string = {TYPE_STRING, sizeof(String), __alignof(String)};
|
||||
global Ast_Type type__bool = {TYPE_BOOL, sizeof(bool), __alignof(bool)};
|
||||
global Ast_Type type__type = {TYPE_TYPE};
|
||||
global Ast_Type type__any = {TYPE_ANY};
|
||||
|
||||
global Ast_Type type__f32 = {TYPE_F32, sizeof(F32), __alignof(F32)};
|
||||
global Ast_Type type__f64 = {TYPE_F64, sizeof(F64), __alignof(F64)};
|
||||
@@ -163,11 +161,12 @@ global Ast_Type type__char = {TYPE_CHAR, sizeof(char), __alignof(char)};
|
||||
global Ast_Type type__int = {TYPE_INT, sizeof(int), __alignof(int)};
|
||||
global Ast_Type *type_char = &type__char;
|
||||
global Ast_Type *type_int = &type__int;
|
||||
global Ast_Type *type_pointer_to_char; // Needs to be inited at runtime
|
||||
global Ast_Type *type_void = &type__void;
|
||||
global Ast_Type *type_pointer_to_void; // Needs to be inited at runtime
|
||||
|
||||
global Ast_Type *type_any = &type__any;
|
||||
global Ast_Type *type_pointer_to_char; // Needs to be inited at runtime
|
||||
global Ast_Type *type_pointer_to_void; // Needs to be inited at runtime
|
||||
global Ast_Type *type_any; // Needs to be inited at runtime
|
||||
|
||||
global Ast_Type *type_type = &type__type;
|
||||
global Ast_Type *type_string = &type__string;
|
||||
global Ast_Type *type_bool = &type__bool;
|
||||
@@ -193,7 +192,7 @@ global Ast_Type *untyped_float = &type__untyped_float;
|
||||
//-----------------------------------------------------------------------------
|
||||
// Type constructors and utillities
|
||||
//-----------------------------------------------------------------------------
|
||||
force_inline B32 is_any(Ast_Type *a){return a->kind == TYPE_ANY;}
|
||||
force_inline B32 is_any(Ast_Type *a){return a == type_any;}
|
||||
force_inline B32 is_struct(Ast_Type *a){return a->kind == TYPE_STRUCT;}
|
||||
force_inline B32 is_lambda(Ast_Type *a){return a->kind == TYPE_LAMBDA;}
|
||||
force_inline B32 is_array(Ast_Type *a){return a->kind == TYPE_ARRAY;}
|
||||
|
||||
Reference in New Issue
Block a user