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 {
x: int,
y: f32,
z: string,
x: int;
y: f32;
z: string;
}
foo := Foo{123, 0.513, "A string"};
x, y, z := expand_to_tuple(foo);
@@ -176,8 +176,8 @@ default_return_values :: proc() {
};
Entity :: struct {
name: string,
id: u32,
name: string;
id: u32;
}
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};
Entity :: struct {
using position: Vector2,
flags: u64,
id: u64,
batch_index: u32,
slot_index: u32,
portable_id: u32,
derived: any,
using position: Vector2;
flags: u64;
id: u64;
batch_index: u32;
slot_index: u32;
portable_id: u32;
derived: any;
}
Rock :: struct {
using entity: ^Entity,
heavy: bool,
using entity: ^Entity;
heavy: bool;
}
Door :: struct {
using entity: ^Entity,
open: bool,
using entity: ^Entity;
open: bool;
}
Monster :: struct {
using entity: ^Entity,
is_robot: bool,
is_zombie: bool,
using entity: ^Entity;
is_robot: bool;
is_zombie: bool;
}
EntityManager :: struct {
batches: [dynamic]^EntityBatch,
next_portable_id: u32,
batches: [dynamic]^EntityBatch;
next_portable_id: u32;
}
ENTITIES_PER_BATCH :: 16;
EntityBatch :: struct {
data: [ENTITIES_PER_BATCH]Entity,
occupied: [ENTITIES_PER_BATCH]bool,
batch_index: u32,
data: [ENTITIES_PER_BATCH]Entity;
occupied: [ENTITIES_PER_BATCH]bool;
batch_index: u32;
}
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
// 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
CallingConvention :: enum {
Invalid = 0,
@@ -38,75 +32,81 @@ CallingConvention :: enum {
Std = 4,
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 {
types: []^TypeInfo,
names: []string,
offsets: []int, // offsets may not be used in tuples
usings: []bool, // usings may not be used in tuples
packed: bool,
ordered: bool,
custom_align: bool,
types: []^TypeInfo;
names: []string;
offsets: []int; // offsets may not be used in tuples
usings: []bool; // usings may not be used in tuples
packed: bool;
ordered: bool;
custom_align: bool;
}
TypeInfo :: union {
size: int,
align: int,
size: int;
align: int;
Named{name: string, base: ^TypeInfo},
Integer{signed: bool},
Rune{},
Float{},
Complex{},
String{},
Boolean{},
Any{},
Named{name: string; base: ^TypeInfo};
Integer{signed: bool};
Rune{};
Float{};
Complex{};
String{};
Boolean{};
Any{};
Pointer{
elem: ^TypeInfo, // nil -> rawptr
},
Atomic{elem: ^TypeInfo},
elem: ^TypeInfo; // nil -> rawptr
};
Atomic{elem: ^TypeInfo};
Procedure{
params: ^TypeInfo, // TypeInfo.Tuple
results: ^TypeInfo, // TypeInfo.Tuple
variadic: bool,
convention: CallingConvention,
},
params: ^TypeInfo; // TypeInfo.Tuple
results: ^TypeInfo; // TypeInfo.Tuple
variadic: bool;
convention: CallingConvention;
};
Array{
elem: ^TypeInfo,
elem_size: int,
count: int,
},
DynamicArray{elem: ^TypeInfo, elem_size: int},
Slice {elem: ^TypeInfo, elem_size: int},
Vector {elem: ^TypeInfo, elem_size, count: int},
Tuple {using record: TypeInfoRecord}, // Only really used for procedures
Struct {using record: TypeInfoRecord},
RawUnion {using record: TypeInfoRecord},
elem: ^TypeInfo;
elem_size: int;
count: int;
};
DynamicArray{elem: ^TypeInfo; elem_size: int};
Slice {elem: ^TypeInfo; elem_size: int};
Vector {elem: ^TypeInfo; elem_size, count: int};
Tuple {using record: TypeInfoRecord}; // Only really used for procedures
Struct {using record: TypeInfoRecord};
RawUnion {using record: TypeInfoRecord};
Union{
common_fields: struct {
types: []^TypeInfo,
names: []string,
offsets: []int, // offsets may not be used in tuples
},
variant_names: []string,
variant_types: []^TypeInfo,
},
types: []^TypeInfo;
names: []string;
offsets: []int; // offsets may not be used in tuples
};
variant_names: []string;
variant_types: []^TypeInfo;
};
Enum{
base: ^TypeInfo,
names: []string,
values: []TypeInfoEnumValue,
},
base: ^TypeInfo;
names: []string;
values: []TypeInfoEnumValue;
};
Map{
key: ^TypeInfo,
value: ^TypeInfo,
generated_struct: ^TypeInfo,
count: int, // == 0 if dynamic
},
key: ^TypeInfo;
value: ^TypeInfo;
generated_struct: ^TypeInfo;
count: int; // == 0 if dynamic
};
BitField{
names: []string,
bits: []i32,
offsets: []i32,
},
names: []string;
bits: []i32;
offsets: []i32;
};
}
// 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,
old_memory: rawptr, old_size: int, flags: u64 = 0) -> rawptr;
Allocator :: struct #ordered {
procedure: AllocatorProc,
data: rawptr,
procedure: AllocatorProc;
data: rawptr;
}
Context :: struct #ordered {
thread_guid: int,
thread_index: int,
thread_guid: int;
thread_index: int;
allocator: Allocator,
allocator: Allocator;
user_data: rawptr,
user_index: int,
user_data: rawptr;
user_index: int;
}
DEFAULT_ALIGNMENT :: align_of([vector 4]f32);
SourceCodeLocation :: struct {
fully_pathed_filename: string,
line, column: i64,
procedure: string,
fully_pathed_filename: string;
line, column: i64;
procedure: string;
}
__INITIAL_MAP_CAP :: 16;
__MapKey :: struct #ordered {
hash: u128,
str: string,
hash: u128;
str: string;
}
__MapFindResult :: struct #ordered {
hash_index: int,
entry_prev: int,
entry_index: int,
hash_index: int;
entry_prev: int;
entry_index: int;
}
__MapEntryHeader :: struct #ordered {
key: __MapKey,
next: int,
key: __MapKey;
next: int;
/*
value: Value_Type,
value: Value_Type;
*/
}
__MapHeader :: struct #ordered {
m: ^raw.DynamicMap,
is_key_string: bool,
entry_size: int,
entry_align: int,
value_offset: int,
value_size: int,
m: ^raw.DynamicMap;
is_key_string: bool;
entry_size: int;
entry_align: int;
value_offset: 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 {
header := __MapHeader{m = ^raw.DynamicMap(m)};
Entry :: struct {
key: __MapKey,
next: int,
value: V,
key: __MapKey;
next: int;
value: V;
}
_, 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" {
TWords :: raw_union {
all: u128,
using _: struct {lo, hi: u64},
all: u128;
using _: struct {lo, hi: u64};
};
} else {
TWords :: raw_union {
all: u128,
using _: struct {hi, lo: u64},
all: u128;
using _: struct {hi, lo: u64};
};
}
+4 -4
View File
@@ -3,10 +3,10 @@
// NOTE: This is only for floating point printing and nothing else
Decimal :: struct {
digits: [384]u8, // big-endian digits
count: int,
decimal_point: int,
neg, trunc: bool,
digits: [384]u8; // big-endian digits
count: int;
decimal_point: int;
neg, trunc: bool;
}
decimal_to_string :: proc(buf: []u8, a: ^Decimal) -> string {
+15 -15
View File
@@ -10,27 +10,27 @@ import (
_BUFFER_SIZE :: 1<<12;
StringBuffer :: union {
Static {buf: []u8},
Dynamic{buf: [dynamic]u8},
Static {buf: []u8};
Dynamic{buf: [dynamic]u8};
}
FmtInfo :: struct {
minus: bool,
plus: bool,
space: bool,
zero: bool,
hash: bool,
width_set: bool,
prec_set: bool,
minus: bool;
plus: bool;
space: bool;
zero: bool;
hash: bool;
width_set: bool;
prec_set: bool;
width: int,
prec: int,
width: int;
prec: int;
reordered: bool,
good_arg_index: bool,
reordered: bool;
good_arg_index: bool;
buf: ^StringBuffer,
arg: any, // Temporary
buf: ^StringBuffer;
arg: any; // Temporary
}
+7 -7
View File
@@ -68,7 +68,7 @@ align_forward :: proc(ptr: rawptr, align: int) -> rawptr {
AllocationHeader :: struct {
size: int,
size: int;
}
allocation_header_fill :: proc(header: ^AllocationHeader, data: rawptr, size: int) {
@@ -93,15 +93,15 @@ allocation_header :: proc(data: rawptr) -> ^AllocationHeader {
// Custom allocators
Arena :: struct {
backing: Allocator,
offset: int,
memory: []u8,
temp_count: int,
backing: Allocator;
offset: int;
memory: []u8;
temp_count: int;
}
ArenaTempMemory :: struct {
arena: ^Arena,
original_count: int,
arena: ^Arena;
original_count: int;
}
+20 -20
View File
@@ -41,9 +41,9 @@ RTLD_GLOBAL :: 0x100;
args := _alloc_command_line_arguments();
_FileTime :: struct #ordered {
seconds: i64,
nanoseconds: i32,
reserved: i32,
seconds: i64;
nanoseconds: i32;
reserved: i32;
}
// Translated from
@@ -51,27 +51,27 @@ _FileTime :: struct #ordered {
// Validity is not guaranteed.
Stat :: struct #ordered {
device_id: u64, // ID of device containing file
serial: u64, // File serial number
nlink: u32, // Number of hard links
mode: u32, // Mode of the file
uid: u32, // User ID of the file's owner
gid: u32, // Group ID of the file's group
_padding: i32, // 32 bits of padding
rdev: u64, // Device ID, if device
size: i64, // Size of the file, in bytes
block_size: i64, // Optimal bllocksize for I/O
blocks: i64, // Number of 512-byte blocks allocated
device_id: u64; // ID of device containing file
serial: u64; // File serial number
nlink: u32; // Number of hard links
mode: u32; // Mode of the file
uid: u32; // User ID of the file's owner
gid: u32; // Group ID of the file's group
_padding: i32; // 32 bits of padding
rdev: u64; // Device ID, if device
size: i64; // Size of the file, in bytes
block_size: i64; // Optimal bllocksize for I/O
blocks: i64; // Number of 512-byte blocks allocated
last_access: _FileTime, // Time of last access
modified: _FileTime, // Time of last modification
status_change: _FileTime, // Time of last status change
last_access: _FileTime; // Time of last access
modified: _FileTime; // Time of last modification
status_change: _FileTime; // Time of last status change
_reserve1,
_reserve2,
_reserve3: i64,
serial_numbe: u64, // File serial number...? Maybe.
_reserve4: i64,
_reserve3: i64;
serial_numbe: u64; // File serial number...? Maybe.
_reserve4: i64;
};
// File type
+20 -20
View File
@@ -47,32 +47,32 @@ RTLD_FIRST :: 0x100;
args: [dynamic]string;
_FileTime :: struct #ordered {
seconds: i64,
nanoseconds: i64
seconds: i64;
nanoseconds: i64;
}
Stat :: struct #ordered {
device_id : i32, // ID of device containing file
mode : u16, // Mode of the file
nlink : u16, // Number of hard links
serial : u64, // File serial number
uid : u32, // User ID of the file's owner
gid : u32, // Group ID of the file's group
rdev : i32, // Device ID, if device
device_id: i32; // ID of device containing file
mode: u16; // Mode of the file
nlink: u16; // Number of hard links
serial: u64; // File serial number
uid: u32; // User ID of the file's owner
gid: u32; // Group ID of the file's group
rdev: i32; // Device ID, if device
last_access : FileTime, // Time of last access
modified : FileTime, // Time of last modification
status_change : FileTime, // Time of last status change
created : FileTime, // Time of creation
last_access: FileTime; // Time of last access
modified: FileTime; // Time of last modification
status_change: FileTime; // Time of last status change
created: FileTime; // Time of creation
size : i64, // Size of the file, in bytes
blocks : i64, // Number of blocks allocated for the file
block_size: i32, // Optimal blocksize for I/O
flags : u32, // User-defined flags for the file
gen_num : u32, // File generation number ...?
_spare : i32, // RESERVED
size: i64; // Size of the file, in bytes
blocks: i64; // Number of blocks allocated for the file
block_size: i32; // Optimal blocksize for I/O
flags: u32; // User-defined flags for the file
gen_num: u32; // File generation number ...?
_spare: i32; // RESERVED
_reserve1,
_reserve2 : i64, // RESERVED
_reserve2: i64; // RESERVED
};
// File type
+13 -13
View File
@@ -1,28 +1,28 @@
Any :: struct #ordered {
data: rawptr,
type_info: ^TypeInfo,
data: rawptr;
type_info: ^TypeInfo;
};
String :: struct #ordered {
data: ^u8,
len: int,
data: ^u8;
len: int;
};
Slice :: struct #ordered {
data: rawptr,
len: int,
cap: int,
data: rawptr;
len: int;
cap: int;
};
DynamicArray :: struct #ordered {
data: rawptr,
len: int,
cap: int,
allocator: Allocator,
data: rawptr;
len: int;
cap: int;
allocator: Allocator;
};
DynamicMap :: struct #ordered {
hashes: [dynamic]int,
entries: DynamicArray,
hashes: [dynamic]int;
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 {
digits: []u8,
count: int,
decimal_point: int,
neg: bool,
digits: []u8;
count: int;
decimal_point: int;
neg: bool;
}
Float_Info :: struct {
mantbits: uint,
expbits: uint,
bias: int,
FloatInfo :: struct {
mantbits: uint;
expbits: uint;
bias: int;
}
_f16_info := Float_Info{10, 5, -15};
_f32_info := Float_Info{23, 8, -127};
_f64_info := Float_Info{52, 11, -1023};
_f16_info := FloatInfo{10, 5, -15};
_f32_info := FloatInfo{23, 8, -127};
_f64_info := FloatInfo{52, 11, -1023};
generic_ftoa :: proc(buf: []u8, val: f64, fmt: u8, prec, bit_size: int) -> []u8 {
bits: u64;
flt: ^Float_Info;
flt: ^FloatInfo;
match bit_size {
case 32:
bits = u64(transmute(u32, f32(val)));
@@ -346,7 +346,7 @@ format_digits :: proc(buf: []u8, shortest: bool, neg: bool, digs: DecimalSlice,
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
d.count = 0;
return;
+5 -5
View File
@@ -4,14 +4,14 @@ import (
)
Semaphore :: struct {
// _handle: win32.Handle,
// _handle: win32.Handle;
}
Mutex :: struct {
_semaphore: Semaphore,
_counter: i32,
_owner: i32,
_recursion: i32,
_semaphore: Semaphore;
_counter: i32;
_owner: i32;
_recursion: i32;
}
current_thread_id :: proc() -> i32 {
+6 -6
View File
@@ -4,20 +4,20 @@ import (
)
Semaphore :: struct {
_handle: win32.Handle,
_handle: win32.Handle;
}
/*
Mutex :: struct {
_semaphore: Semaphore,
_counter: i32,
_owner: i32,
_recursion: i32,
_semaphore: Semaphore;
_counter: i32;
_owner: i32;
_recursion: i32;
}
*/
Mutex :: struct {
_critical_section: win32.CriticalSection,
_critical_section: win32.CriticalSection;
}
current_thread_id :: proc() -> i32 {
+30 -32
View File
@@ -14,42 +14,40 @@ Hglrc :: Handle;
ColorRef :: u32;
LayerPlaneDescriptor :: struct {
size: u16,
version: u16,
flags: u32,
pixel_type: u8,
color_bits: u8,
red_bits: u8,
red_shift: u8,
green_bits: u8,
green_shift: u8,
blue_bits: u8,
blue_shift: u8,
alpha_bits: u8,
alpha_shift: u8,
accum_bits: u8,
accum_red_bits: u8,
accum_green_bits: u8,
accum_blue_bits: u8,
accum_alpha_bits: u8,
depth_bits: u8,
stencil_bits: u8,
aux_buffers: u8,
layer_type: u8,
reserved: u8,
transparent: ColorRef,
size: u16;
version: u16;
flags: u32;
pixel_type: u8;
color_bits: u8;
red_bits: u8;
red_shift: u8;
green_bits: u8;
green_shift: u8;
blue_bits: u8;
blue_shift: u8;
alpha_bits: u8;
alpha_shift: u8;
accum_bits: u8;
accum_red_bits: u8;
accum_green_bits: u8;
accum_blue_bits: u8;
accum_alpha_bits: u8;
depth_bits: u8;
stencil_bits: u8;
aux_buffers: u8;
layer_type: u8;
reserved: u8;
transparent: ColorRef;
}
PointFloat :: struct {
x, y: f32,
}
PointFloat :: struct {x, y: f32};
Glyph_MetricsFloat :: struct {
black_box_x: f32,
black_box_y: f32,
glyph_origin: PointFloat,
cell_inc_x: f32,
cell_inc_y: f32,
black_box_x: f32;
black_box_y: f32;
glyph_origin: PointFloat;
cell_inc_x: f32;
cell_inc_y: f32;
}
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;
Point :: struct #ordered {
x, y: i32,
x, y: i32;
}
WndClassExA :: struct #ordered {
size, style: u32,
wnd_proc: WndProc,
cls_extra, wnd_extra: i32,
instance: Hinstance,
icon: Hicon,
cursor: Hcursor,
background: Hbrush,
menu_name, class_name: ^u8,
sm: Hicon,
size, style: u32;
wnd_proc: WndProc;
cls_extra, wnd_extra: i32;
instance: Hinstance;
icon: Hicon;
cursor: Hcursor;
background: Hbrush;
menu_name, class_name: ^u8;
sm: Hicon;
}
Msg :: struct #ordered {
hwnd: Hwnd,
message: u32,
wparam: Wparam,
lparam: Lparam,
time: u32,
pt: Point,
hwnd: Hwnd;
message: u32;
wparam: Wparam;
lparam: Lparam;
time: u32;
pt: Point;
}
Rect :: struct #ordered {
left: i32,
top: i32,
right: i32,
bottom: i32,
left: i32;
top: i32;
right: i32;
bottom: i32;
}
Filetime :: struct #ordered {
lo, hi: u32,
lo, hi: u32;
}
Systemtime :: struct #ordered {
year, month: u16,
day_of_week, day: u16,
hour, minute, second, millisecond: u16,
year, month: u16;
day_of_week, day: u16;
hour, minute, second, millisecond: u16;
}
ByHandleFileInformation :: struct #ordered {
file_attributes: u32,
file_attributes: u32;
creation_time,
last_access_time,
last_write_time: Filetime,
last_write_time: Filetime;
volume_serial_number,
file_size_high,
file_size_low,
number_of_links,
file_index_high,
file_index_low: u32,
file_index_low: u32;
}
FileAttributeData :: struct #ordered {
file_attributes: u32,
file_attributes: u32;
creation_time,
last_access_time,
last_write_time: Filetime,
last_write_time: Filetime;
file_size_high,
file_size_low: u32,
file_size_low: u32;
}
FindData :: struct #ordered {
file_attributes: u32,
creation_time: Filetime,
last_access_time: Filetime,
last_write_time: Filetime,
file_size_high: u32,
file_size_low: u32,
reserved0: u32,
reserved1: u32,
file_name: [MAX_PATH]u8,
alternate_file_name: [14]u8,
file_attributes: u32;
creation_time: Filetime;
last_access_time: Filetime;
last_write_time: Filetime;
file_size_high: u32;
file_size_low: u32;
reserved0: u32;
reserved1: u32;
file_name: [MAX_PATH]u8;
alternate_file_name: [14]u8;
}
SecurityAttributes :: struct #ordered {
length: u32,
security_descriptor: rawptr,
inherit_handle: Bool,
length: u32;
security_descriptor: rawptr;
inherit_handle: Bool;
}
@@ -114,7 +114,7 @@ SecurityAttributes :: struct #ordered {
PixelFormatDescriptor :: struct #ordered {
size,
version,
flags: u32,
flags: u32;
pixel_type,
color_bits,
@@ -135,33 +135,33 @@ PixelFormatDescriptor :: struct #ordered {
stencil_bits,
aux_buffers,
layer_type,
reserved: u8,
reserved: u8;
layer_mask,
visible_mask,
damage_mask: u32,
damage_mask: u32;
}
CriticalSection :: struct #ordered {
debug_info: ^CriticalSectionDebug,
debug_info: ^CriticalSectionDebug;
lock_count: i32,
recursion_count: i32,
owning_thread: Handle,
lock_semaphore: Handle,
spin_count: ^u32,
lock_count: i32;
recursion_count: i32;
owning_thread: Handle;
lock_semaphore: Handle;
spin_count: ^u32;
}
CriticalSectionDebug :: struct #ordered {
typ: u16,
creator_back_trace_index: u16,
critical_section: ^CriticalSection,
process_locks_list: ^ListEntry,
entry_count: u32,
contention_count: u32,
flags: u32,
creator_back_trace_index_high: u16,
spare_word: u16,
typ: u16;
creator_back_trace_index: u16;
critical_section: ^CriticalSection;
process_locks_list: ^ListEntry;
entry_count: u32;
contention_count: u32;
flags: u32;
creator_back_trace_index_high: u16;
spare_word: u16;
}
ListEntry :: struct #ordered {flink, blink: ^ListEntry};
@@ -546,35 +546,35 @@ FILE_TYPE_PIPE :: 0x0003;
MonitorInfo :: struct #ordered {
size: u32,
monitor: Rect,
work: Rect,
flags: u32,
size: u32;
monitor: Rect;
work: Rect;
flags: u32;
}
WindowPlacement :: struct #ordered {
length: u32,
flags: u32,
show_cmd: u32,
min_pos: Point,
max_pos: Point,
normal_pos: Rect,
length: u32;
flags: u32;
show_cmd: u32;
min_pos: Point;
max_pos: Point;
normal_pos: Rect;
}
BitmapInfoHeader :: struct #ordered {
size: u32,
width, height: i32,
planes, bit_count: i16,
compression: u32,
size_image: u32,
x_pels_per_meter: i32,
y_pels_per_meter: i32,
clr_used: u32,
clr_important: u32,
size: u32;
width, height: i32;
planes, bit_count: i16;
compression: u32;
size_image: u32;
x_pels_per_meter: i32;
y_pels_per_meter: i32;
clr_used: u32;
clr_important: u32;
}
BitmapInfo :: struct #ordered {
using header: BitmapInfoHeader,
colors: [1]RgbQuad,
using header: BitmapInfoHeader;
colors: [1]RgbQuad;
}
+129 -10
View File
@@ -3354,6 +3354,123 @@ bool parse_expect_field_separator(AstFile *f, AstNode *param) {
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) {
TokenKind separator = Token_Comma;
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");
isize decl_count = 0;
AstNode *fields = parse_record_fields(f, &decl_count, FieldFlag_using, str_lit("struct"));
Token close = expect_token(f, Token_CloseBrace);
isize name_count = 0;
AstNode *fields = parse_struct_field_list(f, &name_count);
Token close = expect_token(f, Token_CloseBrace);
Array<AstNode *> decls = {};
if (fields != nullptr) {
@@ -3639,7 +3757,7 @@ AstNode *parse_type_or_ident(AstFile *f) {
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;
case Token_union: {
@@ -3678,16 +3796,16 @@ AstNode *parse_type_or_ident(AstFile *f) {
AstNode *name = names[0];
Token open = expect_token(f, Token_OpenBrace);
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);
array_add(&variants, ast_union_field(f, name, list));
}
}
if (f->curr_token.kind != Token_Comma) {
if (!parse_expect_struct_separator(f, nullptr)) {
break;
}
next_token(f);
}
Token close = expect_token(f, Token_CloseBrace);
@@ -3699,9 +3817,10 @@ AstNode *parse_type_or_ident(AstFile *f) {
case Token_raw_union: {
Token token = expect_token(f, Token_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"));
Token close = expect_token(f, Token_CloseBrace);
isize decl_count = 0;
AstNode *fields = parse_struct_field_list(f, &decl_count);
Token close = expect_token(f, Token_CloseBrace);
Array<AstNode *> decls = {};
if (fields != nullptr) {