Small changes fixing stuff

This commit is contained in:
Krzosa Karol
2022-10-04 11:42:16 +02:00
parent b10f3840df
commit 3c172233f6
8 changed files with 343 additions and 343 deletions

View File

@@ -62,12 +62,10 @@ typedef double F64;
#define kib(x) ((x)*1024llu)
#define mib(x) (kib(x)*1024llu)
#define gib(x) (mib(x)*1024llu)
#define JOIN1(X,Y) X##Y // helper macro
#define JOIN1(X,Y) X##Y
#define JOIN(X,Y) JOIN1(X,Y)
#define string_expand(x) (int)x.len, x.str
#define FLAG32(x) typedef U32 x; enum
#if defined(__clang__)
# define COMPILER_CLANG 1
# if defined(_WIN32)

View File

@@ -95,7 +95,6 @@ typedef U32 Ast_Call_Item_Flag;
enum{
CALL_INDEX = bit_flag(1),
CALL_NAME = bit_flag(2),
CALL_DOT_ANY = bit_flag(3),
CALL_INCLUDED= bit_flag(4),
};

View File

@@ -290,7 +290,7 @@ compile_file(String filename, U32 compile_flags = COMPILE_NULL){
Scratch scratch;
F64 begin = os_time();
String compiler_call = string_fmt(scratch, "clang.exe program.c -Wall -Wno-parentheses-equality -g -o a.exe -lgdi32 -luser32 -lwinmm");
String compiler_call = string_fmt(scratch, "clang.exe program.c -Wall -Wno-unused-function -Wno-parentheses-equality -g -o a.exe -lgdi32 -luser32 -lwinmm");
system((const char *)compiler_call.str);
F64 end = os_time();

View File

@@ -260,6 +260,7 @@ For modules it's a bit different cause they should be distributed as valid.
#include "core_ast.cpp"
#include "core_parsing.cpp"
#include "core_typechecking.h"
#include "core_types.cpp"
#include "core_typechecking.cpp"
#include "core_compiler.cpp"
#include "core_codegen_c_language.cpp"

View File

@@ -1,59 +1,4 @@
function const char *
get_name_of_type(Ast_Type *type){
switch(type->kind){
case TYPE_VOID: return "void";
case TYPE_BOOL: return "Bool";
case TYPE_STRING: return "String";
case TYPE_CHAR: return "char";
case TYPE_F32: return "F32";
case TYPE_F64: return "F64";
case TYPE_S8: return "S8";
case TYPE_INT: return "int";
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";
case TYPE_TUPLE: return "Tuple";
case TYPE_TYPE: return "Type";
invalid_default_case;
}
return "<unknown_type>";
}
//-----------------------------------------------------------------------------
// Type constructors and utillities
//-----------------------------------------------------------------------------
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;}
force_inline B32 is_slice(Ast_Type *a){return a->kind == TYPE_SLICE;}
force_inline B32 is_tuple(Ast_Type *a){return a->kind == TYPE_TUPLE;}
force_inline B32 is_enum(Ast_Type *a){return a->kind == TYPE_ENUM;}
force_inline B32 is_pointer(Ast_Type *a){return a->kind == TYPE_POINTER;}
force_inline B32 is_void(Ast_Type *a){return a->kind == TYPE_VOID;}
force_inline B32 is_void_pointer(Ast_Type *a){return a == type_pointer_to_void;}
force_inline B32 is_string(Ast_Type *a){return a->kind == TYPE_STRING || a->kind == TYPE_UNTYPED_STRING || a == type_pointer_to_char;}
force_inline B32 is_untyped_int(Ast_Type *a){return a->kind == TYPE_UNTYPED_INT;}
force_inline B32 is_typed_int(Ast_Type *a){return (a->kind >= TYPE_S64 && a->kind <= TYPE_U8);}
force_inline B32 is_int(Ast_Type *a){return (a->kind >= TYPE_S64 && a->kind <= TYPE_U8) || a->kind == TYPE_UNTYPED_INT;}
force_inline B32 is_signed_int(Ast_Type *a){return !a->is_unsigned;}
force_inline B32 is_unsigned_int(Ast_Type *a){return a->is_unsigned;}
force_inline B32 is_float(Ast_Type *a){return a->kind == TYPE_F32 || a->kind == TYPE_F64 || a->kind == TYPE_UNTYPED_FLOAT;}
force_inline B32 is_f32(Ast_Type *a){return a->kind == TYPE_F32;}
force_inline B32 is_f64(Ast_Type *a){return a->kind == TYPE_F64;}
force_inline B32 is_bool(Ast_Type *a){return a->kind == TYPE_BOOL || a->kind == TYPE_UNTYPED_BOOL;}
force_inline B32 is_untyped(Ast_Type *a){return a->kind >= TYPE_UNTYPED_FIRST && a->kind <= TYPE_UNTYPED_LAST;}
force_inline B32 is_typed(Ast_Type *a){return !is_untyped(a);}
force_inline B32 is_numeric(Ast_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 Resolve_Flag
inherit_flag(Resolve_Flag flag, B32 ast_can_be_null){
unset_flag(flag, AST_CAN_BE_NULL);
@@ -140,287 +85,6 @@ operand_rvalue(Ast_Type *type){
return result;
}
//-----------------------------------------------------------------------------
// Hash consed types
//-----------------------------------------------------------------------------
function Ast_Type *
type_new(Allocator *allocator, Ast_Type_Kind kind, SizeU size, SizeU align){
Ast_Type *result = exp_alloc_type(allocator, Ast_Type, AF_ZeroMemory);
result->kind = kind;
result->size = size;
result->align = align;
result->type_id = pctx->type_ids++;
add(pctx->perm, &pctx->all_types, result);
return result;
}
function Ast_Type *
type_copy(Allocator *a, Ast_Type *type){
// @warning: This changes type id !!!!
Ast_Type *result = exp_alloc_type(a, Ast_Type);
memory_copy(result, type, sizeof(Ast_Type));
result->type_id = pctx->type_ids++;
add(pctx->perm, &pctx->all_types, result);
return result;
}
function Ast_Type *
type_pointer(Ast_Type *base){
Ast_Type *result = (Ast_Type *)map_get(&pctx->type_map, (void *)base);
if(!result){
result = type_new(pctx->perm, TYPE_POINTER, pointer_size, pointer_align);
result->base = base;
result->is_unsigned = true;
map_insert(&pctx->type_map, base, result);
}
assert(result->kind == TYPE_POINTER);
return result;
}
function Ast_Type *
type_slice(Ast_Type *base, Ast *ast){
U64 hash_base = hash_ptr(base);
U64 hash = hash_mix(hash_base, hash_u64(ARRAY_SIZE_SLICE));
Ast_Type *result = (Ast_Type *)map_get(&pctx->type_map, hash);
if(result){
assert(result->kind == TYPE_SLICE);
assert(result->arr.base == base);
return result;
}
struct Slice{void *p; S64 len;};
result = type_new(pctx->perm, TYPE_SLICE, sizeof(Slice), alignof(Slice));
result->arr.base = base;
result->arr.slice_hash = hash;
result->ast = ast;
map_insert(&pctx->type_map, hash, result);
return result;
}
function Ast_Type *
type_try_tupling(Array<Ast_Type *> types, Ast *ast){
if(types.len == 0) return type_void;
if(types.len == 1) return types[0];
U64 hash = 13;
For(types) hash = hash_mix(hash, hash_ptr(it));
Ast_Type *result = (Ast_Type *)map_get(&pctx->type_map, hash);
if(result){
assert(result->kind == TYPE_TUPLE);
assert(result->agg.members.len == types.len);
assert(result->agg.members.len > 1);
return result;
}
// @todo alignment, offsets
result = type_new(pctx->perm, TYPE_TUPLE, 0, pointer_align);
result->agg.members = array_make<Ast_Resolved_Member>(pctx->perm, types.len);
For(types){
Ast_Resolved_Member m = {};
m.type = it;
m.offset = 0; // @todo
result->size += it->size;
result->agg.members.add(m);
}
map_insert(&pctx->type_map, hash, result);
assert(result->agg.members.len > 1);
return result;
}
function Ast_Type *
type_array(Ast_Type *base, S64 size){
U64 hash_base = hash_ptr(base);
U64 hash = hash_mix(hash_base, hash_u64(size));
Ast_Type *result = (Ast_Type *)map_get(&pctx->type_map, hash);
if(result){
assert(result->kind == TYPE_ARRAY);
assert(result->arr.size == size);
assert(result->arr.base == base);
return result;
}
result = type_new(pctx->perm, TYPE_ARRAY, size*base->size, pointer_align);
result->arr.base = base;
result->arr.size = size;
result->arr.slice_hash = hash_mix(hash_base, hash_u64(ARRAY_SIZE_SLICE));
map_insert(&pctx->type_map, hash, result);
return result;
}
inline U64
calculate_hash_for_arguments(Ast_Type *a, Ast_Type *b){
U64 result = 13;
result = hash_mix(result, hash_ptr(a));
result = hash_mix(result, hash_ptr(b));
return result;
}
inline U64
calculate_hash_for_arguments(Ast_Type *a){
U64 result = 13;
result = hash_mix(result, hash_ptr(a));
return result;
}
function Ast_Type *
type_lambda(Ast *ast, Array<Ast_Type *> return_vals, Array<Ast_Type *> args){
Ast_Type *ret = type_try_tupling(return_vals, ast);
U64 hash_without_ret = 13;
For(args) hash_without_ret = hash_mix(hash_without_ret, hash_ptr(it));
U64 hash = hash_mix(hash_ptr(ret), hash_without_ret);
Ast_Type *result = (Ast_Type *)map_get(&pctx->type_map, hash);
if(result){
assert(result->kind == TYPE_LAMBDA);
assert(result->func.args.len == args.len);
return result;
}
result = type_new(pctx->perm, TYPE_LAMBDA, pointer_size, pointer_align);
result->ast = ast;
result->func.ret = ret;
result->func.args = args.tight_copy(pctx->perm);
result->func.hash_without_ret = hash_without_ret; // @function_overloading scrap this if we changed course
map_insert(&pctx->type_map, hash, result);
return result;
}
function Ast_Type *
type_enum(Ast_Decl *ast, Ast_Type *type){
if(!type){
type = type_s64;
}
Ast_Type *result = type_new(pctx->perm, TYPE_ENUM, type->size, type->align);
result->base = type;
result->ast = ast;
return result;
}
function Ast_Type *
type_incomplete(Ast *ast){
Ast_Type *result = type_new(pctx->perm, TYPE_INCOMPLETE, 0, 0);
result->ast = ast;
return result;
}
function void type_complete(Ast_Type *type);
function void
type_struct_complete(Ast_Type *type, Ast_Decl *node){
assert(node->kind == AST_STRUCT);
// @todo: compute size, alignement, offset !!!
// @note: resolve all the struct members first
Scratch scratch;
Array<Ast_Resolved_Member> members = {scratch};
type->kind = TYPE_COMPLETING;
size_t members_size = 0;
For(node->scope->decls){
resolve_decl(it);
assert(it->type->kind != TYPE_INCOMPLETE);
assert(is_pow2(it->type->align));
Ast_Resolved_Member m = {};
m.offset = type->size;
members_size += it->type->size;
type->align = max(type->align, it->type->align);
type->size = it->type->size + align_up(type->size, it->type->align);
m.name = it->name;
m.value = it->value;
members.add(m);
}
type->size = align_up(type->size, type->align);
type->padding = type->size - members_size;
type->agg.members = members.tight_copy(pctx->perm);
type->kind = TYPE_STRUCT;
node->unique_name = pctx->intern(string_fmt(scratch, "%Q%Q", symbol_prefix, node->name));
}
function void
type_complete(Ast_Type *type){
if(!type) {
return;
}
if(type->kind == TYPE_COMPLETING){
compiler_error(type->ast->pos, "Cyclic type dependency");
}
else if(type->kind != TYPE_INCOMPLETE){
return;
}
type_struct_complete(type, (Ast_Decl *)type->ast);
add(pctx->perm, &pctx->ordered_decls, (Ast_Decl *)type->ast);
}
function void
init_type(){
type_pointer_to_char = type_pointer(type_char);
type_pointer_to_void = type_pointer(type_void);
}
function void
typename_base(String_Builder *sb, Ast_Type *type){
switch(type->kind){
case TYPE_INCOMPLETE: sb->addf("INCOMPLETE"); break;
case TYPE_COMPLETING: sb->addf("COMPLETING"); break;
case TYPE_TYPE: sb->addf("TYPE"); break;
case TYPE_POINTER:
sb->addf("*");
typename_base(sb, type->base);
break;
case TYPE_LAMBDA:
sb->addf("(");
For(type->func.args) {
typename_base(sb, it);
if(!type->func.args.is_last(&it)) sb->addf(", ");
}
sb->addf("):");
typename_base(sb, type->func.ret);
break;
case TYPE_ARRAY:
sb->addf("[%d]", (int)type->arr.size);
typename_base(sb, type->arr.base);
break;
case TYPE_SLICE:
sb->addf("[]");
typename_base(sb, type->base);
break;
case TYPE_STRUCT:
case TYPE_ENUM:{
// @todo direct access
auto constant = (Ast_Decl *)type->ast;
auto name = constant->name;
sb->addf("%Q", name);
break;
}
case TYPE_UNTYPED_BOOL: sb->addf("Untyped_Bool"); break;
case TYPE_UNTYPED_INT: sb->addf("Untyped_Int"); break;
case TYPE_UNTYPED_FLOAT: sb->addf("Untyped_Float"); break;
case TYPE_UNTYPED_STRING: sb->addf("Untyped_String"); break;
default: {
sb->addf("%s", get_name_of_type(type));
}
}
}
function String
get_typename(Allocator *a, Ast_Type *type){
pctx->helper_builder.addf("[");
typename_base(&pctx->helper_builder, type);
pctx->helper_builder.addf("]");
String result = string_flatten(a, &pctx->helper_builder);
pctx->helper_builder.reset();
return result;
}
function String
typestring(Ast_Type *type){
return get_typename(&pctx->stage_arena, type);
}
function void
check_value_bounds(Token *pos, Value *a){
if(!is_int(a->type)) return;

336
core_types.cpp Normal file
View File

@@ -0,0 +1,336 @@
function const char *
get_name_of_type(Ast_Type *type){
switch(type->kind){
case TYPE_VOID: return "void";
case TYPE_BOOL: return "Bool";
case TYPE_STRING: return "String";
case TYPE_CHAR: return "char";
case TYPE_F32: return "F32";
case TYPE_F64: return "F64";
case TYPE_S8: return "S8";
case TYPE_INT: return "int";
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";
case TYPE_TUPLE: return "Tuple";
case TYPE_TYPE: return "Type";
invalid_default_case;
}
return "<unknown_type>";
}
//-----------------------------------------------------------------------------
// Type constructors and utillities
//-----------------------------------------------------------------------------
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;}
force_inline B32 is_slice(Ast_Type *a){return a->kind == TYPE_SLICE;}
force_inline B32 is_tuple(Ast_Type *a){return a->kind == TYPE_TUPLE;}
force_inline B32 is_enum(Ast_Type *a){return a->kind == TYPE_ENUM;}
force_inline B32 is_pointer(Ast_Type *a){return a->kind == TYPE_POINTER;}
force_inline B32 is_void(Ast_Type *a){return a->kind == TYPE_VOID;}
force_inline B32 is_void_pointer(Ast_Type *a){return a == type_pointer_to_void;}
force_inline B32 is_string(Ast_Type *a){return a->kind == TYPE_STRING || a->kind == TYPE_UNTYPED_STRING || a == type_pointer_to_char;}
force_inline B32 is_untyped_int(Ast_Type *a){return a->kind == TYPE_UNTYPED_INT;}
force_inline B32 is_typed_int(Ast_Type *a){return (a->kind >= TYPE_S64 && a->kind <= TYPE_U8);}
force_inline B32 is_int(Ast_Type *a){return (a->kind >= TYPE_S64 && a->kind <= TYPE_U8) || a->kind == TYPE_UNTYPED_INT;}
force_inline B32 is_signed_int(Ast_Type *a){return !a->is_unsigned;}
force_inline B32 is_unsigned_int(Ast_Type *a){return a->is_unsigned;}
force_inline B32 is_float(Ast_Type *a){return a->kind == TYPE_F32 || a->kind == TYPE_F64 || a->kind == TYPE_UNTYPED_FLOAT;}
force_inline B32 is_f32(Ast_Type *a){return a->kind == TYPE_F32;}
force_inline B32 is_f64(Ast_Type *a){return a->kind == TYPE_F64;}
force_inline B32 is_bool(Ast_Type *a){return a->kind == TYPE_BOOL || a->kind == TYPE_UNTYPED_BOOL;}
force_inline B32 is_untyped(Ast_Type *a){return a->kind >= TYPE_UNTYPED_FIRST && a->kind <= TYPE_UNTYPED_LAST;}
force_inline B32 is_typed(Ast_Type *a){return !is_untyped(a);}
force_inline B32 is_numeric(Ast_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);
}
//-----------------------------------------------------------------------------
// Hash consed types
//-----------------------------------------------------------------------------
function Ast_Type *
type_new(Allocator *allocator, Ast_Type_Kind kind, SizeU size, SizeU align){
Ast_Type *result = exp_alloc_type(allocator, Ast_Type, AF_ZeroMemory);
result->kind = kind;
result->size = size;
result->align = align;
result->type_id = pctx->type_ids++;
add(pctx->perm, &pctx->all_types, result);
return result;
}
function Ast_Type *
type_copy(Allocator *a, Ast_Type *type){
// @warning: This changes type id !!!!
Ast_Type *result = exp_alloc_type(a, Ast_Type);
memory_copy(result, type, sizeof(Ast_Type));
result->type_id = pctx->type_ids++;
add(pctx->perm, &pctx->all_types, result);
return result;
}
function Ast_Type *
type_pointer(Ast_Type *base){
Ast_Type *result = (Ast_Type *)map_get(&pctx->type_map, (void *)base);
if(!result){
result = type_new(pctx->perm, TYPE_POINTER, pointer_size, pointer_align);
result->base = base;
result->is_unsigned = true;
map_insert(&pctx->type_map, base, result);
}
assert(result->kind == TYPE_POINTER);
return result;
}
function Ast_Type *
type_slice(Ast_Type *base, Ast *ast){
U64 hash_base = hash_ptr(base);
U64 hash = hash_mix(hash_base, hash_u64(ARRAY_SIZE_SLICE));
Ast_Type *result = (Ast_Type *)map_get(&pctx->type_map, hash);
if(result){
assert(result->kind == TYPE_SLICE);
assert(result->arr.base == base);
return result;
}
struct Slice{void *p; S64 len;};
result = type_new(pctx->perm, TYPE_SLICE, sizeof(Slice), alignof(Slice));
result->arr.base = base;
result->arr.slice_hash = hash;
result->ast = ast;
map_insert(&pctx->type_map, hash, result);
return result;
}
function Ast_Type *
type_try_tupling(Array<Ast_Type *> types, Ast *ast){
if(types.len == 0) return type_void;
if(types.len == 1) return types[0];
U64 hash = 13;
For(types) hash = hash_mix(hash, hash_ptr(it));
Ast_Type *result = (Ast_Type *)map_get(&pctx->type_map, hash);
if(result){
assert(result->kind == TYPE_TUPLE);
assert(result->agg.members.len == types.len);
assert(result->agg.members.len > 1);
return result;
}
// @todo alignment, offsets
result = type_new(pctx->perm, TYPE_TUPLE, 0, pointer_align);
result->agg.members = array_make<Ast_Resolved_Member>(pctx->perm, types.len);
For(types){
Ast_Resolved_Member m = {};
m.type = it;
m.offset = 0; // @todo
result->size += it->size;
result->agg.members.add(m);
}
map_insert(&pctx->type_map, hash, result);
assert(result->agg.members.len > 1);
return result;
}
function Ast_Type *
type_array(Ast_Type *base, S64 size){
U64 hash_base = hash_ptr(base);
U64 hash = hash_mix(hash_base, hash_u64(size));
Ast_Type *result = (Ast_Type *)map_get(&pctx->type_map, hash);
if(result){
assert(result->kind == TYPE_ARRAY);
assert(result->arr.size == size);
assert(result->arr.base == base);
return result;
}
result = type_new(pctx->perm, TYPE_ARRAY, size*base->size, pointer_align);
result->arr.base = base;
result->arr.size = size;
result->arr.slice_hash = hash_mix(hash_base, hash_u64(ARRAY_SIZE_SLICE));
map_insert(&pctx->type_map, hash, result);
return result;
}
inline U64
calculate_hash_for_arguments(Ast_Type *a, Ast_Type *b){
U64 result = 13;
result = hash_mix(result, hash_ptr(a));
result = hash_mix(result, hash_ptr(b));
return result;
}
inline U64
calculate_hash_for_arguments(Ast_Type *a){
U64 result = 13;
result = hash_mix(result, hash_ptr(a));
return result;
}
function Ast_Type *
type_lambda(Ast *ast, Array<Ast_Type *> return_vals, Array<Ast_Type *> args){
Ast_Type *ret = type_try_tupling(return_vals, ast);
U64 hash_without_ret = 13;
For(args) hash_without_ret = hash_mix(hash_without_ret, hash_ptr(it));
U64 hash = hash_mix(hash_ptr(ret), hash_without_ret);
Ast_Type *result = (Ast_Type *)map_get(&pctx->type_map, hash);
if(result){
assert(result->kind == TYPE_LAMBDA);
assert(result->func.args.len == args.len);
return result;
}
result = type_new(pctx->perm, TYPE_LAMBDA, pointer_size, pointer_align);
result->ast = ast;
result->func.ret = ret;
result->func.args = args.tight_copy(pctx->perm);
result->func.hash_without_ret = hash_without_ret;
map_insert(&pctx->type_map, hash, result);
return result;
}
function Ast_Type *
type_enum(Ast_Decl *ast, Ast_Type *type){
if(!type){
type = type_s64;
}
Ast_Type *result = type_new(pctx->perm, TYPE_ENUM, type->size, type->align);
result->base = type;
result->ast = ast;
return result;
}
function Ast_Type *
type_incomplete(Ast *ast){
Ast_Type *result = type_new(pctx->perm, TYPE_INCOMPLETE, 0, 0);
result->ast = ast;
return result;
}
function void type_complete(Ast_Type *type);
function void
type_struct_complete(Ast_Type *type, Ast_Decl *node){
assert(node->kind == AST_STRUCT);
// @todo: compute size, alignement, offset !!!
// @note: resolve all the struct members first
Scratch scratch;
Array<Ast_Resolved_Member> members = {scratch};
type->kind = TYPE_COMPLETING;
size_t members_size = 0;
For(node->scope->decls){
resolve_decl(it);
assert(it->type->kind != TYPE_INCOMPLETE);
assert(is_pow2(it->type->align));
Ast_Resolved_Member m = {};
m.offset = type->size;
members_size += it->type->size;
type->align = max(type->align, it->type->align);
type->size = it->type->size + align_up(type->size, it->type->align);
m.name = it->name;
m.value = it->value;
members.add(m);
}
type->size = align_up(type->size, type->align);
type->padding = type->size - members_size;
type->agg.members = members.tight_copy(pctx->perm);
type->kind = TYPE_STRUCT;
node->unique_name = pctx->intern(string_fmt(scratch, "%Q%Q", symbol_prefix, node->name));
}
function void
type_complete(Ast_Type *type){
if(!type) {
return;
}
if(type->kind == TYPE_COMPLETING){
compiler_error(type->ast->pos, "Cyclic type dependency");
}
else if(type->kind != TYPE_INCOMPLETE){
return;
}
type_struct_complete(type, (Ast_Decl *)type->ast);
add(pctx->perm, &pctx->ordered_decls, (Ast_Decl *)type->ast);
}
function void
init_type(){
type_pointer_to_char = type_pointer(type_char);
type_pointer_to_void = type_pointer(type_void);
}
function void
typename_base(String_Builder *sb, Ast_Type *type){
switch(type->kind){
case TYPE_INCOMPLETE: sb->addf("INCOMPLETE"); break;
case TYPE_COMPLETING: sb->addf("COMPLETING"); break;
case TYPE_TYPE: sb->addf("TYPE"); break;
case TYPE_POINTER:
sb->addf("*");
typename_base(sb, type->base);
break;
case TYPE_LAMBDA:
sb->addf("(");
For(type->func.args) {
typename_base(sb, it);
if(!type->func.args.is_last(&it)) sb->addf(", ");
}
sb->addf("):");
typename_base(sb, type->func.ret);
break;
case TYPE_ARRAY:
sb->addf("[%d]", (int)type->arr.size);
typename_base(sb, type->arr.base);
break;
case TYPE_SLICE:
sb->addf("[]");
typename_base(sb, type->base);
break;
case TYPE_STRUCT:
case TYPE_ENUM:{
// @todo direct access
auto constant = (Ast_Decl *)type->ast;
auto name = constant->name;
sb->addf("%Q", name);
break;
}
case TYPE_UNTYPED_BOOL: sb->addf("Untyped_Bool"); break;
case TYPE_UNTYPED_INT: sb->addf("Untyped_Int"); break;
case TYPE_UNTYPED_FLOAT: sb->addf("Untyped_Float"); break;
case TYPE_UNTYPED_STRING: sb->addf("Untyped_String"); break;
default: {
sb->addf("%s", get_name_of_type(type));
}
}
}
function String
get_typename(Allocator *a, Ast_Type *type){
pctx->helper_builder.addf("[");
typename_base(&pctx->helper_builder, type);
pctx->helper_builder.addf("]");
String result = string_flatten(a, &pctx->helper_builder);
pctx->helper_builder.reset();
return result;
}
function String
typestring(Ast_Type *type){
return get_typename(&pctx->stage_arena, type);
}

View File

@@ -102,7 +102,7 @@ struct Ast_Type{
struct{
Ast_Type * ret;
Array<Ast_Type *> args;
U64 hash_without_ret; // @function_overloading scrap this if we changed course
U64 hash_without_ret;
}func;
};
};

View File

@@ -8,3 +8,5 @@ WinMain :: (hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: LPSTR, nS
for y := 0, y < Mu.window.y, y+=1
for x := 0, x < Mu.window.x, x+=1
Mu.screen[x + y*Mu.window.x] = 0xFFFFFF00
return 0