Merge branch 'master' of github.com:odin-lang/odin

This commit is contained in:
Mikkel Hjortshoej
2018-02-07 21:23:28 +01:00
20 changed files with 205 additions and 142 deletions

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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,

View File

@@ -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};

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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,

View File

@@ -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 ---;

View File

@@ -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();
}
}

View File

@@ -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:

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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; \
}) \

View File

@@ -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"), \