mirror of
https://github.com/odin-lang/Odin.git
synced 2026-04-22 06:15:20 +00:00
Merge branch 'master' of github.com:odin-lang/odin
This commit is contained in:
@@ -266,13 +266,7 @@ make_source_code_location :: inline proc "contextless" (file: string, line, colu
|
||||
__init_context_from_ptr :: proc "contextless" (c: ^Context, other: ^Context) {
|
||||
if c == nil do return;
|
||||
c^ = other^;
|
||||
|
||||
if c.allocator.procedure == nil {
|
||||
c.allocator = default_allocator();
|
||||
}
|
||||
if c.thread_id == 0 {
|
||||
c.thread_id = os.current_thread_id();
|
||||
}
|
||||
__init_context(c);
|
||||
}
|
||||
|
||||
__init_context :: proc "contextless" (c: ^Context) {
|
||||
|
||||
48
core/c.odin
48
core/c.odin
@@ -1,38 +1,38 @@
|
||||
CHAR_BIT :: 8;
|
||||
|
||||
c_bool :: #alias bool;
|
||||
c_char :: #alias u8;
|
||||
c_byte :: #alias u8;
|
||||
c_schar :: #alias i8;
|
||||
c_uchar :: #alias u8;
|
||||
c_short :: #alias i16;
|
||||
c_ushort :: #alias u16;
|
||||
c_int :: #alias i32;
|
||||
c_uint :: #alias u32;
|
||||
c_bool :: bool;
|
||||
c_char :: u8;
|
||||
c_byte :: u8;
|
||||
c_schar :: i8;
|
||||
c_uchar :: u8;
|
||||
c_short :: i16;
|
||||
c_ushort :: u16;
|
||||
c_int :: i32;
|
||||
c_uint :: u32;
|
||||
|
||||
when ODIN_OS == "windows" || size_of(rawptr) == 4 {
|
||||
c_long :: #alias i32;
|
||||
c_long :: i32;
|
||||
} else {
|
||||
c_long :: #alias i64;
|
||||
c_long :: i64;
|
||||
}
|
||||
|
||||
when ODIN_OS == "windows" || size_of(rawptr) == 4 {
|
||||
c_ulong :: #alias u32;
|
||||
c_ulong :: u32;
|
||||
} else {
|
||||
c_ulong :: #alias u64;
|
||||
c_ulong :: u64;
|
||||
}
|
||||
|
||||
c_longlong :: #alias i64;
|
||||
c_ulonglong :: #alias u64;
|
||||
c_float :: #alias f32;
|
||||
c_double :: #alias f64;
|
||||
c_complex_float :: #alias complex64;
|
||||
c_complex_double :: #alias complex128;
|
||||
c_longlong :: i64;
|
||||
c_ulonglong :: u64;
|
||||
c_float :: f32;
|
||||
c_double :: f64;
|
||||
c_complex_float :: complex64;
|
||||
c_complex_double :: complex128;
|
||||
|
||||
_ :: compile_assert(size_of(uintptr) == size_of(int));
|
||||
|
||||
c_size_t :: #alias uint;
|
||||
c_ssize_t :: #alias int;
|
||||
c_ptrdiff_t :: #alias int;
|
||||
c_uintptr_t :: #alias uintptr;
|
||||
c_intptr_t :: #alias int;
|
||||
c_size_t :: uint;
|
||||
c_ssize_t :: int;
|
||||
c_ptrdiff_t :: int;
|
||||
c_uintptr_t :: uintptr;
|
||||
c_intptr_t :: int;
|
||||
|
||||
@@ -8,7 +8,7 @@ import "core:raw.odin"
|
||||
|
||||
_BUFFER_SIZE :: 1<<12;
|
||||
|
||||
String_Buffer :: [dynamic]byte;
|
||||
String_Buffer :: distinct [dynamic]byte;
|
||||
|
||||
Fmt_Info :: struct {
|
||||
minus: bool,
|
||||
|
||||
@@ -14,14 +14,14 @@ EPSILON :: 1.19209290e-7;
|
||||
τ :: TAU;
|
||||
π :: PI;
|
||||
|
||||
Vec2 :: [2]f32;
|
||||
Vec3 :: [3]f32;
|
||||
Vec4 :: [4]f32;
|
||||
Vec2 :: distinct [2]f32;
|
||||
Vec3 :: distinct [3]f32;
|
||||
Vec4 :: distinct [4]f32;
|
||||
|
||||
// Column major
|
||||
Mat2 :: [2][2]f32;
|
||||
Mat3 :: [3][3]f32;
|
||||
Mat4 :: [4][4]f32;
|
||||
Mat2 :: distinct [2][2]f32;
|
||||
Mat3 :: distinct [3][3]f32;
|
||||
Mat4 :: distinct [4][4]f32;
|
||||
|
||||
Quat :: struct {x, y, z: f32, w: f32 = 1};
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ allocation_header :: proc(data: rawptr) -> ^AllocationHeader {
|
||||
}
|
||||
|
||||
|
||||
Fixed_Byte_Buffer :: [dynamic]byte;
|
||||
Fixed_Byte_Buffer :: distinct [dynamic]byte;
|
||||
|
||||
make_fixed_byte_buffer :: proc(backing: []byte) -> Fixed_Byte_Buffer {
|
||||
s := transmute(raw.Slice)backing;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
foreign import api "system:api"
|
||||
|
||||
Handle :: int;
|
||||
Errno :: int;
|
||||
Handle :: distinct int;
|
||||
Errno :: distinct int;
|
||||
|
||||
O_RDONLY :: 1;
|
||||
O_WRONLY :: 2;
|
||||
|
||||
@@ -4,9 +4,9 @@ foreign import libc "system:c"
|
||||
import "core:strings.odin"
|
||||
import "core:mem.odin"
|
||||
|
||||
Handle :: i32;
|
||||
File_Time :: u64;
|
||||
Errno :: i32;
|
||||
Handle :: distinct i32;
|
||||
File_Time :: distinct u64;
|
||||
Errno :: distinct i32;
|
||||
|
||||
|
||||
O_RDONLY :: 0x00000;
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import win32 "core:sys/windows.odin"
|
||||
import "core:mem.odin"
|
||||
|
||||
Handle :: uintptr;
|
||||
File_Time :: u64;
|
||||
Handle :: distinct uintptr;
|
||||
File_Time :: distinct u64;
|
||||
Errno :: distinct int;
|
||||
|
||||
|
||||
INVALID_HANDLE :: ~Handle(0);
|
||||
@@ -22,7 +23,6 @@ O_SYNC :: 0x01000;
|
||||
O_ASYNC :: 0x02000;
|
||||
O_CLOEXEC :: 0x80000;
|
||||
|
||||
Errno :: int;
|
||||
|
||||
ERROR_NONE: Errno : 0;
|
||||
ERROR_FILE_NOT_FOUND: Errno : 2;
|
||||
|
||||
@@ -4,9 +4,9 @@ foreign import libc "system:c"
|
||||
import "core:strings.odin"
|
||||
import "core:mem.odin"
|
||||
|
||||
Handle :: i32;
|
||||
File_Time :: u64;
|
||||
Errno :: int;
|
||||
Handle :: distinct i32;
|
||||
File_Time :: distinct u64;
|
||||
Errno :: distinct int;
|
||||
|
||||
|
||||
O_RDONLY :: 0x00000;
|
||||
|
||||
@@ -12,8 +12,8 @@ CONTEXT_FORWARD_COMPATIBLE_BIT_ARB :: 0x0002;
|
||||
CONTEXT_CORE_PROFILE_BIT_ARB :: 0x00000001;
|
||||
CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB :: 0x00000002;
|
||||
|
||||
Hglrc :: Handle;
|
||||
Color_Ref :: u32;
|
||||
Hglrc :: distinct Handle;
|
||||
Color_Ref :: distinct u32;
|
||||
|
||||
Layer_Plane_Descriptor :: struct {
|
||||
size: u16,
|
||||
|
||||
@@ -6,27 +6,27 @@ when ODIN_OS == "windows" {
|
||||
foreign import "system:shell32.lib"
|
||||
}
|
||||
|
||||
Handle :: rawptr;
|
||||
Hwnd :: Handle;
|
||||
Hdc :: Handle;
|
||||
Hinstance :: Handle;
|
||||
Hicon :: Handle;
|
||||
Hcursor :: Handle;
|
||||
Hmenu :: Handle;
|
||||
Hbrush :: Handle;
|
||||
Hgdiobj :: Handle;
|
||||
Hmodule :: Handle;
|
||||
Hmonitor :: Handle;
|
||||
Hrawinput :: Handle;
|
||||
HKL :: Handle;
|
||||
Wparam :: uint;
|
||||
Lparam :: int;
|
||||
Lresult :: int;
|
||||
Wnd_Proc :: #type proc "c" (Hwnd, u32, Wparam, Lparam) -> Lresult;
|
||||
Handle :: distinct rawptr;
|
||||
Hwnd :: distinct Handle;
|
||||
Hdc :: distinct Handle;
|
||||
Hinstance :: distinct Handle;
|
||||
Hicon :: distinct Handle;
|
||||
Hcursor :: distinct Handle;
|
||||
Hmenu :: distinct Handle;
|
||||
Hbrush :: distinct Handle;
|
||||
Hgdiobj :: distinct Handle;
|
||||
Hmodule :: distinct Handle;
|
||||
Hmonitor :: distinct Handle;
|
||||
Hrawinput :: distinct Handle;
|
||||
HKL :: distinct Handle;
|
||||
Wparam :: distinct uint;
|
||||
Lparam :: distinct int;
|
||||
Lresult :: distinct int;
|
||||
Wnd_Proc :: distinct #type proc "c" (Hwnd, u32, Wparam, Lparam) -> Lresult;
|
||||
|
||||
Long_Ptr :: int;
|
||||
Long_Ptr :: distinct int;
|
||||
|
||||
Bool :: b32;
|
||||
Bool :: distinct b32;
|
||||
|
||||
Point :: struct {
|
||||
x, y: i32,
|
||||
@@ -139,7 +139,7 @@ Security_Attributes :: struct {
|
||||
|
||||
Process_Information :: struct {
|
||||
process: Handle,
|
||||
thread: Handle,
|
||||
thread: Handle,
|
||||
process_id: u32,
|
||||
thread_id: u32
|
||||
}
|
||||
@@ -484,7 +484,7 @@ PFD_DEPTH_DONTCARE :: 0x20000000;
|
||||
PFD_DOUBLEBUFFER_DONTCARE :: 0x40000000;
|
||||
PFD_STEREO_DONTCARE :: 0x80000000;
|
||||
|
||||
GET_FILEEX_INFO_LEVELS :: i32;
|
||||
GET_FILEEX_INFO_LEVELS :: distinct i32;
|
||||
GetFileExInfoStandard: GET_FILEEX_INFO_LEVELS : 0;
|
||||
GetFileExMaxInfoLevel: GET_FILEEX_INFO_LEVELS : 1;
|
||||
|
||||
@@ -511,14 +511,14 @@ MOVEFILE_WRITE_THROUGH :: 0x00000008;
|
||||
MOVEFILE_CREATE_HARDLINK :: 0x00000010;
|
||||
MOVEFILE_FAIL_IF_NOT_TRACKABLE :: 0x00000020;
|
||||
|
||||
FILE_NOTIFY_CHANGE_FILE_NAME :: 0x00000001;
|
||||
FILE_NOTIFY_CHANGE_DIR_NAME :: 0x00000002;
|
||||
FILE_NOTIFY_CHANGE_ATTRIBUTES :: 0x00000004;
|
||||
FILE_NOTIFY_CHANGE_SIZE :: 0x00000008;
|
||||
FILE_NOTIFY_CHANGE_LAST_WRITE :: 0x00000010;
|
||||
FILE_NOTIFY_CHANGE_LAST_ACCESS :: 0x00000020;
|
||||
FILE_NOTIFY_CHANGE_CREATION :: 0x00000040;
|
||||
FILE_NOTIFY_CHANGE_SECURITY :: 0x00000100;
|
||||
FILE_NOTIFY_CHANGE_FILE_NAME :: 0x00000001;
|
||||
FILE_NOTIFY_CHANGE_DIR_NAME :: 0x00000002;
|
||||
FILE_NOTIFY_CHANGE_ATTRIBUTES :: 0x00000004;
|
||||
FILE_NOTIFY_CHANGE_SIZE :: 0x00000008;
|
||||
FILE_NOTIFY_CHANGE_LAST_WRITE :: 0x00000010;
|
||||
FILE_NOTIFY_CHANGE_LAST_ACCESS :: 0x00000020;
|
||||
FILE_NOTIFY_CHANGE_CREATION :: 0x00000040;
|
||||
FILE_NOTIFY_CHANGE_SECURITY :: 0x00000100;
|
||||
|
||||
FILE_FLAG_WRITE_THROUGH :: 0x80000000;
|
||||
FILE_FLAG_OVERLAPPED :: 0x40000000;
|
||||
@@ -550,9 +550,9 @@ CP_UTF8 :: 65001; // UTF-8 translation
|
||||
@(default_calling_convention = "std")
|
||||
foreign kernel32 {
|
||||
@(link_name="GetLastError") get_last_error :: proc() -> i32 ---;
|
||||
@(link_name="CreateProcessA") create_process_a :: proc(application_name, command_line: ^byte,
|
||||
process_attributes, thread_attributes: ^Security_Attributes,
|
||||
inherit_handle: Bool, creation_flags: u32, environment: rawptr,
|
||||
@(link_name="CreateProcessA") create_process_a :: proc(application_name, command_line: ^byte,
|
||||
process_attributes, thread_attributes: ^Security_Attributes,
|
||||
inherit_handle: Bool, creation_flags: u32, environment: rawptr,
|
||||
current_direcotry: ^byte, startup_info : ^Startup_Info,
|
||||
process_information : ^Process_Information) -> Bool ---;
|
||||
@(link_name="GetExitCodeProcess") get_exit_code_process :: proc(process: Handle, exit: ^u32) -> Bool ---;
|
||||
@@ -630,7 +630,7 @@ foreign kernel32 {
|
||||
@(link_name="FindNextChangeNotification") find_next_change_notification :: proc(h: Handle) -> Bool ---;
|
||||
@(link_name="FindCloseChangeNotification") find_close_change_notification :: proc(h: Handle) -> Bool ---;
|
||||
|
||||
@(link_name="ReadDirectoryChangesW") read_directory_changes_w :: proc(dir: Handle, buf: rawptr, buf_length: u32,
|
||||
@(link_name="ReadDirectoryChangesW") read_directory_changes_w :: proc(dir: Handle, buf: rawptr, buf_length: u32,
|
||||
watch_subtree: Bool, notify_filter: u32,
|
||||
bytes_returned: ^u32, overlapped: ^Overlapped,
|
||||
completion: rawptr) -> Bool ---;
|
||||
|
||||
@@ -22,7 +22,7 @@ when ODIN_OS == "windows" {
|
||||
@(link_name="general_stuff")
|
||||
general_stuff :: proc() {
|
||||
fmt.println("# general_stuff");
|
||||
{ // `do` for inline statmes rather than block
|
||||
{ // `do` for inline statments rather than block
|
||||
foo :: proc() do fmt.println("Foo!");
|
||||
if false do foo();
|
||||
for false do foo();
|
||||
@@ -93,6 +93,21 @@ general_stuff :: proc() {
|
||||
// Having specific sized booleans is very useful when dealing with foreign code
|
||||
// and to enforce specific alignment for a boolean, especially within a struct
|
||||
}
|
||||
|
||||
{ // `distinct` types
|
||||
// Originally, all type declarations would create a distinct type unless #type_alias was present.
|
||||
// Now the behaviour has been reversed. All type declarations create a type alias unless `distinct` is present.
|
||||
// If the type expression is `struct`, `union`, `enum`, `proc`, or `bit_field`, the types will always been distinct.
|
||||
|
||||
Int32 :: i32;
|
||||
compile_assert(Int32 == i32);
|
||||
|
||||
My_Int32 :: distinct i32;
|
||||
compile_assert(My_Int32 != i32);
|
||||
|
||||
My_Struct :: struct{x: int};
|
||||
compile_assert(My_Struct != struct{x: int});
|
||||
}
|
||||
}
|
||||
|
||||
default_struct_values :: proc() {
|
||||
@@ -601,7 +616,7 @@ array_programming :: proc() {
|
||||
}
|
||||
|
||||
{
|
||||
Vector3 :: [3]f32;
|
||||
Vector3 :: distinct [3]f32;
|
||||
a := Vector3{1, 2, 3};
|
||||
b := Vector3{5, 6, 7};
|
||||
c := (a * b)/2 + 1;
|
||||
@@ -675,7 +690,7 @@ enum_export :: proc() {
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
when true {
|
||||
when false {
|
||||
general_stuff();
|
||||
default_struct_values();
|
||||
union_type();
|
||||
@@ -687,4 +702,3 @@ main :: proc() {
|
||||
enum_export();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -170,22 +170,57 @@ void check_init_constant(Checker *c, Entity *e, Operand *operand) {
|
||||
e->Constant.value = operand->value;
|
||||
}
|
||||
|
||||
AstNode *remove_type_alias(AstNode *node) {
|
||||
|
||||
bool is_type_distinct(AstNode *node) {
|
||||
for (;;) {
|
||||
if (node == nullptr) {
|
||||
return false;
|
||||
}
|
||||
if (node->kind == AstNode_ParenExpr) {
|
||||
node = node->ParenExpr.expr;
|
||||
} else if (node->kind == AstNode_HelperType) {
|
||||
node = node->HelperType.type;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (node->kind) {
|
||||
case AstNode_DistinctType:
|
||||
return true;
|
||||
|
||||
case AstNode_StructType:
|
||||
case AstNode_UnionType:
|
||||
case AstNode_EnumType:
|
||||
case AstNode_BitFieldType:
|
||||
case AstNode_ProcType:
|
||||
return true;
|
||||
|
||||
case AstNode_PointerType:
|
||||
case AstNode_ArrayType:
|
||||
case AstNode_DynamicArrayType:
|
||||
case AstNode_MapType:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
AstNode *remove_type_alias_clutter(AstNode *node) {
|
||||
for (;;) {
|
||||
if (node == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
if (node->kind == AstNode_ParenExpr) {
|
||||
node = node->ParenExpr.expr;
|
||||
} else if (node->kind == AstNode_AliasType) {
|
||||
node = node->AliasType.type;
|
||||
} else if (node->kind == AstNode_DistinctType) {
|
||||
node = node->DistinctType.type;
|
||||
} else {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void check_type_decl(Checker *c, Entity *e, AstNode *type_expr, Type *def, bool is_alias) {
|
||||
void check_type_decl(Checker *c, Entity *e, AstNode *type_expr, Type *def) {
|
||||
GB_ASSERT(e->type == nullptr);
|
||||
|
||||
DeclInfo *decl = decl_info_of_entity(&c->info, e);
|
||||
@@ -193,7 +228,8 @@ void check_type_decl(Checker *c, Entity *e, AstNode *type_expr, Type *def, bool
|
||||
error(decl->attributes[0], "Attributes are not allowed on type declarations");
|
||||
}
|
||||
|
||||
AstNode *te = remove_type_alias(type_expr);
|
||||
bool is_distinct = is_type_distinct(type_expr);
|
||||
AstNode *te = remove_type_alias_clutter(type_expr);
|
||||
e->type = t_invalid;
|
||||
String name = e->token.string;
|
||||
Type *named = make_type_named(c->allocator, name, nullptr, e);
|
||||
@@ -205,16 +241,20 @@ void check_type_decl(Checker *c, Entity *e, AstNode *type_expr, Type *def, bool
|
||||
|
||||
Type *bt = check_type(c, te, named);
|
||||
named->Named.base = base_type(bt);
|
||||
if (is_alias) {
|
||||
if (is_type_named(bt)) {
|
||||
e->type = bt;
|
||||
e->TypeName.is_type_alias = true;
|
||||
} else {
|
||||
gbString str = type_to_string(bt);
|
||||
error(type_expr, "Type alias declaration with a non-named type '%s'", str);
|
||||
gb_string_free(str);
|
||||
}
|
||||
if (!is_distinct) {
|
||||
e->type = bt;
|
||||
e->TypeName.is_type_alias = true;
|
||||
}
|
||||
// if (is_alias) {
|
||||
// if (is_type_named(bt)) {
|
||||
// e->type = bt;
|
||||
// e->TypeName.is_type_alias = true;
|
||||
// } else {
|
||||
// gbString str = type_to_string(bt);
|
||||
// error(type_expr, "Type alias declaration with a non-named type '%s'", str);
|
||||
// gb_string_free(str);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
void check_const_decl(Checker *c, Entity *e, AstNode *type_expr, AstNode *init, Type *named_type) {
|
||||
@@ -261,7 +301,7 @@ void check_const_decl(Checker *c, Entity *e, AstNode *type_expr, AstNode *init,
|
||||
error(e->token, "A type declaration cannot have an type parameter");
|
||||
}
|
||||
d->type_expr = d->init_expr;
|
||||
check_type_decl(c, e, d->type_expr, named_type, false);
|
||||
check_type_decl(c, e, d->type_expr, named_type);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -866,8 +906,7 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {
|
||||
check_const_decl(c, e, d->type_expr, d->init_expr, named_type);
|
||||
break;
|
||||
case Entity_TypeName: {
|
||||
bool is_alias = unparen_expr(d->type_expr)->kind == AstNode_AliasType;
|
||||
check_type_decl(c, e, d->type_expr, named_type, is_alias);
|
||||
check_type_decl(c, e, d->type_expr, named_type);
|
||||
break;
|
||||
}
|
||||
case Entity_Procedure:
|
||||
|
||||
@@ -57,7 +57,7 @@ ExprKind check_expr_base (Checker *c, Operand *operand, AstNode *
|
||||
void check_expr_with_type_hint (Checker *c, Operand *o, AstNode *e, Type *t);
|
||||
Type * check_type (Checker *c, AstNode *expression, Type *named_type = nullptr);
|
||||
Type * make_optional_ok_type (gbAllocator a, Type *value);
|
||||
void check_type_decl (Checker *c, Entity *e, AstNode *type_expr, Type *def, bool alias);
|
||||
void check_type_decl (Checker *c, Entity *e, AstNode *type_expr, Type *def);
|
||||
Entity * check_selector (Checker *c, Operand *operand, AstNode *node, Type *type_hint);
|
||||
Entity * check_ident (Checker *c, Operand *o, AstNode *n, Type *named_type, Type *type_hint, bool allow_import_name);
|
||||
Entity * find_polymorphic_struct_entity (Checker *c, Type *original_type, isize param_count, Array<Operand> ordered_operands);
|
||||
@@ -6255,12 +6255,11 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
|
||||
str = write_expr_to_string(str, ht->type);
|
||||
case_end;
|
||||
|
||||
case_ast_node(ht, AliasType, node);
|
||||
str = gb_string_appendc(str, "#type_alias ");
|
||||
case_ast_node(ht, DistinctType, node);
|
||||
str = gb_string_appendc(str, "distinct ");
|
||||
str = write_expr_to_string(str, ht->type);
|
||||
case_end;
|
||||
|
||||
|
||||
case_ast_node(pt, PolyType, node);
|
||||
str = gb_string_append_rune(str, '$');
|
||||
str = write_expr_to_string(str, pt->type);
|
||||
|
||||
@@ -203,7 +203,9 @@ Type *check_assignment_variable(Checker *c, Operand *lhs, Operand *rhs) {
|
||||
bool used = false;
|
||||
|
||||
if (lhs->mode == Addressing_Invalid ||
|
||||
(lhs->type == t_invalid && lhs->mode != Addressing_ProcGroup)) {
|
||||
(lhs->type == t_invalid &&
|
||||
lhs->mode != Addressing_ProcGroup &&
|
||||
lhs->mode != Addressing_Builtin)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -1963,10 +1963,10 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
|
||||
return check_type_internal(c, ht->type, type, named_type);
|
||||
case_end;
|
||||
|
||||
case_ast_node(at, AliasType, e);
|
||||
error(e, "Invalid use of '#type_alias'");
|
||||
case_ast_node(dt, DistinctType, e);
|
||||
error(e, "Invalid use of a distinct type");
|
||||
// NOTE(bill): Treat it as a HelperType to remove errors
|
||||
return check_type_internal(c, at->type, type, named_type);
|
||||
return check_type_internal(c, dt->type, type, named_type);
|
||||
case_end;
|
||||
|
||||
case_ast_node(pt, PolyType, e);
|
||||
|
||||
39
src/ir.cpp
39
src/ir.cpp
@@ -905,7 +905,9 @@ irValue *ir_instr_local(irProcedure *p, Entity *e, bool zero_initialized) {
|
||||
i->Local.entity = e;
|
||||
i->Local.type = make_type_pointer(p->module->allocator, e->type);
|
||||
i->Local.zero_initialized = zero_initialized;
|
||||
i->Local.alignment = type_align_of(p->module->allocator, e->type);
|
||||
// i->Local.alignment = type_align_of(p->module->allocator, e->type);
|
||||
// TODO(bill): determine the correct alignment
|
||||
i->Local.alignment = gb_max(16, type_align_of(p->module->allocator, e->type));
|
||||
array_init(&i->Local.referrers, heap_allocator()); // TODO(bill): Replace heap allocator here
|
||||
ir_module_add_value(p->module, e, v);
|
||||
return v;
|
||||
@@ -1611,6 +1613,19 @@ irValue *ir_emit_comment(irProcedure *p, String text) {
|
||||
return ir_emit(p, ir_instr_comment(p, text));
|
||||
}
|
||||
|
||||
void ir_emit_init_context(irProcedure *proc, irValue *c = nullptr) {
|
||||
irModule *m = proc->module;
|
||||
gbAllocator a = m->allocator;
|
||||
irValue **args = gb_alloc_array(a, irValue *, 1);
|
||||
args[0] = c ? c : m->global_default_context;
|
||||
ir_emit_global_call(proc, "__init_context", args, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
irValue *ir_copy_value_to_ptr(irProcedure *proc, irValue *val, Type *new_type, i64 alignment) {
|
||||
i64 type_alignment = type_align_of(proc->module->allocator, new_type);
|
||||
if (alignment < type_alignment) {
|
||||
@@ -1628,14 +1643,21 @@ irValue *ir_emit_bitcast(irProcedure *proc, irValue *data, Type *type) {
|
||||
|
||||
irValue *ir_emit_transmute(irProcedure *proc, irValue *value, Type *t);
|
||||
irValue *ir_address_from_load_or_generate_local(irProcedure *proc, irValue *val);
|
||||
irValue *ir_emit_struct_ep(irProcedure *proc, irValue *s, i32 index);
|
||||
|
||||
|
||||
irValue *ir_find_or_generate_context_ptr(irProcedure *proc) {
|
||||
if (proc->context_stack.count > 0) {
|
||||
return proc->context_stack[proc->context_stack.count-1];
|
||||
}
|
||||
irValue *c = ir_add_local_generated(proc, t_context);
|
||||
ir_emit_store(proc, c, ir_emit_load(proc, proc->module->global_default_context));
|
||||
array_add(&proc->context_stack, c);
|
||||
ir_emit_store(proc, c, ir_emit_load(proc, proc->module->global_default_context));
|
||||
|
||||
irValue *ep = ir_emit_struct_ep(proc, c, 0);
|
||||
irValue *v = ir_emit_global_call(proc, "default_allocator", nullptr, 0);
|
||||
ir_emit_store(proc, ep, v);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
@@ -1790,15 +1812,9 @@ void ir_emit_if(irProcedure *proc, irValue *cond, irBlock *true_block, irBlock *
|
||||
ir_start_block(proc, nullptr);
|
||||
}
|
||||
|
||||
void ir_emit_startup_runtime(irProcedure *proc) {
|
||||
GB_ASSERT(proc->parent == nullptr && proc->name == "main");
|
||||
ir_emit(proc, ir_alloc_instr(proc, irInstr_StartupRuntime));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
irValue *ir_emit_struct_ep(irProcedure *proc, irValue *s, i32 index);
|
||||
irValue *ir_emit_comp(irProcedure *proc, TokenKind op_kind, irValue *left, irValue *right);
|
||||
|
||||
irValue *ir_gen_map_header(irProcedure *proc, irValue *map_val_ptr, Type *map_type) {
|
||||
@@ -8671,12 +8687,7 @@ void ir_gen_tree(irGen *s) {
|
||||
ir_begin_procedure_body(proc);
|
||||
defer (ir_end_procedure_body(proc));
|
||||
|
||||
{
|
||||
irValue **args = gb_alloc_array(a, irValue *, 1);
|
||||
args[0] = m->global_default_context;
|
||||
ir_emit_global_call(proc, "__init_context", args, 1);
|
||||
}
|
||||
|
||||
ir_emit_init_context(proc);
|
||||
|
||||
ir_setup_type_info_data(proc);
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ Token ast_node_token(AstNode *node) {
|
||||
|
||||
case AstNode_TypeType: return node->TypeType.token;
|
||||
case AstNode_HelperType: return node->HelperType.token;
|
||||
case AstNode_AliasType: return node->AliasType.token;
|
||||
case AstNode_DistinctType: return node->DistinctType.token;
|
||||
case AstNode_PolyType: return node->PolyType.token;
|
||||
case AstNode_ProcType: return node->ProcType.token;
|
||||
case AstNode_PointerType: return node->PointerType.token;
|
||||
@@ -321,8 +321,8 @@ AstNode *clone_ast_node(gbAllocator a, AstNode *node) {
|
||||
case AstNode_HelperType:
|
||||
n->HelperType.type = clone_ast_node(a, n->HelperType.type);
|
||||
break;
|
||||
case AstNode_AliasType:
|
||||
n->AliasType.type = clone_ast_node(a, n->AliasType.type);
|
||||
case AstNode_DistinctType:
|
||||
n->DistinctType.type = clone_ast_node(a, n->DistinctType.type);
|
||||
break;
|
||||
case AstNode_ProcType:
|
||||
n->ProcType.params = clone_ast_node(a, n->ProcType.params);
|
||||
@@ -837,14 +837,13 @@ AstNode *ast_helper_type(AstFile *f, Token token, AstNode *type) {
|
||||
return result;
|
||||
}
|
||||
|
||||
AstNode *ast_alias_type(AstFile *f, Token token, AstNode *type) {
|
||||
AstNode *result = make_ast_node(f, AstNode_AliasType);
|
||||
result->AliasType.token = token;
|
||||
result->AliasType.type = type;
|
||||
AstNode *ast_distinct_type(AstFile *f, Token token, AstNode *type) {
|
||||
AstNode *result = make_ast_node(f, AstNode_DistinctType);
|
||||
result->DistinctType.token = token;
|
||||
result->DistinctType.type = type;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
AstNode *ast_poly_type(AstFile *f, Token token, AstNode *type, AstNode *specialization) {
|
||||
AstNode *result = make_ast_node(f, AstNode_PolyType);
|
||||
result->PolyType.token = token;
|
||||
@@ -1277,8 +1276,8 @@ bool is_semicolon_optional_for_node(AstFile *f, AstNode *s) {
|
||||
|
||||
case AstNode_HelperType:
|
||||
return is_semicolon_optional_for_node(f, s->HelperType.type);
|
||||
case AstNode_AliasType:
|
||||
return is_semicolon_optional_for_node(f, s->AliasType.type);
|
||||
case AstNode_DistinctType:
|
||||
return is_semicolon_optional_for_node(f, s->DistinctType.type);
|
||||
|
||||
case AstNode_PointerType:
|
||||
return is_semicolon_optional_for_node(f, s->PointerType.type);
|
||||
@@ -1614,15 +1613,19 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
|
||||
return ast_paren_expr(f, operand, open, close);
|
||||
}
|
||||
|
||||
case Token_distinct: {
|
||||
Token token = expect_token(f, Token_distinct);
|
||||
AstNode *type = parse_type(f);
|
||||
return ast_distinct_type(f, token, type);
|
||||
}
|
||||
|
||||
case Token_Hash: {
|
||||
Token token = expect_token(f, Token_Hash);
|
||||
if (allow_token(f, Token_type)) {
|
||||
return ast_helper_type(f, token, parse_type(f));
|
||||
}
|
||||
Token name = expect_token(f, Token_Ident);
|
||||
if (name.string == "type_alias") {
|
||||
return ast_alias_type(f, token, parse_type(f));
|
||||
} else if (name.string == "run") {
|
||||
if (name.string == "run") {
|
||||
AstNode *expr = parse_expr(f, false);
|
||||
operand = ast_run_expr(f, token, name, expr);
|
||||
if (unparen_expr(expr)->kind != AstNode_CallExpr) {
|
||||
|
||||
@@ -408,7 +408,7 @@ AST_NODE_KIND(_TypeBegin, "", struct {}) \
|
||||
Token token; \
|
||||
AstNode *type; \
|
||||
}) \
|
||||
AST_NODE_KIND(AliasType, "alias type", struct { \
|
||||
AST_NODE_KIND(DistinctType, "distinct type", struct { \
|
||||
Token token; \
|
||||
AstNode *type; \
|
||||
}) \
|
||||
|
||||
@@ -110,6 +110,7 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \
|
||||
TOKEN_KIND(Token_dynamic, "dynamic"), \
|
||||
TOKEN_KIND(Token_cast, "cast"), \
|
||||
TOKEN_KIND(Token_transmute, "transmute"), \
|
||||
TOKEN_KIND(Token_distinct, "distinct"), \
|
||||
TOKEN_KIND(Token_using, "using"), \
|
||||
TOKEN_KIND(Token_inline, "inline"), \
|
||||
TOKEN_KIND(Token_no_inline, "no_inline"), \
|
||||
|
||||
Reference in New Issue
Block a user