mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-13 23:01:24 -07:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 49d337c830 | |||
| 294092979e | |||
| c454ede184 | |||
| d854c5003c |
@@ -4,7 +4,7 @@
|
|||||||
set exe_name=odin.exe
|
set exe_name=odin.exe
|
||||||
|
|
||||||
:: Debug = 0, Release = 1
|
:: Debug = 0, Release = 1
|
||||||
set release_mode=0
|
set release_mode=1
|
||||||
set compiler_flags= -nologo -Oi -TP -fp:fast -fp:except- -Gm- -MP -FC -GS- -EHsc- -GR-
|
set compiler_flags= -nologo -Oi -TP -fp:fast -fp:except- -Gm- -MP -FC -GS- -EHsc- -GR-
|
||||||
|
|
||||||
if %release_mode% EQU 0 ( rem Debug
|
if %release_mode% EQU 0 ( rem Debug
|
||||||
@@ -17,13 +17,10 @@ if %release_mode% EQU 0 ( rem Debug
|
|||||||
set compiler_warnings= ^
|
set compiler_warnings= ^
|
||||||
-W4 -WX ^
|
-W4 -WX ^
|
||||||
-wd4100 -wd4101 -wd4127 -wd4189 ^
|
-wd4100 -wd4101 -wd4127 -wd4189 ^
|
||||||
-wd4201 ^
|
-wd4201 -wd4204 -wd4244 ^
|
||||||
-wd4512
|
-wd4306 ^
|
||||||
rem -wd4100 -wd4101 -wd4127 -wd4189 ^
|
-wd4456 -wd4457 -wd4480 ^
|
||||||
rem -wd4201 -wd4204 -wd4244 ^
|
-wd4505 -wd4512 -wd4550
|
||||||
rem -wd4306 ^
|
|
||||||
rem -wd4456 -wd4457 -wd4480 ^
|
|
||||||
rem -wd4505 -wd4512 -wd4550
|
|
||||||
|
|
||||||
set compiler_includes=
|
set compiler_includes=
|
||||||
set libs= ^
|
set libs= ^
|
||||||
|
|||||||
+87
-87
@@ -10,9 +10,9 @@ import (
|
|||||||
// In general, PascalCase for types and snake_case for values
|
// In general, PascalCase for types and snake_case for values
|
||||||
//
|
//
|
||||||
// Import Name: snake_case (but prefer single word)
|
// Import Name: snake_case (but prefer single word)
|
||||||
// Types: PascalCase
|
// Types: Ada_Case
|
||||||
// Union Variants: PascalCase
|
// Union Variants: Ada_Case
|
||||||
// Enum Values: PascalCase
|
// Enum Values: Ada_Case
|
||||||
// Procedures: snake_case
|
// Procedures: snake_case
|
||||||
// Local Variables: snake_case
|
// Local Variables: snake_case
|
||||||
// Constant Variables: SCREAMING_SNAKE_CASE
|
// Constant Variables: SCREAMING_SNAKE_CASE
|
||||||
@@ -26,7 +26,7 @@ import (
|
|||||||
// implemented within the compiler rather than in this "preload" file
|
// implemented within the compiler rather than in this "preload" file
|
||||||
|
|
||||||
// NOTE(bill): This must match the compiler's
|
// NOTE(bill): This must match the compiler's
|
||||||
CallingConvention :: enum {
|
Calling_Convention :: enum {
|
||||||
Invalid = 0,
|
Invalid = 0,
|
||||||
Odin = 1,
|
Odin = 1,
|
||||||
Contextless = 2,
|
Contextless = 2,
|
||||||
@@ -36,9 +36,9 @@ CallingConvention :: enum {
|
|||||||
}
|
}
|
||||||
// IMPORTANT NOTE(bill): Do not change the order of any of this data
|
// IMPORTANT NOTE(bill): Do not change the order of any of this data
|
||||||
// The compiler relies upon this _exact_ order
|
// The compiler relies upon this _exact_ order
|
||||||
TypeInfo :: struct #ordered {
|
Type_Info :: struct #ordered {
|
||||||
// Core Types
|
// Core Types
|
||||||
EnumValue :: union {
|
Enum_Value :: union {
|
||||||
rune,
|
rune,
|
||||||
i8, i16, i32, i64, i128, int,
|
i8, i16, i32, i64, i128, int,
|
||||||
u8, u16, u32, u64, u128, uint,
|
u8, u16, u32, u64, u128, uint,
|
||||||
@@ -46,7 +46,7 @@ TypeInfo :: struct #ordered {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Variant Types
|
// Variant Types
|
||||||
Named :: struct #ordered {name: string; base: ^TypeInfo};
|
Named :: struct #ordered {name: string; base: ^Type_Info};
|
||||||
Integer :: struct #ordered {signed: bool};
|
Integer :: struct #ordered {signed: bool};
|
||||||
Rune :: struct{};
|
Rune :: struct{};
|
||||||
Float :: struct{};
|
Float :: struct{};
|
||||||
@@ -55,28 +55,28 @@ TypeInfo :: struct #ordered {
|
|||||||
Boolean :: struct{};
|
Boolean :: struct{};
|
||||||
Any :: struct{};
|
Any :: struct{};
|
||||||
Pointer :: struct #ordered {
|
Pointer :: struct #ordered {
|
||||||
elem: ^TypeInfo; // nil -> rawptr
|
elem: ^Type_Info; // nil -> rawptr
|
||||||
};
|
};
|
||||||
Procedure :: struct #ordered {
|
Procedure :: struct #ordered {
|
||||||
params: ^TypeInfo; // TypeInfo.Tuple
|
params: ^Type_Info; // Type_Info.Tuple
|
||||||
results: ^TypeInfo; // TypeInfo.Tuple
|
results: ^Type_Info; // Type_Info.Tuple
|
||||||
variadic: bool;
|
variadic: bool;
|
||||||
convention: CallingConvention;
|
convention: Calling_Convention;
|
||||||
};
|
};
|
||||||
Array :: struct #ordered {
|
Array :: struct #ordered {
|
||||||
elem: ^TypeInfo;
|
elem: ^Type_Info;
|
||||||
elem_size: int;
|
elem_size: int;
|
||||||
count: int;
|
count: int;
|
||||||
};
|
};
|
||||||
DynamicArray :: struct #ordered {elem: ^TypeInfo; elem_size: int};
|
Dynamic_Array :: struct #ordered {elem: ^Type_Info; elem_size: int};
|
||||||
Slice :: struct #ordered {elem: ^TypeInfo; elem_size: int};
|
Slice :: struct #ordered {elem: ^Type_Info; elem_size: int};
|
||||||
Vector :: struct #ordered {elem: ^TypeInfo; elem_size, count: int};
|
Vector :: struct #ordered {elem: ^Type_Info; elem_size, count: int};
|
||||||
Tuple :: struct #ordered { // Only really used for procedures
|
Tuple :: struct #ordered { // Only really used for procedures
|
||||||
types: []^TypeInfo;
|
types: []^Type_Info;
|
||||||
names: []string;
|
names: []string;
|
||||||
};
|
};
|
||||||
Struct :: struct #ordered {
|
Struct :: struct #ordered {
|
||||||
types: []^TypeInfo;
|
types: []^Type_Info;
|
||||||
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
|
||||||
@@ -86,20 +86,20 @@ TypeInfo :: struct #ordered {
|
|||||||
custom_align: bool;
|
custom_align: bool;
|
||||||
};
|
};
|
||||||
Union :: struct #ordered {
|
Union :: struct #ordered {
|
||||||
variants: []^TypeInfo;
|
variants: []^Type_Info;
|
||||||
tag_offset: int;
|
tag_offset: int;
|
||||||
};
|
};
|
||||||
Enum :: struct #ordered {
|
Enum :: struct #ordered {
|
||||||
base: ^TypeInfo;
|
base: ^Type_Info;
|
||||||
names: []string;
|
names: []string;
|
||||||
values: []EnumValue;
|
values: []Enum_Value;
|
||||||
};
|
};
|
||||||
Map :: struct #ordered {
|
Map :: struct #ordered {
|
||||||
key: ^TypeInfo;
|
key: ^Type_Info;
|
||||||
value: ^TypeInfo;
|
value: ^Type_Info;
|
||||||
generated_struct: ^TypeInfo;
|
generated_struct: ^Type_Info;
|
||||||
};
|
};
|
||||||
BitField :: struct #ordered {
|
Bit_Field :: struct #ordered {
|
||||||
names: []string;
|
names: []string;
|
||||||
bits: []i32;
|
bits: []i32;
|
||||||
offsets: []i32;
|
offsets: []i32;
|
||||||
@@ -122,7 +122,7 @@ TypeInfo :: struct #ordered {
|
|||||||
Pointer,
|
Pointer,
|
||||||
Procedure,
|
Procedure,
|
||||||
Array,
|
Array,
|
||||||
DynamicArray,
|
Dynamic_Array,
|
||||||
Slice,
|
Slice,
|
||||||
Vector,
|
Vector,
|
||||||
Tuple,
|
Tuple,
|
||||||
@@ -130,13 +130,13 @@ TypeInfo :: struct #ordered {
|
|||||||
Union,
|
Union,
|
||||||
Enum,
|
Enum,
|
||||||
Map,
|
Map,
|
||||||
BitField,
|
Bit_Field,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE(bill): only the ones that are needed (not all types)
|
// NOTE(bill): only the ones that are needed (not all types)
|
||||||
// This will be set by the compiler
|
// This will be set by the compiler
|
||||||
__type_table: []TypeInfo;
|
__type_table: []Type_Info;
|
||||||
|
|
||||||
__argv__: ^^u8;
|
__argv__: ^^u8;
|
||||||
__argc__: i32;
|
__argc__: i32;
|
||||||
@@ -171,7 +171,7 @@ Context :: struct #ordered {
|
|||||||
|
|
||||||
DEFAULT_ALIGNMENT :: align_of([vector 4]f32);
|
DEFAULT_ALIGNMENT :: align_of([vector 4]f32);
|
||||||
|
|
||||||
SourceCodeLocation :: struct #ordered {
|
Source_Code_Location :: struct #ordered {
|
||||||
file_path: string;
|
file_path: string;
|
||||||
line, column: i64;
|
line, column: i64;
|
||||||
procedure: string;
|
procedure: string;
|
||||||
@@ -180,27 +180,27 @@ SourceCodeLocation :: struct #ordered {
|
|||||||
|
|
||||||
__INITIAL_MAP_CAP :: 16;
|
__INITIAL_MAP_CAP :: 16;
|
||||||
|
|
||||||
__MapKey :: struct #ordered {
|
__Map_Key :: struct #ordered {
|
||||||
hash: u128;
|
hash: u128;
|
||||||
str: string;
|
str: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
__MapFindResult :: struct #ordered {
|
__Map_Find_Result :: struct #ordered {
|
||||||
hash_index: int;
|
hash_index: int;
|
||||||
entry_prev: int;
|
entry_prev: int;
|
||||||
entry_index: int;
|
entry_index: int;
|
||||||
}
|
}
|
||||||
|
|
||||||
__MapEntryHeader :: struct #ordered {
|
__Map_Entry_Header :: struct #ordered {
|
||||||
key: __MapKey;
|
key: __Map_Key;
|
||||||
next: int;
|
next: int;
|
||||||
/*
|
/*
|
||||||
value: Value_Type;
|
value: Value_Type;
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
__MapHeader :: struct #ordered {
|
__Map_Header :: struct #ordered {
|
||||||
m: ^raw.DynamicMap;
|
m: ^raw.Map;
|
||||||
is_key_string: bool;
|
is_key_string: bool;
|
||||||
entry_size: int;
|
entry_size: int;
|
||||||
entry_align: int;
|
entry_align: int;
|
||||||
@@ -210,24 +210,24 @@ __MapHeader :: struct #ordered {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
type_info_base :: proc(info: ^TypeInfo) -> ^TypeInfo {
|
type_info_base :: proc(info: ^Type_Info) -> ^Type_Info {
|
||||||
if info == nil do return nil;
|
if info == nil do return nil;
|
||||||
|
|
||||||
base := info;
|
base := info;
|
||||||
match i in base.variant {
|
match i in base.variant {
|
||||||
case TypeInfo.Named: base = i.base;
|
case Type_Info.Named: base = i.base;
|
||||||
}
|
}
|
||||||
return base;
|
return base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type_info_base_without_enum :: proc(info: ^TypeInfo) -> ^TypeInfo {
|
type_info_base_without_enum :: proc(info: ^Type_Info) -> ^Type_Info {
|
||||||
if info == nil do return nil;
|
if info == nil do return nil;
|
||||||
|
|
||||||
base := info;
|
base := info;
|
||||||
match i in base.variant {
|
match i in base.variant {
|
||||||
case TypeInfo.Named: base = i.base;
|
case Type_Info.Named: base = i.base;
|
||||||
case TypeInfo.Enum: base = i.base;
|
case Type_Info.Enum: base = i.base;
|
||||||
}
|
}
|
||||||
return base;
|
return base;
|
||||||
}
|
}
|
||||||
@@ -243,8 +243,8 @@ foreign __llvm_core {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
make_source_code_location :: proc(file: string, line, column: i64, procedure: string) -> SourceCodeLocation #cc_contextless #inline {
|
make_source_code_location :: proc(file: string, line, column: i64, procedure: string) -> Source_Code_Location #cc_contextless #inline {
|
||||||
return SourceCodeLocation{file, line, column, procedure};
|
return Source_Code_Location{file, line, column, procedure};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -344,7 +344,7 @@ append :: proc(array: ^$T/[dynamic]$E, args: ...E) -> int {
|
|||||||
}
|
}
|
||||||
// TODO(bill): Better error handling for failed reservation
|
// TODO(bill): Better error handling for failed reservation
|
||||||
if ok {
|
if ok {
|
||||||
a := cast(^raw.DynamicArray)array;
|
a := cast(^raw.Dynamic_Array)array;
|
||||||
data := cast(^E)a.data;
|
data := cast(^E)a.data;
|
||||||
assert(data != nil);
|
assert(data != nil);
|
||||||
__mem_copy(data + a.len, &args[0], size_of(E) * arg_len);
|
__mem_copy(data + a.len, &args[0], size_of(E) * arg_len);
|
||||||
@@ -378,7 +378,7 @@ pop :: proc(array: ^$T/[dynamic]$E) -> E #cc_contextless {
|
|||||||
if array == nil do return E{};
|
if array == nil do return E{};
|
||||||
assert(len(array) > 0);
|
assert(len(array) > 0);
|
||||||
res := array[len(array)-1];
|
res := array[len(array)-1];
|
||||||
(^raw.DynamicArray)(array).len -= 1;
|
(^raw.Dynamic_Array)(array).len -= 1;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -386,20 +386,20 @@ clear :: proc(slice: ^$T/[]$E) #cc_contextless #inline {
|
|||||||
if slice != nil do (cast(^raw.Slice)slice).len = 0;
|
if slice != nil do (cast(^raw.Slice)slice).len = 0;
|
||||||
}
|
}
|
||||||
clear :: proc(array: ^$T/[dynamic]$E) #cc_contextless #inline {
|
clear :: proc(array: ^$T/[dynamic]$E) #cc_contextless #inline {
|
||||||
if array != nil do (cast(^raw.DynamicArray)array).len = 0;
|
if array != nil do (cast(^raw.Dynamic_Array)array).len = 0;
|
||||||
}
|
}
|
||||||
clear :: proc(m: ^$T/map[$K]$V) #cc_contextless #inline {
|
clear :: proc(m: ^$T/map[$K]$V) #cc_contextless #inline {
|
||||||
if m == nil do return;
|
if m == nil do return;
|
||||||
raw_map := cast(^raw.DynamicMap)m;
|
raw_map := cast(^raw.Map)m;
|
||||||
hashes := cast(^raw.DynamicArray)&raw_map.hashes;
|
hashes := cast(^raw.Dynamic_Array)&raw_map.hashes;
|
||||||
entries := cast(^raw.DynamicArray)&raw_map.entries;
|
entries := cast(^raw.Dynamic_Array)&raw_map.entries;
|
||||||
hashes.len = 0;
|
hashes.len = 0;
|
||||||
entries.len = 0;
|
entries.len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
reserve :: proc(array: ^$T/[dynamic]$E, capacity: int) -> bool {
|
reserve :: proc(array: ^$T/[dynamic]$E, capacity: int) -> bool {
|
||||||
if array == nil do return false;
|
if array == nil do return false;
|
||||||
a := cast(^raw.DynamicArray)array;
|
a := cast(^raw.Dynamic_Array)array;
|
||||||
|
|
||||||
if capacity <= a.cap do return true;
|
if capacity <= a.cap do return true;
|
||||||
|
|
||||||
@@ -421,15 +421,15 @@ reserve :: proc(array: ^$T/[dynamic]$E, capacity: int) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
__get_map_header :: proc(m: ^$T/map[$K]$V) -> __MapHeader #cc_contextless {
|
__get_map_header :: proc(m: ^$T/map[$K]$V) -> __Map_Header #cc_contextless {
|
||||||
header := __MapHeader{m = cast(^raw.DynamicMap)m};
|
header := __Map_Header{m = cast(^raw.Map)m};
|
||||||
Entry :: struct {
|
Entry :: struct {
|
||||||
key: __MapKey;
|
key: __Map_Key;
|
||||||
next: int;
|
next: int;
|
||||||
value: V;
|
value: V;
|
||||||
}
|
}
|
||||||
|
|
||||||
_, is_string := type_info_base(type_info_of(K)).variant.(TypeInfo.String);
|
_, is_string := type_info_base(type_info_of(K)).variant.(Type_Info.String);
|
||||||
header.is_key_string = is_string;
|
header.is_key_string = is_string;
|
||||||
header.entry_size = size_of(Entry);
|
header.entry_size = size_of(Entry);
|
||||||
header.entry_align = align_of(Entry);
|
header.entry_align = align_of(Entry);
|
||||||
@@ -438,11 +438,11 @@ __get_map_header :: proc(m: ^$T/map[$K]$V) -> __MapHeader #cc_contextless {
|
|||||||
return header;
|
return header;
|
||||||
}
|
}
|
||||||
|
|
||||||
__get_map_key :: proc(key: $K) -> __MapKey #cc_contextless {
|
__get_map_key :: proc(key: $K) -> __Map_Key #cc_contextless {
|
||||||
map_key: __MapKey;
|
map_key: __Map_Key;
|
||||||
ti := type_info_base_without_enum(type_info_of(K));
|
ti := type_info_base_without_enum(type_info_of(K));
|
||||||
match _ in ti {
|
match _ in ti {
|
||||||
case TypeInfo.Integer:
|
case Type_Info.Integer:
|
||||||
match 8*size_of(key) {
|
match 8*size_of(key) {
|
||||||
case 8: map_key.hash = u128(( ^u8)(&key)^);
|
case 8: map_key.hash = u128(( ^u8)(&key)^);
|
||||||
case 16: map_key.hash = u128(( ^u16)(&key)^);
|
case 16: map_key.hash = u128(( ^u16)(&key)^);
|
||||||
@@ -451,17 +451,17 @@ __get_map_key :: proc(key: $K) -> __MapKey #cc_contextless {
|
|||||||
case 128: map_key.hash = u128((^u128)(&key)^);
|
case 128: map_key.hash = u128((^u128)(&key)^);
|
||||||
case: panic("Unhandled integer size");
|
case: panic("Unhandled integer size");
|
||||||
}
|
}
|
||||||
case TypeInfo.Rune:
|
case Type_Info.Rune:
|
||||||
map_key.hash = u128((cast(^rune)&key)^);
|
map_key.hash = u128((cast(^rune)&key)^);
|
||||||
case TypeInfo.Pointer:
|
case Type_Info.Pointer:
|
||||||
map_key.hash = u128(uint((^rawptr)(&key)^));
|
map_key.hash = u128(uint((^rawptr)(&key)^));
|
||||||
case TypeInfo.Float:
|
case Type_Info.Float:
|
||||||
match 8*size_of(key) {
|
match 8*size_of(key) {
|
||||||
case 32: map_key.hash = u128((^u32)(&key)^);
|
case 32: map_key.hash = u128((^u32)(&key)^);
|
||||||
case 64: map_key.hash = u128((^u64)(&key)^);
|
case 64: map_key.hash = u128((^u64)(&key)^);
|
||||||
case: panic("Unhandled float size");
|
case: panic("Unhandled float size");
|
||||||
}
|
}
|
||||||
case TypeInfo.String:
|
case Type_Info.String:
|
||||||
str := (^string)(&key)^;
|
str := (^string)(&key)^;
|
||||||
map_key.hash = __default_hash_string(str);
|
map_key.hash = __default_hash_string(str);
|
||||||
map_key.str = str;
|
map_key.str = str;
|
||||||
@@ -494,10 +494,10 @@ new_clone :: proc(data: $T) -> ^T #inline {
|
|||||||
|
|
||||||
free :: proc(ptr: rawptr) do free_ptr(ptr);
|
free :: proc(ptr: rawptr) do free_ptr(ptr);
|
||||||
free :: proc(str: $T/string) do free_ptr((^raw.String )(&str).data);
|
free :: proc(str: $T/string) do free_ptr((^raw.String )(&str).data);
|
||||||
free :: proc(array: $T/[dynamic]$E) do free_ptr((^raw.DynamicArray)(&array).data);
|
free :: proc(array: $T/[dynamic]$E) do free_ptr((^raw.Dynamic_Array)(&array).data);
|
||||||
free :: proc(slice: $T/[]$E) do free_ptr((^raw.Slice )(&slice).data);
|
free :: proc(slice: $T/[]$E) do free_ptr((^raw.Slice )(&slice).data);
|
||||||
free :: proc(m: $T/map[$K]$V) {
|
free :: proc(m: $T/map[$K]$V) {
|
||||||
raw := cast(^raw.DynamicMap)&m;
|
raw := cast(^raw.Map)&m;
|
||||||
free(raw.hashes);
|
free(raw.hashes);
|
||||||
free(raw.entries.data);
|
free(raw.entries.data);
|
||||||
}
|
}
|
||||||
@@ -525,14 +525,14 @@ make :: proc(T: type/[dynamic]$E, len: int = 8, using location := #caller_locati
|
|||||||
__slice_expr_error(file_path, int(line), int(column), 0, len, cap);
|
__slice_expr_error(file_path, int(line), int(column), 0, len, cap);
|
||||||
data := cast(^E)alloc(cap * size_of(E), align_of(E));
|
data := cast(^E)alloc(cap * size_of(E), align_of(E));
|
||||||
for i in 0..len do (data+i)^ = E{};
|
for i in 0..len do (data+i)^ = E{};
|
||||||
s := raw.DynamicArray{data = data, len = len, cap = cap, allocator = context.allocator};
|
s := raw.Dynamic_Array{data = data, len = len, cap = cap, allocator = context.allocator};
|
||||||
return (cast(^T)&s)^;
|
return (cast(^T)&s)^;
|
||||||
}
|
}
|
||||||
make :: proc(T: type/[dynamic]$E, len, cap: int, using location := #caller_location) -> T {
|
make :: proc(T: type/[dynamic]$E, len, cap: int, using location := #caller_location) -> T {
|
||||||
__slice_expr_error(file_path, int(line), int(column), 0, len, cap);
|
__slice_expr_error(file_path, int(line), int(column), 0, len, cap);
|
||||||
data := cast(^E)alloc(cap * size_of(E), align_of(E));
|
data := cast(^E)alloc(cap * size_of(E), align_of(E));
|
||||||
for i in 0..len do (data+i)^ = E{};
|
for i in 0..len do (data+i)^ = E{};
|
||||||
s := raw.DynamicArray{data = data, len = len, cap = cap, allocator = context.allocator};
|
s := raw.Dynamic_Array{data = data, len = len, cap = cap, allocator = context.allocator};
|
||||||
return (cast(^T)&s)^;
|
return (cast(^T)&s)^;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -671,7 +671,7 @@ __substring_expr_error :: proc(file: string, line, column: int, low, high: int)
|
|||||||
file, line, column, low, high);
|
file, line, column, low, high);
|
||||||
__debug_trap();
|
__debug_trap();
|
||||||
}
|
}
|
||||||
__type_assertion_check :: proc(ok: bool, file: string, line, column: int, from, to: ^TypeInfo) #cc_contextless {
|
__type_assertion_check :: proc(ok: bool, file: string, line, column: int, from, to: ^Type_Info) #cc_contextless {
|
||||||
if ok do return;
|
if ok do return;
|
||||||
fmt.fprintf(os.stderr, "%s(%d:%d) Invalid type_assertion from %T to %T\n",
|
fmt.fprintf(os.stderr, "%s(%d:%d) Invalid type_assertion from %T to %T\n",
|
||||||
file, line, column, from, to);
|
file, line, column, from, to);
|
||||||
@@ -767,7 +767,7 @@ __abs_complex128 :: proc(x: complex128) -> f64 #inline #cc_contextless {
|
|||||||
|
|
||||||
|
|
||||||
__dynamic_array_make :: proc(array_: rawptr, elem_size, elem_align: int, len, cap: int) {
|
__dynamic_array_make :: proc(array_: rawptr, elem_size, elem_align: int, len, cap: int) {
|
||||||
array := cast(^raw.DynamicArray)array_;
|
array := cast(^raw.Dynamic_Array)array_;
|
||||||
array.allocator = context.allocator;
|
array.allocator = context.allocator;
|
||||||
assert(array.allocator.procedure != nil);
|
assert(array.allocator.procedure != nil);
|
||||||
|
|
||||||
@@ -778,7 +778,7 @@ __dynamic_array_make :: proc(array_: rawptr, elem_size, elem_align: int, len, ca
|
|||||||
}
|
}
|
||||||
|
|
||||||
__dynamic_array_reserve :: proc(array_: rawptr, elem_size, elem_align: int, cap: int) -> bool {
|
__dynamic_array_reserve :: proc(array_: rawptr, elem_size, elem_align: int, cap: int) -> bool {
|
||||||
array := cast(^raw.DynamicArray)array_;
|
array := cast(^raw.Dynamic_Array)array_;
|
||||||
|
|
||||||
if cap <= array.cap do return true;
|
if cap <= array.cap do return true;
|
||||||
|
|
||||||
@@ -800,7 +800,7 @@ __dynamic_array_reserve :: proc(array_: rawptr, elem_size, elem_align: int, cap:
|
|||||||
}
|
}
|
||||||
|
|
||||||
__dynamic_array_resize :: proc(array_: rawptr, elem_size, elem_align: int, len: int) -> bool {
|
__dynamic_array_resize :: proc(array_: rawptr, elem_size, elem_align: int, len: int) -> bool {
|
||||||
array := cast(^raw.DynamicArray)array_;
|
array := cast(^raw.Dynamic_Array)array_;
|
||||||
|
|
||||||
ok := __dynamic_array_reserve(array_, elem_size, elem_align, len);
|
ok := __dynamic_array_reserve(array_, elem_size, elem_align, len);
|
||||||
if ok do array.len = len;
|
if ok do array.len = len;
|
||||||
@@ -810,7 +810,7 @@ __dynamic_array_resize :: proc(array_: rawptr, elem_size, elem_align: int, len:
|
|||||||
|
|
||||||
__dynamic_array_append :: proc(array_: rawptr, elem_size, elem_align: int,
|
__dynamic_array_append :: proc(array_: rawptr, elem_size, elem_align: int,
|
||||||
items: rawptr, item_count: int) -> int {
|
items: rawptr, item_count: int) -> int {
|
||||||
array := cast(^raw.DynamicArray)array_;
|
array := cast(^raw.Dynamic_Array)array_;
|
||||||
|
|
||||||
if items == nil do return 0;
|
if items == nil do return 0;
|
||||||
if item_count <= 0 do return 0;
|
if item_count <= 0 do return 0;
|
||||||
@@ -832,7 +832,7 @@ __dynamic_array_append :: proc(array_: rawptr, elem_size, elem_align: int,
|
|||||||
}
|
}
|
||||||
|
|
||||||
__dynamic_array_append_nothing :: proc(array_: rawptr, elem_size, elem_align: int) -> int {
|
__dynamic_array_append_nothing :: proc(array_: rawptr, elem_size, elem_align: int) -> int {
|
||||||
array := cast(^raw.DynamicArray)array_;
|
array := cast(^raw.Dynamic_Array)array_;
|
||||||
|
|
||||||
ok := true;
|
ok := true;
|
||||||
if array.cap <= array.len+1 {
|
if array.cap <= array.len+1 {
|
||||||
@@ -881,18 +881,18 @@ __default_hash :: proc(data: []u8) -> u128 {
|
|||||||
}
|
}
|
||||||
__default_hash_string :: proc(s: string) -> u128 do return __default_hash(cast([]u8)s);
|
__default_hash_string :: proc(s: string) -> u128 do return __default_hash(cast([]u8)s);
|
||||||
|
|
||||||
__dynamic_map_reserve :: proc(using header: __MapHeader, cap: int) {
|
__dynamic_map_reserve :: proc(using header: __Map_Header, cap: int) {
|
||||||
__dynamic_array_reserve(&m.hashes, size_of(int), align_of(int), cap);
|
__dynamic_array_reserve(&m.hashes, size_of(int), align_of(int), cap);
|
||||||
__dynamic_array_reserve(&m.entries, entry_size, entry_align, cap);
|
__dynamic_array_reserve(&m.entries, entry_size, entry_align, cap);
|
||||||
}
|
}
|
||||||
|
|
||||||
__dynamic_map_rehash :: proc(using header: __MapHeader, new_count: int) {
|
__dynamic_map_rehash :: proc(using header: __Map_Header, new_count: int) {
|
||||||
new_header: __MapHeader = header;
|
new_header: __Map_Header = header;
|
||||||
nm: raw.DynamicMap;
|
nm: raw.Map;
|
||||||
new_header.m = &nm;
|
new_header.m = &nm;
|
||||||
|
|
||||||
header_hashes := cast(^raw.DynamicArray)&header.m.hashes;
|
header_hashes := cast(^raw.Dynamic_Array)&header.m.hashes;
|
||||||
nm_hashes := cast(^raw.DynamicArray)&nm.hashes;
|
nm_hashes := cast(^raw.Dynamic_Array)&nm.hashes;
|
||||||
|
|
||||||
__dynamic_array_resize(nm_hashes, size_of(int), align_of(int), new_count);
|
__dynamic_array_resize(nm_hashes, size_of(int), align_of(int), new_count);
|
||||||
__dynamic_array_reserve(&nm.entries, entry_size, entry_align, m.entries.len);
|
__dynamic_array_reserve(&nm.entries, entry_size, entry_align, m.entries.len);
|
||||||
@@ -925,7 +925,7 @@ __dynamic_map_rehash :: proc(using header: __MapHeader, new_count: int) {
|
|||||||
header.m^ = nm;
|
header.m^ = nm;
|
||||||
}
|
}
|
||||||
|
|
||||||
__dynamic_map_get :: proc(h: __MapHeader, key: __MapKey) -> rawptr {
|
__dynamic_map_get :: proc(h: __Map_Header, key: __Map_Key) -> rawptr {
|
||||||
index := __dynamic_map_find(h, key).entry_index;
|
index := __dynamic_map_find(h, key).entry_index;
|
||||||
if index >= 0 {
|
if index >= 0 {
|
||||||
data := cast(^u8)__dynamic_map_get_entry(h, index);
|
data := cast(^u8)__dynamic_map_get_entry(h, index);
|
||||||
@@ -934,7 +934,7 @@ __dynamic_map_get :: proc(h: __MapHeader, key: __MapKey) -> rawptr {
|
|||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
__dynamic_map_set :: proc(using h: __MapHeader, key: __MapKey, value: rawptr) {
|
__dynamic_map_set :: proc(using h: __Map_Header, key: __Map_Key, value: rawptr) {
|
||||||
index: int;
|
index: int;
|
||||||
assert(value != nil);
|
assert(value != nil);
|
||||||
|
|
||||||
@@ -968,17 +968,17 @@ __dynamic_map_set :: proc(using h: __MapHeader, key: __MapKey, value: rawptr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
__dynamic_map_grow :: proc(using h: __MapHeader) {
|
__dynamic_map_grow :: proc(using h: __Map_Header) {
|
||||||
new_count := max(2*m.entries.cap + 8, __INITIAL_MAP_CAP);
|
new_count := max(2*m.entries.cap + 8, __INITIAL_MAP_CAP);
|
||||||
__dynamic_map_rehash(h, new_count);
|
__dynamic_map_rehash(h, new_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
__dynamic_map_full :: proc(using h: __MapHeader) -> bool #inline {
|
__dynamic_map_full :: proc(using h: __Map_Header) -> bool #inline {
|
||||||
return int(0.75 * f64(len(m.hashes))) <= m.entries.cap;
|
return int(0.75 * f64(len(m.hashes))) <= m.entries.cap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
__dynamic_map_hash_equal :: proc(h: __MapHeader, a, b: __MapKey) -> bool {
|
__dynamic_map_hash_equal :: proc(h: __Map_Header, a, b: __Map_Key) -> bool {
|
||||||
if a.hash == b.hash {
|
if a.hash == b.hash {
|
||||||
if h.is_key_string do return a.str == b.str;
|
if h.is_key_string do return a.str == b.str;
|
||||||
return true;
|
return true;
|
||||||
@@ -986,8 +986,8 @@ __dynamic_map_hash_equal :: proc(h: __MapHeader, a, b: __MapKey) -> bool {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
__dynamic_map_find :: proc(using h: __MapHeader, key: __MapKey) -> __MapFindResult {
|
__dynamic_map_find :: proc(using h: __Map_Header, key: __Map_Key) -> __Map_Find_Result {
|
||||||
fr := __MapFindResult{-1, -1, -1};
|
fr := __Map_Find_Result{-1, -1, -1};
|
||||||
if len(m.hashes) > 0 {
|
if len(m.hashes) > 0 {
|
||||||
fr.hash_index = int(key.hash % u128(len(m.hashes)));
|
fr.hash_index = int(key.hash % u128(len(m.hashes)));
|
||||||
fr.entry_index = m.hashes[fr.hash_index];
|
fr.entry_index = m.hashes[fr.hash_index];
|
||||||
@@ -1001,7 +1001,7 @@ __dynamic_map_find :: proc(using h: __MapHeader, key: __MapKey) -> __MapFindResu
|
|||||||
return fr;
|
return fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
__dynamic_map_add_entry :: proc(using h: __MapHeader, key: __MapKey) -> int {
|
__dynamic_map_add_entry :: proc(using h: __Map_Header, key: __Map_Key) -> int {
|
||||||
prev := m.entries.len;
|
prev := m.entries.len;
|
||||||
c := __dynamic_array_append_nothing(&m.entries, entry_size, entry_align);
|
c := __dynamic_array_append_nothing(&m.entries, entry_size, entry_align);
|
||||||
if c != prev {
|
if c != prev {
|
||||||
@@ -1012,18 +1012,18 @@ __dynamic_map_add_entry :: proc(using h: __MapHeader, key: __MapKey) -> int {
|
|||||||
return prev;
|
return prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
__dynamic_map_delete :: proc(using h: __MapHeader, key: __MapKey) {
|
__dynamic_map_delete :: proc(using h: __Map_Header, key: __Map_Key) {
|
||||||
fr := __dynamic_map_find(h, key);
|
fr := __dynamic_map_find(h, key);
|
||||||
if fr.entry_index >= 0 {
|
if fr.entry_index >= 0 {
|
||||||
__dynamic_map_erase(h, fr);
|
__dynamic_map_erase(h, fr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__dynamic_map_get_entry :: proc(using h: __MapHeader, index: int) -> ^__MapEntryHeader {
|
__dynamic_map_get_entry :: proc(using h: __Map_Header, index: int) -> ^__Map_Entry_Header {
|
||||||
return cast(^__MapEntryHeader)(cast(^u8)m.entries.data + index*entry_size);
|
return cast(^__Map_Entry_Header)(cast(^u8)m.entries.data + index*entry_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
__dynamic_map_erase :: proc(using h: __MapHeader, fr: __MapFindResult) {
|
__dynamic_map_erase :: proc(using h: __Map_Header, fr: __Map_Find_Result) {
|
||||||
if fr.entry_prev < 0 {
|
if fr.entry_prev < 0 {
|
||||||
m.hashes[fr.hash_index] = __dynamic_map_get_entry(h, fr.entry_index).next;
|
m.hashes[fr.hash_index] = __dynamic_map_get_entry(h, fr.entry_index).next;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+69
-69
@@ -10,12 +10,12 @@ import (
|
|||||||
|
|
||||||
_BUFFER_SIZE :: 1<<12;
|
_BUFFER_SIZE :: 1<<12;
|
||||||
|
|
||||||
StringBuffer :: union {
|
String_Buffer :: union {
|
||||||
[]u8,
|
[]u8,
|
||||||
[dynamic]u8,
|
[dynamic]u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
FmtInfo :: struct {
|
Fmt_Info :: struct {
|
||||||
minus: bool;
|
minus: bool;
|
||||||
plus: bool;
|
plus: bool;
|
||||||
space: bool;
|
space: bool;
|
||||||
@@ -31,47 +31,47 @@ FmtInfo :: struct {
|
|||||||
reordered: bool;
|
reordered: bool;
|
||||||
good_arg_index: bool;
|
good_arg_index: bool;
|
||||||
|
|
||||||
buf: ^StringBuffer;
|
buf: ^String_Buffer;
|
||||||
arg: any; // Temporary
|
arg: any; // Temporary
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
string_buffer_data :: proc(buf: ^StringBuffer) -> []u8 {
|
string_buffer_data :: proc(buf: ^String_Buffer) -> []u8 {
|
||||||
match b in buf {
|
match b in buf {
|
||||||
case []u8: return b[..];
|
case []u8: return b[..];
|
||||||
case [dynamic]u8: return b[..];
|
case [dynamic]u8: return b[..];
|
||||||
}
|
}
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
string_buffer_data :: proc(buf: StringBuffer) -> []u8 {
|
string_buffer_data :: proc(buf: String_Buffer) -> []u8 {
|
||||||
match b in buf {
|
match b in buf {
|
||||||
case []u8: return b[..];
|
case []u8: return b[..];
|
||||||
case [dynamic]u8: return b[..];
|
case [dynamic]u8: return b[..];
|
||||||
}
|
}
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
to_string :: proc(buf: StringBuffer) -> string {
|
to_string :: proc(buf: String_Buffer) -> string {
|
||||||
return string(string_buffer_data(buf));
|
return string(string_buffer_data(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
write_string :: proc(buf: ^StringBuffer, s: string) {
|
write_string :: proc(buf: ^String_Buffer, s: string) {
|
||||||
write_bytes(buf, cast([]u8)s);
|
write_bytes(buf, cast([]u8)s);
|
||||||
}
|
}
|
||||||
write_bytes :: proc(buf: ^StringBuffer, data: []u8) {
|
write_bytes :: proc(buf: ^String_Buffer, data: []u8) {
|
||||||
match b in buf {
|
match b in buf {
|
||||||
case []u8: append(b, ...data);
|
case []u8: append(b, ...data);
|
||||||
case [dynamic]u8: append(b, ...data);
|
case [dynamic]u8: append(b, ...data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
write_byte :: proc(buf: ^StringBuffer, data: u8) {
|
write_byte :: proc(buf: ^String_Buffer, data: u8) {
|
||||||
match b in buf {
|
match b in buf {
|
||||||
case []u8: append(b, data);
|
case []u8: append(b, data);
|
||||||
case [dynamic]u8: append(b, data);
|
case [dynamic]u8: append(b, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
write_rune :: proc(buf: ^StringBuffer, r: rune) {
|
write_rune :: proc(buf: ^String_Buffer, r: rune) {
|
||||||
if r < utf8.RUNE_SELF {
|
if r < utf8.RUNE_SELF {
|
||||||
write_byte(buf, u8(r));
|
write_byte(buf, u8(r));
|
||||||
return;
|
return;
|
||||||
@@ -81,12 +81,12 @@ write_rune :: proc(buf: ^StringBuffer, r: rune) {
|
|||||||
write_bytes(buf, b[..n]);
|
write_bytes(buf, b[..n]);
|
||||||
}
|
}
|
||||||
|
|
||||||
write_int :: proc(buf: ^StringBuffer, i: i128, base: int) {
|
write_int :: proc(buf: ^String_Buffer, i: i128, base: int) {
|
||||||
b: [129]u8;
|
b: [129]u8;
|
||||||
s := strconv.append_bits(b[..0], u128(i), base, true, 128, strconv.digits, 0);
|
s := strconv.append_bits(b[..0], u128(i), base, true, 128, strconv.digits, 0);
|
||||||
write_string(buf, s);
|
write_string(buf, s);
|
||||||
}
|
}
|
||||||
write_int :: proc(buf: ^StringBuffer, i: i64, base: int) {
|
write_int :: proc(buf: ^String_Buffer, i: i64, base: int) {
|
||||||
b: [129]u8;
|
b: [129]u8;
|
||||||
s := strconv.append_bits(b[..0], u128(i), base, true, 64, strconv.digits, 0);
|
s := strconv.append_bits(b[..0], u128(i), base, true, 64, strconv.digits, 0);
|
||||||
write_string(buf, s);
|
write_string(buf, s);
|
||||||
@@ -96,7 +96,7 @@ write_int :: proc(buf: ^StringBuffer, i: i64, base: int) {
|
|||||||
|
|
||||||
fprint :: proc(fd: os.Handle, args: ...any) -> int {
|
fprint :: proc(fd: os.Handle, args: ...any) -> int {
|
||||||
data: [_BUFFER_SIZE]u8;
|
data: [_BUFFER_SIZE]u8;
|
||||||
buf := StringBuffer(data[..0]);
|
buf := String_Buffer(data[..0]);
|
||||||
sbprint(&buf, ...args);
|
sbprint(&buf, ...args);
|
||||||
res := string_buffer_data(buf);
|
res := string_buffer_data(buf);
|
||||||
os.write(fd, res);
|
os.write(fd, res);
|
||||||
@@ -105,7 +105,7 @@ fprint :: proc(fd: os.Handle, args: ...any) -> int {
|
|||||||
|
|
||||||
fprintln :: proc(fd: os.Handle, args: ...any) -> int {
|
fprintln :: proc(fd: os.Handle, args: ...any) -> int {
|
||||||
data: [_BUFFER_SIZE]u8;
|
data: [_BUFFER_SIZE]u8;
|
||||||
buf := StringBuffer(data[..0]);
|
buf := String_Buffer(data[..0]);
|
||||||
sbprintln(&buf, ...args);
|
sbprintln(&buf, ...args);
|
||||||
res := string_buffer_data(buf);
|
res := string_buffer_data(buf);
|
||||||
os.write(fd, res);
|
os.write(fd, res);
|
||||||
@@ -113,7 +113,7 @@ fprintln :: proc(fd: os.Handle, args: ...any) -> int {
|
|||||||
}
|
}
|
||||||
fprintf :: proc(fd: os.Handle, fmt: string, args: ...any) -> int {
|
fprintf :: proc(fd: os.Handle, fmt: string, args: ...any) -> int {
|
||||||
data: [_BUFFER_SIZE]u8;
|
data: [_BUFFER_SIZE]u8;
|
||||||
buf := StringBuffer(data[..0]);
|
buf := String_Buffer(data[..0]);
|
||||||
sbprintf(&buf, fmt, ...args);
|
sbprintf(&buf, fmt, ...args);
|
||||||
res := string_buffer_data(buf);
|
res := string_buffer_data(buf);
|
||||||
os.write(fd, res);
|
os.write(fd, res);
|
||||||
@@ -133,17 +133,17 @@ printf_err :: proc(fmt: string, args: ...any) -> int { return fprintf(os.stderr
|
|||||||
// aprint* procedures return a string that was allocated with the current context
|
// aprint* procedures return a string that was allocated with the current context
|
||||||
// They must be freed accordingly
|
// They must be freed accordingly
|
||||||
aprint :: proc(args: ...any) -> string {
|
aprint :: proc(args: ...any) -> string {
|
||||||
buf := StringBuffer(make([dynamic]u8));
|
buf := String_Buffer(make([dynamic]u8));
|
||||||
sbprint(&buf, ...args);
|
sbprint(&buf, ...args);
|
||||||
return to_string(buf);
|
return to_string(buf);
|
||||||
}
|
}
|
||||||
aprintln :: proc(args: ...any) -> string {
|
aprintln :: proc(args: ...any) -> string {
|
||||||
buf := StringBuffer(make([dynamic]u8));
|
buf := String_Buffer(make([dynamic]u8));
|
||||||
sbprintln(&buf, ...args);
|
sbprintln(&buf, ...args);
|
||||||
return to_string(buf);
|
return to_string(buf);
|
||||||
}
|
}
|
||||||
aprintf :: proc(fmt: string, args: ...any) -> string {
|
aprintf :: proc(fmt: string, args: ...any) -> string {
|
||||||
buf := StringBuffer(make([dynamic]u8));
|
buf := String_Buffer(make([dynamic]u8));
|
||||||
sbprintf(&buf, fmt, ...args);
|
sbprintf(&buf, fmt, ...args);
|
||||||
return to_string(buf);
|
return to_string(buf);
|
||||||
}
|
}
|
||||||
@@ -151,15 +151,15 @@ aprintf :: proc(fmt: string, args: ...any) -> string {
|
|||||||
|
|
||||||
// bprint* procedures return a string using a buffer from an array
|
// bprint* procedures return a string using a buffer from an array
|
||||||
bprint :: proc(buf: []u8, args: ...any) -> string {
|
bprint :: proc(buf: []u8, args: ...any) -> string {
|
||||||
sb := StringBuffer(buf[..0..len(buf)]);
|
sb := String_Buffer(buf[..0..len(buf)]);
|
||||||
return sbprint(&sb, ...args);
|
return sbprint(&sb, ...args);
|
||||||
}
|
}
|
||||||
bprintln :: proc(buf: []u8, args: ...any) -> string {
|
bprintln :: proc(buf: []u8, args: ...any) -> string {
|
||||||
sb := StringBuffer(buf[..0..len(buf)]);
|
sb := String_Buffer(buf[..0..len(buf)]);
|
||||||
return sbprintln(&sb, ...args);
|
return sbprintln(&sb, ...args);
|
||||||
}
|
}
|
||||||
bprintf :: proc(buf: []u8, fmt: string, args: ...any) -> string {
|
bprintf :: proc(buf: []u8, fmt: string, args: ...any) -> string {
|
||||||
sb := StringBuffer(buf[..0..len(buf)]);
|
sb := String_Buffer(buf[..0..len(buf)]);
|
||||||
return sbprintf(&sb, fmt, ...args);
|
return sbprintf(&sb, fmt, ...args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,17 +168,17 @@ bprintf :: proc(buf: []u8, fmt: string, args: ...any) -> string {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
fprint_type :: proc(fd: os.Handle, info: ^TypeInfo) {
|
fprint_type :: proc(fd: os.Handle, info: ^Type_Info) {
|
||||||
data: [_BUFFER_SIZE]u8;
|
data: [_BUFFER_SIZE]u8;
|
||||||
buf := StringBuffer(data[..0]);
|
buf := String_Buffer(data[..0]);
|
||||||
write_type(&buf, info);
|
write_type(&buf, info);
|
||||||
os.write(fd, string_buffer_data(buf));
|
os.write(fd, string_buffer_data(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
write_type :: proc(buf: ^StringBuffer, ti: ^TypeInfo) {
|
write_type :: proc(buf: ^String_Buffer, ti: ^Type_Info) {
|
||||||
if ti == nil do return;
|
if ti == nil do return;
|
||||||
|
|
||||||
using TypeInfo;
|
using Type_Info;
|
||||||
match info in ti.variant {
|
match info in ti.variant {
|
||||||
case Named:
|
case Named:
|
||||||
write_string(buf, info.name);
|
write_string(buf, info.name);
|
||||||
@@ -252,11 +252,11 @@ write_type :: proc(buf: ^StringBuffer, ti: ^TypeInfo) {
|
|||||||
|
|
||||||
case Array:
|
case Array:
|
||||||
write_string(buf, "[");
|
write_string(buf, "[");
|
||||||
fi := FmtInfo{buf = buf};
|
fi := Fmt_Info{buf = buf};
|
||||||
write_int(buf, i64(info.count), 10);
|
write_int(buf, i64(info.count), 10);
|
||||||
write_string(buf, "]");
|
write_string(buf, "]");
|
||||||
write_type(buf, info.elem);
|
write_type(buf, info.elem);
|
||||||
case DynamicArray:
|
case Dynamic_Array:
|
||||||
write_string(buf, "[dynamic]");
|
write_string(buf, "[dynamic]");
|
||||||
write_type(buf, info.elem);
|
write_type(buf, info.elem);
|
||||||
case Slice:
|
case Slice:
|
||||||
@@ -311,7 +311,7 @@ write_type :: proc(buf: ^StringBuffer, ti: ^TypeInfo) {
|
|||||||
}
|
}
|
||||||
write_string(buf, "}");
|
write_string(buf, "}");
|
||||||
|
|
||||||
case BitField:
|
case Bit_Field:
|
||||||
write_string(buf, "bit_field ");
|
write_string(buf, "bit_field ");
|
||||||
if ti.align != 1 {
|
if ti.align != 1 {
|
||||||
write_string(buf, "#align ");
|
write_string(buf, "#align ");
|
||||||
@@ -352,7 +352,7 @@ _parse_int :: proc(s: string, offset: int) -> (result: int, offset: int, ok: boo
|
|||||||
return result, offset+i, i != 0;
|
return result, offset+i, i != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
_arg_number :: proc(fi: ^FmtInfo, arg_index: int, format: string, offset, arg_count: int) -> (index, offset: int, ok: bool) {
|
_arg_number :: proc(fi: ^Fmt_Info, arg_index: int, format: string, offset, arg_count: int) -> (index, offset: int, ok: bool) {
|
||||||
parse_arg_number :: proc(format: string) -> (int, int, bool) {
|
parse_arg_number :: proc(format: string) -> (int, int, bool) {
|
||||||
if len(format) < 3 do return 0, 1, false;
|
if len(format) < 3 do return 0, 1, false;
|
||||||
|
|
||||||
@@ -408,7 +408,7 @@ int_from_arg :: proc(args: []any, arg_index: int) -> (int, int, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fmt_bad_verb :: proc(using fi: ^FmtInfo, verb: rune) {
|
fmt_bad_verb :: proc(using fi: ^Fmt_Info, verb: rune) {
|
||||||
assert(verb != 'v');
|
assert(verb != 'v');
|
||||||
write_string(buf, "%!");
|
write_string(buf, "%!");
|
||||||
write_rune(buf, verb);
|
write_rune(buf, verb);
|
||||||
@@ -423,7 +423,7 @@ fmt_bad_verb :: proc(using fi: ^FmtInfo, verb: rune) {
|
|||||||
write_byte(buf, ')');
|
write_byte(buf, ')');
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt_bool :: proc(using fi: ^FmtInfo, b: bool, verb: rune) {
|
fmt_bool :: proc(using fi: ^Fmt_Info, b: bool, verb: rune) {
|
||||||
match verb {
|
match verb {
|
||||||
case 't', 'v':
|
case 't', 'v':
|
||||||
s := "false";
|
s := "false";
|
||||||
@@ -435,7 +435,7 @@ fmt_bool :: proc(using fi: ^FmtInfo, b: bool, verb: rune) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fmt_write_padding :: proc(fi: ^FmtInfo, width: int) {
|
fmt_write_padding :: proc(fi: ^Fmt_Info, width: int) {
|
||||||
if width <= 0 do return;
|
if width <= 0 do return;
|
||||||
|
|
||||||
pad_byte: u8 = '0';
|
pad_byte: u8 = '0';
|
||||||
@@ -446,7 +446,7 @@ fmt_write_padding :: proc(fi: ^FmtInfo, width: int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_fmt_int :: proc(fi: ^FmtInfo, u: u128, base: int, is_signed: bool, bit_size: int, digits: string) {
|
_fmt_int :: proc(fi: ^Fmt_Info, u: u128, base: int, is_signed: bool, bit_size: int, digits: string) {
|
||||||
_, neg := strconv.is_integer_negative(u128(u), is_signed, bit_size);
|
_, neg := strconv.is_integer_negative(u128(u), is_signed, bit_size);
|
||||||
|
|
||||||
BUF_SIZE :: 256;
|
BUF_SIZE :: 256;
|
||||||
@@ -486,10 +486,10 @@ _fmt_int :: proc(fi: ^FmtInfo, u: u128, base: int, is_signed: bool, bit_size: in
|
|||||||
buf: [256]u8;
|
buf: [256]u8;
|
||||||
start := 0;
|
start := 0;
|
||||||
|
|
||||||
flags: strconv.IntFlag;
|
flags: strconv.Int_Flag;
|
||||||
if fi.hash && !fi.zero do flags |= strconv.IntFlag.Prefix;
|
if fi.hash && !fi.zero do flags |= strconv.Int_Flag.Prefix;
|
||||||
if fi.plus do flags |= strconv.IntFlag.Plus;
|
if fi.plus do flags |= strconv.Int_Flag.Plus;
|
||||||
if fi.space do flags |= strconv.IntFlag.Space;
|
if fi.space do flags |= strconv.Int_Flag.Space;
|
||||||
s := strconv.append_bits(buf[start..start], u128(u), base, is_signed, bit_size, digits, flags);
|
s := strconv.append_bits(buf[start..start], u128(u), base, is_signed, bit_size, digits, flags);
|
||||||
|
|
||||||
if fi.hash && fi.zero {
|
if fi.hash && fi.zero {
|
||||||
@@ -517,7 +517,7 @@ _fmt_int :: proc(fi: ^FmtInfo, u: u128, base: int, is_signed: bool, bit_size: in
|
|||||||
__DIGITS_LOWER := "0123456789abcdefx";
|
__DIGITS_LOWER := "0123456789abcdefx";
|
||||||
__DIGITS_UPPER := "0123456789ABCDEFX";
|
__DIGITS_UPPER := "0123456789ABCDEFX";
|
||||||
|
|
||||||
fmt_rune :: proc(fi: ^FmtInfo, r: rune, verb: rune) {
|
fmt_rune :: proc(fi: ^Fmt_Info, r: rune, verb: rune) {
|
||||||
match verb {
|
match verb {
|
||||||
case 'c', 'r', 'v':
|
case 'c', 'r', 'v':
|
||||||
write_rune(fi.buf, r);
|
write_rune(fi.buf, r);
|
||||||
@@ -526,7 +526,7 @@ fmt_rune :: proc(fi: ^FmtInfo, r: rune, verb: rune) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt_int :: proc(fi: ^FmtInfo, u: u128, is_signed: bool, bit_size: int, verb: rune) {
|
fmt_int :: proc(fi: ^Fmt_Info, u: u128, is_signed: bool, bit_size: int, verb: rune) {
|
||||||
match verb {
|
match verb {
|
||||||
case 'v': _fmt_int(fi, u, 10, is_signed, bit_size, __DIGITS_LOWER);
|
case 'v': _fmt_int(fi, u, 10, is_signed, bit_size, __DIGITS_LOWER);
|
||||||
case 'b': _fmt_int(fi, u, 2, is_signed, bit_size, __DIGITS_LOWER);
|
case 'b': _fmt_int(fi, u, 2, is_signed, bit_size, __DIGITS_LOWER);
|
||||||
@@ -551,7 +551,7 @@ fmt_int :: proc(fi: ^FmtInfo, u: u128, is_signed: bool, bit_size: int, verb: run
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_pad :: proc(fi: ^FmtInfo, s: string) {
|
_pad :: proc(fi: ^Fmt_Info, s: string) {
|
||||||
if !fi.width_set {
|
if !fi.width_set {
|
||||||
write_string(fi.buf, s);
|
write_string(fi.buf, s);
|
||||||
return;
|
return;
|
||||||
@@ -568,7 +568,7 @@ _pad :: proc(fi: ^FmtInfo, s: string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt_float :: proc(fi: ^FmtInfo, v: f64, bit_size: int, verb: rune) {
|
fmt_float :: proc(fi: ^Fmt_Info, v: f64, bit_size: int, verb: rune) {
|
||||||
match verb {
|
match verb {
|
||||||
// case 'e', 'E', 'f', 'F', 'g', 'G', 'v':
|
// case 'e', 'E', 'f', 'F', 'g', 'G', 'v':
|
||||||
// case 'f', 'F', 'v':
|
// case 'f', 'F', 'v':
|
||||||
@@ -611,7 +611,7 @@ fmt_float :: proc(fi: ^FmtInfo, v: f64, bit_size: int, verb: rune) {
|
|||||||
fmt_bad_verb(fi, verb);
|
fmt_bad_verb(fi, verb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt_string :: proc(fi: ^FmtInfo, s: string, verb: rune) {
|
fmt_string :: proc(fi: ^Fmt_Info, s: string, verb: rune) {
|
||||||
match verb {
|
match verb {
|
||||||
case 's', 'v':
|
case 's', 'v':
|
||||||
write_string(fi.buf, s);
|
write_string(fi.buf, s);
|
||||||
@@ -633,7 +633,7 @@ fmt_string :: proc(fi: ^FmtInfo, s: string, verb: rune) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt_pointer :: proc(fi: ^FmtInfo, p: rawptr, verb: rune) {
|
fmt_pointer :: proc(fi: ^Fmt_Info, p: rawptr, verb: rune) {
|
||||||
match verb {
|
match verb {
|
||||||
case 'p', 'v':
|
case 'p', 'v':
|
||||||
// Okay
|
// Okay
|
||||||
@@ -651,7 +651,7 @@ fmt_pointer :: proc(fi: ^FmtInfo, p: rawptr, verb: rune) {
|
|||||||
enum_value_to_string :: proc(v: any) -> (string, bool) {
|
enum_value_to_string :: proc(v: any) -> (string, bool) {
|
||||||
v.type_info = type_info_base(v.type_info);
|
v.type_info = type_info_base(v.type_info);
|
||||||
|
|
||||||
using TypeInfo;
|
using Type_Info;
|
||||||
match e in v.type_info.variant {
|
match e in v.type_info.variant {
|
||||||
case: return "", false;
|
case: return "", false;
|
||||||
case Enum:
|
case Enum:
|
||||||
@@ -700,7 +700,7 @@ enum_value_to_string :: proc(v: any) -> (string, bool) {
|
|||||||
|
|
||||||
string_to_enum_value :: proc(T: type, s: string) -> (T, bool) {
|
string_to_enum_value :: proc(T: type, s: string) -> (T, bool) {
|
||||||
ti := type_info_base(type_info_of(T));
|
ti := type_info_base(type_info_of(T));
|
||||||
if e, ok := ti.variant.(TypeInfo.Enum); ok {
|
if e, ok := ti.variant.(Type_Info.Enum); ok {
|
||||||
for str, idx in e.names {
|
for str, idx in e.names {
|
||||||
if s == str {
|
if s == str {
|
||||||
// NOTE(bill): Unsafe cast
|
// NOTE(bill): Unsafe cast
|
||||||
@@ -712,13 +712,13 @@ string_to_enum_value :: proc(T: type, s: string) -> (T, bool) {
|
|||||||
return T{}, false;
|
return T{}, false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt_enum :: proc(fi: ^FmtInfo, v: any, verb: rune) {
|
fmt_enum :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
||||||
if v.type_info == nil || v.data == nil {
|
if v.type_info == nil || v.data == nil {
|
||||||
write_string(fi.buf, "<nil>");
|
write_string(fi.buf, "<nil>");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
using TypeInfo;
|
using Type_Info;
|
||||||
match e in v.type_info.variant {
|
match e in v.type_info.variant {
|
||||||
case: fmt_bad_verb(fi, verb);
|
case: fmt_bad_verb(fi, verb);
|
||||||
case Enum:
|
case Enum:
|
||||||
@@ -735,13 +735,13 @@ fmt_enum :: proc(fi: ^FmtInfo, v: any, verb: rune) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fmt_value :: proc(fi: ^FmtInfo, v: any, verb: rune) {
|
fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
||||||
if v.data == nil || v.type_info == nil {
|
if v.data == nil || v.type_info == nil {
|
||||||
write_string(fi.buf, "<nil>");
|
write_string(fi.buf, "<nil>");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
using TypeInfo;
|
using Type_Info;
|
||||||
match info in v.type_info.variant {
|
match info in v.type_info.variant {
|
||||||
case Named:
|
case Named:
|
||||||
match b in info.base.variant {
|
match b in info.base.variant {
|
||||||
@@ -800,8 +800,8 @@ fmt_value :: proc(fi: ^FmtInfo, v: any, verb: rune) {
|
|||||||
case String: fmt_arg(fi, v, verb);
|
case String: fmt_arg(fi, v, verb);
|
||||||
|
|
||||||
case Pointer:
|
case Pointer:
|
||||||
if v.type_info == type_info_of(^TypeInfo) {
|
if v.type_info == type_info_of(^Type_Info) {
|
||||||
write_type(fi.buf, (cast(^^TypeInfo)v.data)^);
|
write_type(fi.buf, (cast(^^Type_Info)v.data)^);
|
||||||
} else {
|
} else {
|
||||||
fmt_pointer(fi, (cast(^rawptr)v.data)^, verb);
|
fmt_pointer(fi, (cast(^rawptr)v.data)^, verb);
|
||||||
}
|
}
|
||||||
@@ -816,10 +816,10 @@ fmt_value :: proc(fi: ^FmtInfo, v: any, verb: rune) {
|
|||||||
fmt_arg(fi, any{rawptr(data), info.elem}, verb);
|
fmt_arg(fi, any{rawptr(data), info.elem}, verb);
|
||||||
}
|
}
|
||||||
|
|
||||||
case DynamicArray:
|
case Dynamic_Array:
|
||||||
write_byte(fi.buf, '[');
|
write_byte(fi.buf, '[');
|
||||||
defer write_byte(fi.buf, ']');
|
defer write_byte(fi.buf, ']');
|
||||||
array := cast(^raw.DynamicArray)v.data;
|
array := cast(^raw.Dynamic_Array)v.data;
|
||||||
for i in 0..array.len {
|
for i in 0..array.len {
|
||||||
if i > 0 do write_string(fi.buf, ", ");
|
if i > 0 do write_string(fi.buf, ", ");
|
||||||
|
|
||||||
@@ -858,9 +858,9 @@ fmt_value :: proc(fi: ^FmtInfo, v: any, verb: rune) {
|
|||||||
write_string(fi.buf, "map[");
|
write_string(fi.buf, "map[");
|
||||||
defer write_byte(fi.buf, ']');
|
defer write_byte(fi.buf, ']');
|
||||||
|
|
||||||
entries := &((cast(^raw.DynamicMap)v.data).entries);
|
entries := &((cast(^raw.Map)v.data).entries);
|
||||||
gs := type_info_base(info.generated_struct).variant.(Struct);
|
gs := type_info_base(info.generated_struct).variant.(Struct);
|
||||||
ed := type_info_base(gs.types[1]).variant.(DynamicArray);
|
ed := type_info_base(gs.types[1]).variant.(Dynamic_Array);
|
||||||
entry_type := ed.elem.variant.(Struct);
|
entry_type := ed.elem.variant.(Struct);
|
||||||
entry_size := ed.elem_size;
|
entry_size := ed.elem_size;
|
||||||
|
|
||||||
@@ -868,12 +868,12 @@ fmt_value :: proc(fi: ^FmtInfo, v: any, verb: rune) {
|
|||||||
if i > 0 do write_string(fi.buf, ", ");
|
if i > 0 do write_string(fi.buf, ", ");
|
||||||
|
|
||||||
data := cast(^u8)entries.data + i*entry_size;
|
data := cast(^u8)entries.data + i*entry_size;
|
||||||
header := cast(^__MapEntryHeader)data;
|
header := cast(^__Map_Entry_Header)data;
|
||||||
|
|
||||||
if types.is_string(info.key) {
|
if types.is_string(info.key) {
|
||||||
write_string(fi.buf, header.key.str);
|
write_string(fi.buf, header.key.str);
|
||||||
} else {
|
} else {
|
||||||
fi := FmtInfo{buf = fi.buf};
|
fi := Fmt_Info{buf = fi.buf};
|
||||||
fmt_arg(&fi, any{rawptr(&header.key.hash), info.key}, 'v');
|
fmt_arg(&fi, any{rawptr(&header.key.hash), info.key}, 'v');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -924,7 +924,7 @@ fmt_value :: proc(fi: ^FmtInfo, v: any, verb: rune) {
|
|||||||
|
|
||||||
case Union:
|
case Union:
|
||||||
data := cast(^u8)v.data;
|
data := cast(^u8)v.data;
|
||||||
tipp := cast(^^TypeInfo)(data + info.tag_offset);
|
tipp := cast(^^Type_Info)(data + info.tag_offset);
|
||||||
if data == nil || tipp == nil {
|
if data == nil || tipp == nil {
|
||||||
write_string(fi.buf, "(union)");
|
write_string(fi.buf, "(union)");
|
||||||
} else {
|
} else {
|
||||||
@@ -942,7 +942,7 @@ fmt_value :: proc(fi: ^FmtInfo, v: any, verb: rune) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt_complex :: proc(fi: ^FmtInfo, c: complex128, bits: int, verb: rune) {
|
fmt_complex :: proc(fi: ^Fmt_Info, c: complex128, bits: int, verb: rune) {
|
||||||
match verb {
|
match verb {
|
||||||
case 'f', 'F', 'v':
|
case 'f', 'F', 'v':
|
||||||
r, i := real(c), imag(c);
|
r, i := real(c), imag(c);
|
||||||
@@ -963,11 +963,11 @@ _u128_to_lo_hi :: proc(a: u128) -> (lo, hi: u64) { return u64(a), u64(a>>64); }
|
|||||||
_i128_to_lo_hi :: proc(a: u128) -> (lo: u64 hi: i64) { return u64(a), i64(a>>64); }
|
_i128_to_lo_hi :: proc(a: u128) -> (lo: u64 hi: i64) { return u64(a), i64(a>>64); }
|
||||||
|
|
||||||
|
|
||||||
do_foo :: proc(fi: ^FmtInfo, f: f64) {
|
do_foo :: proc(fi: ^Fmt_Info, f: f64) {
|
||||||
fmt_string(fi, "Hellope$%!", 'v');
|
fmt_string(fi, "Hellope$%!", 'v');
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt_arg :: proc(fi: ^FmtInfo, arg: any, verb: rune) {
|
fmt_arg :: proc(fi: ^Fmt_Info, arg: any, verb: rune) {
|
||||||
if arg == nil {
|
if arg == nil {
|
||||||
write_string(fi.buf, "<nil>");
|
write_string(fi.buf, "<nil>");
|
||||||
return;
|
return;
|
||||||
@@ -977,7 +977,7 @@ fmt_arg :: proc(fi: ^FmtInfo, arg: any, verb: rune) {
|
|||||||
if verb == 'T' {
|
if verb == 'T' {
|
||||||
ti := arg.type_info;
|
ti := arg.type_info;
|
||||||
match a in arg {
|
match a in arg {
|
||||||
case ^TypeInfo: ti = a;
|
case ^Type_Info: ti = a;
|
||||||
}
|
}
|
||||||
write_type(fi.buf, ti);
|
write_type(fi.buf, ti);
|
||||||
return;
|
return;
|
||||||
@@ -1022,8 +1022,8 @@ fmt_arg :: proc(fi: ^FmtInfo, arg: any, verb: rune) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
sbprint :: proc(buf: ^StringBuffer, args: ...any) -> string {
|
sbprint :: proc(buf: ^String_Buffer, args: ...any) -> string {
|
||||||
fi: FmtInfo;
|
fi: Fmt_Info;
|
||||||
prev_string := false;
|
prev_string := false;
|
||||||
|
|
||||||
fi.buf = buf;
|
fi.buf = buf;
|
||||||
@@ -1039,8 +1039,8 @@ sbprint :: proc(buf: ^StringBuffer, args: ...any) -> string {
|
|||||||
return to_string(buf^);
|
return to_string(buf^);
|
||||||
}
|
}
|
||||||
|
|
||||||
sbprintln :: proc(buf: ^StringBuffer, args: ...any) -> string {
|
sbprintln :: proc(buf: ^String_Buffer, args: ...any) -> string {
|
||||||
fi: FmtInfo;
|
fi: Fmt_Info;
|
||||||
fi.buf = buf;
|
fi.buf = buf;
|
||||||
|
|
||||||
for arg, i in args {
|
for arg, i in args {
|
||||||
@@ -1052,15 +1052,15 @@ sbprintln :: proc(buf: ^StringBuffer, args: ...any) -> string {
|
|||||||
return to_string(buf^);
|
return to_string(buf^);
|
||||||
}
|
}
|
||||||
|
|
||||||
sbprintf :: proc(b: ^StringBuffer, fmt: string, args: ...any) -> string {
|
sbprintf :: proc(b: ^String_Buffer, fmt: string, args: ...any) -> string {
|
||||||
fi: FmtInfo;
|
fi: Fmt_Info;
|
||||||
arg_index: int = 0;
|
arg_index: int = 0;
|
||||||
end := len(fmt);
|
end := len(fmt);
|
||||||
was_prev_index := false;
|
was_prev_index := false;
|
||||||
|
|
||||||
|
|
||||||
for i := 0; i < end; /**/ {
|
for i := 0; i < end; /**/ {
|
||||||
fi = FmtInfo{buf = b, good_arg_index = true};
|
fi = Fmt_Info{buf = b, good_arg_index = true};
|
||||||
|
|
||||||
prev_i := i;
|
prev_i := i;
|
||||||
for i < end && fmt[i] != '%' {
|
for i < end && fmt[i] != '%' {
|
||||||
|
|||||||
+6
-6
@@ -194,7 +194,7 @@ end_arena_temp_memory :: proc(using tmp: ArenaTempMemory) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
align_of_type_info :: proc(type_info: ^TypeInfo) -> int {
|
align_of_type_info :: proc(type_info: ^Type_Info) -> int {
|
||||||
prev_pow2 :: proc(n: i64) -> i64 {
|
prev_pow2 :: proc(n: i64) -> i64 {
|
||||||
if n <= 0 do return 0;
|
if n <= 0 do return 0;
|
||||||
n |= n >> 1;
|
n |= n >> 1;
|
||||||
@@ -208,7 +208,7 @@ align_of_type_info :: proc(type_info: ^TypeInfo) -> int {
|
|||||||
|
|
||||||
WORD_SIZE :: size_of(int);
|
WORD_SIZE :: size_of(int);
|
||||||
MAX_ALIGN :: size_of([vector 64]f64); // TODO(bill): Should these constants be builtin constants?
|
MAX_ALIGN :: size_of([vector 64]f64); // TODO(bill): Should these constants be builtin constants?
|
||||||
using TypeInfo;
|
using Type_Info;
|
||||||
match info in type_info.variant {
|
match info in type_info.variant {
|
||||||
case Named:
|
case Named:
|
||||||
return align_of_type_info(info.base);
|
return align_of_type_info(info.base);
|
||||||
@@ -230,7 +230,7 @@ align_of_type_info :: proc(type_info: ^TypeInfo) -> int {
|
|||||||
return WORD_SIZE;
|
return WORD_SIZE;
|
||||||
case Array:
|
case Array:
|
||||||
return align_of_type_info(info.elem);
|
return align_of_type_info(info.elem);
|
||||||
case DynamicArray:
|
case Dynamic_Array:
|
||||||
return WORD_SIZE;
|
return WORD_SIZE;
|
||||||
case Slice:
|
case Slice:
|
||||||
return WORD_SIZE;
|
return WORD_SIZE;
|
||||||
@@ -259,9 +259,9 @@ align_formula :: proc(size, align: int) -> int {
|
|||||||
return result - result%align;
|
return result - result%align;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_of_type_info :: proc(type_info: ^TypeInfo) -> int {
|
size_of_type_info :: proc(type_info: ^Type_Info) -> int {
|
||||||
WORD_SIZE :: size_of(int);
|
WORD_SIZE :: size_of(int);
|
||||||
using TypeInfo;
|
using Type_Info;
|
||||||
match info in type_info.variant {
|
match info in type_info.variant {
|
||||||
case Named:
|
case Named:
|
||||||
return size_of_type_info(info.base);
|
return size_of_type_info(info.base);
|
||||||
@@ -288,7 +288,7 @@ size_of_type_info :: proc(type_info: ^TypeInfo) -> int {
|
|||||||
align := align_of_type_info(info.elem);
|
align := align_of_type_info(info.elem);
|
||||||
alignment := align_formula(size, align);
|
alignment := align_formula(size, align);
|
||||||
return alignment*(count-1) + size;
|
return alignment*(count-1) + size;
|
||||||
case DynamicArray:
|
case Dynamic_Array:
|
||||||
return size_of(rawptr) + 2*size_of(int) + size_of(Allocator);
|
return size_of(rawptr) + 2*size_of(int) + size_of(Allocator);
|
||||||
case Slice:
|
case Slice:
|
||||||
return 2*WORD_SIZE;
|
return 2*WORD_SIZE;
|
||||||
|
|||||||
+7
-7
@@ -5,7 +5,7 @@ foreign_system_library (
|
|||||||
import "strings.odin";
|
import "strings.odin";
|
||||||
|
|
||||||
Handle :: i32;
|
Handle :: i32;
|
||||||
FileTime :: u64;
|
File_Time :: u64;
|
||||||
Errno :: i32;
|
Errno :: i32;
|
||||||
|
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ RTLD_GLOBAL :: 0x100;
|
|||||||
// "Argv" arguments converted to Odin strings
|
// "Argv" arguments converted to Odin strings
|
||||||
args := _alloc_command_line_arguments();
|
args := _alloc_command_line_arguments();
|
||||||
|
|
||||||
_FileTime :: struct #ordered {
|
_File_Time :: struct #ordered {
|
||||||
seconds: i64;
|
seconds: i64;
|
||||||
nanoseconds: i32;
|
nanoseconds: i32;
|
||||||
reserved: i32;
|
reserved: i32;
|
||||||
@@ -63,9 +63,9 @@ Stat :: struct #ordered {
|
|||||||
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: _File_Time; // Time of last access
|
||||||
modified: _FileTime; // Time of last modification
|
modified: _File_Time; // Time of last modification
|
||||||
status_change: _FileTime; // Time of last status change
|
status_change: _File_Time; // Time of last status change
|
||||||
|
|
||||||
_reserve1,
|
_reserve1,
|
||||||
_reserve2,
|
_reserve2,
|
||||||
@@ -195,8 +195,8 @@ stdout: Handle = 1;
|
|||||||
stderr: Handle = 2;
|
stderr: Handle = 2;
|
||||||
|
|
||||||
/* TODO(zangent): Implement these!
|
/* TODO(zangent): Implement these!
|
||||||
last_write_time :: proc(fd: Handle) -> FileTime {}
|
last_write_time :: proc(fd: Handle) -> File_Time {}
|
||||||
last_write_time_by_name :: proc(name: string) -> FileTime {}
|
last_write_time_by_name :: proc(name: string) -> File_Time {}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
stat :: proc(path: string) -> (Stat, int) #inline {
|
stat :: proc(path: string) -> (Stat, int) #inline {
|
||||||
|
|||||||
+12
-12
@@ -2,7 +2,7 @@ import win32 "sys/windows.odin";
|
|||||||
import "mem.odin";
|
import "mem.odin";
|
||||||
|
|
||||||
Handle :: int;
|
Handle :: int;
|
||||||
FileTime :: u64;
|
File_Time :: u64;
|
||||||
|
|
||||||
|
|
||||||
INVALID_HANDLE: Handle : -1;
|
INVALID_HANDLE: Handle : -1;
|
||||||
@@ -75,8 +75,8 @@ open :: proc(path: string, mode: int = O_RDONLY, perm: u32 = 0) -> (Handle, Errn
|
|||||||
}
|
}
|
||||||
|
|
||||||
share_mode := u32(win32.FILE_SHARE_READ|win32.FILE_SHARE_WRITE);
|
share_mode := u32(win32.FILE_SHARE_READ|win32.FILE_SHARE_WRITE);
|
||||||
sa: ^win32.SecurityAttributes = nil;
|
sa: ^win32.Security_Attributes = nil;
|
||||||
sa_inherit := win32.SecurityAttributes{length = size_of(win32.SecurityAttributes), inherit_handle = 1};
|
sa_inherit := win32.Security_Attributes{length = size_of(win32.Security_Attributes), inherit_handle = 1};
|
||||||
if mode&O_CLOEXEC == 0 {
|
if mode&O_CLOEXEC == 0 {
|
||||||
sa = &sa_inherit;
|
sa = &sa_inherit;
|
||||||
}
|
}
|
||||||
@@ -202,17 +202,17 @@ get_std_handle :: proc(h: int) -> Handle {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
last_write_time :: proc(fd: Handle) -> FileTime {
|
last_write_time :: proc(fd: Handle) -> File_Time {
|
||||||
file_info: win32.ByHandleFileInformation;
|
file_info: win32.By_Handle_File_Information;
|
||||||
win32.get_file_information_by_handle(win32.Handle(fd), &file_info);
|
win32.get_file_information_by_handle(win32.Handle(fd), &file_info);
|
||||||
lo := FileTime(file_info.last_write_time.lo);
|
lo := File_Time(file_info.last_write_time.lo);
|
||||||
hi := FileTime(file_info.last_write_time.hi);
|
hi := File_Time(file_info.last_write_time.hi);
|
||||||
return lo | hi << 32;
|
return lo | hi << 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
last_write_time_by_name :: proc(name: string) -> FileTime {
|
last_write_time_by_name :: proc(name: string) -> File_Time {
|
||||||
last_write_time: win32.Filetime;
|
last_write_time: win32.Filetime;
|
||||||
data: win32.FileAttributeData;
|
data: win32.File_Attribute_Data;
|
||||||
buf: [1024]u8;
|
buf: [1024]u8;
|
||||||
|
|
||||||
assert(len(buf) > len(name));
|
assert(len(buf) > len(name));
|
||||||
@@ -223,8 +223,8 @@ last_write_time_by_name :: proc(name: string) -> FileTime {
|
|||||||
last_write_time = data.last_write_time;
|
last_write_time = data.last_write_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
l := FileTime(last_write_time.lo);
|
l := File_Time(last_write_time.lo);
|
||||||
h := FileTime(last_write_time.hi);
|
h := File_Time(last_write_time.hi);
|
||||||
return l | h << 32;
|
return l | h << 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -284,7 +284,7 @@ _alloc_command_line_arguments :: proc() -> []string {
|
|||||||
j += 1;
|
j += 1;
|
||||||
case 0xd800 <= str[j] && str[j] < 0xdc00:
|
case 0xd800 <= str[j] && str[j] < 0xdc00:
|
||||||
if i+4 > len do return "";
|
if i+4 > len do return "";
|
||||||
c := rune((str[j] - 0xd800) << 10) + rune((str[j+1]) - 0xdc00) + 0x10000;
|
c := rune((str[j] - 0xd800) << 10) + rune((str[j+1]) - 0xdc00) + 0x10000;
|
||||||
buf[i] = u8(0xf0 + (c >> 18)); i += 1;
|
buf[i] = u8(0xf0 + (c >> 18)); i += 1;
|
||||||
buf[i] = u8(0x80 + ((c >> 12) & 0x3f)); i += 1;
|
buf[i] = u8(0x80 + ((c >> 12) & 0x3f)); i += 1;
|
||||||
buf[i] = u8(0x80 + ((c >> 6) & 0x3f)); i += 1;
|
buf[i] = u8(0x80 + ((c >> 6) & 0x3f)); i += 1;
|
||||||
|
|||||||
+8
-8
@@ -6,7 +6,7 @@ foreign_system_library (
|
|||||||
import "strings.odin";
|
import "strings.odin";
|
||||||
|
|
||||||
Handle :: i32;
|
Handle :: i32;
|
||||||
FileTime :: u64;
|
File_Time :: u64;
|
||||||
Errno :: int;
|
Errno :: int;
|
||||||
|
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ RTLD_FIRST :: 0x100;
|
|||||||
|
|
||||||
args: [dynamic]string;
|
args: [dynamic]string;
|
||||||
|
|
||||||
_FileTime :: struct #ordered {
|
_File_Time :: struct #ordered {
|
||||||
seconds: i64;
|
seconds: i64;
|
||||||
nanoseconds: i64;
|
nanoseconds: i64;
|
||||||
}
|
}
|
||||||
@@ -60,10 +60,10 @@ Stat :: struct #ordered {
|
|||||||
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: File_Time; // Time of last access
|
||||||
modified: FileTime; // Time of last modification
|
modified: File_Time; // Time of last modification
|
||||||
status_change: FileTime; // Time of last status change
|
status_change: File_Time; // Time of last status change
|
||||||
created: FileTime; // Time of creation
|
created: File_Time; // 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
|
||||||
@@ -212,8 +212,8 @@ stdout: Handle = 1; // get_std_handle(win32.STD_OUTPUT_HANDLE);
|
|||||||
stderr: Handle = 2; // get_std_handle(win32.STD_ERROR_HANDLE);
|
stderr: Handle = 2; // get_std_handle(win32.STD_ERROR_HANDLE);
|
||||||
|
|
||||||
/* TODO(zangent): Implement these!
|
/* TODO(zangent): Implement these!
|
||||||
last_write_time :: proc(fd: Handle) -> FileTime {}
|
last_write_time :: proc(fd: Handle) -> File_Time {}
|
||||||
last_write_time_by_name :: proc(name: string) -> FileTime {}
|
last_write_time_by_name :: proc(name: string) -> File_Time {}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
stat :: proc(path: string) -> (Stat, bool) #inline {
|
stat :: proc(path: string) -> (Stat, bool) #inline {
|
||||||
|
|||||||
+4
-4
@@ -1,6 +1,6 @@
|
|||||||
Any :: struct #ordered {
|
Any :: struct #ordered {
|
||||||
data: rawptr;
|
data: rawptr;
|
||||||
type_info: ^TypeInfo;
|
type_info: ^Type_Info;
|
||||||
};
|
};
|
||||||
|
|
||||||
String :: struct #ordered {
|
String :: struct #ordered {
|
||||||
@@ -14,15 +14,15 @@ Slice :: struct #ordered {
|
|||||||
cap: int;
|
cap: int;
|
||||||
};
|
};
|
||||||
|
|
||||||
DynamicArray :: struct #ordered {
|
Dynamic_Array :: struct #ordered {
|
||||||
data: rawptr;
|
data: rawptr;
|
||||||
len: int;
|
len: int;
|
||||||
cap: int;
|
cap: int;
|
||||||
allocator: Allocator;
|
allocator: Allocator;
|
||||||
};
|
};
|
||||||
|
|
||||||
DynamicMap :: struct #ordered {
|
Map :: struct #ordered {
|
||||||
hashes: [dynamic]int;
|
hashes: [dynamic]int;
|
||||||
entries: DynamicArray;
|
entries: Dynamic_Array;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+5
-5
@@ -1,6 +1,6 @@
|
|||||||
import . "decimal.odin";
|
import . "decimal.odin";
|
||||||
|
|
||||||
IntFlag :: enum {
|
Int_Flag :: enum {
|
||||||
Prefix = 1<<0,
|
Prefix = 1<<0,
|
||||||
Plus = 1<<1,
|
Plus = 1<<1,
|
||||||
Space = 1<<2,
|
Space = 1<<2,
|
||||||
@@ -445,7 +445,7 @@ is_integer_negative :: proc(u: u128, is_signed: bool, bit_size: int) -> (unsigne
|
|||||||
return u, neg;
|
return u, neg;
|
||||||
}
|
}
|
||||||
|
|
||||||
append_bits :: proc(buf: []u8, u: u128, base: int, is_signed: bool, bit_size: int, digits: string, flags: IntFlag) -> string {
|
append_bits :: proc(buf: []u8, u: u128, base: int, is_signed: bool, bit_size: int, digits: string, flags: Int_Flag) -> string {
|
||||||
if base < 2 || base > MAX_BASE {
|
if base < 2 || base > MAX_BASE {
|
||||||
panic("strconv: illegal base passed to append_bits");
|
panic("strconv: illegal base passed to append_bits");
|
||||||
}
|
}
|
||||||
@@ -461,7 +461,7 @@ append_bits :: proc(buf: []u8, u: u128, base: int, is_signed: bool, bit_size: in
|
|||||||
}
|
}
|
||||||
i-=1; a[i] = digits[uint(u % b)];
|
i-=1; a[i] = digits[uint(u % b)];
|
||||||
|
|
||||||
if flags&IntFlag.Prefix != 0 {
|
if flags&Int_Flag.Prefix != 0 {
|
||||||
ok := true;
|
ok := true;
|
||||||
match base {
|
match base {
|
||||||
case 2: i-=1; a[i] = 'b';
|
case 2: i-=1; a[i] = 'b';
|
||||||
@@ -478,9 +478,9 @@ append_bits :: proc(buf: []u8, u: u128, base: int, is_signed: bool, bit_size: in
|
|||||||
|
|
||||||
if neg {
|
if neg {
|
||||||
i-=1; a[i] = '-';
|
i-=1; a[i] = '-';
|
||||||
} else if flags&IntFlag.Plus != 0 {
|
} else if flags&Int_Flag.Plus != 0 {
|
||||||
i-=1; a[i] = '+';
|
i-=1; a[i] = '+';
|
||||||
} else if flags&IntFlag.Space != 0 {
|
} else if flags&Int_Flag.Space != 0 {
|
||||||
i-=1; a[i] = ' ';
|
i-=1; a[i] = ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ Mutex :: struct {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Mutex :: struct {
|
Mutex :: struct {
|
||||||
_critical_section: win32.CriticalSection;
|
_critical_section: win32.Critical_Section;
|
||||||
}
|
}
|
||||||
|
|
||||||
current_thread_id :: proc() -> i32 {
|
current_thread_id :: proc() -> i32 {
|
||||||
|
|||||||
+18
-18
@@ -11,9 +11,9 @@ CONTEXT_CORE_PROFILE_BIT_ARB :: 0x00000001;
|
|||||||
CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB :: 0x00000002;
|
CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB :: 0x00000002;
|
||||||
|
|
||||||
Hglrc :: Handle;
|
Hglrc :: Handle;
|
||||||
ColorRef :: u32;
|
Color_Ref :: u32;
|
||||||
|
|
||||||
LayerPlaneDescriptor :: struct {
|
Layer_Plane_Descriptor :: struct {
|
||||||
size: u16;
|
size: u16;
|
||||||
version: u16;
|
version: u16;
|
||||||
flags: u32;
|
flags: u32;
|
||||||
@@ -37,29 +37,29 @@ LayerPlaneDescriptor :: struct {
|
|||||||
aux_buffers: u8;
|
aux_buffers: u8;
|
||||||
layer_type: u8;
|
layer_type: u8;
|
||||||
reserved: u8;
|
reserved: u8;
|
||||||
transparent: ColorRef;
|
transparent: Color_Ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
PointFloat :: struct {x, y: f32};
|
Point_Float :: struct {x, y: f32};
|
||||||
|
|
||||||
Glyph_MetricsFloat :: struct {
|
Glyph_Metrics_Float :: struct {
|
||||||
black_box_x: f32;
|
black_box_x: f32;
|
||||||
black_box_y: f32;
|
black_box_y: f32;
|
||||||
glyph_origin: PointFloat;
|
glyph_origin: Point_Float;
|
||||||
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;
|
Create_Context_Attribs_ARB_Type :: #type proc(hdc: Hdc, h_share_context: rawptr, attribList: ^i32) -> Hglrc;
|
||||||
ChoosePixelFormatARBType :: proc(hdc: Hdc, attrib_i_list: ^i32, attrib_f_list: ^f32, max_formats: u32, formats: ^i32, num_formats : ^u32) -> Bool #cc_c;
|
Choose_Pixel_Format_ARB_Type :: #type proc(hdc: Hdc, attrib_i_list: ^i32, attrib_f_list: ^f32, max_formats: u32, formats: ^i32, num_formats : ^u32) -> Bool #cc_c;
|
||||||
SwapIntervalEXTType :: proc(interval: i32) -> bool #cc_c;
|
Swap_Interval_EXT_Type :: #type proc(interval: i32) -> bool #cc_c;
|
||||||
GetExtensionsStringARBType :: proc(Hdc) -> ^u8 #cc_c;
|
Get_Extensions_String_ARB_Type :: #type proc(Hdc) -> ^u8 #cc_c;
|
||||||
|
|
||||||
// Procedures
|
// Procedures
|
||||||
create_context_attribs_arb: CreateContextAttribsARBType;
|
create_context_attribs_arb: Create_Context_Attribs_ARB_Type;
|
||||||
choose_pixel_format_arb: ChoosePixelFormatARBType;
|
choose_pixel_format_arb: Choose_Pixel_Format_ARB_Type;
|
||||||
swap_interval_ext: SwapIntervalEXTType;
|
swap_interval_ext: Swap_Interval_EXT_Type;
|
||||||
get_extensions_string_arb: GetExtensionsStringARBType;
|
get_extensions_string_arb: Get_Extensions_String_ARB_Type;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -70,14 +70,14 @@ foreign opengl32 {
|
|||||||
delete_context :: proc(hglrc: Hglrc) -> Bool #link_name "wglDeleteContext" ---;
|
delete_context :: proc(hglrc: Hglrc) -> Bool #link_name "wglDeleteContext" ---;
|
||||||
copy_context :: proc(src, dst: Hglrc, mask: u32) -> Bool #link_name "wglCopyContext" ---;
|
copy_context :: proc(src, dst: Hglrc, mask: u32) -> Bool #link_name "wglCopyContext" ---;
|
||||||
create_layer_context :: proc(hdc: Hdc, layer_plane: i32) -> Hglrc #link_name "wglCreateLayerContext" ---;
|
create_layer_context :: proc(hdc: Hdc, layer_plane: i32) -> Hglrc #link_name "wglCreateLayerContext" ---;
|
||||||
describe_layer_plane :: proc(hdc: Hdc, pixel_format, layer_plane: i32, bytes: u32, pd: ^LayerPlaneDescriptor) -> Bool #link_name "wglDescribeLayerPlane" ---;
|
describe_layer_plane :: proc(hdc: Hdc, pixel_format, layer_plane: i32, bytes: u32, pd: ^Layer_Plane_Descriptor) -> Bool #link_name "wglDescribeLayerPlane" ---;
|
||||||
get_current_context :: proc() -> Hglrc #link_name "wglGetCurrentContext" ---;
|
get_current_context :: proc() -> Hglrc #link_name "wglGetCurrentContext" ---;
|
||||||
get_current_dc :: proc() -> Hdc #link_name "wglGetCurrentDC" ---;
|
get_current_dc :: proc() -> Hdc #link_name "wglGetCurrentDC" ---;
|
||||||
get_layer_palette_entries :: proc(hdc: Hdc, layer_plane, start, entries: i32, cr: ^ColorRef) -> i32 #link_name "wglGetLayerPaletteEntries" ---;
|
get_layer_palette_entries :: proc(hdc: Hdc, layer_plane, start, entries: i32, cr: ^Color_Ref) -> i32 #link_name "wglGetLayerPaletteEntries" ---;
|
||||||
realize_layer_palette :: proc(hdc: Hdc, layer_plane: i32, realize: Bool) -> Bool #link_name "wglRealizeLayerPalette" ---;
|
realize_layer_palette :: proc(hdc: Hdc, layer_plane: i32, realize: Bool) -> Bool #link_name "wglRealizeLayerPalette" ---;
|
||||||
set_layer_palette_entries :: proc(hdc: Hdc, layer_plane, start, entries: i32, cr: ^ColorRef) -> i32 #link_name "wglSetLayerPaletteEntries" ---;
|
set_layer_palette_entries :: proc(hdc: Hdc, layer_plane, start, entries: i32, cr: ^Color_Ref) -> i32 #link_name "wglSetLayerPaletteEntries" ---;
|
||||||
share_lists :: proc(hglrc1, hglrc2: Hglrc) -> Bool #link_name "wglShareLists" ---;
|
share_lists :: proc(hglrc1, hglrc2: Hglrc) -> Bool #link_name "wglShareLists" ---;
|
||||||
swap_layer_buffers :: proc(hdc: Hdc, planes: u32) -> Bool #link_name "wglSwapLayerBuffers" ---;
|
swap_layer_buffers :: proc(hdc: Hdc, planes: u32) -> Bool #link_name "wglSwapLayerBuffers" ---;
|
||||||
use_font_bitmaps :: proc(hdc: Hdc, first, count, list_base: u32) -> Bool #link_name "wglUseFontBitmaps" ---;
|
use_font_bitmaps :: proc(hdc: Hdc, first, count, list_base: u32) -> Bool #link_name "wglUseFontBitmaps" ---;
|
||||||
use_font_outlines :: proc(hdc: Hdc, first, count, list_base: u32, deviation, extrusion: f32, format: i32, gmf: ^Glyph_MetricsFloat) -> Bool #link_name "wglUseFontOutlines" ---;
|
use_font_outlines :: proc(hdc: Hdc, first, count, list_base: u32, deviation, extrusion: f32, format: i32, gmf: ^Glyph_Metrics_Float) -> Bool #link_name "wglUseFontOutlines" ---;
|
||||||
}
|
}
|
||||||
|
|||||||
+45
-45
@@ -20,7 +20,7 @@ Hmonitor :: Handle;
|
|||||||
Wparam :: uint;
|
Wparam :: uint;
|
||||||
Lparam :: int;
|
Lparam :: int;
|
||||||
Lresult :: int;
|
Lresult :: int;
|
||||||
WndProc :: proc(Hwnd, u32, Wparam, Lparam) -> Lresult #cc_c;
|
Wnd_Proc :: proc(Hwnd, u32, Wparam, Lparam) -> Lresult #cc_c;
|
||||||
|
|
||||||
Bool :: i32;
|
Bool :: i32;
|
||||||
FALSE: Bool : 0;
|
FALSE: Bool : 0;
|
||||||
@@ -30,9 +30,9 @@ Point :: struct #ordered {
|
|||||||
x, y: i32;
|
x, y: i32;
|
||||||
}
|
}
|
||||||
|
|
||||||
WndClassExA :: struct #ordered {
|
Wnd_Class_Ex_A :: struct #ordered {
|
||||||
size, style: u32;
|
size, style: u32;
|
||||||
wnd_proc: WndProc;
|
wnd_proc: Wnd_Proc;
|
||||||
cls_extra, wnd_extra: i32;
|
cls_extra, wnd_extra: i32;
|
||||||
instance: Hinstance;
|
instance: Hinstance;
|
||||||
icon: Hicon;
|
icon: Hicon;
|
||||||
@@ -68,7 +68,7 @@ Systemtime :: struct #ordered {
|
|||||||
hour, minute, second, millisecond: u16;
|
hour, minute, second, millisecond: u16;
|
||||||
}
|
}
|
||||||
|
|
||||||
ByHandleFileInformation :: struct #ordered {
|
By_Handle_File_Information :: struct #ordered {
|
||||||
file_attributes: u32;
|
file_attributes: u32;
|
||||||
creation_time,
|
creation_time,
|
||||||
last_access_time,
|
last_access_time,
|
||||||
@@ -81,7 +81,7 @@ ByHandleFileInformation :: struct #ordered {
|
|||||||
file_index_low: u32;
|
file_index_low: u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileAttributeData :: struct #ordered {
|
File_Attribute_Data :: struct #ordered {
|
||||||
file_attributes: u32;
|
file_attributes: u32;
|
||||||
creation_time,
|
creation_time,
|
||||||
last_access_time,
|
last_access_time,
|
||||||
@@ -90,7 +90,7 @@ FileAttributeData :: struct #ordered {
|
|||||||
file_size_low: u32;
|
file_size_low: u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
FindData :: struct #ordered {
|
Find_Data :: struct #ordered{
|
||||||
file_attributes: u32;
|
file_attributes: u32;
|
||||||
creation_time: Filetime;
|
creation_time: Filetime;
|
||||||
last_access_time: Filetime;
|
last_access_time: Filetime;
|
||||||
@@ -103,7 +103,7 @@ FindData :: struct #ordered {
|
|||||||
alternate_file_name: [14]u8;
|
alternate_file_name: [14]u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
SecurityAttributes :: struct #ordered {
|
Security_Attributes :: struct #ordered {
|
||||||
length: u32;
|
length: u32;
|
||||||
security_descriptor: rawptr;
|
security_descriptor: rawptr;
|
||||||
inherit_handle: Bool;
|
inherit_handle: Bool;
|
||||||
@@ -111,7 +111,7 @@ SecurityAttributes :: struct #ordered {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
PixelFormatDescriptor :: struct #ordered {
|
Pixel_Format_Descriptor :: struct #ordered {
|
||||||
size,
|
size,
|
||||||
version,
|
version,
|
||||||
flags: u32;
|
flags: u32;
|
||||||
@@ -142,8 +142,8 @@ PixelFormatDescriptor :: struct #ordered {
|
|||||||
damage_mask: u32;
|
damage_mask: u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
CriticalSection :: struct #ordered {
|
Critical_Section :: struct #ordered {
|
||||||
debug_info: ^CriticalSectionDebug;
|
debug_info: ^Critical_Section_Debug;
|
||||||
|
|
||||||
lock_count: i32;
|
lock_count: i32;
|
||||||
recursion_count: i32;
|
recursion_count: i32;
|
||||||
@@ -152,11 +152,11 @@ CriticalSection :: struct #ordered {
|
|||||||
spin_count: ^u32;
|
spin_count: ^u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
CriticalSectionDebug :: struct #ordered {
|
Critical_Section_Debug :: struct #ordered {
|
||||||
typ: u16;
|
typ: u16;
|
||||||
creator_back_trace_index: u16;
|
creator_back_trace_index: u16;
|
||||||
critical_section: ^CriticalSection;
|
critical_section: ^Critical_Section;
|
||||||
process_locks_list: ^ListEntry;
|
process_locks_list: ^List_Entry;
|
||||||
entry_count: u32;
|
entry_count: u32;
|
||||||
contention_count: u32;
|
contention_count: u32;
|
||||||
flags: u32;
|
flags: u32;
|
||||||
@@ -164,7 +164,7 @@ CriticalSectionDebug :: struct #ordered {
|
|||||||
spare_word: u16;
|
spare_word: u16;
|
||||||
}
|
}
|
||||||
|
|
||||||
ListEntry :: struct #ordered {flink, blink: ^ListEntry};
|
List_Entry :: struct #ordered {flink, blink: ^List_Entry};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -328,15 +328,15 @@ foreign kernel32 {
|
|||||||
get_file_size_ex :: proc(file_handle: Handle, file_size: ^i64) -> Bool #cc_std #link_name "GetFileSizeEx" ---;
|
get_file_size_ex :: proc(file_handle: Handle, file_size: ^i64) -> Bool #cc_std #link_name "GetFileSizeEx" ---;
|
||||||
get_file_attributes_a :: proc(filename: ^u8) -> u32 #cc_std #link_name "GetFileAttributesA" ---;
|
get_file_attributes_a :: proc(filename: ^u8) -> u32 #cc_std #link_name "GetFileAttributesA" ---;
|
||||||
get_file_attributes_ex_a :: proc(filename: ^u8, info_level_id: GET_FILEEX_INFO_LEVELS, file_info: rawptr) -> Bool #cc_std #link_name "GetFileAttributesExA" ---;
|
get_file_attributes_ex_a :: proc(filename: ^u8, info_level_id: GET_FILEEX_INFO_LEVELS, file_info: rawptr) -> Bool #cc_std #link_name "GetFileAttributesExA" ---;
|
||||||
get_file_information_by_handle :: proc(file_handle: Handle, file_info: ^ByHandleFileInformation) -> Bool #cc_std #link_name "GetFileInformationByHandle" ---;
|
get_file_information_by_handle :: proc(file_handle: Handle, file_info: ^By_Handle_File_Information) -> Bool #cc_std #link_name "GetFileInformationByHandle" ---;
|
||||||
|
|
||||||
get_file_type :: proc(file_handle: Handle) -> u32 #cc_std #link_name "GetFileType" ---;
|
get_file_type :: proc(file_handle: Handle) -> u32 #cc_std #link_name "GetFileType" ---;
|
||||||
set_file_pointer :: proc(file_handle: Handle, distance_to_move: i32, distance_to_move_high: ^i32, move_method: u32) -> u32 #cc_std #link_name "SetFilePointer" ---;
|
set_file_pointer :: proc(file_handle: Handle, distance_to_move: i32, distance_to_move_high: ^i32, move_method: u32) -> u32 #cc_std #link_name "SetFilePointer" ---;
|
||||||
|
|
||||||
set_handle_information :: proc(obj: Handle, mask, flags: u32) -> Bool #cc_std #link_name "SetHandleInformation" ---;
|
set_handle_information :: proc(obj: Handle, mask, flags: u32) -> Bool #cc_std #link_name "SetHandleInformation" ---;
|
||||||
|
|
||||||
find_first_file_a :: proc(file_name : ^u8, data : ^FindData) -> Handle #cc_std #link_name "FindFirstFileA" ---;
|
find_first_file_a :: proc(file_name : ^u8, data : ^Find_Data) -> Handle #cc_std #link_name "FindFirstFileA" ---;
|
||||||
find_next_file_a :: proc(file : Handle, data : ^FindData) -> Bool #cc_std #link_name "FindNextFileA" ---;
|
find_next_file_a :: proc(file : Handle, data : ^Find_Data) -> Bool #cc_std #link_name "FindNextFileA" ---;
|
||||||
find_close :: proc(file : Handle) -> Bool #cc_std #link_name "FindClose" ---;
|
find_close :: proc(file : Handle) -> Bool #cc_std #link_name "FindClose" ---;
|
||||||
|
|
||||||
|
|
||||||
@@ -346,7 +346,7 @@ foreign kernel32 {
|
|||||||
get_process_heap :: proc() -> Handle #cc_std #link_name "GetProcessHeap" ---;
|
get_process_heap :: proc() -> Handle #cc_std #link_name "GetProcessHeap" ---;
|
||||||
|
|
||||||
|
|
||||||
create_semaphore_a :: proc(attributes: ^SecurityAttributes, initial_count, maximum_count: i32, name: ^u8) -> Handle #cc_std #link_name "CreateSemaphoreA" ---;
|
create_semaphore_a :: proc(attributes: ^Security_Attributes, initial_count, maximum_count: i32, name: ^u8) -> Handle #cc_std #link_name "CreateSemaphoreA" ---;
|
||||||
release_semaphore :: proc(semaphore: Handle, release_count: i32, previous_count: ^i32) -> Bool #cc_std #link_name "ReleaseSemaphore" ---;
|
release_semaphore :: proc(semaphore: Handle, release_count: i32, previous_count: ^i32) -> Bool #cc_std #link_name "ReleaseSemaphore" ---;
|
||||||
wait_for_single_object :: proc(handle: Handle, milliseconds: u32) -> u32 #cc_std #link_name "WaitForSingleObject" ---;
|
wait_for_single_object :: proc(handle: Handle, milliseconds: u32) -> u32 #cc_std #link_name "WaitForSingleObject" ---;
|
||||||
|
|
||||||
@@ -368,22 +368,22 @@ foreign kernel32 {
|
|||||||
write_barrier :: proc() #cc_std #link_name "WriteBarrier" ---;
|
write_barrier :: proc() #cc_std #link_name "WriteBarrier" ---;
|
||||||
read_barrier :: proc() #cc_std #link_name "ReadBarrier" ---;
|
read_barrier :: proc() #cc_std #link_name "ReadBarrier" ---;
|
||||||
|
|
||||||
create_thread :: proc(thread_attributes: ^SecurityAttributes, stack_size: int, start_routine: rawptr,
|
create_thread :: proc(thread_attributes: ^Security_Attributes, stack_size: int, start_routine: rawptr,
|
||||||
parameter: rawptr, creation_flags: u32, thread_id: ^u32) -> Handle #cc_std #link_name "CreateThread" ---;
|
parameter: rawptr, creation_flags: u32, thread_id: ^u32) -> Handle #cc_std #link_name "CreateThread" ---;
|
||||||
resume_thread :: proc(thread: Handle) -> u32 #cc_std #link_name "ResumeThread" ---;
|
resume_thread :: proc(thread: Handle) -> u32 #cc_std #link_name "ResumeThread" ---;
|
||||||
get_thread_priority :: proc(thread: Handle) -> i32 #cc_std #link_name "GetThreadPriority" ---;
|
get_thread_priority :: proc(thread: Handle) -> i32 #cc_std #link_name "GetThreadPriority" ---;
|
||||||
set_thread_priority :: proc(thread: Handle, priority: i32) -> Bool #cc_std #link_name "SetThreadPriority" ---;
|
set_thread_priority :: proc(thread: Handle, priority: i32) -> Bool #cc_std #link_name "SetThreadPriority" ---;
|
||||||
get_exit_code_thread :: proc(thread: Handle, exit_code: ^u32) -> Bool #cc_std #link_name "GetExitCodeThread" ---;
|
get_exit_code_thread :: proc(thread: Handle, exit_code: ^u32) -> Bool #cc_std #link_name "GetExitCodeThread" ---;
|
||||||
|
|
||||||
initialize_critical_section :: proc(critical_section: ^CriticalSection) #cc_std #link_name "InitializeCriticalSection" ---;
|
initialize_critical_section :: proc(critical_section: ^Critical_Section) #cc_std #link_name "InitializeCriticalSection" ---;
|
||||||
initialize_critical_section_and_spin_count :: proc(critical_section: ^CriticalSection, spin_count: u32) #cc_std #link_name "InitializeCriticalSectionAndSpinCount" ---;
|
initialize_critical_section_and_spin_count :: proc(critical_section: ^Critical_Section, spin_count: u32) #cc_std #link_name "InitializeCriticalSectionAndSpinCount" ---;
|
||||||
delete_critical_section :: proc(critical_section: ^CriticalSection) #cc_std #link_name "DeleteCriticalSection" ---;
|
delete_critical_section :: proc(critical_section: ^Critical_Section) #cc_std #link_name "DeleteCriticalSection" ---;
|
||||||
set_critical_section_spin_count :: proc(critical_section: ^CriticalSection, spin_count: u32) -> u32 #cc_std #link_name "SetCriticalSectionSpinCount" ---;
|
set_critical_section_spin_count :: proc(critical_section: ^Critical_Section, spin_count: u32) -> u32 #cc_std #link_name "SetCriticalSectionSpinCount" ---;
|
||||||
try_enter_critical_section :: proc(critical_section: ^CriticalSection) -> Bool #cc_std #link_name "TryEnterCriticalSection" ---;
|
try_enter_critical_section :: proc(critical_section: ^Critical_Section) -> Bool #cc_std #link_name "TryEnterCriticalSection" ---;
|
||||||
enter_critical_section :: proc(critical_section: ^CriticalSection) #cc_std #link_name "EnterCriticalSection" ---;
|
enter_critical_section :: proc(critical_section: ^Critical_Section) #cc_std #link_name "EnterCriticalSection" ---;
|
||||||
leave_critical_section :: proc(critical_section: ^CriticalSection) #cc_std #link_name "LeaveCriticalSection" ---;
|
leave_critical_section :: proc(critical_section: ^Critical_Section) #cc_std #link_name "LeaveCriticalSection" ---;
|
||||||
|
|
||||||
create_event_a :: proc(event_attributes: ^SecurityAttributes, manual_reset, initial_state: Bool, name: ^u8) -> Handle #cc_std #link_name "CreateEventA" ---;
|
create_event_a :: proc(event_attributes: ^Security_Attributes, manual_reset, initial_state: Bool, name: ^u8) -> Handle #cc_std #link_name "CreateEventA" ---;
|
||||||
|
|
||||||
load_library_a :: proc(c_str: ^u8) -> Hmodule #cc_std #link_name "LoadLibraryA" ---;
|
load_library_a :: proc(c_str: ^u8) -> Hmodule #cc_std #link_name "LoadLibraryA" ---;
|
||||||
free_library :: proc(h: Hmodule) #cc_std #link_name "FreeLibrary" ---;
|
free_library :: proc(h: Hmodule) #cc_std #link_name "FreeLibrary" ---;
|
||||||
@@ -398,7 +398,7 @@ foreign user32 {
|
|||||||
screen_to_client :: proc(h: Hwnd, p: ^Point) -> i32 #cc_std #link_name "ScreenToClient" ---;
|
screen_to_client :: proc(h: Hwnd, p: ^Point) -> i32 #cc_std #link_name "ScreenToClient" ---;
|
||||||
post_quit_message :: proc(exit_code: i32) #cc_std #link_name "PostQuitMessage" ---;
|
post_quit_message :: proc(exit_code: i32) #cc_std #link_name "PostQuitMessage" ---;
|
||||||
set_window_text_a :: proc(hwnd: Hwnd, c_string: ^u8) -> Bool #cc_std #link_name "SetWindowTextA" ---;
|
set_window_text_a :: proc(hwnd: Hwnd, c_string: ^u8) -> Bool #cc_std #link_name "SetWindowTextA" ---;
|
||||||
register_class_ex_a :: proc(wc: ^WndClassExA) -> i16 #cc_std #link_name "RegisterClassExA" ---;
|
register_class_ex_a :: proc(wc: ^Wnd_Class_Ex_A) -> i16 #cc_std #link_name "RegisterClassExA" ---;
|
||||||
|
|
||||||
create_window_ex_a :: proc(ex_style: u32,
|
create_window_ex_a :: proc(ex_style: u32,
|
||||||
class_name, title: ^u8,
|
class_name, title: ^u8,
|
||||||
@@ -424,15 +424,15 @@ foreign user32 {
|
|||||||
get_active_window :: proc() -> Hwnd #cc_std #link_name "GetActiveWindow" ---;
|
get_active_window :: proc() -> Hwnd #cc_std #link_name "GetActiveWindow" ---;
|
||||||
|
|
||||||
destroy_window :: proc(wnd: Hwnd) -> Bool #cc_std #link_name "DestroyWindow" ---;
|
destroy_window :: proc(wnd: Hwnd) -> Bool #cc_std #link_name "DestroyWindow" ---;
|
||||||
describe_pixel_format :: proc(dc: Hdc, pixel_format: i32, bytes : u32, pfd: ^PixelFormatDescriptor) -> i32 #cc_std #link_name "DescribePixelFormat" ---;
|
describe_pixel_format :: proc(dc: Hdc, pixel_format: i32, bytes: u32, pfd: ^Pixel_Format_Descriptor) -> i32 #cc_std #link_name "DescribePixelFormat" ---;
|
||||||
|
|
||||||
get_monitor_info_a :: proc(monitor: Hmonitor, mi: ^MonitorInfo) -> Bool #cc_std #link_name "GetMonitorInfoA" ---;
|
get_monitor_info_a :: proc(monitor: Hmonitor, mi: ^Monitor_Info) -> Bool #cc_std #link_name "GetMonitor_InfoA" ---;
|
||||||
monitor_from_window :: proc(wnd: Hwnd, flags : u32) -> Hmonitor #cc_std #link_name "MonitorFromWindow" ---;
|
monitor_from_window :: proc(wnd: Hwnd, flags : u32) -> Hmonitor #cc_std #link_name "MonitorFromWindow" ---;
|
||||||
|
|
||||||
set_window_pos :: proc(wnd: Hwnd, wndInsertAfter: Hwnd, x, y, width, height: i32, flags: u32) #cc_std #link_name "SetWindowPos" ---;
|
set_window_pos :: proc(wnd: Hwnd, wndInsertAfter: Hwnd, x, y, width, height: i32, flags: u32) #cc_std #link_name "SetWindowPos" ---;
|
||||||
|
|
||||||
get_window_placement :: proc(wnd: Hwnd, wndpl: ^WindowPlacement) -> Bool #cc_std #link_name "GetWindowPlacement" ---;
|
get_window_placement :: proc(wnd: Hwnd, wndpl: ^Window_Placement) -> Bool #cc_std #link_name "GetWindowPlacement" ---;
|
||||||
set_window_placement :: proc(wnd: Hwnd, wndpl: ^WindowPlacement) -> Bool #cc_std #link_name "SetWindowPlacement" ---;
|
set_window_placement :: proc(wnd: Hwnd, wndpl: ^Window_Placement) -> Bool #cc_std #link_name "SetWindowPlacement" ---;
|
||||||
get_window_rect :: proc(wnd: Hwnd, rect: ^Rect) -> Bool #cc_std #link_name "GetWindowRect" ---;
|
get_window_rect :: proc(wnd: Hwnd, rect: ^Rect) -> Bool #cc_std #link_name "GetWindowRect" ---;
|
||||||
|
|
||||||
get_window_long_ptr_a :: proc(wnd: Hwnd, index: i32) -> i64 #cc_std #link_name "GetWindowLongPtrA" ---;
|
get_window_long_ptr_a :: proc(wnd: Hwnd, index: i32) -> i64 #cc_std #link_name "GetWindowLongPtrA" ---;
|
||||||
@@ -452,18 +452,18 @@ foreign user32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreign gdi32 {
|
foreign gdi32 {
|
||||||
get_stock_object :: proc(fn_object: i32) -> Hgdiobj #cc_std #link_name "GetStockObject" ---;
|
get_stock_object :: proc(fn_object: i32) -> Hgdiobj #cc_std #link_name "GetStockObject" ---;
|
||||||
|
|
||||||
stretch_dibits :: proc(hdc: Hdc,
|
stretch_dibits :: proc(hdc: Hdc,
|
||||||
x_dst, y_dst, width_dst, height_dst: i32,
|
x_dst, y_dst, width_dst, height_dst: i32,
|
||||||
x_src, y_src, width_src, header_src: i32,
|
x_src, y_src, width_src, header_src: i32,
|
||||||
bits: rawptr, bits_info: ^BitmapInfo,
|
bits: rawptr, bits_info: ^BitmapInfo,
|
||||||
usage: u32,
|
usage: u32,
|
||||||
rop: u32) -> i32 #cc_std #link_name "StretchDIBits" ---;
|
rop: u32) -> i32 #cc_std #link_name "StretchDIBits" ---;
|
||||||
|
|
||||||
set_pixel_format :: proc(hdc: Hdc, pixel_format: i32, pfd: ^PixelFormatDescriptor) -> Bool #cc_std #link_name "SetPixelFormat" ---;
|
set_pixel_format :: proc(hdc: Hdc, pixel_format: i32, pfd: ^Pixel_Format_Descriptor) -> Bool #cc_std #link_name "SetPixelFormat" ---;
|
||||||
choose_pixel_format :: proc(hdc: Hdc, pfd: ^PixelFormatDescriptor) -> i32 #cc_std #link_name "ChoosePixelFormat" ---;
|
choose_pixel_format :: proc(hdc: Hdc, pfd: ^Pixel_Format_Descriptor) -> i32 #cc_std #link_name "ChoosePixelFormat" ---;
|
||||||
swap_buffers :: proc(hdc: Hdc) -> Bool #cc_std #link_name "SwapBuffers" ---;
|
swap_buffers :: proc(hdc: Hdc) -> Bool #cc_std #link_name "SwapBuffers" ---;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -488,7 +488,7 @@ HIWORD :: proc(lParam: Lparam) -> u16 { return u16((u32(lParam) >> 16) & 0xffff)
|
|||||||
LOWORD :: proc(wParam: Wparam) -> u16 { return u16(wParam); }
|
LOWORD :: proc(wParam: Wparam) -> u16 { return u16(wParam); }
|
||||||
LOWORD :: proc(lParam: Lparam) -> u16 { return u16(lParam); }
|
LOWORD :: proc(lParam: Lparam) -> u16 { return u16(lParam); }
|
||||||
|
|
||||||
is_key_down :: proc(key: KeyCode) -> bool #inline { return get_async_key_state(i32(key)) < 0; }
|
is_key_down :: proc(key: Key_Code) -> bool #inline { return get_async_key_state(i32(key)) < 0; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -545,14 +545,14 @@ FILE_TYPE_CHAR :: 0x0002;
|
|||||||
FILE_TYPE_PIPE :: 0x0003;
|
FILE_TYPE_PIPE :: 0x0003;
|
||||||
|
|
||||||
|
|
||||||
MonitorInfo :: struct #ordered {
|
Monitor_Info :: struct #ordered {
|
||||||
size: u32;
|
size: u32;
|
||||||
monitor: Rect;
|
monitor: Rect;
|
||||||
work: Rect;
|
work: Rect;
|
||||||
flags: u32;
|
flags: u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
WindowPlacement :: struct #ordered {
|
Window_Placement :: struct #ordered {
|
||||||
length: u32;
|
length: u32;
|
||||||
flags: u32;
|
flags: u32;
|
||||||
show_cmd: u32;
|
show_cmd: u32;
|
||||||
@@ -561,7 +561,7 @@ WindowPlacement :: struct #ordered {
|
|||||||
normal_pos: Rect;
|
normal_pos: Rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
BitmapInfoHeader :: struct #ordered {
|
Bitmap_Info_Header :: struct #ordered {
|
||||||
size: u32;
|
size: u32;
|
||||||
width, height: i32;
|
width, height: i32;
|
||||||
planes, bit_count: i16;
|
planes, bit_count: i16;
|
||||||
@@ -573,15 +573,15 @@ BitmapInfoHeader :: struct #ordered {
|
|||||||
clr_important: u32;
|
clr_important: u32;
|
||||||
}
|
}
|
||||||
BitmapInfo :: struct #ordered {
|
BitmapInfo :: struct #ordered {
|
||||||
using header: BitmapInfoHeader;
|
using header: Bitmap_Info_Header;
|
||||||
colors: [1]RgbQuad;
|
colors: [1]Rgb_Quad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RgbQuad :: struct #ordered { blue, green, red, reserved: u8 }
|
Rgb_Quad :: struct #ordered {blue, green, red, reserved: u8}
|
||||||
|
|
||||||
|
|
||||||
KeyCode :: enum i32 {
|
Key_Code :: enum i32 {
|
||||||
Lbutton = 0x01,
|
Lbutton = 0x01,
|
||||||
Rbutton = 0x02,
|
Rbutton = 0x02,
|
||||||
Cancel = 0x03,
|
Cancel = 0x03,
|
||||||
|
|||||||
+2
-2
@@ -3,7 +3,7 @@ _ :: compile_assert(ODIN_OS == "windows");
|
|||||||
import win32 "sys/windows.odin";
|
import win32 "sys/windows.odin";
|
||||||
|
|
||||||
Thread :: struct {
|
Thread :: struct {
|
||||||
using specific: OsSpecific;
|
using specific: Os_Specific;
|
||||||
procedure: Proc;
|
procedure: Proc;
|
||||||
data: any;
|
data: any;
|
||||||
user_index: int;
|
user_index: int;
|
||||||
@@ -12,7 +12,7 @@ Thread :: struct {
|
|||||||
use_init_context: bool;
|
use_init_context: bool;
|
||||||
|
|
||||||
Proc :: #type proc(^Thread) -> int;
|
Proc :: #type proc(^Thread) -> int;
|
||||||
OsSpecific :: struct {
|
Os_Specific :: struct {
|
||||||
win32_thread: win32.Handle;
|
win32_thread: win32.Handle;
|
||||||
win32_thread_id: u32;
|
win32_thread_id: u32;
|
||||||
}
|
}
|
||||||
|
|||||||
+41
-41
@@ -1,103 +1,103 @@
|
|||||||
is_signed :: proc(info: ^TypeInfo) -> bool {
|
is_signed :: proc(info: ^Type_Info) -> bool {
|
||||||
if info == nil do return false;
|
if info == nil do return false;
|
||||||
match i in type_info_base(info).variant {
|
match i in type_info_base(info).variant {
|
||||||
case TypeInfo.Integer: return i.signed;
|
case Type_Info.Integer: return i.signed;
|
||||||
case TypeInfo.Float: return true;
|
case Type_Info.Float: return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
is_integer :: proc(info: ^TypeInfo) -> bool {
|
is_integer :: proc(info: ^Type_Info) -> bool {
|
||||||
if info == nil do return false;
|
if info == nil do return false;
|
||||||
_, ok := type_info_base(info).variant.(TypeInfo.Integer);
|
_, ok := type_info_base(info).variant.(Type_Info.Integer);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
is_rune :: proc(info: ^TypeInfo) -> bool {
|
is_rune :: proc(info: ^Type_Info) -> bool {
|
||||||
if info == nil do return false;
|
if info == nil do return false;
|
||||||
_, ok := type_info_base(info).variant.(TypeInfo.Rune);
|
_, ok := type_info_base(info).variant.(Type_Info.Rune);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
is_float :: proc(info: ^TypeInfo) -> bool {
|
is_float :: proc(info: ^Type_Info) -> bool {
|
||||||
if info == nil do return false;
|
if info == nil do return false;
|
||||||
_, ok := type_info_base(info).variant.(TypeInfo.Float);
|
_, ok := type_info_base(info).variant.(Type_Info.Float);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
is_complex :: proc(info: ^TypeInfo) -> bool {
|
is_complex :: proc(info: ^Type_Info) -> bool {
|
||||||
if info == nil do return false;
|
if info == nil do return false;
|
||||||
_, ok := type_info_base(info).variant.(TypeInfo.Complex);
|
_, ok := type_info_base(info).variant.(Type_Info.Complex);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
is_any :: proc(info: ^TypeInfo) -> bool {
|
is_any :: proc(info: ^Type_Info) -> bool {
|
||||||
if info == nil do return false;
|
if info == nil do return false;
|
||||||
_, ok := type_info_base(info).variant.(TypeInfo.Any);
|
_, ok := type_info_base(info).variant.(Type_Info.Any);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
is_string :: proc(info: ^TypeInfo) -> bool {
|
is_string :: proc(info: ^Type_Info) -> bool {
|
||||||
if info == nil do return false;
|
if info == nil do return false;
|
||||||
_, ok := type_info_base(info).variant.(TypeInfo.String);
|
_, ok := type_info_base(info).variant.(Type_Info.String);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
is_boolean :: proc(info: ^TypeInfo) -> bool {
|
is_boolean :: proc(info: ^Type_Info) -> bool {
|
||||||
if info == nil do return false;
|
if info == nil do return false;
|
||||||
_, ok := type_info_base(info).variant.(TypeInfo.Boolean);
|
_, ok := type_info_base(info).variant.(Type_Info.Boolean);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
is_pointer :: proc(info: ^TypeInfo) -> bool {
|
is_pointer :: proc(info: ^Type_Info) -> bool {
|
||||||
if info == nil do return false;
|
if info == nil do return false;
|
||||||
_, ok := type_info_base(info).variant.(TypeInfo.Pointer);
|
_, ok := type_info_base(info).variant.(Type_Info.Pointer);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
is_procedure :: proc(info: ^TypeInfo) -> bool {
|
is_procedure :: proc(info: ^Type_Info) -> bool {
|
||||||
if info == nil do return false;
|
if info == nil do return false;
|
||||||
_, ok := type_info_base(info).variant.(TypeInfo.Procedure);
|
_, ok := type_info_base(info).variant.(Type_Info.Procedure);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
is_array :: proc(info: ^TypeInfo) -> bool {
|
is_array :: proc(info: ^Type_Info) -> bool {
|
||||||
if info == nil do return false;
|
if info == nil do return false;
|
||||||
_, ok := type_info_base(info).variant.(TypeInfo.Array);
|
_, ok := type_info_base(info).variant.(Type_Info.Array);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
is_dynamic_array :: proc(info: ^TypeInfo) -> bool {
|
is_dynamic_array :: proc(info: ^Type_Info) -> bool {
|
||||||
if info == nil do return false;
|
if info == nil do return false;
|
||||||
_, ok := type_info_base(info).variant.(TypeInfo.DynamicArray);
|
_, ok := type_info_base(info).variant.(Type_Info.Dynamic_Array);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
is_dynamic_map :: proc(info: ^TypeInfo) -> bool {
|
is_dynamic_map :: proc(info: ^Type_Info) -> bool {
|
||||||
if info == nil do return false;
|
if info == nil do return false;
|
||||||
_, ok := type_info_base(info).variant.(TypeInfo.Map);
|
_, ok := type_info_base(info).variant.(Type_Info.Map);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
is_slice :: proc(info: ^TypeInfo) -> bool {
|
is_slice :: proc(info: ^Type_Info) -> bool {
|
||||||
if info == nil do return false;
|
if info == nil do return false;
|
||||||
_, ok := type_info_base(info).variant.(TypeInfo.Slice);
|
_, ok := type_info_base(info).variant.(Type_Info.Slice);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
is_vector :: proc(info: ^TypeInfo) -> bool {
|
is_vector :: proc(info: ^Type_Info) -> bool {
|
||||||
if info == nil do return false;
|
if info == nil do return false;
|
||||||
_, ok := type_info_base(info).variant.(TypeInfo.Vector);
|
_, ok := type_info_base(info).variant.(Type_Info.Vector);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
is_tuple :: proc(info: ^TypeInfo) -> bool {
|
is_tuple :: proc(info: ^Type_Info) -> bool {
|
||||||
if info == nil do return false;
|
if info == nil do return false;
|
||||||
_, ok := type_info_base(info).variant.(TypeInfo.Tuple);
|
_, ok := type_info_base(info).variant.(Type_Info.Tuple);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
is_struct :: proc(info: ^TypeInfo) -> bool {
|
is_struct :: proc(info: ^Type_Info) -> bool {
|
||||||
if info == nil do return false;
|
if info == nil do return false;
|
||||||
s, ok := type_info_base(info).variant.(TypeInfo.Struct);
|
s, ok := type_info_base(info).variant.(Type_Info.Struct);
|
||||||
return ok && !s.is_raw_union;
|
return ok && !s.is_raw_union;
|
||||||
}
|
}
|
||||||
is_raw_union :: proc(info: ^TypeInfo) -> bool {
|
is_raw_union :: proc(info: ^Type_Info) -> bool {
|
||||||
if info == nil do return false;
|
if info == nil do return false;
|
||||||
s, ok := type_info_base(info).variant.(TypeInfo.Struct);
|
s, ok := type_info_base(info).variant.(Type_Info.Struct);
|
||||||
return ok && s.is_raw_union;
|
return ok && s.is_raw_union;
|
||||||
}
|
}
|
||||||
is_union :: proc(info: ^TypeInfo) -> bool {
|
is_union :: proc(info: ^Type_Info) -> bool {
|
||||||
if info == nil do return false;
|
if info == nil do return false;
|
||||||
_, ok := type_info_base(info).variant.(TypeInfo.Union);
|
_, ok := type_info_base(info).variant.(Type_Info.Union);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
is_enum :: proc(info: ^TypeInfo) -> bool {
|
is_enum :: proc(info: ^Type_Info) -> bool {
|
||||||
if info == nil do return false;
|
if info == nil do return false;
|
||||||
_, ok := type_info_base(info).variant.(TypeInfo.Enum);
|
_, ok := type_info_base(info).variant.(Type_Info.Enum);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -28,9 +28,9 @@ RUNE3_MAX :: 1<<16 - 1;
|
|||||||
LOCB :: 0b1000_0000;
|
LOCB :: 0b1000_0000;
|
||||||
HICB :: 0b1011_1111;
|
HICB :: 0b1011_1111;
|
||||||
|
|
||||||
AcceptRange :: struct { lo, hi: u8 }
|
Accept_Range :: struct {lo, hi: u8};
|
||||||
|
|
||||||
accept_ranges := [5]AcceptRange{
|
accept_ranges := [5]Accept_Range{
|
||||||
{0x80, 0xbf},
|
{0x80, 0xbf},
|
||||||
{0xa0, 0xbf},
|
{0xa0, 0xbf},
|
||||||
{0x80, 0x9f},
|
{0x80, 0x9f},
|
||||||
|
|||||||
@@ -237,7 +237,7 @@ String path_to_fullpath(gbAllocator a, String s) {
|
|||||||
String path_to_fullpath(gbAllocator a, String s) {
|
String path_to_fullpath(gbAllocator a, String s) {
|
||||||
char *p;
|
char *p;
|
||||||
gb_mutex_lock(&string_buffer_mutex);
|
gb_mutex_lock(&string_buffer_mutex);
|
||||||
p = realpath(cast(char *)s.data, 0);
|
p = realpath(cast(char *)s.text, 0);
|
||||||
gb_mutex_unlock(&string_buffer_mutex);
|
gb_mutex_unlock(&string_buffer_mutex);
|
||||||
if(p == nullptr) return make_string_c("");
|
if(p == nullptr) return make_string_c("");
|
||||||
return make_string_c(p);
|
return make_string_c(p);
|
||||||
@@ -283,7 +283,7 @@ String get_fullpath_core(gbAllocator a, String path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
String const ODIN_VERSION = str_lit("0.6.1");
|
String const ODIN_VERSION = str_lit("0.6.2");
|
||||||
|
|
||||||
void init_build_context(void) {
|
void init_build_context(void) {
|
||||||
BuildContext *bc = &build_context;
|
BuildContext *bc = &build_context;
|
||||||
|
|||||||
+3
-1
@@ -8136,7 +8136,9 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
|
|||||||
o->type = t->Pointer.elem;
|
o->type = t->Pointer.elem;
|
||||||
} else {
|
} else {
|
||||||
gbString str = expr_to_string(o->expr);
|
gbString str = expr_to_string(o->expr);
|
||||||
error(o->expr, "Cannot dereference `%s`", str);
|
gbString typ = type_to_string(o->type);
|
||||||
|
error(o->expr, "Cannot dereference `%s` of type `%s`", str, typ);
|
||||||
|
gb_string_free(typ);
|
||||||
gb_string_free(str);
|
gb_string_free(str);
|
||||||
o->mode = Addressing_Invalid;
|
o->mode = Addressing_Invalid;
|
||||||
o->expr = node;
|
o->expr = node;
|
||||||
|
|||||||
+6
-6
@@ -1341,14 +1341,14 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type);
|
|||||||
|
|
||||||
void init_preload(Checker *c) {
|
void init_preload(Checker *c) {
|
||||||
if (t_type_info == nullptr) {
|
if (t_type_info == nullptr) {
|
||||||
Entity *type_info_entity = find_core_entity(c, str_lit("TypeInfo"));
|
Entity *type_info_entity = find_core_entity(c, str_lit("Type_Info"));
|
||||||
|
|
||||||
t_type_info = type_info_entity->type;
|
t_type_info = type_info_entity->type;
|
||||||
t_type_info_ptr = make_type_pointer(c->allocator, t_type_info);
|
t_type_info_ptr = make_type_pointer(c->allocator, t_type_info);
|
||||||
GB_ASSERT(is_type_struct(type_info_entity->type));
|
GB_ASSERT(is_type_struct(type_info_entity->type));
|
||||||
TypeStruct *tis = &base_type(type_info_entity->type)->Struct;
|
TypeStruct *tis = &base_type(type_info_entity->type)->Struct;
|
||||||
|
|
||||||
Entity *type_info_enum_value = find_sub_core_entity(tis, str_lit("EnumValue"));
|
Entity *type_info_enum_value = find_sub_core_entity(tis, str_lit("Enum_Value"));
|
||||||
|
|
||||||
t_type_info_enum_value = type_info_enum_value->type;
|
t_type_info_enum_value = type_info_enum_value->type;
|
||||||
t_type_info_enum_value_ptr = make_type_pointer(c->allocator, t_type_info_enum_value);
|
t_type_info_enum_value_ptr = make_type_pointer(c->allocator, t_type_info_enum_value);
|
||||||
@@ -1361,7 +1361,7 @@ void init_preload(Checker *c) {
|
|||||||
TypeUnion *tiv = &tiv_type->Union;
|
TypeUnion *tiv = &tiv_type->Union;
|
||||||
|
|
||||||
if (tiv->variants.count != 20) {
|
if (tiv->variants.count != 20) {
|
||||||
compiler_error("Invalid `TypeInfo` layout");
|
compiler_error("Invalid `Type_Info` layout");
|
||||||
}
|
}
|
||||||
t_type_info_named = tiv->variants[ 0];
|
t_type_info_named = tiv->variants[ 0];
|
||||||
t_type_info_integer = tiv->variants[ 1];
|
t_type_info_integer = tiv->variants[ 1];
|
||||||
@@ -1420,18 +1420,18 @@ void init_preload(Checker *c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (t_source_code_location == nullptr) {
|
if (t_source_code_location == nullptr) {
|
||||||
Entity *e = find_core_entity(c, str_lit("SourceCodeLocation"));
|
Entity *e = find_core_entity(c, str_lit("Source_Code_Location"));
|
||||||
t_source_code_location = e->type;
|
t_source_code_location = e->type;
|
||||||
t_source_code_location_ptr = make_type_pointer(c->allocator, t_allocator);
|
t_source_code_location_ptr = make_type_pointer(c->allocator, t_allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t_map_key == nullptr) {
|
if (t_map_key == nullptr) {
|
||||||
Entity *e = find_core_entity(c, str_lit("__MapKey"));
|
Entity *e = find_core_entity(c, str_lit("__Map_Key"));
|
||||||
t_map_key = e->type;
|
t_map_key = e->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t_map_header == nullptr) {
|
if (t_map_header == nullptr) {
|
||||||
Entity *e = find_core_entity(c, str_lit("__MapHeader"));
|
Entity *e = find_core_entity(c, str_lit("__Map_Header"));
|
||||||
t_map_header = e->type;
|
t_map_header = e->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -3613,7 +3613,7 @@ String ir_mangle_name(irGen *s, String path, Entity *e) {
|
|||||||
cast(char *)new_name, max_len,
|
cast(char *)new_name, max_len,
|
||||||
"%.*s-%u.%.*s",
|
"%.*s-%u.%.*s",
|
||||||
cast(int)base_len, base,
|
cast(int)base_len, base,
|
||||||
file->id,
|
cast(u32)file->id,
|
||||||
LIT(name));
|
LIT(name));
|
||||||
}
|
}
|
||||||
if (require_suffix_id) {
|
if (require_suffix_id) {
|
||||||
|
|||||||
+34
-3
@@ -293,7 +293,7 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) {
|
|||||||
|
|
||||||
case Type_Union: {
|
case Type_Union: {
|
||||||
if (t->Union.variants.count == 0) {
|
if (t->Union.variants.count == 0) {
|
||||||
ir_write_string(f, "%%..opaque");
|
ir_print_encoded_local(f, str_lit("..opaque"));
|
||||||
} else {
|
} else {
|
||||||
// NOTE(bill): The zero size array is used to fix the alignment used in a structure as
|
// NOTE(bill): The zero size array is used to fix the alignment used in a structure as
|
||||||
// LLVM takes the first element's alignment as the entire alignment (like C)
|
// LLVM takes the first element's alignment as the entire alignment (like C)
|
||||||
@@ -1723,10 +1723,41 @@ void ir_print_proc(irFileBuffer *f, irModule *m, irProcedure *proc) {
|
|||||||
|
|
||||||
void ir_print_type_name(irFileBuffer *f, irModule *m, irValue *v) {
|
void ir_print_type_name(irFileBuffer *f, irModule *m, irValue *v) {
|
||||||
GB_ASSERT(v->kind == irValue_TypeName);
|
GB_ASSERT(v->kind == irValue_TypeName);
|
||||||
Type *bt = base_type(ir_type(v));
|
Type *t = base_type(v->TypeName.type);
|
||||||
ir_print_encoded_local(f, v->TypeName.name);
|
ir_print_encoded_local(f, v->TypeName.name);
|
||||||
ir_write_string(f, str_lit(" = type "));
|
ir_write_string(f, str_lit(" = type "));
|
||||||
ir_print_type(f, m, base_type(v->TypeName.type));
|
|
||||||
|
|
||||||
|
switch (t->kind) {
|
||||||
|
case Type_Union:
|
||||||
|
if (t->Union.variants.count == 0) {
|
||||||
|
ir_write_string(f, str_lit("{}"));
|
||||||
|
} else {
|
||||||
|
ir_print_type(f, m, t);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Type_Struct:
|
||||||
|
if (t->Struct.fields.count == 0) {
|
||||||
|
if (t->Struct.is_packed) {
|
||||||
|
ir_write_byte(f, '<');
|
||||||
|
}
|
||||||
|
ir_write_byte(f, '{');
|
||||||
|
if (t->Struct.custom_align > 0) {
|
||||||
|
ir_fprintf(f, "[0 x <%lld x i8>]", t->Struct.custom_align);
|
||||||
|
}
|
||||||
|
ir_write_byte(f, '}');
|
||||||
|
if (t->Struct.is_packed) {
|
||||||
|
ir_write_byte(f, '>');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ir_print_type(f, m, t);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ir_print_type(f, m, t);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
ir_write_byte(f, '\n');
|
ir_write_byte(f, '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -1,6 +1,8 @@
|
|||||||
#define USE_CUSTOM_BACKEND 0
|
#define USE_CUSTOM_BACKEND 0
|
||||||
#define USE_THREADED_PARSER 1
|
|
||||||
// #define NO_ARRAY_BOUNDS_CHECK
|
// #define NO_ARRAY_BOUNDS_CHECK
|
||||||
|
#if !defined(USE_THREADED_PARSER)
|
||||||
|
#define USE_THREADED_PARSER 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "common.cpp"
|
#include "common.cpp"
|
||||||
#include "timings.cpp"
|
#include "timings.cpp"
|
||||||
|
|||||||
+1
-1
@@ -2556,7 +2556,7 @@ String ssa_mangle_name(ssaModule *m, String path, Entity *e) {
|
|||||||
cast(char *)new_name, max_len,
|
cast(char *)new_name, max_len,
|
||||||
"%.*s-%u.%.*s",
|
"%.*s-%u.%.*s",
|
||||||
cast(int)base_len, base,
|
cast(int)base_len, base,
|
||||||
file->id,
|
cast(u32)file->id,
|
||||||
LIT(name));
|
LIT(name));
|
||||||
if (is_overloaded) {
|
if (is_overloaded) {
|
||||||
char *str = cast(char *)new_name + new_name_len-1;
|
char *str = cast(char *)new_name + new_name_len-1;
|
||||||
|
|||||||
Reference in New Issue
Block a user