Use semicolons as field delimiters in records

This commit is contained in:
Ginger Bill
2017-07-10 13:49:50 +01:00
parent 81336b58cb
commit 66e4aaffc5
15 changed files with 460 additions and 343 deletions
+24 -24
View File
@@ -42,9 +42,9 @@ general_stuff :: proc() {
Foo :: struct { Foo :: struct {
x: int, x: int;
y: f32, y: f32;
z: string, z: string;
} }
foo := Foo{123, 0.513, "A string"}; foo := Foo{123, 0.513, "A string"};
x, y, z := expand_to_tuple(foo); x, y, z := expand_to_tuple(foo);
@@ -176,8 +176,8 @@ default_return_values :: proc() {
}; };
Entity :: struct { Entity :: struct {
name: string, name: string;
id: u32, id: u32;
} }
some_thing :: proc(input: int) -> (result: ^Entity = nil, err := Error.None) { some_thing :: proc(input: int) -> (result: ^Entity = nil, err := Error.None) {
@@ -256,39 +256,39 @@ explicit_parametric_polymorphic_procedures :: proc() {
Vector2 :: struct {x, y: f32}; Vector2 :: struct {x, y: f32};
Entity :: struct { Entity :: struct {
using position: Vector2, using position: Vector2;
flags: u64, flags: u64;
id: u64, id: u64;
batch_index: u32, batch_index: u32;
slot_index: u32, slot_index: u32;
portable_id: u32, portable_id: u32;
derived: any, derived: any;
} }
Rock :: struct { Rock :: struct {
using entity: ^Entity, using entity: ^Entity;
heavy: bool, heavy: bool;
} }
Door :: struct { Door :: struct {
using entity: ^Entity, using entity: ^Entity;
open: bool, open: bool;
} }
Monster :: struct { Monster :: struct {
using entity: ^Entity, using entity: ^Entity;
is_robot: bool, is_robot: bool;
is_zombie: bool, is_zombie: bool;
} }
EntityManager :: struct { EntityManager :: struct {
batches: [dynamic]^EntityBatch, batches: [dynamic]^EntityBatch;
next_portable_id: u32, next_portable_id: u32;
} }
ENTITIES_PER_BATCH :: 16; ENTITIES_PER_BATCH :: 16;
EntityBatch :: struct { EntityBatch :: struct {
data: [ENTITIES_PER_BATCH]Entity, data: [ENTITIES_PER_BATCH]Entity;
occupied: [ENTITIES_PER_BATCH]bool, occupied: [ENTITIES_PER_BATCH]bool;
batch_index: u32, batch_index: u32;
} }
use_empty_slot :: proc(manager: ^EntityManager, batch: ^EntityBatch) -> ^Entity { use_empty_slot :: proc(manager: ^EntityManager, batch: ^EntityBatch) -> ^Entity {
+88 -88
View File
@@ -23,12 +23,6 @@ import (
// implemented within the compiler rather than in this "preload" file // implemented within the compiler rather than in this "preload" file
// IMPORTANT NOTE(bill): Do not change the order of any of this data
// The compiler relies upon this _exact_ order
TypeInfoEnumValue :: raw_union {
f: f64,
i: i128,
}
// NOTE(bill): This must match the compiler's // NOTE(bill): This must match the compiler's
CallingConvention :: enum { CallingConvention :: enum {
Invalid = 0, Invalid = 0,
@@ -38,75 +32,81 @@ CallingConvention :: enum {
Std = 4, Std = 4,
Fast = 5, Fast = 5,
} }
// IMPORTANT NOTE(bill): Do not change the order of any of this data
// The compiler relies upon this _exact_ order
TypeInfoEnumValue :: raw_union {
f: f64;
i: i128;
}
TypeInfoRecord :: struct #ordered { TypeInfoRecord :: struct #ordered {
types: []^TypeInfo, types: []^TypeInfo;
names: []string, names: []string;
offsets: []int, // offsets may not be used in tuples offsets: []int; // offsets may not be used in tuples
usings: []bool, // usings may not be used in tuples usings: []bool; // usings may not be used in tuples
packed: bool, packed: bool;
ordered: bool, ordered: bool;
custom_align: bool, custom_align: bool;
} }
TypeInfo :: union { TypeInfo :: union {
size: int, size: int;
align: int, align: int;
Named{name: string, base: ^TypeInfo}, Named{name: string; base: ^TypeInfo};
Integer{signed: bool}, Integer{signed: bool};
Rune{}, Rune{};
Float{}, Float{};
Complex{}, Complex{};
String{}, String{};
Boolean{}, Boolean{};
Any{}, Any{};
Pointer{ Pointer{
elem: ^TypeInfo, // nil -> rawptr elem: ^TypeInfo; // nil -> rawptr
}, };
Atomic{elem: ^TypeInfo}, Atomic{elem: ^TypeInfo};
Procedure{ Procedure{
params: ^TypeInfo, // TypeInfo.Tuple params: ^TypeInfo; // TypeInfo.Tuple
results: ^TypeInfo, // TypeInfo.Tuple results: ^TypeInfo; // TypeInfo.Tuple
variadic: bool, variadic: bool;
convention: CallingConvention, convention: CallingConvention;
}, };
Array{ Array{
elem: ^TypeInfo, elem: ^TypeInfo;
elem_size: int, elem_size: int;
count: int, count: int;
}, };
DynamicArray{elem: ^TypeInfo, elem_size: int}, DynamicArray{elem: ^TypeInfo; elem_size: int};
Slice {elem: ^TypeInfo, elem_size: int}, Slice {elem: ^TypeInfo; elem_size: int};
Vector {elem: ^TypeInfo, elem_size, count: int}, Vector {elem: ^TypeInfo; elem_size, count: int};
Tuple {using record: TypeInfoRecord}, // Only really used for procedures Tuple {using record: TypeInfoRecord}; // Only really used for procedures
Struct {using record: TypeInfoRecord}, Struct {using record: TypeInfoRecord};
RawUnion {using record: TypeInfoRecord}, RawUnion {using record: TypeInfoRecord};
Union{ Union{
common_fields: struct { common_fields: struct {
types: []^TypeInfo, types: []^TypeInfo;
names: []string, names: []string;
offsets: []int, // offsets may not be used in tuples offsets: []int; // offsets may not be used in tuples
}, };
variant_names: []string, variant_names: []string;
variant_types: []^TypeInfo, variant_types: []^TypeInfo;
}, };
Enum{ Enum{
base: ^TypeInfo, base: ^TypeInfo;
names: []string, names: []string;
values: []TypeInfoEnumValue, values: []TypeInfoEnumValue;
}, };
Map{ Map{
key: ^TypeInfo, key: ^TypeInfo;
value: ^TypeInfo, value: ^TypeInfo;
generated_struct: ^TypeInfo, generated_struct: ^TypeInfo;
count: int, // == 0 if dynamic count: int; // == 0 if dynamic
}, };
BitField{ BitField{
names: []string, names: []string;
bits: []i32, bits: []i32;
offsets: []i32, offsets: []i32;
}, };
} }
// NOTE(bill): only the ones that are needed (not all types) // NOTE(bill): only the ones that are needed (not all types)
@@ -127,58 +127,58 @@ AllocatorProc :: proc(allocator_data: rawptr, mode: AllocatorMode,
size, alignment: int, size, alignment: int,
old_memory: rawptr, old_size: int, flags: u64 = 0) -> rawptr; old_memory: rawptr, old_size: int, flags: u64 = 0) -> rawptr;
Allocator :: struct #ordered { Allocator :: struct #ordered {
procedure: AllocatorProc, procedure: AllocatorProc;
data: rawptr, data: rawptr;
} }
Context :: struct #ordered { Context :: struct #ordered {
thread_guid: int, thread_guid: int;
thread_index: int, thread_index: int;
allocator: Allocator, allocator: Allocator;
user_data: rawptr, user_data: rawptr;
user_index: int, user_index: int;
} }
DEFAULT_ALIGNMENT :: align_of([vector 4]f32); DEFAULT_ALIGNMENT :: align_of([vector 4]f32);
SourceCodeLocation :: struct { SourceCodeLocation :: struct {
fully_pathed_filename: string, fully_pathed_filename: string;
line, column: i64, line, column: i64;
procedure: string, procedure: string;
} }
__INITIAL_MAP_CAP :: 16; __INITIAL_MAP_CAP :: 16;
__MapKey :: struct #ordered { __MapKey :: struct #ordered {
hash: u128, hash: u128;
str: string, str: string;
} }
__MapFindResult :: struct #ordered { __MapFindResult :: struct #ordered {
hash_index: int, hash_index: int;
entry_prev: int, entry_prev: int;
entry_index: int, entry_index: int;
} }
__MapEntryHeader :: struct #ordered { __MapEntryHeader :: struct #ordered {
key: __MapKey, key: __MapKey;
next: int, next: int;
/* /*
value: Value_Type, value: Value_Type;
*/ */
} }
__MapHeader :: struct #ordered { __MapHeader :: struct #ordered {
m: ^raw.DynamicMap, m: ^raw.DynamicMap;
is_key_string: bool, is_key_string: bool;
entry_size: int, entry_size: int;
entry_align: int, entry_align: int;
value_offset: int, value_offset: int;
value_size: int, value_size: int;
} }
@@ -387,9 +387,9 @@ reserve :: proc(array: ^[dynamic]$T, capacity: int) -> bool {
__get_map_header :: proc(m: ^map[$K]$V) -> __MapHeader #cc_contextless { __get_map_header :: proc(m: ^map[$K]$V) -> __MapHeader #cc_contextless {
header := __MapHeader{m = ^raw.DynamicMap(m)}; header := __MapHeader{m = ^raw.DynamicMap(m)};
Entry :: struct { Entry :: struct {
key: __MapKey, key: __MapKey;
next: int, next: int;
value: V, value: V;
} }
_, is_string := type_info_base(type_info(K)).(^TypeInfo.String); _, is_string := type_info_base(type_info(K)).(^TypeInfo.String);
+4 -4
View File
@@ -7,13 +7,13 @@ __multi3 :: proc(a, b: u128) -> u128 #cc_c #link_name "__multi3" {
when ODIN_ENDIAN == "bit" { when ODIN_ENDIAN == "bit" {
TWords :: raw_union { TWords :: raw_union {
all: u128, all: u128;
using _: struct {lo, hi: u64}, using _: struct {lo, hi: u64};
}; };
} else { } else {
TWords :: raw_union { TWords :: raw_union {
all: u128, all: u128;
using _: struct {hi, lo: u64}, using _: struct {hi, lo: u64};
}; };
} }
+4 -4
View File
@@ -3,10 +3,10 @@
// NOTE: This is only for floating point printing and nothing else // NOTE: This is only for floating point printing and nothing else
Decimal :: struct { Decimal :: struct {
digits: [384]u8, // big-endian digits digits: [384]u8; // big-endian digits
count: int, count: int;
decimal_point: int, decimal_point: int;
neg, trunc: bool, neg, trunc: bool;
} }
decimal_to_string :: proc(buf: []u8, a: ^Decimal) -> string { decimal_to_string :: proc(buf: []u8, a: ^Decimal) -> string {
+15 -15
View File
@@ -10,27 +10,27 @@ import (
_BUFFER_SIZE :: 1<<12; _BUFFER_SIZE :: 1<<12;
StringBuffer :: union { StringBuffer :: union {
Static {buf: []u8}, Static {buf: []u8};
Dynamic{buf: [dynamic]u8}, Dynamic{buf: [dynamic]u8};
} }
FmtInfo :: struct { FmtInfo :: struct {
minus: bool, minus: bool;
plus: bool, plus: bool;
space: bool, space: bool;
zero: bool, zero: bool;
hash: bool, hash: bool;
width_set: bool, width_set: bool;
prec_set: bool, prec_set: bool;
width: int, width: int;
prec: int, prec: int;
reordered: bool, reordered: bool;
good_arg_index: bool, good_arg_index: bool;
buf: ^StringBuffer, buf: ^StringBuffer;
arg: any, // Temporary arg: any; // Temporary
} }
+7 -7
View File
@@ -68,7 +68,7 @@ align_forward :: proc(ptr: rawptr, align: int) -> rawptr {
AllocationHeader :: struct { AllocationHeader :: struct {
size: int, size: int;
} }
allocation_header_fill :: proc(header: ^AllocationHeader, data: rawptr, size: int) { allocation_header_fill :: proc(header: ^AllocationHeader, data: rawptr, size: int) {
@@ -93,15 +93,15 @@ allocation_header :: proc(data: rawptr) -> ^AllocationHeader {
// Custom allocators // Custom allocators
Arena :: struct { Arena :: struct {
backing: Allocator, backing: Allocator;
offset: int, offset: int;
memory: []u8, memory: []u8;
temp_count: int, temp_count: int;
} }
ArenaTempMemory :: struct { ArenaTempMemory :: struct {
arena: ^Arena, arena: ^Arena;
original_count: int, original_count: int;
} }
+20 -20
View File
@@ -41,9 +41,9 @@ RTLD_GLOBAL :: 0x100;
args := _alloc_command_line_arguments(); args := _alloc_command_line_arguments();
_FileTime :: struct #ordered { _FileTime :: struct #ordered {
seconds: i64, seconds: i64;
nanoseconds: i32, nanoseconds: i32;
reserved: i32, reserved: i32;
} }
// Translated from // Translated from
@@ -51,27 +51,27 @@ _FileTime :: struct #ordered {
// Validity is not guaranteed. // Validity is not guaranteed.
Stat :: struct #ordered { Stat :: struct #ordered {
device_id: u64, // ID of device containing file device_id: u64; // ID of device containing file
serial: u64, // File serial number serial: u64; // File serial number
nlink: u32, // Number of hard links nlink: u32; // Number of hard links
mode: u32, // Mode of the file mode: u32; // Mode of the file
uid: u32, // User ID of the file's owner uid: u32; // User ID of the file's owner
gid: u32, // Group ID of the file's group gid: u32; // Group ID of the file's group
_padding: i32, // 32 bits of padding _padding: i32; // 32 bits of padding
rdev: u64, // Device ID, if device rdev: u64; // Device ID, if device
size: i64, // Size of the file, in bytes size: i64; // Size of the file, in bytes
block_size: i64, // Optimal bllocksize for I/O block_size: i64; // Optimal bllocksize for I/O
blocks: i64, // Number of 512-byte blocks allocated blocks: i64; // Number of 512-byte blocks allocated
last_access: _FileTime, // Time of last access last_access: _FileTime; // Time of last access
modified: _FileTime, // Time of last modification modified: _FileTime; // Time of last modification
status_change: _FileTime, // Time of last status change status_change: _FileTime; // Time of last status change
_reserve1, _reserve1,
_reserve2, _reserve2,
_reserve3: i64, _reserve3: i64;
serial_numbe: u64, // File serial number...? Maybe. serial_numbe: u64; // File serial number...? Maybe.
_reserve4: i64, _reserve4: i64;
}; };
// File type // File type
+20 -20
View File
@@ -47,32 +47,32 @@ RTLD_FIRST :: 0x100;
args: [dynamic]string; args: [dynamic]string;
_FileTime :: struct #ordered { _FileTime :: struct #ordered {
seconds: i64, seconds: i64;
nanoseconds: i64 nanoseconds: i64;
} }
Stat :: struct #ordered { Stat :: struct #ordered {
device_id : i32, // ID of device containing file device_id: i32; // ID of device containing file
mode : u16, // Mode of the file mode: u16; // Mode of the file
nlink : u16, // Number of hard links nlink: u16; // Number of hard links
serial : u64, // File serial number serial: u64; // File serial number
uid : u32, // User ID of the file's owner uid: u32; // User ID of the file's owner
gid : u32, // Group ID of the file's group gid: u32; // Group ID of the file's group
rdev : i32, // Device ID, if device rdev: i32; // Device ID, if device
last_access : FileTime, // Time of last access last_access: FileTime; // Time of last access
modified : FileTime, // Time of last modification modified: FileTime; // Time of last modification
status_change : FileTime, // Time of last status change status_change: FileTime; // Time of last status change
created : FileTime, // Time of creation created: FileTime; // Time of creation
size : i64, // Size of the file, in bytes size: i64; // Size of the file, in bytes
blocks : i64, // Number of blocks allocated for the file blocks: i64; // Number of blocks allocated for the file
block_size: i32, // Optimal blocksize for I/O block_size: i32; // Optimal blocksize for I/O
flags : u32, // User-defined flags for the file flags: u32; // User-defined flags for the file
gen_num : u32, // File generation number ...? gen_num: u32; // File generation number ...?
_spare : i32, // RESERVED _spare: i32; // RESERVED
_reserve1, _reserve1,
_reserve2 : i64, // RESERVED _reserve2: i64; // RESERVED
}; };
// File type // File type
+13 -13
View File
@@ -1,28 +1,28 @@
Any :: struct #ordered { Any :: struct #ordered {
data: rawptr, data: rawptr;
type_info: ^TypeInfo, type_info: ^TypeInfo;
}; };
String :: struct #ordered { String :: struct #ordered {
data: ^u8, data: ^u8;
len: int, len: int;
}; };
Slice :: struct #ordered { Slice :: struct #ordered {
data: rawptr, data: rawptr;
len: int, len: int;
cap: int, cap: int;
}; };
DynamicArray :: struct #ordered { DynamicArray :: struct #ordered {
data: rawptr, data: rawptr;
len: int, len: int;
cap: int, cap: int;
allocator: Allocator, allocator: Allocator;
}; };
DynamicMap :: struct #ordered { DynamicMap :: struct #ordered {
hashes: [dynamic]int, hashes: [dynamic]int;
entries: DynamicArray, entries: DynamicArray;
}; };
+13 -13
View File
@@ -211,27 +211,27 @@ append_float :: proc(buf: []u8, f: f64, fmt: u8, prec, bit_size: int) -> string
DecimalSlice :: struct { DecimalSlice :: struct {
digits: []u8, digits: []u8;
count: int, count: int;
decimal_point: int, decimal_point: int;
neg: bool, neg: bool;
} }
Float_Info :: struct { FloatInfo :: struct {
mantbits: uint, mantbits: uint;
expbits: uint, expbits: uint;
bias: int, bias: int;
} }
_f16_info := Float_Info{10, 5, -15}; _f16_info := FloatInfo{10, 5, -15};
_f32_info := Float_Info{23, 8, -127}; _f32_info := FloatInfo{23, 8, -127};
_f64_info := Float_Info{52, 11, -1023}; _f64_info := FloatInfo{52, 11, -1023};
generic_ftoa :: proc(buf: []u8, val: f64, fmt: u8, prec, bit_size: int) -> []u8 { generic_ftoa :: proc(buf: []u8, val: f64, fmt: u8, prec, bit_size: int) -> []u8 {
bits: u64; bits: u64;
flt: ^Float_Info; flt: ^FloatInfo;
match bit_size { match bit_size {
case 32: case 32:
bits = u64(transmute(u32, f32(val))); bits = u64(transmute(u32, f32(val)));
@@ -346,7 +346,7 @@ format_digits :: proc(buf: []u8, shortest: bool, neg: bool, digs: DecimalSlice,
return buf; return buf;
} }
round_shortest :: proc(d: ^Decimal, mant: u64, exp: int, flt: ^Float_Info) { round_shortest :: proc(d: ^Decimal, mant: u64, exp: int, flt: ^FloatInfo) {
if mant == 0 { // If mantissa is zero, the number is zero if mant == 0 { // If mantissa is zero, the number is zero
d.count = 0; d.count = 0;
return; return;
+5 -5
View File
@@ -4,14 +4,14 @@ import (
) )
Semaphore :: struct { Semaphore :: struct {
// _handle: win32.Handle, // _handle: win32.Handle;
} }
Mutex :: struct { Mutex :: struct {
_semaphore: Semaphore, _semaphore: Semaphore;
_counter: i32, _counter: i32;
_owner: i32, _owner: i32;
_recursion: i32, _recursion: i32;
} }
current_thread_id :: proc() -> i32 { current_thread_id :: proc() -> i32 {
+6 -6
View File
@@ -4,20 +4,20 @@ import (
) )
Semaphore :: struct { Semaphore :: struct {
_handle: win32.Handle, _handle: win32.Handle;
} }
/* /*
Mutex :: struct { Mutex :: struct {
_semaphore: Semaphore, _semaphore: Semaphore;
_counter: i32, _counter: i32;
_owner: i32, _owner: i32;
_recursion: i32, _recursion: i32;
} }
*/ */
Mutex :: struct { Mutex :: struct {
_critical_section: win32.CriticalSection, _critical_section: win32.CriticalSection;
} }
current_thread_id :: proc() -> i32 { current_thread_id :: proc() -> i32 {
+30 -32
View File
@@ -14,42 +14,40 @@ Hglrc :: Handle;
ColorRef :: u32; ColorRef :: u32;
LayerPlaneDescriptor :: struct { LayerPlaneDescriptor :: struct {
size: u16, size: u16;
version: u16, version: u16;
flags: u32, flags: u32;
pixel_type: u8, pixel_type: u8;
color_bits: u8, color_bits: u8;
red_bits: u8, red_bits: u8;
red_shift: u8, red_shift: u8;
green_bits: u8, green_bits: u8;
green_shift: u8, green_shift: u8;
blue_bits: u8, blue_bits: u8;
blue_shift: u8, blue_shift: u8;
alpha_bits: u8, alpha_bits: u8;
alpha_shift: u8, alpha_shift: u8;
accum_bits: u8, accum_bits: u8;
accum_red_bits: u8, accum_red_bits: u8;
accum_green_bits: u8, accum_green_bits: u8;
accum_blue_bits: u8, accum_blue_bits: u8;
accum_alpha_bits: u8, accum_alpha_bits: u8;
depth_bits: u8, depth_bits: u8;
stencil_bits: u8, stencil_bits: u8;
aux_buffers: u8, aux_buffers: u8;
layer_type: u8, layer_type: u8;
reserved: u8, reserved: u8;
transparent: ColorRef, transparent: ColorRef;
} }
PointFloat :: struct { PointFloat :: struct {x, y: f32};
x, y: f32,
}
Glyph_MetricsFloat :: struct { Glyph_MetricsFloat :: struct {
black_box_x: f32, black_box_x: f32;
black_box_y: f32, black_box_y: f32;
glyph_origin: PointFloat, glyph_origin: PointFloat;
cell_inc_x: f32, cell_inc_x: f32;
cell_inc_y: f32, cell_inc_y: f32;
} }
CreateContextAttribsARBType :: proc(hdc: Hdc, h_share_context: rawptr, attribList: ^i32) -> Hglrc; CreateContextAttribsARBType :: proc(hdc: Hdc, h_share_context: rawptr, attribList: ^i32) -> Hglrc;
+82 -82
View File
@@ -27,86 +27,86 @@ FALSE: Bool : 0;
TRUE: Bool : 1; TRUE: Bool : 1;
Point :: struct #ordered { Point :: struct #ordered {
x, y: i32, x, y: i32;
} }
WndClassExA :: struct #ordered { WndClassExA :: struct #ordered {
size, style: u32, size, style: u32;
wnd_proc: WndProc, wnd_proc: WndProc;
cls_extra, wnd_extra: i32, cls_extra, wnd_extra: i32;
instance: Hinstance, instance: Hinstance;
icon: Hicon, icon: Hicon;
cursor: Hcursor, cursor: Hcursor;
background: Hbrush, background: Hbrush;
menu_name, class_name: ^u8, menu_name, class_name: ^u8;
sm: Hicon, sm: Hicon;
} }
Msg :: struct #ordered { Msg :: struct #ordered {
hwnd: Hwnd, hwnd: Hwnd;
message: u32, message: u32;
wparam: Wparam, wparam: Wparam;
lparam: Lparam, lparam: Lparam;
time: u32, time: u32;
pt: Point, pt: Point;
} }
Rect :: struct #ordered { Rect :: struct #ordered {
left: i32, left: i32;
top: i32, top: i32;
right: i32, right: i32;
bottom: i32, bottom: i32;
} }
Filetime :: struct #ordered { Filetime :: struct #ordered {
lo, hi: u32, lo, hi: u32;
} }
Systemtime :: struct #ordered { Systemtime :: struct #ordered {
year, month: u16, year, month: u16;
day_of_week, day: u16, day_of_week, day: u16;
hour, minute, second, millisecond: u16, hour, minute, second, millisecond: u16;
} }
ByHandleFileInformation :: struct #ordered { ByHandleFileInformation :: struct #ordered {
file_attributes: u32, file_attributes: u32;
creation_time, creation_time,
last_access_time, last_access_time,
last_write_time: Filetime, last_write_time: Filetime;
volume_serial_number, volume_serial_number,
file_size_high, file_size_high,
file_size_low, file_size_low,
number_of_links, number_of_links,
file_index_high, file_index_high,
file_index_low: u32, file_index_low: u32;
} }
FileAttributeData :: struct #ordered { FileAttributeData :: struct #ordered {
file_attributes: u32, file_attributes: u32;
creation_time, creation_time,
last_access_time, last_access_time,
last_write_time: Filetime, last_write_time: Filetime;
file_size_high, file_size_high,
file_size_low: u32, file_size_low: u32;
} }
FindData :: struct #ordered { FindData :: struct #ordered {
file_attributes: u32, file_attributes: u32;
creation_time: Filetime, creation_time: Filetime;
last_access_time: Filetime, last_access_time: Filetime;
last_write_time: Filetime, last_write_time: Filetime;
file_size_high: u32, file_size_high: u32;
file_size_low: u32, file_size_low: u32;
reserved0: u32, reserved0: u32;
reserved1: u32, reserved1: u32;
file_name: [MAX_PATH]u8, file_name: [MAX_PATH]u8;
alternate_file_name: [14]u8, alternate_file_name: [14]u8;
} }
SecurityAttributes :: struct #ordered { SecurityAttributes :: struct #ordered {
length: u32, length: u32;
security_descriptor: rawptr, security_descriptor: rawptr;
inherit_handle: Bool, inherit_handle: Bool;
} }
@@ -114,7 +114,7 @@ SecurityAttributes :: struct #ordered {
PixelFormatDescriptor :: struct #ordered { PixelFormatDescriptor :: struct #ordered {
size, size,
version, version,
flags: u32, flags: u32;
pixel_type, pixel_type,
color_bits, color_bits,
@@ -135,33 +135,33 @@ PixelFormatDescriptor :: struct #ordered {
stencil_bits, stencil_bits,
aux_buffers, aux_buffers,
layer_type, layer_type,
reserved: u8, reserved: u8;
layer_mask, layer_mask,
visible_mask, visible_mask,
damage_mask: u32, damage_mask: u32;
} }
CriticalSection :: struct #ordered { CriticalSection :: struct #ordered {
debug_info: ^CriticalSectionDebug, debug_info: ^CriticalSectionDebug;
lock_count: i32, lock_count: i32;
recursion_count: i32, recursion_count: i32;
owning_thread: Handle, owning_thread: Handle;
lock_semaphore: Handle, lock_semaphore: Handle;
spin_count: ^u32, spin_count: ^u32;
} }
CriticalSectionDebug :: struct #ordered { CriticalSectionDebug :: struct #ordered {
typ: u16, typ: u16;
creator_back_trace_index: u16, creator_back_trace_index: u16;
critical_section: ^CriticalSection, critical_section: ^CriticalSection;
process_locks_list: ^ListEntry, process_locks_list: ^ListEntry;
entry_count: u32, entry_count: u32;
contention_count: u32, contention_count: u32;
flags: u32, flags: u32;
creator_back_trace_index_high: u16, creator_back_trace_index_high: u16;
spare_word: u16, spare_word: u16;
} }
ListEntry :: struct #ordered {flink, blink: ^ListEntry}; ListEntry :: struct #ordered {flink, blink: ^ListEntry};
@@ -546,35 +546,35 @@ FILE_TYPE_PIPE :: 0x0003;
MonitorInfo :: struct #ordered { MonitorInfo :: struct #ordered {
size: u32, size: u32;
monitor: Rect, monitor: Rect;
work: Rect, work: Rect;
flags: u32, flags: u32;
} }
WindowPlacement :: struct #ordered { WindowPlacement :: struct #ordered {
length: u32, length: u32;
flags: u32, flags: u32;
show_cmd: u32, show_cmd: u32;
min_pos: Point, min_pos: Point;
max_pos: Point, max_pos: Point;
normal_pos: Rect, normal_pos: Rect;
} }
BitmapInfoHeader :: struct #ordered { BitmapInfoHeader :: struct #ordered {
size: u32, size: u32;
width, height: i32, width, height: i32;
planes, bit_count: i16, planes, bit_count: i16;
compression: u32, compression: u32;
size_image: u32, size_image: u32;
x_pels_per_meter: i32, x_pels_per_meter: i32;
y_pels_per_meter: i32, y_pels_per_meter: i32;
clr_used: u32, clr_used: u32;
clr_important: u32, clr_important: u32;
} }
BitmapInfo :: struct #ordered { BitmapInfo :: struct #ordered {
using header: BitmapInfoHeader, using header: BitmapInfoHeader;
colors: [1]RgbQuad, colors: [1]RgbQuad;
} }
+129 -10
View File
@@ -3354,6 +3354,123 @@ bool parse_expect_field_separator(AstFile *f, AstNode *param) {
return false; return false;
} }
bool parse_expect_struct_separator(AstFile *f, AstNode *param) {
Token token = f->curr_token;
if (allow_token(f, Token_Semicolon)) {
return true;
}
if (token.kind == Token_Colon) {
next_token(f);
error(f->curr_token, "Expected a semicolon, got a comma");
return true;
}
if (token.kind == Token_CloseBrace) {
if (token.pos.line == f->prev_token.pos.line) {
return true;
}
}
expect_token_after(f, Token_Semicolon, "field list");
return false;
}
AstNode *parse_struct_field_list(AstFile *f, isize *name_count_) {
CommentGroup docs = f->lead_comment;
Token start_token = f->curr_token;
Array<AstNode *> params = make_ast_node_array(f);
Array<AstNodeAndFlags> list = {}; array_init(&list, heap_allocator());
defer (array_free(&list));
isize total_name_count = 0;
while (f->curr_token.kind != Token_CloseBrace &&
f->curr_token.kind != Token_Colon &&
f->curr_token.kind != Token_EOF) {
u32 flags = parse_field_prefixes(f);
AstNode *param = parse_var_type(f, false, false);
AstNodeAndFlags naf = {param, flags};
array_add(&list, naf);
if (f->curr_token.kind != Token_Comma) {
break;
}
next_token(f);
}
if (f->curr_token.kind == Token_Colon) {
Array<AstNode *> names = convert_to_ident_list(f, list, true); // Copy for semantic reasons
if (names.count == 0) {
syntax_error(f->curr_token, "Empty field declaration");
}
u32 set_flags = 0;
if (list.count > 0) {
set_flags = list[0].flags;
}
set_flags = check_field_prefixes(f, names.count, FieldFlag_using, set_flags);
total_name_count += names.count;
AstNode *type = nullptr;
expect_token_after(f, Token_Colon, "field list");
type = parse_var_type(f, false, false);
parse_expect_struct_separator(f, type);
AstNode *param = ast_field(f, names, type, nullptr, set_flags, docs, f->line_comment);
array_add(&params, param);
while (f->curr_token.kind != Token_CloseBrace &&
f->curr_token.kind != Token_EOF) {
CommentGroup docs = f->lead_comment;
u32 set_flags = parse_field_prefixes(f);
Array<AstNode *> names = parse_ident_list(f);
if (names.count == 0) {
syntax_error(f->curr_token, "Empty field declaration");
break;
}
set_flags = check_field_prefixes(f, names.count, FieldFlag_using, set_flags);
total_name_count += names.count;
AstNode *type = nullptr;
expect_token_after(f, Token_Colon, "field list");
type = parse_var_type(f, false, false);
bool ok = parse_expect_struct_separator(f, param);
AstNode *param = ast_field(f, names, type, nullptr, set_flags, docs, f->line_comment);
array_add(&params, param);
if (!ok) {
break;
}
}
if (name_count_) *name_count_ = total_name_count;
return ast_field_list(f, start_token, params);
}
for_array(i, list) {
Array<AstNode *> names = {};
AstNode *type = list[i].node;
Token token = blank_token;
array_init_count(&names, heap_allocator(), 1);
token.pos = ast_node_token(type).pos;
names[0] = ast_ident(f, token);
u32 flags = check_field_prefixes(f, list.count, FieldFlag_using, list[i].flags);
AstNode *param = ast_field(f, names, list[i].node, nullptr, flags, docs, f->line_comment);
array_add(&params, param);
}
if (name_count_) *name_count_ = total_name_count;
return ast_field_list(f, start_token, params);
}
AstNode *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, TokenKind follow, bool allow_default_parameters) { AstNode *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, TokenKind follow, bool allow_default_parameters) {
TokenKind separator = Token_Comma; TokenKind separator = Token_Comma;
Token start_token = f->curr_token; Token start_token = f->curr_token;
@@ -3629,9 +3746,10 @@ AstNode *parse_type_or_ident(AstFile *f) {
} }
Token open = expect_token_after(f, Token_OpenBrace, "struct"); Token open = expect_token_after(f, Token_OpenBrace, "struct");
isize decl_count = 0;
AstNode *fields = parse_record_fields(f, &decl_count, FieldFlag_using, str_lit("struct")); isize name_count = 0;
Token close = expect_token(f, Token_CloseBrace); AstNode *fields = parse_struct_field_list(f, &name_count);
Token close = expect_token(f, Token_CloseBrace);
Array<AstNode *> decls = {}; Array<AstNode *> decls = {};
if (fields != nullptr) { if (fields != nullptr) {
@@ -3639,7 +3757,7 @@ AstNode *parse_type_or_ident(AstFile *f) {
decls = fields->FieldList.list; decls = fields->FieldList.list;
} }
return ast_struct_type(f, token, decls, decl_count, is_packed, is_ordered, align); return ast_struct_type(f, token, decls, name_count, is_packed, is_ordered, align);
} break; } break;
case Token_union: { case Token_union: {
@@ -3678,16 +3796,16 @@ AstNode *parse_type_or_ident(AstFile *f) {
AstNode *name = names[0]; AstNode *name = names[0];
Token open = expect_token(f, Token_OpenBrace); Token open = expect_token(f, Token_OpenBrace);
isize decl_count = 0; isize decl_count = 0;
AstNode *list = parse_record_fields(f, &decl_count, FieldFlag_using, str_lit("union")); AstNode *list = parse_struct_field_list(f, &decl_count);
// AstNode *list = parse_record_fields(f, &decl_count, FieldFlag_using, str_lit("union"));
Token close = expect_token(f, Token_CloseBrace); Token close = expect_token(f, Token_CloseBrace);
array_add(&variants, ast_union_field(f, name, list)); array_add(&variants, ast_union_field(f, name, list));
} }
} }
if (f->curr_token.kind != Token_Comma) { if (!parse_expect_struct_separator(f, nullptr)) {
break; break;
} }
next_token(f);
} }
Token close = expect_token(f, Token_CloseBrace); Token close = expect_token(f, Token_CloseBrace);
@@ -3699,9 +3817,10 @@ AstNode *parse_type_or_ident(AstFile *f) {
case Token_raw_union: { case Token_raw_union: {
Token token = expect_token(f, Token_raw_union); Token token = expect_token(f, Token_raw_union);
Token open = expect_token_after(f, Token_OpenBrace, "raw_union"); Token open = expect_token_after(f, Token_OpenBrace, "raw_union");
isize decl_count = 0;
AstNode *fields = parse_record_fields(f, &decl_count, FieldFlag_using, str_lit("raw_union")); isize decl_count = 0;
Token close = expect_token(f, Token_CloseBrace); AstNode *fields = parse_struct_field_list(f, &decl_count);
Token close = expect_token(f, Token_CloseBrace);
Array<AstNode *> decls = {}; Array<AstNode *> decls = {};
if (fields != nullptr) { if (fields != nullptr) {