mirror of
https://github.com/odin-lang/Odin.git
synced 2026-06-13 05:43:41 +00:00
Remove usage of do in core library
This commit is contained in:
@@ -170,7 +170,9 @@ multi_map_count :: proc(m: $M/Map($Value), key: u64) -> int {
|
||||
multi_map_get :: proc{multi_map_get_array, multi_map_get_slice};
|
||||
|
||||
multi_map_get_array :: proc(m: $M/Map($Value), key: u64, items: ^Array(Value)) {
|
||||
if items == nil do return;
|
||||
if items == nil {
|
||||
return;
|
||||
}
|
||||
e := multi_map_find_first(m, key);
|
||||
for e != nil {
|
||||
array_append(items, e.value);
|
||||
|
||||
@@ -5,7 +5,9 @@ import "core:os"
|
||||
|
||||
load_library :: proc(path: string, global_symbols := false) -> (Library, bool) {
|
||||
flags := os.RTLD_NOW;
|
||||
if global_symbols do flags |= os.RTLD_GLOBAL;
|
||||
if global_symbols {
|
||||
flags |= os.RTLD_GLOBAL;
|
||||
}
|
||||
lib := os.dlopen(path, flags);
|
||||
return Library(lib), lib != nil;
|
||||
}
|
||||
|
||||
@@ -92,7 +92,9 @@ _encode :: proc(out, data: []byte, ENC_TBL := ENC_TABLE, allocator := context.al
|
||||
}
|
||||
|
||||
decode :: proc(data: string, DEC_TBL := DEC_TABLE, allocator := context.allocator) -> []byte #no_bounds_check{
|
||||
if len(data) == 0 do return []byte{};
|
||||
if len(data) == 0 {
|
||||
return nil;
|
||||
}
|
||||
|
||||
outi := 0;
|
||||
olen := len(data);
|
||||
@@ -113,7 +115,9 @@ decode :: proc(data: string, DEC_TBL := DEC_TABLE, allocator := context.allocato
|
||||
data = data[1:];
|
||||
if input == byte(PADDING) && j >= 2 && len(data) < 8 {
|
||||
assert(!(len(data) + j < 8 - 1), "Corrupted input");
|
||||
for k := 0; k < 8-1-j; k +=1 do assert(len(data) < k || data[k] == byte(PADDING), "Corrupted input");
|
||||
for k := 0; k < 8-1-j; k +=1 {
|
||||
assert(len(data) < k || data[k] == byte(PADDING), "Corrupted input");
|
||||
}
|
||||
dlen, end = j, true;
|
||||
assert(dlen != 1 && dlen != 3 && dlen != 6, "Corrupted input");
|
||||
break;
|
||||
|
||||
@@ -2,46 +2,48 @@ package base64
|
||||
|
||||
// @note(zh): Encoding utility for Base64
|
||||
// A secondary param can be used to supply a custom alphabet to
|
||||
// @link(encode) and a matching decoding table to @link(decode).
|
||||
// @link(encode) and a matching decoding table to @link(decode).
|
||||
// If none is supplied it just uses the standard Base64 alphabet.
|
||||
// Incase your specific version does not use padding, you may
|
||||
// truncate it from the encoded output.
|
||||
|
||||
ENC_TABLE := [64]byte {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
||||
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
|
||||
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||
'w', 'x', 'y', 'z', '0', '1', '2', '3',
|
||||
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
|
||||
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||
'w', 'x', 'y', 'z', '0', '1', '2', '3',
|
||||
'4', '5', '6', '7', '8', '9', '+', '/'
|
||||
};
|
||||
|
||||
PADDING :: '=';
|
||||
|
||||
DEC_TABLE := [128]int {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, 62, -1, -1, -1, 63,
|
||||
52, 53, 54, 55, 56, 57, 58, 59,
|
||||
60, 61, -1, -1, -1, -1, -1, -1,
|
||||
-1, 0, 1, 2, 3, 4, 5, 6,
|
||||
7, 8, 9, 10, 11, 12, 13, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22,
|
||||
23, 24, 25, -1, -1, -1, -1, -1,
|
||||
-1, 26, 27, 28, 29, 30, 31, 32,
|
||||
33, 34, 35, 36, 37, 38, 39, 40,
|
||||
41, 42, 43, 44, 45, 46, 47, 48,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, 62, -1, -1, -1, 63,
|
||||
52, 53, 54, 55, 56, 57, 58, 59,
|
||||
60, 61, -1, -1, -1, -1, -1, -1,
|
||||
-1, 0, 1, 2, 3, 4, 5, 6,
|
||||
7, 8, 9, 10, 11, 12, 13, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22,
|
||||
23, 24, 25, -1, -1, -1, -1, -1,
|
||||
-1, 26, 27, 28, 29, 30, 31, 32,
|
||||
33, 34, 35, 36, 37, 38, 39, 40,
|
||||
41, 42, 43, 44, 45, 46, 47, 48,
|
||||
49, 50, 51, -1, -1, -1, -1, -1
|
||||
};
|
||||
|
||||
encode :: proc(data: []byte, ENC_TBL := ENC_TABLE, allocator := context.allocator) -> string #no_bounds_check {
|
||||
length := len(data);
|
||||
if length == 0 do return "";
|
||||
if length == 0 {
|
||||
return "";
|
||||
}
|
||||
|
||||
out_length := ((4 * length / 3) + 3) &~ 3;
|
||||
out := make([]byte, out_length, allocator);
|
||||
@@ -51,8 +53,8 @@ encode :: proc(data: []byte, ENC_TBL := ENC_TABLE, allocator := context.allocato
|
||||
for i, d := 0, 0; i < length; i, d = i + 3, d + 4 {
|
||||
c0, c1, c2 = int(data[i]), -1, -1;
|
||||
|
||||
if i + 1 < length do c1 = int(data[i + 1]);
|
||||
if i + 2 < length do c2 = int(data[i + 2]);
|
||||
if i + 1 < length { c1 = int(data[i + 1]); }
|
||||
if i + 2 < length { c2 = int(data[i + 2]); }
|
||||
|
||||
block = (c0 << 16) | (max(c1, 0) << 8) | max(c2, 0);
|
||||
|
||||
@@ -66,7 +68,9 @@ encode :: proc(data: []byte, ENC_TBL := ENC_TABLE, allocator := context.allocato
|
||||
|
||||
decode :: proc(data: string, DEC_TBL := DEC_TABLE, allocator := context.allocator) -> []byte #no_bounds_check {
|
||||
length := len(data);
|
||||
if length == 0 do return []byte{};
|
||||
if length == 0 {
|
||||
return nil;
|
||||
}
|
||||
|
||||
pad_count := data[length - 1] == PADDING ? (data[length - 2] == PADDING ? 2 : 1) : 0;
|
||||
out_length := ((length * 6) >> 3) - pad_count;
|
||||
|
||||
@@ -32,7 +32,9 @@ Parser :: struct {
|
||||
|
||||
print_value :: proc(value: Value, pretty := true, indent := 0) {
|
||||
print_indent :: proc(indent: int) {
|
||||
for _ in 0..<indent do fmt.print("\t");
|
||||
for _ in 0..<indent {
|
||||
fmt.print("\t");
|
||||
}
|
||||
}
|
||||
|
||||
switch v in value {
|
||||
@@ -42,22 +44,22 @@ print_value :: proc(value: Value, pretty := true, indent := 0) {
|
||||
case string: fmt.print(v);
|
||||
case Array:
|
||||
fmt.print("[");
|
||||
if pretty do fmt.println();
|
||||
if pretty { fmt.println(); }
|
||||
for e, i in v {
|
||||
if pretty {
|
||||
print_indent(indent+1);
|
||||
print_value(e, pretty, indent+1);
|
||||
fmt.println(",");
|
||||
} else {
|
||||
if i > 0 do fmt.print(", ");
|
||||
if i > 0 { fmt.print(", "); }
|
||||
print_value(e);
|
||||
}
|
||||
}
|
||||
if pretty do print_indent(indent);
|
||||
if pretty { print_indent(indent); }
|
||||
fmt.print("]");
|
||||
case Dict:
|
||||
fmt.print("{");
|
||||
if pretty do fmt.println();
|
||||
if pretty { fmt.println(); }
|
||||
|
||||
i := 0;
|
||||
for name, val in v {
|
||||
@@ -67,14 +69,14 @@ print_value :: proc(value: Value, pretty := true, indent := 0) {
|
||||
print_value(val, pretty, indent+1);
|
||||
fmt.println(",");
|
||||
} else {
|
||||
if i > 0 do fmt.print(", ");
|
||||
if i > 0 { fmt.print(", "); }
|
||||
fmt.printf("%s = ", name);
|
||||
print_value(val, pretty, indent+1);
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if pretty do print_indent(indent);
|
||||
if pretty { print_indent(indent); }
|
||||
fmt.print("}");
|
||||
case:
|
||||
fmt.print("nil");
|
||||
@@ -149,17 +151,23 @@ destroy :: proc(p: ^Parser) {
|
||||
destroy_value :: proc(value: Value) {
|
||||
#partial switch v in value {
|
||||
case Array:
|
||||
for elem in v do destroy_value(elem);
|
||||
for elem in v {
|
||||
destroy_value(elem);
|
||||
}
|
||||
delete(v);
|
||||
|
||||
case Dict:
|
||||
for _, dv in v do destroy_value(dv);
|
||||
for _, dv in v {
|
||||
destroy_value(dv);
|
||||
}
|
||||
delete(v);
|
||||
}
|
||||
}
|
||||
|
||||
delete(p.tokens);
|
||||
for s in p.allocated_strings do delete(s);
|
||||
for s in p.allocated_strings {
|
||||
delete(s);
|
||||
}
|
||||
delete(p.allocated_strings);
|
||||
delete(p.dict_stack);
|
||||
|
||||
@@ -348,7 +356,9 @@ expect_token :: proc(p: ^Parser, kind: Kind) -> Token {
|
||||
prev := p.curr_token;
|
||||
if prev.kind != kind {
|
||||
got := prev.lit;
|
||||
if got == "\n" do got = ";";
|
||||
if got == "\n" {
|
||||
got = ";";
|
||||
}
|
||||
error(p, prev.pos, "Expected %s, got %s", kind_to_string[kind], got);
|
||||
}
|
||||
next_token(p);
|
||||
@@ -411,7 +421,7 @@ parse_operand :: proc(p: ^Parser) -> (Value, Pos) {
|
||||
case .Ident:
|
||||
next_token(p);
|
||||
v, ok := lookup_value(p, tok.lit);
|
||||
if !ok do error(p, tok.pos, "Undeclared identifier %s", tok.lit);
|
||||
if !ok { error(p, tok.pos, "Undeclared identifier %s", tok.lit); }
|
||||
return v, tok.pos;
|
||||
|
||||
case .True:
|
||||
@@ -438,7 +448,7 @@ parse_operand :: proc(p: ^Parser) -> (Value, Pos) {
|
||||
case .String:
|
||||
next_token(p);
|
||||
str, ok := unquote_string(p, tok);
|
||||
if !ok do error(p, tok.pos, "Unable to unquote string");
|
||||
if !ok { error(p, tok.pos, "Unable to unquote string"); }
|
||||
return string(str), tok.pos;
|
||||
|
||||
case .Open_Paren:
|
||||
@@ -480,7 +490,7 @@ parse_operand :: proc(p: ^Parser) -> (Value, Pos) {
|
||||
}
|
||||
|
||||
name, ok := unquote_string(p, name_tok);
|
||||
if !ok do error(p, tok.pos, "Unable to unquote string");
|
||||
if !ok { error(p, tok.pos, "Unable to unquote string"); }
|
||||
expect_token(p, .Assign);
|
||||
elem, _ := parse_expr(p);
|
||||
|
||||
@@ -520,7 +530,7 @@ parse_atom_expr :: proc(p: ^Parser, operand: Value, pos: Pos) -> (Value, Pos) {
|
||||
continue;
|
||||
}
|
||||
name, usok := unquote_string(p, tok);
|
||||
if !usok do error(p, tok.pos, "Unable to unquote string");
|
||||
if !usok { error(p, tok.pos, "Unable to unquote string"); }
|
||||
val, found := d[name];
|
||||
if !found {
|
||||
error(p, tok.pos, "Field %s not found in dictionary", name);
|
||||
@@ -594,7 +604,7 @@ parse_unary_expr :: proc(p: ^Parser) -> (Value, Pos) {
|
||||
next_token(p);
|
||||
tok := expect_token(p, .String);
|
||||
v, ok := lookup_value(p, tok.lit);
|
||||
if !ok do error(p, tok.pos, "Undeclared identifier %s", tok.lit);
|
||||
if !ok { error(p, tok.pos, "Undeclared identifier %s", tok.lit); }
|
||||
return parse_atom_expr(p, v, tok.pos);
|
||||
|
||||
case .Add, .Sub:
|
||||
@@ -603,8 +613,8 @@ parse_unary_expr :: proc(p: ^Parser) -> (Value, Pos) {
|
||||
expr, pos := parse_unary_expr(p);
|
||||
|
||||
#partial switch e in expr {
|
||||
case i64: if op.kind == .Sub do return -e, pos;
|
||||
case f64: if op.kind == .Sub do return -e, pos;
|
||||
case i64: if op.kind == .Sub { return -e, pos; }
|
||||
case f64: if op.kind == .Sub { return -e, pos; }
|
||||
case:
|
||||
error(p, op.pos, "Unary operator %s can only be used on integers or floats", op.lit);
|
||||
return nil, op.pos;
|
||||
@@ -678,7 +688,7 @@ calculate_binary_value :: proc(p: ^Parser, op: Kind, a, b: Value) -> (Value, boo
|
||||
|
||||
case bool:
|
||||
b, ok := y.(bool);
|
||||
if !ok do return nil, false;
|
||||
if !ok { return nil, false; }
|
||||
#partial switch op {
|
||||
case .Eq: return a == b, true;
|
||||
case .NotEq: return a != b, true;
|
||||
@@ -688,7 +698,7 @@ calculate_binary_value :: proc(p: ^Parser, op: Kind, a, b: Value) -> (Value, boo
|
||||
|
||||
case i64:
|
||||
b, ok := y.(i64);
|
||||
if !ok do return nil, false;
|
||||
if !ok { return nil, false; }
|
||||
#partial switch op {
|
||||
case .Add: return a + b, true;
|
||||
case .Sub: return a - b, true;
|
||||
@@ -705,7 +715,7 @@ calculate_binary_value :: proc(p: ^Parser, op: Kind, a, b: Value) -> (Value, boo
|
||||
|
||||
case f64:
|
||||
b, ok := y.(f64);
|
||||
if !ok do return nil, false;
|
||||
if !ok { return nil, false; }
|
||||
|
||||
#partial switch op {
|
||||
case .Add: return a + b, true;
|
||||
@@ -722,7 +732,7 @@ calculate_binary_value :: proc(p: ^Parser, op: Kind, a, b: Value) -> (Value, boo
|
||||
|
||||
case string:
|
||||
b, ok := y.(string);
|
||||
if !ok do return nil, false;
|
||||
if !ok { return nil, false; }
|
||||
|
||||
#partial switch op {
|
||||
case .Add:
|
||||
@@ -825,7 +835,7 @@ parse_assignment :: proc(p: ^Parser) -> bool {
|
||||
if allow_token(p, .Ident) || allow_token(p, .String) {
|
||||
expect_token(p, .Assign);
|
||||
name, ok := unquote_string(p, tok);
|
||||
if !ok do error(p, tok.pos, "Unable to unquote string");
|
||||
if !ok { error(p, tok.pos, "Unable to unquote string"); }
|
||||
expr, _ := parse_expr(p);
|
||||
d := top_dict(p);
|
||||
if _, ok2 := d[name]; ok2 {
|
||||
|
||||
@@ -162,9 +162,9 @@ token_lookup :: proc(ident: string) -> Kind {
|
||||
return Ident;
|
||||
}
|
||||
|
||||
is_literal :: proc(tok: Kind) -> bool do return _literal_start < tok && tok < _literal_end;
|
||||
is_operator :: proc(tok: Kind) -> bool do return _operator_start < tok && tok < _operator_end;
|
||||
is_keyword :: proc(tok: Kind) -> bool do return _keyword_start < tok && tok < _keyword_end;
|
||||
is_literal :: proc(tok: Kind) -> bool { return _literal_start < tok && tok < _literal_end; }
|
||||
is_operator :: proc(tok: Kind) -> bool { return _operator_start < tok && tok < _operator_end; }
|
||||
is_keyword :: proc(tok: Kind) -> bool { return _keyword_start < tok && tok < _keyword_end; }
|
||||
|
||||
|
||||
tokenizer_init :: proc(t: ^Tokenizer, src: []byte, file := "") {
|
||||
|
||||
@@ -161,7 +161,7 @@ marshal_arg :: proc(b: ^strings.Builder, v: any) -> Marshal_Error {
|
||||
case Type_Info_Array:
|
||||
write_byte(b, '[');
|
||||
for i in 0..<info.count {
|
||||
if i > 0 do write_string(b, ", ");
|
||||
if i > 0 { write_string(b, ", "); }
|
||||
|
||||
data := uintptr(v.data) + uintptr(i*info.elem_size);
|
||||
marshal_arg(b, any{rawptr(data), info.elem.id});
|
||||
@@ -172,7 +172,7 @@ marshal_arg :: proc(b: ^strings.Builder, v: any) -> Marshal_Error {
|
||||
write_byte(b, '[');
|
||||
array := cast(^mem.Raw_Dynamic_Array)v.data;
|
||||
for i in 0..<array.len {
|
||||
if i > 0 do write_string(b, ", ");
|
||||
if i > 0 { write_string(b, ", "); }
|
||||
|
||||
data := uintptr(array.data) + uintptr(i*info.elem_size);
|
||||
marshal_arg(b, any{rawptr(data), info.elem.id});
|
||||
@@ -183,7 +183,7 @@ marshal_arg :: proc(b: ^strings.Builder, v: any) -> Marshal_Error {
|
||||
write_byte(b, '[');
|
||||
slice := cast(^mem.Raw_Slice)v.data;
|
||||
for i in 0..<slice.len {
|
||||
if i > 0 do write_string(b, ", ");
|
||||
if i > 0 { write_string(b, ", "); }
|
||||
|
||||
data := uintptr(slice.data) + uintptr(i*info.elem_size);
|
||||
marshal_arg(b, any{rawptr(data), info.elem.id});
|
||||
@@ -205,7 +205,7 @@ marshal_arg :: proc(b: ^strings.Builder, v: any) -> Marshal_Error {
|
||||
entry_size := ed.elem_size;
|
||||
|
||||
for i in 0..<entries.len {
|
||||
if i > 0 do write_string(b, ", ");
|
||||
if i > 0 { write_string(b, ", "); }
|
||||
|
||||
data := uintptr(entries.data) + uintptr(i*entry_size);
|
||||
header := cast(^Map_Entry_Header)data;
|
||||
@@ -223,7 +223,7 @@ marshal_arg :: proc(b: ^strings.Builder, v: any) -> Marshal_Error {
|
||||
case Type_Info_Struct:
|
||||
write_byte(b, '{');
|
||||
for name, i in info.names {
|
||||
if i > 0 do write_string(b, ", ");
|
||||
if i > 0 { write_string(b, ", "); }
|
||||
write_quoted_string(b, name);
|
||||
write_string(b, ": ");
|
||||
|
||||
@@ -271,7 +271,7 @@ marshal_arg :: proc(b: ^strings.Builder, v: any) -> Marshal_Error {
|
||||
|
||||
write_byte(b, '{');
|
||||
for name, i in info.names {
|
||||
if i > 0 do write_string(b, ", ");
|
||||
if i > 0 { write_string(b, ", "); }
|
||||
|
||||
bits := u64(info.bits[i]);
|
||||
offset := u64(info.offsets[i]);
|
||||
@@ -317,15 +317,21 @@ marshal_arg :: proc(b: ^strings.Builder, v: any) -> Marshal_Error {
|
||||
bit_data = u64(x);
|
||||
case 16:
|
||||
x := (^u16)(v.data)^;
|
||||
if do_byte_swap do x = bits.byte_swap(x);
|
||||
if do_byte_swap {
|
||||
x = bits.byte_swap(x);
|
||||
}
|
||||
bit_data = u64(x);
|
||||
case 32:
|
||||
x := (^u32)(v.data)^;
|
||||
if do_byte_swap do x = bits.byte_swap(x);
|
||||
if do_byte_swap {
|
||||
x = bits.byte_swap(x);
|
||||
}
|
||||
bit_data = u64(x);
|
||||
case 64:
|
||||
x := (^u64)(v.data)^;
|
||||
if do_byte_swap do x = bits.byte_swap(x);
|
||||
if do_byte_swap {
|
||||
x = bits.byte_swap(x);
|
||||
}
|
||||
bit_data = u64(x);
|
||||
case: panic("unknown bit_size size");
|
||||
}
|
||||
|
||||
@@ -183,9 +183,11 @@ get_token :: proc(t: ^Tokenizer) -> (token: Token, err: Error) {
|
||||
case "false": token.kind = .False;
|
||||
case "true": token.kind = .True;
|
||||
case:
|
||||
if t.spec == .JSON5 do switch str {
|
||||
case "Infinity": token.kind = .Infinity;
|
||||
case "NaN": token.kind = .NaN;
|
||||
if t.spec == .JSON5 {
|
||||
switch str {
|
||||
case "Infinity": token.kind = .Infinity;
|
||||
case "NaN": token.kind = .NaN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -361,7 +363,9 @@ is_valid_number :: proc(str: string, spec: Specification) -> bool {
|
||||
s = s[1:];
|
||||
case '1'..'9':
|
||||
s = s[1:];
|
||||
for len(s) > 0 && '0' <= s[0] && s[0] <= '9' do s = s[1:];
|
||||
for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
|
||||
s = s[1:];
|
||||
}
|
||||
case '.':
|
||||
if spec == .JSON5 { // Allow leading decimal point
|
||||
s = s[1:];
|
||||
@@ -380,7 +384,9 @@ is_valid_number :: proc(str: string, spec: Specification) -> bool {
|
||||
|
||||
if len(s) >= 2 && s[0] == '.' && '0' <= s[1] && s[1] <= '9' {
|
||||
s = s[2:];
|
||||
for len(s) > 0 && '0' <= s[0] && s[0] <= '9' do s = s[1:];
|
||||
for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
|
||||
s = s[1:];
|
||||
}
|
||||
}
|
||||
|
||||
if len(s) >= 2 && (s[0] == 'e' || s[0] == 'E') {
|
||||
@@ -392,7 +398,9 @@ is_valid_number :: proc(str: string, spec: Specification) -> bool {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for len(s) > 0 && '0' <= s[0] && s[0] <= '9' do s = s[1:];
|
||||
for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
|
||||
s = s[1:];
|
||||
}
|
||||
}
|
||||
|
||||
// The string should be empty now to be valid
|
||||
|
||||
@@ -65,7 +65,9 @@ destroy_value :: proc(value: Value) {
|
||||
}
|
||||
delete(v);
|
||||
case Array:
|
||||
for elem in v do destroy_value(elem);
|
||||
for elem in v {
|
||||
destroy_value(elem);
|
||||
}
|
||||
delete(v);
|
||||
case String:
|
||||
delete(v);
|
||||
|
||||
@@ -200,7 +200,9 @@ sbprint :: proc(buf: ^strings.Builder, args: ..any, sep := " ") -> string {
|
||||
// and were expecting `*print` to be the same `*println` except for the added newline
|
||||
// so I am going to keep the same behaviour as `*println` for `*print`
|
||||
for _, i in args {
|
||||
if i > 0 do strings.write_string(buf, sep);
|
||||
if i > 0 {
|
||||
strings.write_string(buf, sep);
|
||||
}
|
||||
|
||||
fmt_value(&fi, args[i], 'v');
|
||||
}
|
||||
@@ -212,7 +214,9 @@ sbprintln :: proc(buf: ^strings.Builder, args: ..any, sep := " ") -> string {
|
||||
fi.buf = buf;
|
||||
|
||||
for _, i in args {
|
||||
if i > 0 do strings.write_string(buf, sep);
|
||||
if i > 0 {
|
||||
strings.write_string(buf, sep);
|
||||
}
|
||||
|
||||
fmt_value(&fi, args[i], 'v');
|
||||
}
|
||||
@@ -479,10 +483,15 @@ sbprintf :: proc(b: ^strings.Builder, fmt: string, args: ..any) -> string {
|
||||
if !fi.reordered && arg_index < len(args) {
|
||||
strings.write_string(b, "%!(EXTRA ");
|
||||
for arg, index in args[arg_index:] {
|
||||
if index > 0 do strings.write_string(b, ", ");
|
||||
if index > 0 {
|
||||
strings.write_string(b, ", ");
|
||||
}
|
||||
|
||||
if arg == nil do strings.write_string(b, "<nil>");
|
||||
else do fmt_arg(&fi, args[index], 'v');
|
||||
if arg == nil {
|
||||
strings.write_string(b, "<nil>");
|
||||
} else {
|
||||
fmt_arg(&fi, args[index], 'v');
|
||||
}
|
||||
}
|
||||
strings.write_string(b, ")");
|
||||
}
|
||||
@@ -502,7 +511,9 @@ _parse_int :: proc(s: string, offset: int) -> (result: int, new_offset: int, ok:
|
||||
new_offset = offset;
|
||||
for new_offset <= len(s) {
|
||||
c := s[new_offset];
|
||||
if !is_digit(c) do break;
|
||||
if !is_digit(c) {
|
||||
break;
|
||||
}
|
||||
new_offset += 1;
|
||||
|
||||
result *= 10;
|
||||
@@ -514,7 +525,9 @@ _parse_int :: proc(s: string, offset: int) -> (result: int, new_offset: int, ok:
|
||||
|
||||
_arg_number :: proc(fi: ^Info, arg_index: int, format: string, offset, arg_count: int) -> (index, new_offset: int, ok: bool) {
|
||||
parse_arg_number :: proc(format: string) -> (int, int, bool) {
|
||||
if len(format) < 3 do return 0, 1, false;
|
||||
if len(format) < 3 {
|
||||
return 0, 1, false;
|
||||
}
|
||||
|
||||
for i in 1..<len(format) {
|
||||
if format[i] == ']' {
|
||||
@@ -585,10 +598,14 @@ fmt_bool :: proc(using fi: ^Info, b: bool, verb: rune) {
|
||||
|
||||
|
||||
fmt_write_padding :: proc(fi: ^Info, width: int) {
|
||||
if width <= 0 do return;
|
||||
if width <= 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
pad_byte: byte = '0';
|
||||
if fi.space do pad_byte = ' ';
|
||||
if fi.space {
|
||||
pad_byte = ' ';
|
||||
}
|
||||
|
||||
for i := 0; i < width; i += 1 {
|
||||
strings.write_byte(fi.buf, pad_byte);
|
||||
@@ -636,9 +653,9 @@ _fmt_int :: proc(fi: ^Info, u: u64, base: int, is_signed: bool, bit_size: int, d
|
||||
start := 0;
|
||||
|
||||
flags: strconv.Int_Flags;
|
||||
if fi.hash && !fi.zero do flags |= {.Prefix};
|
||||
if fi.plus do flags |= {.Plus};
|
||||
if fi.space do flags |= {.Space};
|
||||
if fi.hash && !fi.zero { flags |= {.Prefix}; }
|
||||
if fi.plus { flags |= {.Plus}; }
|
||||
if fi.space { flags |= {.Space}; }
|
||||
s := strconv.append_bits(buf[start:], u, base, is_signed, bit_size, digits, flags);
|
||||
|
||||
if fi.hash && fi.zero {
|
||||
@@ -702,9 +719,9 @@ _fmt_int_128 :: proc(fi: ^Info, u: u128, base: int, is_signed: bool, bit_size: i
|
||||
start := 0;
|
||||
|
||||
flags: strconv.Int_Flags;
|
||||
if fi.hash && !fi.zero do flags |= {.Prefix};
|
||||
if fi.plus do flags |= {.Plus};
|
||||
if fi.space do flags |= {.Space};
|
||||
if fi.hash && !fi.zero { flags |= {.Prefix}; }
|
||||
if fi.plus { flags |= {.Plus}; }
|
||||
if fi.space { flags |= {.Space}; }
|
||||
s := strconv.append_bits_128(buf[start:], u, base, is_signed, bit_size, digits, flags);
|
||||
|
||||
if fi.hash && fi.zero {
|
||||
@@ -810,7 +827,9 @@ fmt_float :: proc(fi: ^Info, v: f64, bit_size: int, verb: rune) {
|
||||
switch verb {
|
||||
case 'f', 'F', 'v':
|
||||
prec: int = 3;
|
||||
if fi.prec_set do prec = fi.prec;
|
||||
if fi.prec_set {
|
||||
prec = fi.prec;
|
||||
}
|
||||
buf: [386]byte;
|
||||
|
||||
str := strconv.append_float(buf[1:], v, 'f', prec, bit_size);
|
||||
@@ -844,7 +863,9 @@ fmt_float :: proc(fi: ^Info, v: f64, bit_size: int, verb: rune) {
|
||||
|
||||
case 'e', 'E':
|
||||
prec: int = 3;
|
||||
if fi.prec_set do prec = fi.prec;
|
||||
if fi.prec_set {
|
||||
prec = fi.prec;
|
||||
}
|
||||
buf: [386]byte;
|
||||
|
||||
str := strconv.append_float(buf[1:], v, 'e', prec, bit_size);
|
||||
@@ -920,9 +941,13 @@ fmt_string :: proc(fi: ^Info, s: string, verb: rune) {
|
||||
defer fi.space = space;
|
||||
|
||||
for i in 0..<len(s) {
|
||||
if i > 0 && space do strings.write_byte(fi.buf, ' ');
|
||||
if i > 0 && space {
|
||||
strings.write_byte(fi.buf, ' ');
|
||||
}
|
||||
char_set := __DIGITS_UPPER;
|
||||
if verb == 'x' do char_set = __DIGITS_LOWER;
|
||||
if verb == 'x' {
|
||||
char_set = __DIGITS_LOWER;
|
||||
}
|
||||
_fmt_int(fi, u64(s[i]), 16, false, 8, char_set);
|
||||
}
|
||||
|
||||
@@ -1089,19 +1114,19 @@ fmt_bit_set :: proc(fi: ^Info, v: any, name: string = "") {
|
||||
bits = u128(x);
|
||||
case 16:
|
||||
x := (^u16)(v.data)^;
|
||||
if do_byte_swap do x = byte_swap(x);
|
||||
if do_byte_swap { x = byte_swap(x); }
|
||||
bits = u128(x);
|
||||
case 32:
|
||||
x := (^u32)(v.data)^;
|
||||
if do_byte_swap do x = byte_swap(x);
|
||||
if do_byte_swap { x = byte_swap(x); }
|
||||
bits = u128(x);
|
||||
case 64:
|
||||
x := (^u64)(v.data)^;
|
||||
if do_byte_swap do x = byte_swap(x);
|
||||
if do_byte_swap { x = byte_swap(x); }
|
||||
bits = u128(x);
|
||||
case 128:
|
||||
x := (^u128)(v.data)^;
|
||||
if do_byte_swap do x = byte_swap(x);
|
||||
if do_byte_swap { x = byte_swap(x); }
|
||||
bits = u128(x);
|
||||
case: panic("unknown bit_size size");
|
||||
}
|
||||
@@ -1123,14 +1148,18 @@ fmt_bit_set :: proc(fi: ^Info, v: any, name: string = "") {
|
||||
continue loop;
|
||||
}
|
||||
|
||||
if commas > 0 do strings.write_string(fi.buf, ", ");
|
||||
if commas > 0 {
|
||||
strings.write_string(fi.buf, ", ");
|
||||
}
|
||||
|
||||
if is_enum do for ev, evi in e.values {
|
||||
v := u64(ev);
|
||||
if v == u64(i) {
|
||||
strings.write_string(fi.buf, e.names[evi]);
|
||||
commas += 1;
|
||||
continue loop;
|
||||
if is_enum {
|
||||
for ev, evi in e.values {
|
||||
v := u64(ev);
|
||||
if v == u64(i) {
|
||||
strings.write_string(fi.buf, e.names[evi]);
|
||||
commas += 1;
|
||||
continue loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
v := i64(i) + info.lower;
|
||||
@@ -1185,12 +1214,14 @@ fmt_bit_field :: proc(fi: ^Info, v: any, bit_field_name: string = "") {
|
||||
|
||||
fmt_opaque :: proc(fi: ^Info, v: any) {
|
||||
is_nil :: proc(data: rawptr, n: int) -> bool {
|
||||
if data == nil do return true;
|
||||
if n == 0 do return true;
|
||||
if data == nil { return true; }
|
||||
if n == 0 { return true; }
|
||||
|
||||
a := (^byte)(data);
|
||||
for i in 0..<n do if mem.ptr_offset(a, i)^ != 0 {
|
||||
return false;
|
||||
for i in 0..<n {
|
||||
if mem.ptr_offset(a, i)^ != 0 {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1206,7 +1237,7 @@ fmt_opaque :: proc(fi: ^Info, v: any) {
|
||||
|
||||
if ot, ok := rt.type_info_base(type_info).variant.(rt.Type_Info_Opaque); ok {
|
||||
elem := rt.type_info_base(ot.elem);
|
||||
if elem == nil do return;
|
||||
if elem == nil { return; }
|
||||
reflect.write_type(fi.buf, type_info);
|
||||
strings.write_byte(fi.buf, '{');
|
||||
defer strings.write_byte(fi.buf, '}');
|
||||
@@ -1269,9 +1300,13 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
||||
fi.hash = false;
|
||||
fi.indent += 1;
|
||||
|
||||
if hash do strings.write_byte(fi.buf, '\n');
|
||||
if hash {
|
||||
strings.write_byte(fi.buf, '\n');
|
||||
}
|
||||
defer {
|
||||
if hash do for in 0..<indent do strings.write_byte(fi.buf, '\t');
|
||||
if hash {
|
||||
for in 0..<indent { strings.write_byte(fi.buf, '\t'); }
|
||||
}
|
||||
strings.write_byte(fi.buf, ']' if is_soa else '}');
|
||||
}
|
||||
|
||||
@@ -1285,11 +1320,11 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
||||
}
|
||||
|
||||
for index in 0..<uintptr(b.soa_len) {
|
||||
if !hash && index > 0 do strings.write_string(fi.buf, ", ");
|
||||
if !hash && index > 0 { strings.write_string(fi.buf, ", "); }
|
||||
|
||||
field_count := -1;
|
||||
|
||||
if !hash && field_count > 0 do strings.write_string(fi.buf, ", ");
|
||||
if !hash && field_count > 0 { strings.write_string(fi.buf, ", "); }
|
||||
|
||||
strings.write_string(fi.buf, base_type_name);
|
||||
strings.write_byte(fi.buf, '{');
|
||||
@@ -1298,8 +1333,10 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
||||
for name, i in b.names {
|
||||
field_count += 1;
|
||||
|
||||
if !hash && field_count > 0 do strings.write_string(fi.buf, ", ");
|
||||
if hash do for in 0..<fi.indent do strings.write_byte(fi.buf, '\t');
|
||||
if !hash && field_count > 0 { strings.write_string(fi.buf, ", "); }
|
||||
if hash {
|
||||
for in 0..<fi.indent { strings.write_byte(fi.buf, '\t'); }
|
||||
}
|
||||
|
||||
strings.write_string(fi.buf, name);
|
||||
strings.write_string(fi.buf, " = ");
|
||||
@@ -1313,7 +1350,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
||||
fmt_arg(fi, any{data, t.id}, 'v');
|
||||
}
|
||||
|
||||
if hash do strings.write_string(fi.buf, ",\n");
|
||||
if hash { strings.write_string(fi.buf, ",\n"); }
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -1321,8 +1358,10 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
||||
for name, i in b.names {
|
||||
field_count += 1;
|
||||
|
||||
if !hash && field_count > 0 do strings.write_string(fi.buf, ", ");
|
||||
if hash do for in 0..<fi.indent do strings.write_byte(fi.buf, '\t');
|
||||
if !hash && field_count > 0 { strings.write_string(fi.buf, ", "); }
|
||||
if hash {
|
||||
for in 0..<fi.indent { strings.write_byte(fi.buf, '\t'); }
|
||||
}
|
||||
|
||||
strings.write_string(fi.buf, name);
|
||||
strings.write_string(fi.buf, " = ");
|
||||
@@ -1334,7 +1373,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
||||
fmt_arg(fi, any{data, t.id}, 'v');
|
||||
}
|
||||
|
||||
if hash do strings.write_string(fi.buf, ",\n");
|
||||
if hash { strings.write_string(fi.buf, ",\n"); }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1365,35 +1404,37 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
||||
a := any{ptr, info.elem.id};
|
||||
|
||||
elem := runtime.type_info_base(info.elem);
|
||||
if elem != nil do #partial switch e in elem.variant {
|
||||
case runtime.Type_Info_Array,
|
||||
runtime.Type_Info_Slice,
|
||||
runtime.Type_Info_Dynamic_Array,
|
||||
runtime.Type_Info_Map:
|
||||
if ptr == nil {
|
||||
strings.write_string(fi.buf, "<nil>");
|
||||
return;
|
||||
}
|
||||
if fi.record_level < 1 {
|
||||
fi.record_level += 1;
|
||||
defer fi.record_level -= 1;
|
||||
strings.write_byte(fi.buf, '&');
|
||||
fmt_value(fi, a, verb);
|
||||
return;
|
||||
}
|
||||
if elem != nil {
|
||||
#partial switch e in elem.variant {
|
||||
case runtime.Type_Info_Array,
|
||||
runtime.Type_Info_Slice,
|
||||
runtime.Type_Info_Dynamic_Array,
|
||||
runtime.Type_Info_Map:
|
||||
if ptr == nil {
|
||||
strings.write_string(fi.buf, "<nil>");
|
||||
return;
|
||||
}
|
||||
if fi.record_level < 1 {
|
||||
fi.record_level += 1;
|
||||
defer fi.record_level -= 1;
|
||||
strings.write_byte(fi.buf, '&');
|
||||
fmt_value(fi, a, verb);
|
||||
return;
|
||||
}
|
||||
|
||||
case runtime.Type_Info_Struct,
|
||||
runtime.Type_Info_Union:
|
||||
if ptr == nil {
|
||||
strings.write_string(fi.buf, "<nil>");
|
||||
return;
|
||||
}
|
||||
if fi.record_level < 1 {
|
||||
fi.record_level += 1;
|
||||
defer fi.record_level -= 1;
|
||||
strings.write_byte(fi.buf, '&');
|
||||
fmt_value(fi, a, verb);
|
||||
return;
|
||||
case runtime.Type_Info_Struct,
|
||||
runtime.Type_Info_Union:
|
||||
if ptr == nil {
|
||||
strings.write_string(fi.buf, "<nil>");
|
||||
return;
|
||||
}
|
||||
if fi.record_level < 1 {
|
||||
fi.record_level += 1;
|
||||
defer fi.record_level -= 1;
|
||||
strings.write_byte(fi.buf, '&');
|
||||
fmt_value(fi, a, verb);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1404,7 +1445,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
||||
strings.write_byte(fi.buf, '[');
|
||||
defer strings.write_byte(fi.buf, ']');
|
||||
for i in 0..<info.count {
|
||||
if i > 0 do strings.write_string(fi.buf, ", ");
|
||||
if i > 0 { strings.write_string(fi.buf, ", "); }
|
||||
|
||||
data := uintptr(v.data) + uintptr(i*info.elem_size);
|
||||
fmt_arg(fi, any{rawptr(data), info.elem.id}, verb);
|
||||
@@ -1414,7 +1455,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
||||
strings.write_byte(fi.buf, '[');
|
||||
defer strings.write_byte(fi.buf, ']');
|
||||
for i in 0..<info.count {
|
||||
if i > 0 do strings.write_string(fi.buf, ", ");
|
||||
if i > 0 { strings.write_string(fi.buf, ", "); }
|
||||
|
||||
idx, ok := stored_enum_value_to_string(info.index, info.min_value, i);
|
||||
if ok {
|
||||
@@ -1438,7 +1479,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
||||
defer strings.write_byte(fi.buf, ']');
|
||||
array := cast(^mem.Raw_Dynamic_Array)v.data;
|
||||
for i in 0..<array.len {
|
||||
if i > 0 do strings.write_string(fi.buf, ", ");
|
||||
if i > 0 { strings.write_string(fi.buf, ", "); }
|
||||
|
||||
data := uintptr(array.data) + uintptr(i*info.elem_size);
|
||||
fmt_arg(fi, any{rawptr(data), info.elem.id}, verb);
|
||||
@@ -1452,7 +1493,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
||||
strings.write_byte(fi.buf, '<');
|
||||
defer strings.write_byte(fi.buf, '>');
|
||||
for i in 0..<info.count {
|
||||
if i > 0 do strings.write_string(fi.buf, ", ");
|
||||
if i > 0 { strings.write_string(fi.buf, ", "); }
|
||||
|
||||
data := uintptr(v.data) + uintptr(i*info.elem_size);
|
||||
fmt_arg(fi, any{rawptr(data), info.elem.id}, verb);
|
||||
@@ -1468,7 +1509,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
||||
defer strings.write_byte(fi.buf, ']');
|
||||
slice := cast(^mem.Raw_Slice)v.data;
|
||||
for i in 0..<slice.len {
|
||||
if i > 0 do strings.write_string(fi.buf, ", ");
|
||||
if i > 0 { strings.write_string(fi.buf, ", "); }
|
||||
|
||||
data := uintptr(slice.data) + uintptr(i*info.elem_size);
|
||||
fmt_arg(fi, any{rawptr(data), info.elem.id}, verb);
|
||||
@@ -1495,7 +1536,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
||||
entry_size := ed.elem_size;
|
||||
|
||||
for i in 0..<entries.len {
|
||||
if i > 0 do strings.write_string(fi.buf, ", ");
|
||||
if i > 0 { strings.write_string(fi.buf, ", "); }
|
||||
|
||||
data := uintptr(entries.data) + uintptr(i*entry_size);
|
||||
header := cast(^runtime.Map_Entry_Header)data;
|
||||
@@ -1530,7 +1571,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
||||
fi.hash = false;
|
||||
|
||||
|
||||
if hash do strings.write_byte(fi.buf, '\n');
|
||||
if hash { strings.write_byte(fi.buf, '\n'); }
|
||||
|
||||
if is_soa {
|
||||
fi.indent += 1;
|
||||
@@ -1559,11 +1600,11 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
||||
|
||||
|
||||
for index in 0..<n {
|
||||
if !hash && index > 0 do strings.write_string(fi.buf, ", ");
|
||||
if !hash && index > 0 { strings.write_string(fi.buf, ", "); }
|
||||
|
||||
field_count := -1;
|
||||
|
||||
if !hash && field_count > 0 do strings.write_string(fi.buf, ", ");
|
||||
if !hash && field_count > 0 { strings.write_string(fi.buf, ", "); }
|
||||
|
||||
strings.write_string(fi.buf, base_type_name);
|
||||
strings.write_byte(fi.buf, '{');
|
||||
@@ -1573,8 +1614,10 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
||||
name := info.names[i];
|
||||
field_count += 1;
|
||||
|
||||
if !hash && field_count > 0 do strings.write_string(fi.buf, ", ");
|
||||
if hash do for in 0..<fi.indent do strings.write_byte(fi.buf, '\t');
|
||||
if !hash && field_count > 0 { strings.write_string(fi.buf, ", "); }
|
||||
if hash {
|
||||
for in 0..<fi.indent { strings.write_byte(fi.buf, '\t'); }
|
||||
}
|
||||
|
||||
strings.write_string(fi.buf, name);
|
||||
strings.write_string(fi.buf, " = ");
|
||||
@@ -1600,7 +1643,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
||||
}
|
||||
}
|
||||
|
||||
if hash do strings.write_string(fi.buf, ",\n");
|
||||
if hash { strings.write_string(fi.buf, ",\n"); }
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -1608,8 +1651,10 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
||||
for name, i in info.names {
|
||||
field_count += 1;
|
||||
|
||||
if !hash && field_count > 0 do strings.write_string(fi.buf, ", ");
|
||||
if hash do for in 0..<fi.indent do strings.write_byte(fi.buf, '\t');
|
||||
if !hash && field_count > 0 { strings.write_string(fi.buf, ", "); }
|
||||
if hash {
|
||||
for in 0..<fi.indent { strings.write_byte(fi.buf, '\t'); }
|
||||
}
|
||||
|
||||
strings.write_string(fi.buf, name);
|
||||
strings.write_string(fi.buf, " = ");
|
||||
@@ -1621,7 +1666,9 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
||||
fmt_arg(fi, any{data, t.id}, 'v');
|
||||
}
|
||||
|
||||
if hash do strings.write_string(fi.buf, ",\n");
|
||||
if hash {
|
||||
strings.write_string(fi.buf, ",\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1767,7 +1814,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
||||
defer strings.write_byte(fi.buf, ']');
|
||||
|
||||
for i in 0..<len {
|
||||
if i > 0 do strings.write_string(fi.buf, ", ");
|
||||
if i > 0 { strings.write_string(fi.buf, ", "); }
|
||||
|
||||
data := uintptr(ptr) + uintptr(i*slice_type.elem_size);
|
||||
fmt_arg(fi, any{rawptr(data), slice_type.elem.id}, verb);
|
||||
@@ -1812,15 +1859,21 @@ fmt_quaternion :: proc(fi: ^Info, q: quaternion256, bits: int, verb: rune) {
|
||||
|
||||
fmt_float(fi, r, bits/4, verb);
|
||||
|
||||
if !fi.plus && i >= 0 do strings.write_rune(fi.buf, '+');
|
||||
if !fi.plus && i >= 0 {
|
||||
strings.write_rune(fi.buf, '+');
|
||||
}
|
||||
fmt_float(fi, i, bits/4, verb);
|
||||
strings.write_rune(fi.buf, 'i');
|
||||
|
||||
if !fi.plus && j >= 0 do strings.write_rune(fi.buf, '+');
|
||||
if !fi.plus && j >= 0 {
|
||||
strings.write_rune(fi.buf, '+');
|
||||
}
|
||||
fmt_float(fi, j, bits/4, verb);
|
||||
strings.write_rune(fi.buf, 'j');
|
||||
|
||||
if !fi.plus && k >= 0 do strings.write_rune(fi.buf, '+');
|
||||
if !fi.plus && k >= 0 {
|
||||
strings.write_rune(fi.buf, '+');
|
||||
}
|
||||
fmt_float(fi, k, bits/4, verb);
|
||||
strings.write_rune(fi.buf, 'k');
|
||||
|
||||
|
||||
@@ -43,7 +43,9 @@ create_file_logger :: proc(h: os.Handle, lowest := Level.Debug, opt := Default_F
|
||||
|
||||
destroy_file_logger :: proc(log: ^Logger) {
|
||||
data := cast(^File_Console_Logger_Data)log.data;
|
||||
if data.file_handle != os.INVALID_HANDLE do os.close(data.file_handle);
|
||||
if data.file_handle != os.INVALID_HANDLE {
|
||||
os.close(data.file_handle);
|
||||
}
|
||||
free(data);
|
||||
}
|
||||
|
||||
@@ -75,8 +77,8 @@ file_console_logger_proc :: proc(logger_data: rawptr, level: Level, text: string
|
||||
t := time.now();
|
||||
y, m, d := time.date(t);
|
||||
h, min, s := time.clock(t);
|
||||
if .Date in options do fmt.sbprintf(&buf, "%d-%02d-%02d ", y, m, d);
|
||||
if .Time in options do fmt.sbprintf(&buf, "%02d:%02d:%02d", h, min, s);
|
||||
if .Date in options { fmt.sbprintf(&buf, "%d-%02d-%02d ", y, m, d); }
|
||||
if .Time in options { fmt.sbprintf(&buf, "%02d:%02d:%02d", h, min, s); }
|
||||
fmt.sbprint(&buf, "] ");
|
||||
}
|
||||
}
|
||||
@@ -89,7 +91,9 @@ file_console_logger_proc :: proc(logger_data: rawptr, level: Level, text: string
|
||||
fmt.sbprintf(&buf, "[{}] ", os.current_thread_id());
|
||||
}
|
||||
|
||||
if data.ident != "" do fmt.sbprintf(&buf, "[%s] ", data.ident);
|
||||
if data.ident != "" {
|
||||
fmt.sbprintf(&buf, "[%s] ", data.ident);
|
||||
}
|
||||
//TODO(Hoej): When we have better atomics and such, make this thread-safe
|
||||
fmt.fprintf(h, "%s %s\n", strings.to_string(buf), text);
|
||||
}
|
||||
@@ -110,14 +114,21 @@ do_level_header :: proc(opts: Options, level: Level, str: ^strings.Builder) {
|
||||
}
|
||||
|
||||
if .Level in opts {
|
||||
if .Terminal_Color in opts do fmt.sbprint(str, col);
|
||||
if .Terminal_Color in opts {
|
||||
fmt.sbprint(str, col);
|
||||
}
|
||||
fmt.sbprint(str, Level_Headers[level]);
|
||||
if .Terminal_Color in opts do fmt.sbprint(str, RESET);
|
||||
if .Terminal_Color in opts {
|
||||
fmt.sbprint(str, RESET);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
do_location_header :: proc(opts: Options, buf: ^strings.Builder, location := #caller_location) {
|
||||
if Location_Header_Opts & opts != nil do fmt.sbprint(buf, "["); else do return;
|
||||
if Location_Header_Opts & opts == nil {
|
||||
return;
|
||||
}
|
||||
fmt.sbprint(buf, "[");
|
||||
|
||||
file := location.file_path;
|
||||
if .Short_File_Path in opts {
|
||||
|
||||
@@ -154,7 +154,9 @@ projection :: proc(x, normal: $T/[$N]$E) -> T where IS_NUMERIC(E) {
|
||||
}
|
||||
|
||||
identity :: proc($T: typeid/[$N][N]$E) -> (m: T) {
|
||||
for i in 0..<N do m[i][i] = E(1);
|
||||
for i in 0..<N {
|
||||
m[i][i] = E(1);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
@@ -115,8 +115,8 @@ vector4_linear_to_srgb :: proc(col: Vector4) -> Vector4 {
|
||||
vector4_hsl_to_rgb :: proc(h, s, l: Float, a: Float = 1) -> Vector4 {
|
||||
hue_to_rgb :: proc(p, q, t: Float) -> Float {
|
||||
t := t;
|
||||
if t < 0 do t += 1;
|
||||
if t > 1 do t -= 1;
|
||||
if t < 0 { t += 1; }
|
||||
if t > 1 { t -= 1; }
|
||||
switch {
|
||||
case t < 1.0/6.0: return p + (q - p) * 6.0 * t;
|
||||
case t < 1.0/2.0: return q;
|
||||
|
||||
@@ -64,7 +64,9 @@ int63 :: proc(r: ^Rand = nil) -> i64 { return i64(uint64(r) << 1 >> 1); }
|
||||
int127 :: proc(r: ^Rand = nil) -> i128 { return i128(uint128(r) << 1 >> 1); }
|
||||
|
||||
int31_max :: proc(n: i32, r: ^Rand = nil) -> i32 {
|
||||
if n <= 0 do panic("Invalid argument to int31_max");
|
||||
if n <= 0 {
|
||||
panic("Invalid argument to int31_max");
|
||||
}
|
||||
if n&(n-1) == 0 {
|
||||
return int31(r) & (n-1);
|
||||
}
|
||||
@@ -77,7 +79,9 @@ int31_max :: proc(n: i32, r: ^Rand = nil) -> i32 {
|
||||
}
|
||||
|
||||
int63_max :: proc(n: i64, r: ^Rand = nil) -> i64 {
|
||||
if n <= 0 do panic("Invalid argument to int63_max");
|
||||
if n <= 0 {
|
||||
panic("Invalid argument to int63_max");
|
||||
}
|
||||
if n&(n-1) == 0 {
|
||||
return int63(r) & (n-1);
|
||||
}
|
||||
@@ -90,7 +94,9 @@ int63_max :: proc(n: i64, r: ^Rand = nil) -> i64 {
|
||||
}
|
||||
|
||||
int127_max :: proc(n: i128, r: ^Rand = nil) -> i128 {
|
||||
if n <= 0 do panic("Invalid argument to int63_max");
|
||||
if n <= 0 {
|
||||
panic("Invalid argument to int63_max");
|
||||
}
|
||||
if n&(n-1) == 0 {
|
||||
return int127(r) & (n-1);
|
||||
}
|
||||
@@ -103,7 +109,9 @@ int127_max :: proc(n: i128, r: ^Rand = nil) -> i128 {
|
||||
}
|
||||
|
||||
int_max :: proc(n: int, r: ^Rand = nil) -> int {
|
||||
if n <= 0 do panic("Invalid argument to int_max");
|
||||
if n <= 0 {
|
||||
panic("Invalid argument to int_max");
|
||||
}
|
||||
when size_of(int) == 4 {
|
||||
return int(int31_max(i32(n), r));
|
||||
} else {
|
||||
@@ -147,7 +155,9 @@ perm :: proc(n: int, r: ^Rand = nil) -> []int {
|
||||
|
||||
shuffle :: proc(array: $T/[]$E, r: ^Rand = nil) {
|
||||
n := i64(len(array));
|
||||
if n < 2 do return;
|
||||
if n < 2 {
|
||||
return;
|
||||
}
|
||||
|
||||
for i := i64(0); i < n; i += 1 {
|
||||
j := int63_max(n, r);
|
||||
|
||||
@@ -46,14 +46,22 @@ Allocator :: struct {
|
||||
DEFAULT_ALIGNMENT :: 2*align_of(rawptr);
|
||||
|
||||
alloc :: inline proc(size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> rawptr {
|
||||
if size == 0 do return nil;
|
||||
if allocator.procedure == nil do return nil;
|
||||
if size == 0 {
|
||||
return nil;
|
||||
}
|
||||
if allocator.procedure == nil {
|
||||
return nil;
|
||||
}
|
||||
return allocator.procedure(allocator.data, Allocator_Mode.Alloc, size, alignment, nil, 0, 0, loc);
|
||||
}
|
||||
|
||||
free :: inline proc(ptr: rawptr, allocator := context.allocator, loc := #caller_location) {
|
||||
if ptr == nil do return;
|
||||
if allocator.procedure == nil do return;
|
||||
if ptr == nil {
|
||||
return;
|
||||
}
|
||||
if allocator.procedure == nil {
|
||||
return;
|
||||
}
|
||||
allocator.procedure(allocator.data, Allocator_Mode.Free, 0, 0, ptr, 0, 0, loc);
|
||||
}
|
||||
|
||||
@@ -129,12 +137,12 @@ new :: inline proc($T: typeid, allocator := context.allocator, loc := #caller_lo
|
||||
}
|
||||
new_aligned :: inline proc($T: typeid, alignment: int, allocator := context.allocator, loc := #caller_location) -> ^T {
|
||||
ptr := (^T)(alloc(size_of(T), alignment, allocator, loc));
|
||||
if ptr != nil do ptr^ = T{};
|
||||
if ptr != nil { ptr^ = T{}; }
|
||||
return ptr;
|
||||
}
|
||||
new_clone :: inline proc(data: $T, allocator := context.allocator, loc := #caller_location) -> ^T {
|
||||
ptr := (^T)(alloc(size_of(T), align_of(T), allocator, loc));
|
||||
if ptr != nil do ptr^ = data;
|
||||
if ptr != nil { ptr^ = data; }
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@@ -188,17 +196,23 @@ make :: proc{
|
||||
|
||||
|
||||
default_resize_align :: proc(old_memory: rawptr, old_size, new_size, alignment: int, allocator := context.allocator, loc := #caller_location) -> rawptr {
|
||||
if old_memory == nil do return alloc(new_size, alignment, allocator, loc);
|
||||
if old_memory == nil {
|
||||
return alloc(new_size, alignment, allocator, loc);
|
||||
}
|
||||
|
||||
if new_size == 0 {
|
||||
free(old_memory, allocator, loc);
|
||||
return nil;
|
||||
}
|
||||
|
||||
if new_size == old_size do return old_memory;
|
||||
if new_size == old_size {
|
||||
return old_memory;
|
||||
}
|
||||
|
||||
new_memory := alloc(new_size, alignment, allocator, loc);
|
||||
if new_memory == nil do return nil;
|
||||
if new_memory == nil {
|
||||
return nil;
|
||||
}
|
||||
|
||||
copy(new_memory, old_memory, min(old_size, new_size));
|
||||
free(old_memory, allocator, loc);
|
||||
|
||||
@@ -186,13 +186,15 @@ any_to_bytes :: inline proc(val: any) -> []byte {
|
||||
}
|
||||
|
||||
|
||||
kilobytes :: inline proc(x: int) -> int do return (x) * 1024;
|
||||
megabytes :: inline proc(x: int) -> int do return kilobytes(x) * 1024;
|
||||
gigabytes :: inline proc(x: int) -> int do return megabytes(x) * 1024;
|
||||
terabytes :: inline proc(x: int) -> int do return gigabytes(x) * 1024;
|
||||
kilobytes :: inline proc(x: int) -> int { return (x) * 1024; }
|
||||
megabytes :: inline proc(x: int) -> int { return kilobytes(x) * 1024; }
|
||||
gigabytes :: inline proc(x: int) -> int { return megabytes(x) * 1024; }
|
||||
terabytes :: inline proc(x: int) -> int { return gigabytes(x) * 1024; }
|
||||
|
||||
is_power_of_two :: inline proc(x: uintptr) -> bool {
|
||||
if x <= 0 do return false;
|
||||
if x <= 0 {
|
||||
return false;
|
||||
}
|
||||
return (x & (x-1)) == 0;
|
||||
}
|
||||
|
||||
@@ -205,7 +207,9 @@ align_forward_uintptr :: proc(ptr, align: uintptr) -> uintptr {
|
||||
|
||||
p := ptr;
|
||||
modulo := p & (align-1);
|
||||
if modulo != 0 do p += align - modulo;
|
||||
if modulo != 0 {
|
||||
p += align - modulo;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -264,7 +268,9 @@ calc_padding_with_header :: proc(ptr: uintptr, align: uintptr, header_size: int)
|
||||
modulo := p & (a-1);
|
||||
|
||||
padding := uintptr(0);
|
||||
if modulo != 0 do padding = a - modulo;
|
||||
if modulo != 0 {
|
||||
padding = a - modulo;
|
||||
}
|
||||
|
||||
needed_space := uintptr(header_size);
|
||||
if padding < needed_space {
|
||||
|
||||
@@ -461,7 +461,9 @@ unparen_expr :: proc(expr: ^Expr) -> (val: ^Expr) {
|
||||
}
|
||||
for {
|
||||
e, ok := val.derived.(Paren_Expr);
|
||||
if !ok do break;
|
||||
if !ok {
|
||||
break;
|
||||
}
|
||||
val = e.expr;
|
||||
}
|
||||
return;
|
||||
|
||||
@@ -841,13 +841,13 @@ parse_attribute :: proc(p: ^Parser, tok: tokenizer.Token, open_kind, close_kind:
|
||||
decl := parse_stmt(p);
|
||||
switch d in &decl.derived {
|
||||
case ast.Value_Decl:
|
||||
if d.docs == nil do d.docs = docs;
|
||||
if d.docs == nil { d.docs = docs; }
|
||||
append(&d.attributes, attribute);
|
||||
case ast.Foreign_Block_Decl:
|
||||
if d.docs == nil do d.docs = docs;
|
||||
if d.docs == nil { d.docs = docs; }
|
||||
append(&d.attributes, attribute);
|
||||
case ast.Foreign_Import_Decl:
|
||||
if d.docs == nil do d.docs = docs;
|
||||
if d.docs == nil { d.docs = docs; }
|
||||
append(&d.attributes, attribute);
|
||||
case:
|
||||
error(p, decl.pos, "expected a value or foreign declaration after an attribute");
|
||||
@@ -1136,10 +1136,12 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
|
||||
}
|
||||
expect_token_after(p, .Colon, "identifier list");
|
||||
decl := parse_value_decl(p, list, docs);
|
||||
if decl != nil do switch d in &decl.derived {
|
||||
case ast.Value_Decl:
|
||||
d.is_using = true;
|
||||
return decl;
|
||||
if decl != nil {
|
||||
switch d in &decl.derived {
|
||||
case ast.Value_Decl:
|
||||
d.is_using = true;
|
||||
return decl;
|
||||
}
|
||||
}
|
||||
|
||||
error(p, tok.pos, "illegal use of 'using' statement");
|
||||
@@ -1442,20 +1444,20 @@ parse_field_prefixes :: proc(p: ^Parser) -> ast.Field_Flags {
|
||||
switch kind {
|
||||
case Invalid, Unknown: // Ignore
|
||||
case Using:
|
||||
if count > 1 do error(p, p.curr_tok.pos, "multiple 'using' in this field list");
|
||||
if count > 0 do flags |= {.Using};
|
||||
if count > 1 { error(p, p.curr_tok.pos, "multiple 'using' in this field list"); }
|
||||
if count > 0 { flags |= {.Using}; }
|
||||
case No_Alias:
|
||||
if count > 1 do error(p, p.curr_tok.pos, "multiple '#no_alias' in this field list");
|
||||
if count > 0 do flags |= {.No_Alias};
|
||||
if count > 1 { error(p, p.curr_tok.pos, "multiple '#no_alias' in this field list"); }
|
||||
if count > 0 { flags |= {.No_Alias}; }
|
||||
case C_Vararg:
|
||||
if count > 1 do error(p, p.curr_tok.pos, "multiple '#c_vararg' in this field list");
|
||||
if count > 0 do flags |= {.C_Vararg};
|
||||
if count > 1 { error(p, p.curr_tok.pos, "multiple '#c_vararg' in this field list"); }
|
||||
if count > 0 { flags |= {.C_Vararg}; }
|
||||
case In:
|
||||
if count > 1 do error(p, p.curr_tok.pos, "multiple 'in' in this field list");
|
||||
if count > 0 do flags |= {.In};
|
||||
if count > 1 { error(p, p.curr_tok.pos, "multiple 'in' in this field list"); }
|
||||
if count > 0 { flags |= {.In}; }
|
||||
case Auto_Cast:
|
||||
if count > 1 do error(p, p.curr_tok.pos, "multiple 'auto_cast' in this field list");
|
||||
if count > 0 do flags |= {.Auto_Cast};
|
||||
if count > 1 { error(p, p.curr_tok.pos, "multiple 'auto_cast' in this field list"); }
|
||||
if count > 0 { flags |= {.Auto_Cast}; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1610,7 +1612,9 @@ parse_field_list :: proc(p: ^Parser, follow: tokenizer.Token_Kind, allowed_flags
|
||||
return false;
|
||||
}
|
||||
is_type_ellipsis :: proc(type: ^ast.Expr) -> bool {
|
||||
if type == nil do return false;
|
||||
if type == nil {
|
||||
return false;
|
||||
}
|
||||
_, ok := type.derived.(ast.Ellipsis);
|
||||
return ok;
|
||||
}
|
||||
@@ -1653,7 +1657,9 @@ parse_field_list :: proc(p: ^Parser, follow: tokenizer.Token_Kind, allowed_flags
|
||||
}
|
||||
|
||||
if is_type_ellipsis(type) {
|
||||
if seen_ellipsis^ do error(p, type.pos, "extra variadic parameter after ellipsis");
|
||||
if seen_ellipsis^ {
|
||||
error(p, type.pos, "extra variadic parameter after ellipsis");
|
||||
}
|
||||
seen_ellipsis^ = true;
|
||||
if len(names) != 1 {
|
||||
error(p, type.pos, "variadic parameters can only have one field name");
|
||||
@@ -1914,7 +1920,9 @@ check_poly_params_for_type :: proc(p: ^Parser, poly_params: ^ast.Field_List, tok
|
||||
}
|
||||
for field in poly_params.list {
|
||||
for name in field.names {
|
||||
if name == nil do continue;
|
||||
if name == nil {
|
||||
continue;
|
||||
}
|
||||
if _, ok := name.derived.(ast.Poly_Type); ok {
|
||||
error(p, name.pos, "polymorphic names are not needed for %s parameters", tok.text);
|
||||
return;
|
||||
@@ -2316,13 +2324,19 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
tag := expect_token_after(p, .Ident, "#");
|
||||
switch tag.text {
|
||||
case "packed":
|
||||
if is_packed do error(p, tag.pos, "duplicate struct tag '#%s'", tag.text);
|
||||
if is_packed {
|
||||
error(p, tag.pos, "duplicate struct tag '#%s'", tag.text);
|
||||
}
|
||||
is_packed = true;
|
||||
case "align":
|
||||
if align != nil do error(p, tag.pos, "duplicate struct tag '#%s'", tag.text);
|
||||
if align != nil {
|
||||
error(p, tag.pos, "duplicate struct tag '#%s'", tag.text);
|
||||
}
|
||||
align = parse_expr(p, true);
|
||||
case "raw_union":
|
||||
if is_raw_union do error(p, tag.pos, "duplicate struct tag '#%s'", tag.text);
|
||||
if is_raw_union {
|
||||
error(p, tag.pos, "duplicate struct tag '#%s'", tag.text);
|
||||
}
|
||||
is_raw_union = true;
|
||||
case:
|
||||
error(p, tag.pos, "invalid struct tag '#%s", tag.text);
|
||||
@@ -2383,10 +2397,14 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
tag := expect_token_after(p, .Ident, "#");
|
||||
switch tag.text {
|
||||
case "align":
|
||||
if align != nil do error(p, tag.pos, "duplicate union tag '#%s'", tag.text);
|
||||
if align != nil {
|
||||
error(p, tag.pos, "duplicate union tag '#%s'", tag.text);
|
||||
}
|
||||
align = parse_expr(p, true);
|
||||
case "maybe":
|
||||
if is_maybe do error(p, tag.pos, "duplicate union tag '#%s'", tag.text);
|
||||
if is_maybe {
|
||||
error(p, tag.pos, "duplicate union tag '#%s'", tag.text);
|
||||
}
|
||||
is_maybe = true;
|
||||
case:
|
||||
error(p, tag.pos, "invalid union tag '#%s", tag.text);
|
||||
@@ -2675,7 +2693,9 @@ parse_call_expr :: proc(p: ^Parser, operand: ^ast.Expr) -> ^ast.Call_Expr {
|
||||
parse_atom_expr :: proc(p: ^Parser, value: ^ast.Expr, lhs: bool) -> (operand: ^ast.Expr) {
|
||||
operand = value;
|
||||
if operand == nil {
|
||||
if p.allow_type do return nil;
|
||||
if p.allow_type {
|
||||
return nil;
|
||||
}
|
||||
error(p, p.curr_tok.pos, "expected an operand");
|
||||
be := ast.new(ast.Bad_Expr, p.curr_tok.pos, end_pos(p.curr_tok));
|
||||
advance_token(p);
|
||||
@@ -3012,12 +3032,14 @@ parse_simple_stmt :: proc(p: ^Parser, flags: Stmt_Allow_Flags) -> ^ast.Stmt {
|
||||
label := lhs[0];
|
||||
stmt := parse_stmt(p);
|
||||
|
||||
if stmt != nil do switch n in &stmt.derived {
|
||||
case ast.Block_Stmt: n.label = label;
|
||||
case ast.If_Stmt: n.label = label;
|
||||
case ast.For_Stmt: n.label = label;
|
||||
case ast.Switch_Stmt: n.label = label;
|
||||
case ast.Type_Switch_Stmt: n.label = label;
|
||||
if stmt != nil {
|
||||
switch n in &stmt.derived {
|
||||
case ast.Block_Stmt: n.label = label;
|
||||
case ast.If_Stmt: n.label = label;
|
||||
case ast.For_Stmt: n.label = label;
|
||||
case ast.Switch_Stmt: n.label = label;
|
||||
case ast.Type_Switch_Stmt: n.label = label;
|
||||
}
|
||||
}
|
||||
|
||||
return stmt;
|
||||
|
||||
@@ -175,7 +175,9 @@ heap_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode,
|
||||
}
|
||||
|
||||
aligned_resize :: proc(p: rawptr, old_size: int, new_size: int, new_alignment: int) -> rawptr {
|
||||
if p == nil do return nil;
|
||||
if p == nil {
|
||||
return nil;
|
||||
}
|
||||
return aligned_alloc(new_size, new_alignment, p);
|
||||
}
|
||||
|
||||
|
||||
@@ -248,13 +248,13 @@ S_ISUID :: 0o4000; // Set user id on execution
|
||||
S_ISGID :: 0o2000; // Set group id on execution
|
||||
S_ISVTX :: 0o1000; // Directory restrcted delete
|
||||
|
||||
S_ISLNK :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFLNK;
|
||||
S_ISREG :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFREG;
|
||||
S_ISDIR :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFDIR;
|
||||
S_ISCHR :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFCHR;
|
||||
S_ISBLK :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFBLK;
|
||||
S_ISFIFO :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFIFO;
|
||||
S_ISSOCK :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFSOCK;
|
||||
S_ISLNK :: inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFLNK; }
|
||||
S_ISREG :: inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFREG; }
|
||||
S_ISDIR :: inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFDIR; }
|
||||
S_ISCHR :: inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFCHR; }
|
||||
S_ISBLK :: inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFBLK; }
|
||||
S_ISFIFO :: inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFIFO; }
|
||||
S_ISSOCK :: inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFSOCK; }
|
||||
|
||||
R_OK :: 4; // Test for read permission
|
||||
W_OK :: 2; // Test for write permission
|
||||
@@ -366,12 +366,12 @@ is_path_separator :: proc(r: rune) -> bool {
|
||||
return r == '/';
|
||||
}
|
||||
|
||||
stat :: inline proc(path: string) -> (Stat, bool) {
|
||||
stat :: inline proc(path: string) -> (Stat, Errno) {
|
||||
s: Stat;
|
||||
cstr := strings.clone_to_cstring(path);
|
||||
defer delete(cstr);
|
||||
ret_int := _unix_stat(cstr, &s);
|
||||
return s, ret_int==0;
|
||||
return s, Errno(ret_int);
|
||||
}
|
||||
|
||||
access :: inline proc(path: string, mask: int) -> bool {
|
||||
@@ -420,7 +420,9 @@ get_current_directory :: proc() -> string {
|
||||
set_current_directory :: proc(path: string) -> (err: Errno) {
|
||||
cstr := strings.clone_to_cstring(path, context.temp_allocator);
|
||||
res := _unix_chdir(cstr);
|
||||
if res == -1 do return Errno(get_last_error());
|
||||
if res == -1 {
|
||||
return Errno(get_last_error());
|
||||
}
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
@@ -463,7 +465,9 @@ get_page_size :: proc() -> int {
|
||||
// NOTE(tetra): The page size never changes, so why do anything complicated
|
||||
// if we don't have to.
|
||||
@static page_size := -1;
|
||||
if page_size != -1 do return page_size;
|
||||
if page_size != -1 {
|
||||
return page_size;
|
||||
}
|
||||
|
||||
page_size = int(_unix_getpagesize());
|
||||
return page_size;
|
||||
|
||||
@@ -56,10 +56,14 @@ heap_resize :: proc(ptr: rawptr, new_size: int) -> rawptr {
|
||||
heap_free(ptr);
|
||||
return nil;
|
||||
}
|
||||
if ptr == nil do return heap_alloc(new_size);
|
||||
if ptr == nil {
|
||||
return heap_alloc(new_size);
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
heap_free :: proc(ptr: rawptr) {
|
||||
if ptr == nil do return;
|
||||
if ptr == nil {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,13 +240,13 @@ S_ISGID :: 0o2000; // Set group id on execution
|
||||
S_ISVTX :: 0o1000; // Directory restrcted delete
|
||||
|
||||
|
||||
S_ISLNK :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFLNK;
|
||||
S_ISREG :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFREG;
|
||||
S_ISDIR :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFDIR;
|
||||
S_ISCHR :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFCHR;
|
||||
S_ISBLK :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFBLK;
|
||||
S_ISFIFO :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFIFO;
|
||||
S_ISSOCK :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFSOCK;
|
||||
S_ISLNK :: inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFLNK; }
|
||||
S_ISREG :: inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFREG; }
|
||||
S_ISDIR :: inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFDIR; }
|
||||
S_ISCHR :: inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFCHR; }
|
||||
S_ISBLK :: inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFBLK; }
|
||||
S_ISFIFO :: inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFIFO; }
|
||||
S_ISSOCK :: inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFSOCK; }
|
||||
|
||||
F_OK :: 0; // Test for file existance
|
||||
X_OK :: 1; // Test for execute permission
|
||||
@@ -451,7 +451,9 @@ get_current_directory :: proc() -> string {
|
||||
set_current_directory :: proc(path: string) -> (err: Errno) {
|
||||
cstr := strings.clone_to_cstring(path, context.temp_allocator);
|
||||
res := _unix_chdir(cstr);
|
||||
if res == -1 do return Errno(get_last_error());
|
||||
if res == -1 {
|
||||
return Errno(get_last_error());
|
||||
}
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
@@ -488,7 +490,9 @@ get_page_size :: proc() -> int {
|
||||
// NOTE(tetra): The page size never changes, so why do anything complicated
|
||||
// if we don't have to.
|
||||
@static page_size := -1;
|
||||
if page_size != -1 do return page_size;
|
||||
if page_size != -1 {
|
||||
return page_size;
|
||||
}
|
||||
|
||||
page_size = int(_unix_getpagesize());
|
||||
return page_size;
|
||||
|
||||
@@ -54,6 +54,7 @@ WSAECONNRESET: Errno : 10054;
|
||||
|
||||
// Windows reserves errors >= 1<<29 for application use
|
||||
ERROR_FILE_IS_PIPE: Errno : 1<<29 + 0;
|
||||
ERROR_FILE_IS_NOT_DIR: Errno : 1<<29 + 1;
|
||||
|
||||
|
||||
// "Argv" arguments converted to Odin strings
|
||||
@@ -65,7 +66,9 @@ is_path_separator :: proc(r: rune) -> bool {
|
||||
}
|
||||
|
||||
open :: proc(path: string, mode: int = O_RDONLY, perm: int = 0) -> (Handle, Errno) {
|
||||
if len(path) == 0 do return INVALID_HANDLE, ERROR_FILE_NOT_FOUND;
|
||||
if len(path) == 0 {
|
||||
return INVALID_HANDLE, ERROR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
access: u32;
|
||||
switch mode & (O_RDONLY|O_WRONLY|O_RDWR) {
|
||||
@@ -104,7 +107,9 @@ open :: proc(path: string, mode: int = O_RDONLY, perm: int = 0) -> (Handle, Errn
|
||||
}
|
||||
wide_path := win32.utf8_to_wstring(path);
|
||||
handle := Handle(win32.CreateFileW(auto_cast wide_path, access, share_mode, sa, create_mode, win32.FILE_ATTRIBUTE_NORMAL, nil));
|
||||
if handle != INVALID_HANDLE do return handle, ERROR_NONE;
|
||||
if handle != INVALID_HANDLE {
|
||||
return handle, ERROR_NONE;
|
||||
}
|
||||
|
||||
err := Errno(win32.GetLastError());
|
||||
return INVALID_HANDLE, err;
|
||||
@@ -119,7 +124,9 @@ close :: proc(fd: Handle) -> Errno {
|
||||
|
||||
|
||||
write :: proc(fd: Handle, data: []byte) -> (int, Errno) {
|
||||
if len(data) == 0 do return 0, ERROR_NONE;
|
||||
if len(data) == 0 {
|
||||
return 0, ERROR_NONE;
|
||||
}
|
||||
|
||||
single_write_length: win32.DWORD;
|
||||
total_write: i64;
|
||||
@@ -141,7 +148,9 @@ write :: proc(fd: Handle, data: []byte) -> (int, Errno) {
|
||||
}
|
||||
|
||||
read :: proc(fd: Handle, data: []byte) -> (int, Errno) {
|
||||
if len(data) == 0 do return 0, ERROR_NONE;
|
||||
if len(data) == 0 {
|
||||
return 0, ERROR_NONE;
|
||||
}
|
||||
|
||||
single_read_length: win32.DWORD;
|
||||
total_read: i64;
|
||||
@@ -172,7 +181,9 @@ seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {
|
||||
hi := i32(offset>>32);
|
||||
lo := i32(offset);
|
||||
ft := win32.GetFileType(win32.HANDLE(fd));
|
||||
if ft == win32.FILE_TYPE_PIPE do return 0, ERROR_FILE_IS_PIPE;
|
||||
if ft == win32.FILE_TYPE_PIPE {
|
||||
return 0, ERROR_FILE_IS_PIPE;
|
||||
}
|
||||
|
||||
dw_ptr := win32.SetFilePointer(win32.HANDLE(fd), lo, &hi, w);
|
||||
if dw_ptr == win32.INVALID_SET_FILE_POINTER {
|
||||
@@ -244,12 +255,16 @@ heap_resize :: proc(ptr: rawptr, new_size: int) -> rawptr {
|
||||
heap_free(ptr);
|
||||
return nil;
|
||||
}
|
||||
if ptr == nil do return heap_alloc(new_size);
|
||||
if ptr == nil {
|
||||
return heap_alloc(new_size);
|
||||
}
|
||||
|
||||
return win32.HeapReAlloc(win32.GetProcessHeap(), win32.HEAP_ZERO_MEMORY, ptr, uint(new_size));
|
||||
}
|
||||
heap_free :: proc(ptr: rawptr) {
|
||||
if ptr == nil do return;
|
||||
if ptr == nil {
|
||||
return;
|
||||
}
|
||||
win32.HeapFree(win32.GetProcessHeap(), 0, ptr);
|
||||
}
|
||||
|
||||
@@ -257,7 +272,9 @@ get_page_size :: proc() -> int {
|
||||
// NOTE(tetra): The page size never changes, so why do anything complicated
|
||||
// if we don't have to.
|
||||
@static page_size := -1;
|
||||
if page_size != -1 do return page_size;
|
||||
if page_size != -1 {
|
||||
return page_size;
|
||||
}
|
||||
|
||||
info: win32.SYSTEM_INFO;
|
||||
win32.GetSystemInfo(&info);
|
||||
@@ -292,7 +309,9 @@ set_current_directory :: proc(path: string) -> (err: Errno) {
|
||||
defer intrinsics.atomic_store(&cwd_gate, false);
|
||||
|
||||
res := win32.SetCurrentDirectoryW(auto_cast wstr);
|
||||
if !res do return Errno(win32.GetLastError());
|
||||
if !res {
|
||||
return Errno(win32.GetLastError());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -368,3 +387,4 @@ is_windows_10 :: proc() -> bool {
|
||||
osvi := get_windows_version_ansi();
|
||||
return (osvi.major_version == 10 && osvi.minor_version == 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,9 @@ import "core:unicode/utf8"
|
||||
|
||||
// returns everything preceding the last path element
|
||||
dir :: proc(path: string, new := false, allocator := context.allocator) -> string {
|
||||
if path == "" do return "";
|
||||
if path == "" {
|
||||
return "";
|
||||
}
|
||||
|
||||
for i := len(path) - 1; i >= 0; i -= 1 {
|
||||
if path[i] == '/' || path[i] == '\\' {
|
||||
@@ -25,7 +27,9 @@ dir :: proc(path: string, new := false, allocator := context.allocator) -> strin
|
||||
|
||||
// returns the final path element
|
||||
base :: proc(path: string, new := false, allocator := context.allocator) -> string {
|
||||
if path == "" do return "";
|
||||
if path == "" {
|
||||
return "";
|
||||
}
|
||||
|
||||
end := len(path) - 1;
|
||||
|
||||
@@ -46,7 +50,9 @@ base :: proc(path: string, new := false, allocator := context.allocator) -> stri
|
||||
|
||||
// returns the final path element, excluding the file extension if there is one
|
||||
name :: proc(path: string, new := false, allocator := context.allocator) -> string {
|
||||
if path == "" do return "";
|
||||
if path == "" {
|
||||
return "";
|
||||
}
|
||||
|
||||
end := len(path) - 1;
|
||||
dot := end;
|
||||
@@ -64,7 +70,9 @@ name :: proc(path: string, new := false, allocator := context.allocator) -> stri
|
||||
|
||||
// returns the file extension, if there is one
|
||||
ext :: proc(path: string, new := false, allocator := context.allocator) -> string {
|
||||
if path == "" do return "";
|
||||
if path == "" {
|
||||
return "";
|
||||
}
|
||||
|
||||
for i := len(path)-1; i >= 0; i -= 1 {
|
||||
switch path[i] {
|
||||
@@ -82,7 +90,9 @@ rel :: proc{rel_between, rel_current};
|
||||
|
||||
// returns the relative path from one path to another
|
||||
rel_between :: proc(from, to: string, allocator := context.allocator) -> string {
|
||||
if from == "" || to == "" do return "";
|
||||
if from == "" || to == "" {
|
||||
return "";
|
||||
}
|
||||
|
||||
from, to := from, to;
|
||||
from = full(from, context.temp_allocator);
|
||||
|
||||
@@ -60,21 +60,21 @@ current :: proc(allocator := context.temp_allocator) -> string {
|
||||
|
||||
|
||||
exists :: proc(path: string) -> bool {
|
||||
if _, ok := os.stat(path); ok {
|
||||
if _, err := os.stat(path); err != 0 {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
is_dir :: proc(path: string) -> bool {
|
||||
if stat, ok := os.stat(path); ok {
|
||||
if stat, err := os.stat(path); err != 0 {
|
||||
return os.S_ISDIR(u32(stat.mode));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
is_file :: proc(path: string) -> bool {
|
||||
if stat, ok := os.stat(path); ok {
|
||||
if stat, err := os.stat(path); err != 0 {
|
||||
return os.S_ISREG(u32(stat.mode));
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -23,7 +23,9 @@ long :: proc(path: string, allocator := context.temp_allocator) -> string {
|
||||
c_path := win32.utf8_to_wstring(path, context.temp_allocator);
|
||||
length := win32.GetLongPathNameW(c_path, nil, 0);
|
||||
|
||||
if length == 0 do return "";
|
||||
if length == 0 {
|
||||
return "";
|
||||
}
|
||||
|
||||
buf := make([]u16, length, context.temp_allocator);
|
||||
|
||||
@@ -38,7 +40,9 @@ short :: proc(path: string, allocator := context.temp_allocator) -> string {
|
||||
c_path := win32.utf8_to_wstring(path, context.temp_allocator);
|
||||
length := win32.GetShortPathNameW(c_path, nil, 0);
|
||||
|
||||
if length == 0 do return "";
|
||||
if length == 0 {
|
||||
return "";
|
||||
}
|
||||
|
||||
buf := make([]u16, length, context.temp_allocator);
|
||||
|
||||
@@ -53,7 +57,9 @@ full :: proc(path: string, allocator := context.temp_allocator) -> string {
|
||||
c_path := win32.utf8_to_wstring(path, context.temp_allocator);
|
||||
length := win32.GetFullPathNameW(c_path, 0, nil, nil);
|
||||
|
||||
if length == 0 do return "";
|
||||
if length == 0 {
|
||||
return "";
|
||||
}
|
||||
|
||||
buf := make([]u16, length, context.temp_allocator);
|
||||
|
||||
@@ -67,7 +73,9 @@ full :: proc(path: string, allocator := context.temp_allocator) -> string {
|
||||
current :: proc(allocator := context.temp_allocator) -> string {
|
||||
length := win32.GetCurrentDirectoryW(0, nil);
|
||||
|
||||
if length == 0 do return "";
|
||||
if length == 0 {
|
||||
return "";
|
||||
}
|
||||
|
||||
buf := make([]u16, length, context.temp_allocator);
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@ backing_type_kind :: proc(T: typeid) -> Type_Kind {
|
||||
|
||||
|
||||
type_info_base :: proc(info: ^runtime.Type_Info) -> ^runtime.Type_Info {
|
||||
if info == nil do return nil;
|
||||
if info == nil { return nil; }
|
||||
|
||||
base := info;
|
||||
loop: for {
|
||||
@@ -130,7 +130,7 @@ type_info_base :: proc(info: ^runtime.Type_Info) -> ^runtime.Type_Info {
|
||||
|
||||
|
||||
type_info_core :: proc(info: ^runtime.Type_Info) -> ^runtime.Type_Info {
|
||||
if info == nil do return nil;
|
||||
if info == nil { return nil; }
|
||||
|
||||
base := info;
|
||||
loop: for {
|
||||
@@ -159,7 +159,7 @@ typeid_base_without_enum :: typeid_core;
|
||||
|
||||
typeid_elem :: proc(id: typeid) -> typeid {
|
||||
ti := type_info_of(id);
|
||||
if ti == nil do return nil;
|
||||
if ti == nil { return nil; }
|
||||
|
||||
bits := 8*ti.size;
|
||||
|
||||
@@ -219,14 +219,16 @@ is_nil :: proc(v: any) -> bool {
|
||||
if data != nil {
|
||||
return true;
|
||||
}
|
||||
for v in data do if v != 0 {
|
||||
return false;
|
||||
for v in data {
|
||||
if v != 0 {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
length :: proc(val: any) -> int {
|
||||
if val == nil do return 0;
|
||||
if val == nil { return 0; }
|
||||
|
||||
#partial switch a in type_info_of(val.id).variant {
|
||||
case Type_Info_Named:
|
||||
@@ -261,7 +263,7 @@ length :: proc(val: any) -> int {
|
||||
}
|
||||
|
||||
capacity :: proc(val: any) -> int {
|
||||
if val == nil do return 0;
|
||||
if val == nil { return 0; }
|
||||
|
||||
#partial switch a in type_info_of(val.id).variant {
|
||||
case Type_Info_Named:
|
||||
@@ -287,7 +289,7 @@ capacity :: proc(val: any) -> int {
|
||||
|
||||
|
||||
index :: proc(val: any, i: int, loc := #caller_location) -> any {
|
||||
if val == nil do return nil;
|
||||
if val == nil { return nil; }
|
||||
|
||||
#partial switch a in type_info_of(val.id).variant {
|
||||
case Type_Info_Named:
|
||||
@@ -327,7 +329,7 @@ index :: proc(val: any, i: int, loc := #caller_location) -> any {
|
||||
return any{data, a.elem.id};
|
||||
|
||||
case Type_Info_String:
|
||||
if a.is_cstring do return nil;
|
||||
if a.is_cstring { return nil; }
|
||||
|
||||
raw := (^mem.Raw_String)(val.data);
|
||||
runtime.bounds_check_error_loc(loc, i, raw.len);
|
||||
@@ -380,7 +382,7 @@ struct_field_by_name :: proc(T: typeid, name: string) -> (field: Struct_Field) {
|
||||
}
|
||||
|
||||
struct_field_value_by_name :: proc(a: any, field: string, recurse := false) -> any {
|
||||
if a == nil do return nil;
|
||||
if a == nil { return nil; }
|
||||
|
||||
ti := runtime.type_info_base(type_info_of(a.id));
|
||||
|
||||
@@ -457,7 +459,9 @@ struct_tag_lookup :: proc(tag: Struct_Tag, key: string) -> (value: Struct_Tag, o
|
||||
i += 1;
|
||||
}
|
||||
t = t[i:];
|
||||
if len(t) == 0 do break;
|
||||
if len(t) == 0 {
|
||||
break;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
loop: for i < len(t) {
|
||||
@@ -470,8 +474,12 @@ struct_tag_lookup :: proc(tag: Struct_Tag, key: string) -> (value: Struct_Tag, o
|
||||
i += 1;
|
||||
}
|
||||
|
||||
if i == 0 do break;
|
||||
if i+1 >= len(t) do break;
|
||||
if i == 0 {
|
||||
break;
|
||||
}
|
||||
if i+1 >= len(t) {
|
||||
break;
|
||||
}
|
||||
|
||||
if t[i] != ':' || t[i+1] != '"' {
|
||||
break;
|
||||
@@ -481,11 +489,15 @@ struct_tag_lookup :: proc(tag: Struct_Tag, key: string) -> (value: Struct_Tag, o
|
||||
|
||||
i = 1;
|
||||
for i < len(t) && t[i] != '"' { // find closing quote
|
||||
if t[i] == '\\' do i += 1; // Skip escaped characters
|
||||
if t[i] == '\\' {
|
||||
i += 1; // Skip escaped characters
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
|
||||
if i >= len(t) do break;
|
||||
if i >= len(t) {
|
||||
break;
|
||||
}
|
||||
|
||||
val := string(t[:i+1]);
|
||||
t = t[i+1:];
|
||||
@@ -499,7 +511,7 @@ struct_tag_lookup :: proc(tag: Struct_Tag, key: string) -> (value: Struct_Tag, o
|
||||
|
||||
|
||||
enum_string :: proc(a: any) -> string {
|
||||
if a == nil do return "";
|
||||
if a == nil { return ""; }
|
||||
ti := runtime.type_info_base(type_info_of(a.id));
|
||||
if e, ok := ti.variant.(runtime.Type_Info_Enum); ok {
|
||||
v, _ := as_i64(a);
|
||||
@@ -520,7 +532,9 @@ enum_from_name :: proc($EnumType: typeid, name: string) -> (value: EnumType, ok:
|
||||
ti := type_info_base(type_info_of(EnumType));
|
||||
if eti, eti_ok := ti.variant.(runtime.Type_Info_Enum); eti_ok {
|
||||
for value_name, i in eti.names {
|
||||
if value_name != name do continue;
|
||||
if value_name != name {
|
||||
continue;
|
||||
}
|
||||
v := eti.values[i];
|
||||
value = EnumType(v);
|
||||
ok = true;
|
||||
@@ -538,7 +552,7 @@ union_variant_type_info :: proc(a: any) -> ^runtime.Type_Info {
|
||||
}
|
||||
|
||||
union_variant_typeid :: proc(a: any) -> typeid {
|
||||
if a == nil do return nil;
|
||||
if a == nil { return nil; }
|
||||
|
||||
ti := runtime.type_info_base(type_info_of(a.id));
|
||||
if info, ok := ti.variant.(runtime.Type_Info_Union); ok {
|
||||
@@ -584,7 +598,7 @@ as_uint :: proc(a: any) -> (value: uint, valid: bool) {
|
||||
}
|
||||
|
||||
as_i64 :: proc(a: any) -> (value: i64, valid: bool) {
|
||||
if a == nil do return;
|
||||
if a == nil { return; }
|
||||
a := a;
|
||||
ti := runtime.type_info_core(type_info_of(a.id));
|
||||
a.id = ti.id;
|
||||
@@ -691,7 +705,7 @@ as_i64 :: proc(a: any) -> (value: i64, valid: bool) {
|
||||
}
|
||||
|
||||
as_u64 :: proc(a: any) -> (value: u64, valid: bool) {
|
||||
if a == nil do return;
|
||||
if a == nil { return; }
|
||||
a := a;
|
||||
ti := runtime.type_info_core(type_info_of(a.id));
|
||||
a.id = ti.id;
|
||||
@@ -799,7 +813,7 @@ as_u64 :: proc(a: any) -> (value: u64, valid: bool) {
|
||||
|
||||
|
||||
as_f64 :: proc(a: any) -> (value: f64, valid: bool) {
|
||||
if a == nil do return;
|
||||
if a == nil { return; }
|
||||
a := a;
|
||||
ti := runtime.type_info_core(type_info_of(a.id));
|
||||
a.id = ti.id;
|
||||
|
||||
@@ -3,7 +3,9 @@ package reflect
|
||||
import "core:strings"
|
||||
|
||||
are_types_identical :: proc(a, b: ^Type_Info) -> bool {
|
||||
if a == b do return true;
|
||||
if a == b {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (a == nil && b != nil) ||
|
||||
(a != nil && b == nil) {
|
||||
@@ -19,12 +21,12 @@ are_types_identical :: proc(a, b: ^Type_Info) -> bool {
|
||||
switch x in a.variant {
|
||||
case Type_Info_Named:
|
||||
y, ok := b.variant.(Type_Info_Named);
|
||||
if !ok do return false;
|
||||
if !ok { return false; }
|
||||
return x.base == y.base;
|
||||
|
||||
case Type_Info_Integer:
|
||||
y, ok := b.variant.(Type_Info_Integer);
|
||||
if !ok do return false;
|
||||
if !ok { return false; }
|
||||
return x.signed == y.signed && x.endianness == y.endianness;
|
||||
|
||||
case Type_Info_Rune:
|
||||
@@ -61,12 +63,12 @@ are_types_identical :: proc(a, b: ^Type_Info) -> bool {
|
||||
|
||||
case Type_Info_Pointer:
|
||||
y, ok := b.variant.(Type_Info_Pointer);
|
||||
if !ok do return false;
|
||||
if !ok { return false; }
|
||||
return are_types_identical(x.elem, y.elem);
|
||||
|
||||
case Type_Info_Procedure:
|
||||
y, ok := b.variant.(Type_Info_Procedure);
|
||||
if !ok do return false;
|
||||
if !ok { return false; }
|
||||
switch {
|
||||
case x.variadic != y.variadic,
|
||||
x.convention != y.convention:
|
||||
@@ -77,31 +79,31 @@ are_types_identical :: proc(a, b: ^Type_Info) -> bool {
|
||||
|
||||
case Type_Info_Array:
|
||||
y, ok := b.variant.(Type_Info_Array);
|
||||
if !ok do return false;
|
||||
if x.count != y.count do return false;
|
||||
if !ok { return false; }
|
||||
if x.count != y.count { return false; }
|
||||
return are_types_identical(x.elem, y.elem);
|
||||
|
||||
case Type_Info_Enumerated_Array:
|
||||
y, ok := b.variant.(Type_Info_Enumerated_Array);
|
||||
if !ok do return false;
|
||||
if x.count != y.count do return false;
|
||||
if !ok { return false; }
|
||||
if x.count != y.count { return false; }
|
||||
return are_types_identical(x.index, y.index) &&
|
||||
are_types_identical(x.elem, y.elem);
|
||||
|
||||
case Type_Info_Dynamic_Array:
|
||||
y, ok := b.variant.(Type_Info_Dynamic_Array);
|
||||
if !ok do return false;
|
||||
if !ok { return false; }
|
||||
return are_types_identical(x.elem, y.elem);
|
||||
|
||||
case Type_Info_Slice:
|
||||
y, ok := b.variant.(Type_Info_Slice);
|
||||
if !ok do return false;
|
||||
if !ok { return false; }
|
||||
return are_types_identical(x.elem, y.elem);
|
||||
|
||||
case Type_Info_Tuple:
|
||||
y, ok := b.variant.(Type_Info_Tuple);
|
||||
if !ok do return false;
|
||||
if len(x.types) != len(y.types) do return false;
|
||||
if !ok { return false; }
|
||||
if len(x.types) != len(y.types) { return false; }
|
||||
for _, i in x.types {
|
||||
xt, yt := x.types[i], y.types[i];
|
||||
if !are_types_identical(xt, yt) {
|
||||
@@ -112,7 +114,7 @@ are_types_identical :: proc(a, b: ^Type_Info) -> bool {
|
||||
|
||||
case Type_Info_Struct:
|
||||
y, ok := b.variant.(Type_Info_Struct);
|
||||
if !ok do return false;
|
||||
if !ok { return false; }
|
||||
switch {
|
||||
case len(x.types) != len(y.types),
|
||||
x.is_packed != y.is_packed,
|
||||
@@ -128,20 +130,20 @@ are_types_identical :: proc(a, b: ^Type_Info) -> bool {
|
||||
xt, yt := x.types[i], y.types[i];
|
||||
xl, yl := x.tags[i], y.tags[i];
|
||||
|
||||
if xn != yn do return false;
|
||||
if !are_types_identical(xt, yt) do return false;
|
||||
if xl != yl do return false;
|
||||
if xn != yn { return false; }
|
||||
if !are_types_identical(xt, yt) { return false; }
|
||||
if xl != yl { return false; }
|
||||
}
|
||||
return true;
|
||||
|
||||
case Type_Info_Union:
|
||||
y, ok := b.variant.(Type_Info_Union);
|
||||
if !ok do return false;
|
||||
if len(x.variants) != len(y.variants) do return false;
|
||||
if !ok { return false; }
|
||||
if len(x.variants) != len(y.variants) { return false; }
|
||||
|
||||
for _, i in x.variants {
|
||||
xv, yv := x.variants[i], y.variants[i];
|
||||
if !are_types_identical(xv, yv) do return false;
|
||||
if !are_types_identical(xv, yv) { return false; }
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -151,48 +153,48 @@ are_types_identical :: proc(a, b: ^Type_Info) -> bool {
|
||||
|
||||
case Type_Info_Map:
|
||||
y, ok := b.variant.(Type_Info_Map);
|
||||
if !ok do return false;
|
||||
if !ok { return false; }
|
||||
return are_types_identical(x.key, y.key) && are_types_identical(x.value, y.value);
|
||||
|
||||
case Type_Info_Bit_Field:
|
||||
y, ok := b.variant.(Type_Info_Bit_Field);
|
||||
if !ok do return false;
|
||||
if len(x.names) != len(y.names) do return false;
|
||||
if !ok { return false; }
|
||||
if len(x.names) != len(y.names) { return false; }
|
||||
|
||||
for _, i in x.names {
|
||||
xb, yb := x.bits[i], y.bits[i];
|
||||
xo, yo := x.offsets[i], y.offsets[i];
|
||||
xn, yn := x.names[i], y.names[i];
|
||||
|
||||
if xb != yb do return false;
|
||||
if xo != yo do return false;
|
||||
if xn != yn do return false;
|
||||
if xb != yb { return false; }
|
||||
if xo != yo { return false; }
|
||||
if xn != yn { return false; }
|
||||
}
|
||||
return true;
|
||||
|
||||
case Type_Info_Bit_Set:
|
||||
y, ok := b.variant.(Type_Info_Bit_Set);
|
||||
if !ok do return false;
|
||||
if !ok { return false; }
|
||||
return x.elem == y.elem && x.lower == y.lower && x.upper == y.upper;
|
||||
|
||||
case Type_Info_Opaque:
|
||||
y, ok := b.variant.(Type_Info_Opaque);
|
||||
if !ok do return false;
|
||||
if !ok { return false; }
|
||||
return x.elem == y.elem;
|
||||
|
||||
case Type_Info_Simd_Vector:
|
||||
y, ok := b.variant.(Type_Info_Simd_Vector);
|
||||
if !ok do return false;
|
||||
if !ok { return false; }
|
||||
return x.count == y.count && x.elem == y.elem;
|
||||
|
||||
case Type_Info_Relative_Pointer:
|
||||
y, ok := b.variant.(Type_Info_Relative_Pointer);
|
||||
if !ok do return false;
|
||||
if !ok { return false; }
|
||||
return x.base_integer == y.base_integer && x.pointer == y.pointer;
|
||||
|
||||
case Type_Info_Relative_Slice:
|
||||
y, ok := b.variant.(Type_Info_Relative_Slice);
|
||||
if !ok do return false;
|
||||
if !ok { return false; }
|
||||
return x.base_integer == y.base_integer && x.slice == y.slice;
|
||||
}
|
||||
|
||||
@@ -200,7 +202,7 @@ are_types_identical :: proc(a, b: ^Type_Info) -> bool {
|
||||
}
|
||||
|
||||
is_signed :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil do return false;
|
||||
if info == nil { return false; }
|
||||
#partial switch i in type_info_base(info).variant {
|
||||
case Type_Info_Integer: return i.signed;
|
||||
case Type_Info_Float: return true;
|
||||
@@ -208,7 +210,7 @@ is_signed :: proc(info: ^Type_Info) -> bool {
|
||||
return false;
|
||||
}
|
||||
is_unsigned :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil do return false;
|
||||
if info == nil { return false; }
|
||||
#partial switch i in type_info_base(info).variant {
|
||||
case Type_Info_Integer: return !i.signed;
|
||||
case Type_Info_Float: return false;
|
||||
@@ -218,127 +220,127 @@ is_unsigned :: proc(info: ^Type_Info) -> bool {
|
||||
|
||||
|
||||
is_integer :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil do return false;
|
||||
if info == nil { return false; }
|
||||
_, ok := type_info_base(info).variant.(Type_Info_Integer);
|
||||
return ok;
|
||||
}
|
||||
is_rune :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil do return false;
|
||||
if info == nil { return false; }
|
||||
_, ok := type_info_base(info).variant.(Type_Info_Rune);
|
||||
return ok;
|
||||
}
|
||||
is_float :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil do return false;
|
||||
if info == nil { return false; }
|
||||
_, ok := type_info_base(info).variant.(Type_Info_Float);
|
||||
return ok;
|
||||
}
|
||||
is_complex :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil do return false;
|
||||
if info == nil { return false; }
|
||||
_, ok := type_info_base(info).variant.(Type_Info_Complex);
|
||||
return ok;
|
||||
}
|
||||
is_quaternion :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil do return false;
|
||||
if info == nil { return false; }
|
||||
_, ok := type_info_base(info).variant.(Type_Info_Quaternion);
|
||||
return ok;
|
||||
}
|
||||
is_any :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil do return false;
|
||||
if info == nil { return false; }
|
||||
_, ok := type_info_base(info).variant.(Type_Info_Any);
|
||||
return ok;
|
||||
}
|
||||
is_string :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil do return false;
|
||||
if info == nil { return false; }
|
||||
_, ok := type_info_base(info).variant.(Type_Info_String);
|
||||
return ok;
|
||||
}
|
||||
is_cstring :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil do return false;
|
||||
if info == nil { return false; }
|
||||
v, ok := type_info_base(info).variant.(Type_Info_String);
|
||||
return ok && v.is_cstring;
|
||||
}
|
||||
is_boolean :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil do return false;
|
||||
if info == nil { return false; }
|
||||
_, ok := type_info_base(info).variant.(Type_Info_Boolean);
|
||||
return ok;
|
||||
}
|
||||
is_pointer :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil do return false;
|
||||
if info == nil { return false; }
|
||||
_, ok := type_info_base(info).variant.(Type_Info_Pointer);
|
||||
return ok;
|
||||
}
|
||||
is_procedure :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil do return false;
|
||||
if info == nil { return false; }
|
||||
_, ok := type_info_base(info).variant.(Type_Info_Procedure);
|
||||
return ok;
|
||||
}
|
||||
is_array :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil do return false;
|
||||
if info == nil { return false; }
|
||||
_, ok := type_info_base(info).variant.(Type_Info_Array);
|
||||
return ok;
|
||||
}
|
||||
is_enumerated_array :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil do return false;
|
||||
if info == nil { return false; }
|
||||
_, ok := type_info_base(info).variant.(Type_Info_Enumerated_Array);
|
||||
return ok;
|
||||
}
|
||||
is_dynamic_array :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil do return false;
|
||||
if info == nil { return false; }
|
||||
_, ok := type_info_base(info).variant.(Type_Info_Dynamic_Array);
|
||||
return ok;
|
||||
}
|
||||
is_dynamic_map :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil do return false;
|
||||
if info == nil { return false; }
|
||||
_, ok := type_info_base(info).variant.(Type_Info_Map);
|
||||
return ok;
|
||||
}
|
||||
is_slice :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil do return false;
|
||||
if info == nil { return false; }
|
||||
_, ok := type_info_base(info).variant.(Type_Info_Slice);
|
||||
return ok;
|
||||
}
|
||||
is_tuple :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil do return false;
|
||||
if info == nil { return false; }
|
||||
_, ok := type_info_base(info).variant.(Type_Info_Tuple);
|
||||
return ok;
|
||||
}
|
||||
is_struct :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil do return false;
|
||||
if info == nil { return false; }
|
||||
s, ok := type_info_base(info).variant.(Type_Info_Struct);
|
||||
return ok && !s.is_raw_union;
|
||||
}
|
||||
is_raw_union :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil do return false;
|
||||
if info == nil { return false; }
|
||||
s, ok := type_info_base(info).variant.(Type_Info_Struct);
|
||||
return ok && s.is_raw_union;
|
||||
}
|
||||
is_union :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil do return false;
|
||||
if info == nil { return false; }
|
||||
_, ok := type_info_base(info).variant.(Type_Info_Union);
|
||||
return ok;
|
||||
}
|
||||
is_enum :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil do return false;
|
||||
if info == nil { return false; }
|
||||
_, ok := type_info_base(info).variant.(Type_Info_Enum);
|
||||
return ok;
|
||||
}
|
||||
is_opaque :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil do return false;
|
||||
if info == nil { return false; }
|
||||
_, ok := type_info_base(info).variant.(Type_Info_Opaque);
|
||||
return ok;
|
||||
}
|
||||
is_simd_vector :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil do return false;
|
||||
if info == nil { return false; }
|
||||
_, ok := type_info_base(info).variant.(Type_Info_Simd_Vector);
|
||||
return ok;
|
||||
}
|
||||
is_relative_pointer :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil do return false;
|
||||
if info == nil { return false; }
|
||||
_, ok := type_info_base(info).variant.(Type_Info_Relative_Pointer);
|
||||
return ok;
|
||||
}
|
||||
is_relative_slice :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil do return false;
|
||||
if info == nil { return false; }
|
||||
_, ok := type_info_base(info).variant.(Type_Info_Relative_Slice);
|
||||
return ok;
|
||||
}
|
||||
@@ -428,7 +430,9 @@ write_type :: proc(buf: ^strings.Builder, ti: ^Type_Info) {
|
||||
t := info.params.variant.(Type_Info_Tuple);
|
||||
write_string(buf, "(");
|
||||
for t, i in t.types {
|
||||
if i > 0 do write_string(buf, ", ");
|
||||
if i > 0 {
|
||||
write_string(buf, ", ");
|
||||
}
|
||||
write_type(buf, t);
|
||||
}
|
||||
write_string(buf, ")");
|
||||
@@ -439,9 +443,9 @@ write_type :: proc(buf: ^strings.Builder, ti: ^Type_Info) {
|
||||
}
|
||||
case Type_Info_Tuple:
|
||||
count := len(info.names);
|
||||
if count != 1 do write_string(buf, "(");
|
||||
if count != 1 { write_string(buf, "("); }
|
||||
for name, i in info.names {
|
||||
if i > 0 do write_string(buf, ", ");
|
||||
if i > 0 { write_string(buf, ", "); }
|
||||
|
||||
t := info.types[i];
|
||||
|
||||
@@ -451,7 +455,7 @@ write_type :: proc(buf: ^strings.Builder, ti: ^Type_Info) {
|
||||
}
|
||||
write_type(buf, t);
|
||||
}
|
||||
if count != 1 do write_string(buf, ")");
|
||||
if count != 1 { write_string(buf, ")"); }
|
||||
|
||||
case Type_Info_Array:
|
||||
write_string(buf, "[");
|
||||
@@ -498,8 +502,8 @@ write_type :: proc(buf: ^strings.Builder, ti: ^Type_Info) {
|
||||
}
|
||||
|
||||
write_string(buf, "struct ");
|
||||
if info.is_packed do write_string(buf, "#packed ");
|
||||
if info.is_raw_union do write_string(buf, "#raw_union ");
|
||||
if info.is_packed { write_string(buf, "#packed "); }
|
||||
if info.is_raw_union { write_string(buf, "#raw_union "); }
|
||||
if info.custom_align {
|
||||
write_string(buf, "#align ");
|
||||
write_i64(buf, i64(ti.align), 10);
|
||||
@@ -507,7 +511,7 @@ write_type :: proc(buf: ^strings.Builder, ti: ^Type_Info) {
|
||||
}
|
||||
write_byte(buf, '{');
|
||||
for name, i in info.names {
|
||||
if i > 0 do write_string(buf, ", ");
|
||||
if i > 0 { write_string(buf, ", "); }
|
||||
write_string(buf, name);
|
||||
write_string(buf, ": ");
|
||||
write_type(buf, info.types[i]);
|
||||
@@ -523,7 +527,7 @@ write_type :: proc(buf: ^strings.Builder, ti: ^Type_Info) {
|
||||
}
|
||||
write_byte(buf, '{');
|
||||
for variant, i in info.variants {
|
||||
if i > 0 do write_string(buf, ", ");
|
||||
if i > 0 { write_string(buf, ", "); }
|
||||
write_type(buf, variant);
|
||||
}
|
||||
write_byte(buf, '}');
|
||||
@@ -533,7 +537,7 @@ write_type :: proc(buf: ^strings.Builder, ti: ^Type_Info) {
|
||||
write_type(buf, info.base);
|
||||
write_string(buf, " {");
|
||||
for name, i in info.names {
|
||||
if i > 0 do write_string(buf, ", ");
|
||||
if i > 0 { write_string(buf, ", "); }
|
||||
write_string(buf, name);
|
||||
}
|
||||
write_byte(buf, '}');
|
||||
@@ -547,7 +551,7 @@ write_type :: proc(buf: ^strings.Builder, ti: ^Type_Info) {
|
||||
}
|
||||
write_string(buf, " {");
|
||||
for name, i in info.names {
|
||||
if i > 0 do write_string(buf, ", ");
|
||||
if i > 0 { write_string(buf, ", "); }
|
||||
write_string(buf, name);
|
||||
write_string(buf, ": ");
|
||||
write_i64(buf, i64(info.bits[i]), 10);
|
||||
|
||||
@@ -408,7 +408,9 @@ foreign {
|
||||
|
||||
|
||||
type_info_base :: proc "contextless" (info: ^Type_Info) -> ^Type_Info {
|
||||
if info == nil do return nil;
|
||||
if info == nil {
|
||||
return nil;
|
||||
}
|
||||
|
||||
base := info;
|
||||
loop: for {
|
||||
@@ -422,7 +424,9 @@ type_info_base :: proc "contextless" (info: ^Type_Info) -> ^Type_Info {
|
||||
|
||||
|
||||
type_info_core :: proc "contextless" (info: ^Type_Info) -> ^Type_Info {
|
||||
if info == nil do return nil;
|
||||
if info == nil {
|
||||
return nil;
|
||||
}
|
||||
|
||||
base := info;
|
||||
loop: for {
|
||||
@@ -477,7 +481,7 @@ foreign {
|
||||
|
||||
|
||||
default_logger_proc :: proc(data: rawptr, level: Logger_Level, text: string, options: Logger_Options, location := #caller_location) {
|
||||
// Do nothing
|
||||
// Nothing
|
||||
}
|
||||
|
||||
default_logger :: proc() -> Logger {
|
||||
@@ -493,14 +497,18 @@ default_context :: proc "contextless" () -> Context {
|
||||
|
||||
@private
|
||||
__init_context_from_ptr :: proc "contextless" (c: ^Context, other: ^Context) {
|
||||
if c == nil do return;
|
||||
if c == nil {
|
||||
return;
|
||||
}
|
||||
c^ = other^;
|
||||
__init_context(c);
|
||||
}
|
||||
|
||||
@private
|
||||
__init_context :: proc "contextless" (c: ^Context) {
|
||||
if c == nil do return;
|
||||
if c == nil {
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE(bill): Do not initialize these procedures with a call as they are not defined with the "contexless" calling convention
|
||||
c.allocator.procedure = default_allocator_proc;
|
||||
@@ -699,14 +707,14 @@ delete :: proc{
|
||||
@builtin
|
||||
new :: inline proc($T: typeid, allocator := context.allocator, loc := #caller_location) -> ^T {
|
||||
ptr := (^T)(mem_alloc(size_of(T), align_of(T), allocator, loc));
|
||||
if ptr != nil do ptr^ = T{};
|
||||
if ptr != nil { ptr^ = T{}; }
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@builtin
|
||||
new_clone :: inline proc(data: $T, allocator := context.allocator, loc := #caller_location) -> ^T {
|
||||
ptr := (^T)(mem_alloc(size_of(T), align_of(T), allocator, loc));
|
||||
if ptr != nil do ptr^ = data;
|
||||
if ptr != nil { ptr^ = data; }
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@@ -771,7 +779,9 @@ make :: proc{
|
||||
|
||||
@builtin
|
||||
clear_map :: inline proc "contextless" (m: ^$T/map[$K]$V) {
|
||||
if m == nil do return;
|
||||
if m == nil {
|
||||
return;
|
||||
}
|
||||
raw_map := (^Raw_Map)(m);
|
||||
entries := (^Raw_Dynamic_Array)(&raw_map.entries);
|
||||
entries.len = 0;
|
||||
@@ -782,19 +792,25 @@ clear_map :: inline proc "contextless" (m: ^$T/map[$K]$V) {
|
||||
|
||||
@builtin
|
||||
reserve_map :: proc(m: ^$T/map[$K]$V, capacity: int) {
|
||||
if m != nil do __dynamic_map_reserve(__get_map_header(m), capacity);
|
||||
if m != nil {
|
||||
__dynamic_map_reserve(__get_map_header(m), capacity);
|
||||
}
|
||||
}
|
||||
|
||||
@builtin
|
||||
delete_key :: proc(m: ^$T/map[$K]$V, key: K) {
|
||||
if m != nil do __dynamic_map_delete_key(__get_map_header(m), __get_map_key(key));
|
||||
if m != nil {
|
||||
__dynamic_map_delete_key(__get_map_header(m), __get_map_key(key));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@builtin
|
||||
append_elem :: proc(array: ^$T/[dynamic]$E, arg: E, loc := #caller_location) {
|
||||
if array == nil do return;
|
||||
if array == nil {
|
||||
return;
|
||||
}
|
||||
|
||||
arg_len := 1;
|
||||
|
||||
@@ -816,10 +832,14 @@ append_elem :: proc(array: ^$T/[dynamic]$E, arg: E, loc := #caller_location) {
|
||||
}
|
||||
@builtin
|
||||
append_elems :: proc(array: ^$T/[dynamic]$E, args: ..E, loc := #caller_location) {
|
||||
if array == nil do return;
|
||||
if array == nil {
|
||||
return;
|
||||
}
|
||||
|
||||
arg_len := len(args);
|
||||
if arg_len <= 0 do return;
|
||||
if arg_len <= 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if cap(array) < len(array)+arg_len {
|
||||
@@ -845,10 +865,14 @@ append_elem_string :: proc(array: ^$T/[dynamic]$E/u8, arg: $A/string, loc := #ca
|
||||
|
||||
@builtin
|
||||
reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, loc := #caller_location) -> bool {
|
||||
if array == nil do return false;
|
||||
if array == nil {
|
||||
return false;
|
||||
}
|
||||
|
||||
old_cap := cap(array);
|
||||
if capacity <= old_cap do return true;
|
||||
if capacity <= old_cap {
|
||||
return true;
|
||||
}
|
||||
|
||||
if array.allocator.procedure == nil {
|
||||
array.allocator = context.allocator;
|
||||
@@ -894,7 +918,9 @@ reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, loc := #caller_lo
|
||||
array.allocator.data, .Alloc, new_size, max_align,
|
||||
nil, old_size, 0, loc,
|
||||
);
|
||||
if new_data == nil do return false;
|
||||
if new_data == nil {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
cap_ptr^ = capacity;
|
||||
@@ -929,7 +955,9 @@ reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, loc := #caller_lo
|
||||
|
||||
@builtin
|
||||
append_soa_elem :: proc(array: ^$T/#soa[dynamic]$E, arg: E, loc := #caller_location) {
|
||||
if array == nil do return;
|
||||
if array == nil {
|
||||
return;
|
||||
}
|
||||
|
||||
arg_len := 1;
|
||||
|
||||
@@ -981,7 +1009,9 @@ append_soa_elem :: proc(array: ^$T/#soa[dynamic]$E, arg: E, loc := #caller_locat
|
||||
|
||||
@builtin
|
||||
append_soa_elems :: proc(array: ^$T/#soa[dynamic]$E, args: ..E, loc := #caller_location) {
|
||||
if array == nil do return;
|
||||
if array == nil {
|
||||
return;
|
||||
}
|
||||
|
||||
arg_len := len(args);
|
||||
if arg_len == 0 {
|
||||
@@ -1118,15 +1148,21 @@ insert_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, index: int, arg: string
|
||||
|
||||
@builtin
|
||||
clear_dynamic_array :: inline proc "contextless" (array: ^$T/[dynamic]$E) {
|
||||
if array != nil do (^Raw_Dynamic_Array)(array).len = 0;
|
||||
if array != nil {
|
||||
(^Raw_Dynamic_Array)(array).len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@builtin
|
||||
reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, capacity: int, loc := #caller_location) -> bool {
|
||||
if array == nil do return false;
|
||||
if array == nil {
|
||||
return false;
|
||||
}
|
||||
a := (^Raw_Dynamic_Array)(array);
|
||||
|
||||
if capacity <= a.cap do return true;
|
||||
if capacity <= a.cap {
|
||||
return true;
|
||||
}
|
||||
|
||||
if a.allocator.procedure == nil {
|
||||
a.allocator = context.allocator;
|
||||
@@ -1141,7 +1177,9 @@ reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, capacity: int, loc := #cal
|
||||
allocator.data, .Resize, new_size, align_of(E),
|
||||
a.data, old_size, 0, loc,
|
||||
);
|
||||
if new_data == nil do return false;
|
||||
if new_data == nil {
|
||||
return false;
|
||||
}
|
||||
|
||||
a.data = new_data;
|
||||
a.cap = capacity;
|
||||
@@ -1150,7 +1188,9 @@ reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, capacity: int, loc := #cal
|
||||
|
||||
@builtin
|
||||
resize_dynamic_array :: proc(array: ^$T/[dynamic]$E, length: int, loc := #caller_location) -> bool {
|
||||
if array == nil do return false;
|
||||
if array == nil {
|
||||
return false;
|
||||
}
|
||||
a := (^Raw_Dynamic_Array)(array);
|
||||
|
||||
if length <= a.cap {
|
||||
@@ -1171,7 +1211,9 @@ resize_dynamic_array :: proc(array: ^$T/[dynamic]$E, length: int, loc := #caller
|
||||
allocator.data, .Resize, new_size, align_of(E),
|
||||
a.data, old_size, 0, loc,
|
||||
);
|
||||
if new_data == nil do return false;
|
||||
if new_data == nil {
|
||||
return false;
|
||||
}
|
||||
|
||||
a.data = new_data;
|
||||
a.len = length;
|
||||
@@ -1188,7 +1230,9 @@ incl_elem :: inline proc(s: ^$S/bit_set[$E; $U], elem: E) -> S {
|
||||
}
|
||||
@builtin
|
||||
incl_elems :: inline proc(s: ^$S/bit_set[$E; $U], elems: ..E) -> S {
|
||||
for elem in elems do s^ |= {elem};
|
||||
for elem in elems {
|
||||
s^ |= {elem};
|
||||
}
|
||||
return s^;
|
||||
}
|
||||
@builtin
|
||||
@@ -1203,7 +1247,9 @@ excl_elem :: inline proc(s: ^$S/bit_set[$E; $U], elem: E) -> S {
|
||||
}
|
||||
@builtin
|
||||
excl_elems :: inline proc(s: ^$S/bit_set[$E; $U], elems: ..E) -> S {
|
||||
for elem in elems do s^ &~= {elem};
|
||||
for elem in elems {
|
||||
s^ &~= {elem};
|
||||
}
|
||||
return s^;
|
||||
}
|
||||
@builtin
|
||||
@@ -1337,7 +1383,9 @@ __dynamic_array_reserve :: proc(array_: rawptr, elem_size, elem_align: int, cap:
|
||||
}
|
||||
assert(array.allocator.procedure != nil);
|
||||
|
||||
if cap <= array.cap do return true;
|
||||
if cap <= array.cap {
|
||||
return true;
|
||||
}
|
||||
|
||||
old_size := array.cap * elem_size;
|
||||
new_size := cap * elem_size;
|
||||
@@ -1356,7 +1404,9 @@ __dynamic_array_resize :: proc(array_: rawptr, elem_size, elem_align: int, len:
|
||||
array := (^Raw_Dynamic_Array)(array_);
|
||||
|
||||
ok := __dynamic_array_reserve(array_, elem_size, elem_align, len, loc);
|
||||
if ok do array.len = len;
|
||||
if ok {
|
||||
array.len = len;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
@@ -1365,8 +1415,12 @@ __dynamic_array_append :: proc(array_: rawptr, elem_size, elem_align: int,
|
||||
items: rawptr, item_count: int, loc := #caller_location) -> int {
|
||||
array := (^Raw_Dynamic_Array)(array_);
|
||||
|
||||
if items == nil do return 0;
|
||||
if item_count <= 0 do return 0;
|
||||
if items == nil {
|
||||
return 0;
|
||||
}
|
||||
if item_count <= 0 {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
ok := true;
|
||||
@@ -1375,7 +1429,9 @@ __dynamic_array_append :: proc(array_: rawptr, elem_size, elem_align: int,
|
||||
ok = __dynamic_array_reserve(array, elem_size, elem_align, cap, loc);
|
||||
}
|
||||
// TODO(bill): Better error handling for failed reservation
|
||||
if !ok do return array.len;
|
||||
if !ok {
|
||||
return array.len;
|
||||
}
|
||||
|
||||
assert(array.data != nil);
|
||||
data := uintptr(array.data) + uintptr(elem_size*array.len);
|
||||
@@ -1394,7 +1450,9 @@ __dynamic_array_append_nothing :: proc(array_: rawptr, elem_size, elem_align: in
|
||||
ok = __dynamic_array_reserve(array, elem_size, elem_align, cap, loc);
|
||||
}
|
||||
// TODO(bill): Better error handling for failed reservation
|
||||
if !ok do return array.len;
|
||||
if !ok {
|
||||
return array.len;
|
||||
}
|
||||
|
||||
assert(array.data != nil);
|
||||
data := uintptr(array.data) + uintptr(elem_size*array.len);
|
||||
@@ -1434,11 +1492,11 @@ __get_map_key :: proc "contextless" (k: $K) -> Map_Key {
|
||||
map_key.hash = default_hash_ptr(&key, size_of(T));
|
||||
|
||||
sz :: 8*size_of(T);
|
||||
when sz == 8 do map_key.key.val = u64(( ^u8)(&key)^);
|
||||
else when sz == 16 do map_key.key.val = u64((^u16)(&key)^);
|
||||
else when sz == 32 do map_key.key.val = u64((^u32)(&key)^);
|
||||
else when sz == 64 do map_key.key.val = u64((^u64)(&key)^);
|
||||
else do #panic("Unhandled integer size");
|
||||
when sz == 8 { map_key.key.val = u64(( ^u8)(&key)^); }
|
||||
else when sz == 16 { map_key.key.val = u64((^u16)(&key)^); }
|
||||
else when sz == 32 { map_key.key.val = u64((^u32)(&key)^); }
|
||||
else when sz == 64 { map_key.key.val = u64((^u64)(&key)^); }
|
||||
else { #panic("Unhandled integer size"); }
|
||||
} else when intrinsics.type_is_rune(T) {
|
||||
map_key.hash = default_hash_ptr(&key, size_of(T));
|
||||
map_key.key.val = u64((^rune)(&key)^);
|
||||
@@ -1449,9 +1507,9 @@ __get_map_key :: proc "contextless" (k: $K) -> Map_Key {
|
||||
map_key.hash = default_hash_ptr(&key, size_of(T));
|
||||
|
||||
sz :: 8*size_of(T);
|
||||
when sz == 32 do map_key.key.val = u64((^u32)(&key)^);
|
||||
else when sz == 64 do map_key.key.val = u64((^u64)(&key)^);
|
||||
else do #panic("Unhandled float size");
|
||||
when sz == 32 { map_key.key.val = u64((^u32)(&key)^); }
|
||||
else when sz == 64 { map_key.key.val = u64((^u64)(&key)^); }
|
||||
else { #panic("Unhandled float size"); }
|
||||
} else when intrinsics.type_is_string(T) {
|
||||
#assert(T == string);
|
||||
str := (^string)(&key)^;
|
||||
@@ -1497,7 +1555,9 @@ source_code_location_hash :: proc(s: Source_Code_Location) -> u64 {
|
||||
__slice_resize :: proc(array_: ^$T/[]$E, new_count: int, allocator: Allocator, loc := #caller_location) -> bool {
|
||||
array := (^Raw_Slice)(array_);
|
||||
|
||||
if new_count < array.len do return true;
|
||||
if new_count < array.len {
|
||||
return true;
|
||||
}
|
||||
|
||||
assert(allocator.procedure != nil);
|
||||
|
||||
@@ -1505,7 +1565,9 @@ __slice_resize :: proc(array_: ^$T/[]$E, new_count: int, allocator: Allocator, l
|
||||
new_size := new_count*size_of(T);
|
||||
|
||||
new_data := mem_resize(array.data, old_size, new_size, align_of(T), allocator, loc);
|
||||
if new_data == nil do return false;
|
||||
if new_data == nil {
|
||||
return false;
|
||||
}
|
||||
array.data = new_data;
|
||||
array.len = new_count;
|
||||
return true;
|
||||
@@ -1516,7 +1578,9 @@ __dynamic_map_reserve :: proc(using header: Map_Header, cap: int, loc := #caller
|
||||
|
||||
old_len := len(m.hashes);
|
||||
__slice_resize(&m.hashes, cap, m.entries.allocator, loc);
|
||||
for i in old_len..<len(m.hashes) do m.hashes[i] = -1;
|
||||
for i in old_len..<len(m.hashes) {
|
||||
m.hashes[i] = -1;
|
||||
}
|
||||
|
||||
}
|
||||
__dynamic_map_rehash :: proc(using header: Map_Header, new_count: int, loc := #caller_location) #no_bounds_check {
|
||||
@@ -1533,10 +1597,14 @@ __dynamic_map_rehash :: proc(using header: Map_Header, new_count: int, loc := #c
|
||||
|
||||
__dynamic_array_reserve(&nm.entries, entry_size, entry_align, m.entries.len, loc);
|
||||
__slice_resize(&nm.hashes, new_count, m.entries.allocator, loc);
|
||||
for i in 0 ..< new_count do nm.hashes[i] = -1;
|
||||
for i in 0 ..< new_count {
|
||||
nm.hashes[i] = -1;
|
||||
}
|
||||
|
||||
for i in 0 ..< m.entries.len {
|
||||
if len(nm.hashes) == 0 do __dynamic_map_grow(new_header, loc);
|
||||
if len(nm.hashes) == 0 {
|
||||
__dynamic_map_grow(new_header, loc);
|
||||
}
|
||||
|
||||
entry_header := __dynamic_map_get_entry(header, i);
|
||||
data := uintptr(entry_header);
|
||||
@@ -1555,7 +1623,9 @@ __dynamic_map_rehash :: proc(using header: Map_Header, new_count: int, loc := #c
|
||||
ndata := uintptr(e);
|
||||
mem_copy(rawptr(ndata+value_offset), rawptr(data+value_offset), value_size);
|
||||
|
||||
if __dynamic_map_full(new_header) do __dynamic_map_grow(new_header, loc);
|
||||
if __dynamic_map_full(new_header) {
|
||||
__dynamic_map_grow(new_header, loc);
|
||||
}
|
||||
}
|
||||
delete(m.hashes, m.entries.allocator, loc);
|
||||
free(m.entries.data, m.entries.allocator, loc);
|
||||
@@ -1635,7 +1705,9 @@ __dynamic_map_find :: proc(using h: Map_Header, key: Map_Key) -> Map_Find_Result
|
||||
fr.entry_index = m.hashes[fr.hash_index];
|
||||
for fr.entry_index >= 0 {
|
||||
entry := __dynamic_map_get_entry(h, fr.entry_index);
|
||||
if __dynamic_map_hash_equal(h, entry.key, key) do return fr;
|
||||
if __dynamic_map_hash_equal(h, entry.key, key) {
|
||||
return fr;
|
||||
}
|
||||
fr.entry_prev = fr.entry_index;
|
||||
fr.entry_index = entry.next;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,9 @@ type_assertion_trap :: proc "contextless" () -> ! {
|
||||
|
||||
|
||||
bounds_check_error :: proc "contextless" (file: string, line, column: int, index, count: int) {
|
||||
if 0 <= index && index < count do return;
|
||||
if 0 <= index && index < count {
|
||||
return;
|
||||
}
|
||||
handle_error :: proc "contextless" (file: string, line, column: int, index, count: int) {
|
||||
context = default_context();
|
||||
fd := os_stderr();
|
||||
@@ -48,17 +50,23 @@ slice_handle_error :: proc "contextless" (file: string, line, column: int, lo, h
|
||||
}
|
||||
|
||||
slice_expr_error_hi :: proc "contextless" (file: string, line, column: int, hi: int, len: int) {
|
||||
if 0 <= hi && hi <= len do return;
|
||||
if 0 <= hi && hi <= len {
|
||||
return;
|
||||
}
|
||||
slice_handle_error(file, line, column, 0, hi, len);
|
||||
}
|
||||
|
||||
slice_expr_error_lo_hi :: proc "contextless" (file: string, line, column: int, lo, hi: int, len: int) {
|
||||
if 0 <= lo && lo <= len && lo <= hi && hi <= len do return;
|
||||
if 0 <= lo && lo <= len && lo <= hi && hi <= len {
|
||||
return;
|
||||
}
|
||||
slice_handle_error(file, line, column, lo, hi, len);
|
||||
}
|
||||
|
||||
dynamic_array_expr_error :: proc "contextless" (file: string, line, column: int, low, high, max: int) {
|
||||
if 0 <= low && low <= high && high <= max do return;
|
||||
if 0 <= low && low <= high && high <= max {
|
||||
return;
|
||||
}
|
||||
handle_error :: proc "contextless" (file: string, line, column: int, low, high, max: int) {
|
||||
context = default_context();
|
||||
fd := os_stderr();
|
||||
@@ -77,7 +85,9 @@ dynamic_array_expr_error :: proc "contextless" (file: string, line, column: int,
|
||||
|
||||
|
||||
type_assertion_check :: proc "contextless" (ok: bool, file: string, line, column: int, from, to: typeid) {
|
||||
if ok do return;
|
||||
if ok {
|
||||
return;
|
||||
}
|
||||
handle_error :: proc "contextless" (file: string, line, column: int, from, to: typeid) {
|
||||
context = default_context();
|
||||
fd := os_stderr();
|
||||
@@ -93,7 +103,9 @@ type_assertion_check :: proc "contextless" (ok: bool, file: string, line, column
|
||||
}
|
||||
|
||||
make_slice_error_loc :: inline proc "contextless" (loc := #caller_location, len: int) {
|
||||
if 0 <= len do return;
|
||||
if 0 <= len {
|
||||
return;
|
||||
}
|
||||
handle_error :: proc "contextless" (loc: Source_Code_Location, len: int) {
|
||||
context = default_context();
|
||||
fd := os_stderr();
|
||||
@@ -107,7 +119,9 @@ make_slice_error_loc :: inline proc "contextless" (loc := #caller_location, len:
|
||||
}
|
||||
|
||||
make_dynamic_array_error_loc :: inline proc "contextless" (using loc := #caller_location, len, cap: int) {
|
||||
if 0 <= len && len <= cap do return;
|
||||
if 0 <= len && len <= cap {
|
||||
return;
|
||||
}
|
||||
handle_error :: proc "contextless" (loc: Source_Code_Location, len, cap: int) {
|
||||
context = default_context();
|
||||
fd := os_stderr();
|
||||
@@ -123,7 +137,9 @@ make_dynamic_array_error_loc :: inline proc "contextless" (using loc := #caller_
|
||||
}
|
||||
|
||||
make_map_expr_error_loc :: inline proc "contextless" (loc := #caller_location, cap: int) {
|
||||
if 0 <= cap do return;
|
||||
if 0 <= cap {
|
||||
return;
|
||||
}
|
||||
handle_error :: proc "contextless" (loc: Source_Code_Location, cap: int) {
|
||||
context = default_context();
|
||||
fd := os_stderr();
|
||||
|
||||
@@ -38,7 +38,9 @@ ptr_offset :: inline proc "contextless" (ptr: $P/^$T, n: int) -> P {
|
||||
}
|
||||
|
||||
is_power_of_two_int :: inline proc(x: int) -> bool {
|
||||
if x <= 0 do return false;
|
||||
if x <= 0 {
|
||||
return false;
|
||||
}
|
||||
return (x & (x-1)) == 0;
|
||||
}
|
||||
|
||||
@@ -47,12 +49,16 @@ align_forward_int :: inline proc(ptr, align: int) -> int {
|
||||
|
||||
p := ptr;
|
||||
modulo := p & (align-1);
|
||||
if modulo != 0 do p += align - modulo;
|
||||
if modulo != 0 {
|
||||
p += align - modulo;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
is_power_of_two_uintptr :: inline proc(x: uintptr) -> bool {
|
||||
if x <= 0 do return false;
|
||||
if x <= 0 {
|
||||
return false;
|
||||
}
|
||||
return (x & (x-1)) == 0;
|
||||
}
|
||||
|
||||
@@ -61,19 +67,27 @@ align_forward_uintptr :: inline proc(ptr, align: uintptr) -> uintptr {
|
||||
|
||||
p := ptr;
|
||||
modulo := p & (align-1);
|
||||
if modulo != 0 do p += align - modulo;
|
||||
if modulo != 0 {
|
||||
p += align - modulo;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
mem_zero :: proc "contextless" (data: rawptr, len: int) -> rawptr {
|
||||
if data == nil do return nil;
|
||||
if len < 0 do return data;
|
||||
if data == nil {
|
||||
return nil;
|
||||
}
|
||||
if len < 0 {
|
||||
return data;
|
||||
}
|
||||
memset(data, 0, len);
|
||||
return data;
|
||||
}
|
||||
|
||||
mem_copy :: proc "contextless" (dst, src: rawptr, len: int) -> rawptr {
|
||||
if src == nil do return dst;
|
||||
if src == nil {
|
||||
return dst;
|
||||
}
|
||||
// NOTE(bill): This _must_ be implemented like C's memmove
|
||||
foreign _ {
|
||||
when ODIN_USE_LLVM_API {
|
||||
@@ -99,7 +113,9 @@ mem_copy :: proc "contextless" (dst, src: rawptr, len: int) -> rawptr {
|
||||
}
|
||||
|
||||
mem_copy_non_overlapping :: proc "contextless" (dst, src: rawptr, len: int) -> rawptr {
|
||||
if src == nil do return dst;
|
||||
if src == nil {
|
||||
return dst;
|
||||
}
|
||||
// NOTE(bill): This _must_ be implemented like C's memcpy
|
||||
foreign _ {
|
||||
when ODIN_USE_LLVM_API {
|
||||
@@ -127,14 +143,22 @@ mem_copy_non_overlapping :: proc "contextless" (dst, src: rawptr, len: int) -> r
|
||||
DEFAULT_ALIGNMENT :: 2*align_of(rawptr);
|
||||
|
||||
mem_alloc :: inline proc(size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> rawptr {
|
||||
if size == 0 do return nil;
|
||||
if allocator.procedure == nil do return nil;
|
||||
if size == 0 {
|
||||
return nil;
|
||||
}
|
||||
if allocator.procedure == nil {
|
||||
return nil;
|
||||
}
|
||||
return allocator.procedure(allocator.data, .Alloc, size, alignment, nil, 0, 0, loc);
|
||||
}
|
||||
|
||||
mem_free :: inline proc(ptr: rawptr, allocator := context.allocator, loc := #caller_location) {
|
||||
if ptr == nil do return;
|
||||
if allocator.procedure == nil do return;
|
||||
if ptr == nil {
|
||||
return;
|
||||
}
|
||||
if allocator.procedure == nil {
|
||||
return;
|
||||
}
|
||||
allocator.procedure(allocator.data, .Free, 0, 0, ptr, 0, 0, loc);
|
||||
}
|
||||
|
||||
@@ -263,7 +287,9 @@ cstring_len :: proc "contextless" (s: cstring) -> int {
|
||||
}
|
||||
|
||||
cstring_to_string :: proc "contextless" (s: cstring) -> string {
|
||||
if s == nil do return "";
|
||||
if s == nil {
|
||||
return "";
|
||||
}
|
||||
ptr := (^byte)(s);
|
||||
n := cstring_len(s);
|
||||
return transmute(string)Raw_String{ptr, n};
|
||||
|
||||
@@ -199,7 +199,7 @@ print_type :: proc(fd: _OS_Handle, ti: ^Type_Info) {
|
||||
t := info.params.variant.(Type_Info_Tuple);
|
||||
print_byte(fd, '(');
|
||||
for t, i in t.types {
|
||||
if i > 0 do print_string(fd, ", ");
|
||||
if i > 0 { print_string(fd, ", "); }
|
||||
print_type(fd, t);
|
||||
}
|
||||
print_string(fd, ")");
|
||||
@@ -210,9 +210,9 @@ print_type :: proc(fd: _OS_Handle, ti: ^Type_Info) {
|
||||
}
|
||||
case Type_Info_Tuple:
|
||||
count := len(info.names);
|
||||
if count != 1 do print_byte(fd, '(');
|
||||
if count != 1 { print_byte(fd, '('); }
|
||||
for name, i in info.names {
|
||||
if i > 0 do print_string(fd, ", ");
|
||||
if i > 0 { print_string(fd, ", "); }
|
||||
|
||||
t := info.types[i];
|
||||
|
||||
@@ -222,7 +222,7 @@ print_type :: proc(fd: _OS_Handle, ti: ^Type_Info) {
|
||||
}
|
||||
print_type(fd, t);
|
||||
}
|
||||
if count != 1 do print_string(fd, ")");
|
||||
if count != 1 { print_string(fd, ")"); }
|
||||
|
||||
case Type_Info_Array:
|
||||
print_byte(fd, '[');
|
||||
@@ -270,8 +270,8 @@ print_type :: proc(fd: _OS_Handle, ti: ^Type_Info) {
|
||||
}
|
||||
|
||||
print_string(fd, "struct ");
|
||||
if info.is_packed do print_string(fd, "#packed ");
|
||||
if info.is_raw_union do print_string(fd, "#raw_union ");
|
||||
if info.is_packed { print_string(fd, "#packed "); }
|
||||
if info.is_raw_union { print_string(fd, "#raw_union "); }
|
||||
if info.custom_align {
|
||||
print_string(fd, "#align ");
|
||||
print_u64(fd, u64(ti.align));
|
||||
@@ -279,7 +279,7 @@ print_type :: proc(fd: _OS_Handle, ti: ^Type_Info) {
|
||||
}
|
||||
print_byte(fd, '{');
|
||||
for name, i in info.names {
|
||||
if i > 0 do print_string(fd, ", ");
|
||||
if i > 0 { print_string(fd, ", "); }
|
||||
print_string(fd, name);
|
||||
print_string(fd, ": ");
|
||||
print_type(fd, info.types[i]);
|
||||
@@ -297,7 +297,7 @@ print_type :: proc(fd: _OS_Handle, ti: ^Type_Info) {
|
||||
}
|
||||
print_byte(fd, '{');
|
||||
for variant, i in info.variants {
|
||||
if i > 0 do print_string(fd, ", ");
|
||||
if i > 0 { print_string(fd, ", "); }
|
||||
print_type(fd, variant);
|
||||
}
|
||||
print_string(fd, "}");
|
||||
@@ -307,7 +307,7 @@ print_type :: proc(fd: _OS_Handle, ti: ^Type_Info) {
|
||||
print_type(fd, info.base);
|
||||
print_string(fd, " {");
|
||||
for name, i in info.names {
|
||||
if i > 0 do print_string(fd, ", ");
|
||||
if i > 0 { print_string(fd, ", "); }
|
||||
print_string(fd, name);
|
||||
}
|
||||
print_string(fd, "}");
|
||||
@@ -321,7 +321,7 @@ print_type :: proc(fd: _OS_Handle, ti: ^Type_Info) {
|
||||
}
|
||||
print_string(fd, " {");
|
||||
for name, i in info.names {
|
||||
if i > 0 do print_string(fd, ", ");
|
||||
if i > 0 { print_string(fd, ", "); }
|
||||
print_string(fd, name);
|
||||
print_string(fd, ": ");
|
||||
print_u64(fd, u64(info.bits[i]));
|
||||
|
||||
@@ -16,11 +16,15 @@ bubble_sort_proc :: proc(array: $A/[]$T, f: proc(T, T) -> int) {
|
||||
if f(array[j], array[j+1]) > 0 {
|
||||
array[j], array[j+1] = array[j+1], array[j];
|
||||
prev_swap = j;
|
||||
if init_swap == -1 do init_swap = j;
|
||||
if init_swap == -1 {
|
||||
init_swap = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if prev_swap == -1 do return;
|
||||
if prev_swap == -1 {
|
||||
return;
|
||||
}
|
||||
|
||||
init_j = max(init_swap-1, 0);
|
||||
last_j = prev_swap;
|
||||
@@ -39,11 +43,15 @@ bubble_sort :: proc(array: $A/[]$T) where intrinsics.type_is_ordered(T) {
|
||||
if array[j] > array[j+1] {
|
||||
array[j], array[j+1] = array[j+1], array[j];
|
||||
prev_swap = j;
|
||||
if init_swap == -1 do init_swap = j;
|
||||
if init_swap == -1 {
|
||||
init_swap = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if prev_swap == -1 do return;
|
||||
if prev_swap == -1 {
|
||||
return;
|
||||
}
|
||||
|
||||
init_j = max(init_swap-1, 0);
|
||||
last_j = prev_swap;
|
||||
@@ -54,16 +62,20 @@ quick_sort_proc :: proc(array: $A/[]$T, f: proc(T, T) -> int) {
|
||||
assert(f != nil);
|
||||
a := array;
|
||||
n := len(a);
|
||||
if n < 2 do return;
|
||||
if n < 2 {
|
||||
return;
|
||||
}
|
||||
|
||||
p := a[n/2];
|
||||
i, j := 0, n-1;
|
||||
|
||||
loop: for {
|
||||
for f(a[i], p) < 0 do i += 1;
|
||||
for f(p, a[j]) < 0 do j -= 1;
|
||||
for f(a[i], p) < 0 { i += 1; }
|
||||
for f(p, a[j]) < 0 { j -= 1; }
|
||||
|
||||
if i >= j do break loop;
|
||||
if i >= j {
|
||||
break loop;
|
||||
}
|
||||
|
||||
a[i], a[j] = a[j], a[i];
|
||||
i += 1;
|
||||
@@ -77,16 +89,20 @@ quick_sort_proc :: proc(array: $A/[]$T, f: proc(T, T) -> int) {
|
||||
quick_sort :: proc(array: $A/[]$T) where intrinsics.type_is_ordered(T) {
|
||||
a := array;
|
||||
n := len(a);
|
||||
if n < 2 do return;
|
||||
if n < 2 {
|
||||
return;
|
||||
}
|
||||
|
||||
p := a[n/2];
|
||||
i, j := 0, n-1;
|
||||
|
||||
loop: for {
|
||||
for a[i] < p do i += 1;
|
||||
for p < a[j] do j -= 1;
|
||||
for a[i] < p { i += 1; }
|
||||
for p < a[j] { j -= 1; }
|
||||
|
||||
if i >= j do break loop;
|
||||
if i >= j {
|
||||
break loop;
|
||||
}
|
||||
|
||||
a[i], a[j] = a[j], a[i];
|
||||
i += 1;
|
||||
@@ -99,7 +115,9 @@ quick_sort :: proc(array: $A/[]$T) where intrinsics.type_is_ordered(T) {
|
||||
|
||||
_log2 :: proc(x: int) -> int {
|
||||
res := 0;
|
||||
for n := x; n != 0; n >>= 1 do res += 1;
|
||||
for n := x; n != 0; n >>= 1 {
|
||||
res += 1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -206,7 +224,9 @@ heap_sort_proc :: proc(array: $A/[]$T, f: proc(T, T) -> int) {
|
||||
}
|
||||
|
||||
n := len(array);
|
||||
if n == 0 do return;
|
||||
if n == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
for i := n/2; i >= 0; i -= 1 {
|
||||
sift_proc(array, i, n-1, f);
|
||||
@@ -238,7 +258,9 @@ heap_sort :: proc(array: $A/[]$T) where intrinsics.type_is_ordered(T) {
|
||||
}
|
||||
|
||||
n := len(array);
|
||||
if n == 0 do return;
|
||||
if n == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
for i := n/2; i >= 0; i -= 1 {
|
||||
sift(array, i, n-1);
|
||||
|
||||
@@ -11,7 +11,9 @@ Decimal :: struct {
|
||||
|
||||
decimal_to_string :: proc(buf: []byte, a: ^Decimal) -> string {
|
||||
digit_zero :: proc(buf: []byte) -> int {
|
||||
for _, i in buf do buf[i] = '0';
|
||||
for _, i in buf {
|
||||
buf[i] = '0';
|
||||
}
|
||||
return len(buf);
|
||||
}
|
||||
|
||||
@@ -202,7 +204,9 @@ shift :: proc(a: ^Decimal, i: int) {
|
||||
can_round_up :: proc(a: ^Decimal, nd: int) -> bool {
|
||||
if nd < 0 || nd >= a.count { return false ; }
|
||||
if a.digits[nd] == '5' && nd+1 == a.count {
|
||||
if a.trunc do return true;
|
||||
if a.trunc {
|
||||
return true;
|
||||
}
|
||||
return nd > 0 && (a.digits[nd-1]-'0')%2 != 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -100,7 +100,9 @@ format_digits :: proc(buf: []byte, shortest: bool, neg: bool, digs: Decimal_Slic
|
||||
n: int,
|
||||
};
|
||||
|
||||
to_bytes :: proc(b: Buffer) -> []byte do return b.b[:b.n];
|
||||
to_bytes :: proc(b: Buffer) -> []byte {
|
||||
return b.b[:b.n];
|
||||
}
|
||||
add_bytes :: proc(buf: ^Buffer, bytes: ..byte) {
|
||||
buf.n += copy(buf.b[buf.n:], bytes);
|
||||
}
|
||||
|
||||
@@ -52,13 +52,17 @@ parse_i64_of_base :: proc(str: string, base: int) -> (value: i64, ok: bool) {
|
||||
continue;
|
||||
}
|
||||
v := i64(_digit_value(r));
|
||||
if v >= i64(base) do break;
|
||||
if v >= i64(base) {
|
||||
break;
|
||||
}
|
||||
value *= i64(base);
|
||||
value += v;
|
||||
i += 1;
|
||||
}
|
||||
|
||||
if neg do value = -value;
|
||||
if neg {
|
||||
value = -value;
|
||||
}
|
||||
ok = i > 0;
|
||||
return;
|
||||
}
|
||||
@@ -106,13 +110,17 @@ parse_i64_maybe_prefixed :: proc(str: string) -> (value: i64, ok: bool) {
|
||||
continue;
|
||||
}
|
||||
v := i64(_digit_value(r));
|
||||
if v >= base do break;
|
||||
if v >= base {
|
||||
break;
|
||||
}
|
||||
value *= base;
|
||||
value += v;
|
||||
i += 1;
|
||||
}
|
||||
|
||||
if neg do value = -value;
|
||||
if neg {
|
||||
value = -value;
|
||||
}
|
||||
ok = i > 0;
|
||||
return;
|
||||
}
|
||||
@@ -145,7 +153,9 @@ parse_u64_of_base :: proc(str: string, base: int) -> (value: u64, ok: bool) {
|
||||
continue;
|
||||
}
|
||||
v := u64(_digit_value(r));
|
||||
if v >= u64(base) do break;
|
||||
if v >= u64(base) {
|
||||
break;
|
||||
}
|
||||
value *= u64(base);
|
||||
value += v;
|
||||
i += 1;
|
||||
@@ -192,7 +202,9 @@ parse_u64_maybe_prefixed :: proc(str: string) -> (value: u64, ok: bool) {
|
||||
continue;
|
||||
}
|
||||
v := u64(_digit_value(r));
|
||||
if v >= base do break;
|
||||
if v >= base {
|
||||
break;
|
||||
}
|
||||
value *= base;
|
||||
value += u64(v);
|
||||
i += 1;
|
||||
@@ -302,10 +314,14 @@ parse_f64 :: proc(s: string) -> (value: f64, ok: bool) {
|
||||
|
||||
for ; i < len(s); i += 1 {
|
||||
r := rune(s[i]);
|
||||
if r == '_' do continue;
|
||||
if r == '_' {
|
||||
continue;
|
||||
}
|
||||
|
||||
v := _digit_value(r);
|
||||
if v >= 10 do break;
|
||||
if v >= 10 {
|
||||
break;
|
||||
}
|
||||
value *= 10;
|
||||
value += f64(v);
|
||||
}
|
||||
@@ -316,10 +332,14 @@ parse_f64 :: proc(s: string) -> (value: f64, ok: bool) {
|
||||
|
||||
for ; i < len(s); i += 1 {
|
||||
r := rune(s[i]);
|
||||
if r == '_' do continue;
|
||||
if r == '_' {
|
||||
continue;
|
||||
}
|
||||
|
||||
v := _digit_value(r);
|
||||
if v >= 10 do break;
|
||||
if v >= 10 {
|
||||
break;
|
||||
}
|
||||
value += f64(v)/pow10;
|
||||
pow10 *= 10;
|
||||
}
|
||||
@@ -340,10 +360,14 @@ parse_f64 :: proc(s: string) -> (value: f64, ok: bool) {
|
||||
exp: u32 = 0;
|
||||
for ; i < len(s); i += 1 {
|
||||
r := rune(s[i]);
|
||||
if r == '_' do continue;
|
||||
if r == '_' {
|
||||
continue;
|
||||
}
|
||||
|
||||
d := u32(_digit_value(r));
|
||||
if d >= 10 do break;
|
||||
if d >= 10 {
|
||||
break;
|
||||
}
|
||||
exp = exp * 10 + d;
|
||||
}
|
||||
if exp > 308 { exp = 308; }
|
||||
@@ -367,8 +391,11 @@ parse_f64 :: proc(s: string) -> (value: f64, ok: bool) {
|
||||
|
||||
append_bool :: proc(buf: []byte, b: bool) -> string {
|
||||
n := 0;
|
||||
if b do n = copy(buf, "true");
|
||||
else do n = copy(buf, "false");
|
||||
if b {
|
||||
n = copy(buf, "true");
|
||||
} else {
|
||||
n = copy(buf, "false");
|
||||
}
|
||||
return string(buf[:n]);
|
||||
}
|
||||
|
||||
@@ -399,7 +426,9 @@ append_float :: proc(buf: []byte, f: f64, fmt: byte, prec, bit_size: int) -> str
|
||||
|
||||
quote :: proc(buf: []byte, str: string) -> string {
|
||||
write_byte :: inline proc(buf: []byte, i: ^int, bytes: ..byte) {
|
||||
if i^ >= len(buf) do return;
|
||||
if i^ >= len(buf) {
|
||||
return;
|
||||
}
|
||||
n := copy(buf[i^:], bytes[:]);
|
||||
i^ += n;
|
||||
}
|
||||
@@ -590,7 +619,9 @@ unquote_char :: proc(str: string, quote: byte) -> (r: rune, multiple_bytes: bool
|
||||
unquote_string :: proc(lit: string, allocator := context.allocator) -> (res: string, allocated, success: bool) {
|
||||
contains_rune :: proc(s: string, r: rune) -> int {
|
||||
for c, offset in s {
|
||||
if c == r do return offset;
|
||||
if c == r {
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ write_quoted_string :: proc(b: ^Builder, str: string, quote: byte = '"') {
|
||||
|
||||
|
||||
write_encoded_rune :: proc(b: ^Builder, r: rune, write_quote := true) {
|
||||
if write_quote do write_byte(b, '\'');
|
||||
if write_quote { write_byte(b, '\''); }
|
||||
switch r {
|
||||
case '\a': write_string(b, `\a"`);
|
||||
case '\b': write_string(b, `\b"`);
|
||||
@@ -156,7 +156,7 @@ write_encoded_rune :: proc(b: ^Builder, r: rune, write_quote := true) {
|
||||
}
|
||||
|
||||
}
|
||||
if write_quote do write_byte(b, '\'');
|
||||
if write_quote { write_byte(b, '\''); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -40,7 +40,9 @@ compare :: proc(lhs, rhs: string) -> int {
|
||||
|
||||
contains_rune :: proc(s: string, r: rune) -> int {
|
||||
for c, offset in s {
|
||||
if c == r do return offset;
|
||||
if c == r {
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -216,7 +218,9 @@ split_after_n :: inline proc(s, sep: string, n: int, allocator := context.alloca
|
||||
|
||||
index_byte :: proc(s: string, c: byte) -> int {
|
||||
for i := 0; i < len(s); i += 1 {
|
||||
if s[i] == c do return i;
|
||||
if s[i] == c {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -224,7 +228,9 @@ index_byte :: proc(s: string, c: byte) -> int {
|
||||
// Returns i1 if c is not present
|
||||
last_index_byte :: proc(s: string, c: byte) -> int {
|
||||
for i := len(s)-1; i >= 0; i -= 1 {
|
||||
if s[i] == c do return i;
|
||||
if s[i] == c {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -66,7 +66,9 @@ wstring_to_utf8 :: proc(s: wstring, N: int, allocator := context.temp_allocator)
|
||||
}
|
||||
|
||||
utf16_to_utf8 :: proc(s: []u16, allocator := context.temp_allocator) -> string {
|
||||
if len(s) == 0 do return "";
|
||||
if len(s) == 0 {
|
||||
return "";
|
||||
}
|
||||
return wstring_to_utf8(cast(wstring)&s[0], len(s), allocator);
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +72,9 @@ create :: proc(procedure: Thread_Proc, priority := Thread_Priority.Normal) -> ^T
|
||||
}
|
||||
|
||||
attrs: unix.pthread_attr_t;
|
||||
if unix.pthread_attr_init(&attrs) != 0 do return nil; // NOTE(tetra, 2019-11-01): POSIX OOM.
|
||||
if unix.pthread_attr_init(&attrs) != 0 {
|
||||
return nil; // NOTE(tetra, 2019-11-01): POSIX OOM.
|
||||
}
|
||||
defer unix.pthread_attr_destroy(&attrs);
|
||||
|
||||
// NOTE(tetra, 2019-11-01): These only fail if their argument is invalid.
|
||||
@@ -80,7 +82,9 @@ create :: proc(procedure: Thread_Proc, priority := Thread_Priority.Normal) -> ^T
|
||||
assert(unix.pthread_attr_setinheritsched(&attrs, unix.PTHREAD_EXPLICIT_SCHED) == 0);
|
||||
|
||||
thread := new(Thread);
|
||||
if thread == nil do return nil;
|
||||
if thread == nil {
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Set thread priority.
|
||||
policy: i32;
|
||||
@@ -111,7 +115,9 @@ create :: proc(procedure: Thread_Proc, priority := Thread_Priority.Normal) -> ^T
|
||||
}
|
||||
|
||||
start :: proc(t: ^Thread) {
|
||||
if sync.atomic_swap(&t.started, true, .Sequentially_Consistent) do return;
|
||||
if sync.atomic_swap(&t.started, true, .Sequentially_Consistent) {
|
||||
return;
|
||||
}
|
||||
sync.condition_signal(&t.start_gate);
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,9 @@ _less_than_half :: inline proc(x, y: Duration) -> bool {
|
||||
}
|
||||
|
||||
duration_round :: proc(d, m: Duration) -> Duration {
|
||||
if m <= 0 do return d;
|
||||
if m <= 0 {
|
||||
return d;
|
||||
}
|
||||
|
||||
r := d % m;
|
||||
if d < 0 {
|
||||
@@ -194,13 +196,15 @@ _abs_date :: proc(abs: u64, full: bool) -> (year: int, month: Month, day: int, y
|
||||
|
||||
day = yday;
|
||||
|
||||
if _is_leap_year(year) do switch {
|
||||
case day > 31+29-1:
|
||||
day -= 1;
|
||||
case day == 31+29-1:
|
||||
month = .February;
|
||||
day = 29;
|
||||
return;
|
||||
if _is_leap_year(year) {
|
||||
switch {
|
||||
case day > 31+29-1:
|
||||
day -= 1;
|
||||
case day == 31+29-1:
|
||||
month = .February;
|
||||
day = 29;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
month = Month(day / 31);
|
||||
|
||||
@@ -66,8 +66,8 @@ sleep :: proc(d: Duration) {
|
||||
seconds := u32(ds);
|
||||
nanoseconds := i64((ds - f64(seconds)) * 1e9);
|
||||
|
||||
if seconds > 0 do _unix_sleep(seconds);
|
||||
if nanoseconds > 0 do nanosleep(nanoseconds);
|
||||
if seconds > 0 { _unix_sleep(seconds); }
|
||||
if nanoseconds > 0 { nanosleep(nanoseconds); }
|
||||
}
|
||||
|
||||
nanosleep :: proc(nanoseconds: i64) -> int {
|
||||
|
||||
@@ -35,19 +35,19 @@ encode :: proc(d: []u16, s: []rune) -> int {
|
||||
loop: for r in s {
|
||||
switch r {
|
||||
case 0..<_surr1, _surr3 ..< _surr_self:
|
||||
if m+1 < n do break loop;
|
||||
if m+1 < n { break loop; }
|
||||
d[n] = u16(r);
|
||||
n += 1;
|
||||
|
||||
case _surr_self .. MAX_RUNE:
|
||||
if m+2 < n do break loop;
|
||||
if m+2 < n { break loop; }
|
||||
r1, r2 := encode_surrogate_pair(r);
|
||||
d[n] = u16(r1);
|
||||
d[n+1] = u16(r2);
|
||||
n += 2;
|
||||
|
||||
case:
|
||||
if m+1 < n do break loop;
|
||||
if m+1 < n { break loop; }
|
||||
d[n] = u16(REPLACEMENT_CHAR);
|
||||
n += 1;
|
||||
}
|
||||
@@ -61,19 +61,19 @@ encode_string :: proc(d: []u16, s: string) -> int {
|
||||
loop: for r in s {
|
||||
switch r {
|
||||
case 0..<_surr1, _surr3 ..< _surr_self:
|
||||
if m+1 < n do break loop;
|
||||
if m+1 < n { break loop; }
|
||||
d[n] = u16(r);
|
||||
n += 1;
|
||||
|
||||
case _surr_self .. MAX_RUNE:
|
||||
if m+2 < n do break loop;
|
||||
if m+2 < n { break loop; }
|
||||
r1, r2 := encode_surrogate_pair(r);
|
||||
d[n] = u16(r1);
|
||||
d[n+1] = u16(r2);
|
||||
n += 2;
|
||||
|
||||
case:
|
||||
if m+1 < n do break loop;
|
||||
if m+1 < n { break loop; }
|
||||
d[n] = u16(REPLACEMENT_CHAR);
|
||||
n += 1;
|
||||
}
|
||||
|
||||
@@ -90,7 +90,9 @@ encode_rune :: proc(c: rune) -> ([4]u8, int) {
|
||||
return buf, 4;
|
||||
}
|
||||
|
||||
decode_rune_in_string :: inline proc(s: string) -> (rune, int) do return decode_rune(transmute([]u8)s);
|
||||
decode_rune_in_string :: inline proc(s: string) -> (rune, int) {
|
||||
return decode_rune(transmute([]u8)s);
|
||||
}
|
||||
decode_rune :: proc(s: []u8) -> (rune, int) {
|
||||
n := len(s);
|
||||
if n < 1 {
|
||||
@@ -159,7 +161,9 @@ runes_to_string :: proc(runes: []rune, allocator := context.allocator) -> string
|
||||
}
|
||||
|
||||
|
||||
decode_last_rune_in_string :: inline proc(s: string) -> (rune, int) do return decode_last_rune(transmute([]u8)s);
|
||||
decode_last_rune_in_string :: inline proc(s: string) -> (rune, int) {
|
||||
return decode_last_rune(transmute([]u8)s);
|
||||
}
|
||||
decode_last_rune :: proc(s: []u8) -> (rune, int) {
|
||||
r: rune;
|
||||
size: int;
|
||||
@@ -179,7 +183,9 @@ decode_last_rune :: proc(s: []u8) -> (rune, int) {
|
||||
limit = max(end - UTF_MAX, 0);
|
||||
|
||||
for start-=1; start >= limit; start-=1 {
|
||||
if rune_start(s[start]) do break;
|
||||
if rune_start(s[start]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
start = max(start, 0);
|
||||
@@ -287,9 +293,13 @@ valid_string :: proc(s: string) -> bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
rune_start :: inline proc(b: u8) -> bool do return b&0xc0 != 0x80;
|
||||
rune_start :: inline proc(b: u8) -> bool {
|
||||
return b&0xc0 != 0x80;
|
||||
}
|
||||
|
||||
rune_count_in_string :: inline proc(s: string) -> int do return rune_count(transmute([]u8)s);
|
||||
rune_count_in_string :: inline proc(s: string) -> int {
|
||||
return rune_count(transmute([]u8)s);
|
||||
}
|
||||
rune_count :: proc(s: []u8) -> int {
|
||||
count := 0;
|
||||
n := len(s);
|
||||
|
||||
@@ -9,7 +9,6 @@ import "core:reflect"
|
||||
import "core:runtime"
|
||||
import "intrinsics"
|
||||
|
||||
|
||||
/*
|
||||
The Odin programming language is fast, concise, readable, pragmatic and open sourced.
|
||||
It is designed with the intent of replacing C with the following goals:
|
||||
@@ -135,9 +134,9 @@ control_flow :: proc() {
|
||||
}
|
||||
|
||||
// NOTE: Unlike other languages like C, there are no parentheses `( )` surrounding the three components.
|
||||
// Braces `{ }` or a `do` are always required>
|
||||
// Braces `{ }` or a `do` are always required
|
||||
for i := 0; i < 10; i += 1 { }
|
||||
for i := 0; i < 10; i += 1 do fmt.print();
|
||||
// for i := 0; i < 10; i += 1 do fmt.print();
|
||||
|
||||
// The initial and post statements are optional
|
||||
i := 0;
|
||||
@@ -620,8 +619,8 @@ union_type :: proc() {
|
||||
case Frog:
|
||||
fmt.println("Ribbit");
|
||||
case Monster:
|
||||
if e.is_robot do fmt.println("Robotic");
|
||||
if e.is_zombie do fmt.println("Grrrr!");
|
||||
if e.is_robot { fmt.println("Robotic"); }
|
||||
if e.is_zombie { fmt.println("Grrrr!"); }
|
||||
fmt.println("I'm a monster");
|
||||
}
|
||||
}
|
||||
@@ -665,8 +664,8 @@ union_type :: proc() {
|
||||
case Frog:
|
||||
fmt.println("Ribbit");
|
||||
case Monster:
|
||||
if e.is_robot do fmt.println("Robotic");
|
||||
if e.is_zombie do fmt.println("Grrrr!");
|
||||
if e.is_robot { fmt.println("Robotic"); }
|
||||
if e.is_zombie { fmt.println("Grrrr!"); }
|
||||
}
|
||||
|
||||
// NOTE(bill): As you can see, the usage code has not changed, only its
|
||||
@@ -712,7 +711,7 @@ union_type :: proc() {
|
||||
using_statement :: proc() {
|
||||
fmt.println("\n# using statement");
|
||||
// using can used to bring entities declared in a scope/namespace
|
||||
// into the current scope. This can be applied to import names, struct
|
||||
// into the current scope. This can be applied to import names, struct
|
||||
// fields, procedure fields, and struct values.
|
||||
|
||||
Vector3 :: struct{x, y, z: f32};
|
||||
@@ -920,7 +919,9 @@ parametric_polymorphism :: proc() {
|
||||
// Only allow types that are specializations of `Table`
|
||||
allocate :: proc(table: ^$T/Table, capacity: int) {
|
||||
c := context;
|
||||
if table.allocator.procedure != nil do c.allocator = table.allocator;
|
||||
if table.allocator.procedure != nil {
|
||||
c.allocator = table.allocator;
|
||||
}
|
||||
context = c;
|
||||
|
||||
table.slots = make_slice(type_of(table.slots), max(capacity, TABLE_SIZE_MIN));
|
||||
@@ -928,7 +929,9 @@ parametric_polymorphism :: proc() {
|
||||
|
||||
expand :: proc(table: ^$T/Table) {
|
||||
c := context;
|
||||
if table.allocator.procedure != nil do c.allocator = table.allocator;
|
||||
if table.allocator.procedure != nil {
|
||||
c.allocator = table.allocator;
|
||||
}
|
||||
context = c;
|
||||
|
||||
old_slots := table.slots;
|
||||
@@ -937,8 +940,10 @@ parametric_polymorphism :: proc() {
|
||||
cap := max(2*len(table.slots), TABLE_SIZE_MIN);
|
||||
allocate(table, cap);
|
||||
|
||||
for s in old_slots do if s.occupied {
|
||||
put(table, s.key, s.value);
|
||||
for s in old_slots {
|
||||
if s.occupied {
|
||||
put(table, s.key, s.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -983,7 +988,9 @@ parametric_polymorphism :: proc() {
|
||||
}
|
||||
|
||||
find_index :: proc(table: ^Table($Key, $Value), key: Key, hash: u32) -> int {
|
||||
if len(table.slots) <= 0 do return -1;
|
||||
if len(table.slots) <= 0 {
|
||||
return -1;
|
||||
}
|
||||
|
||||
index := int(hash % u32(len(table.slots)));
|
||||
for table.slots[index].occupied {
|
||||
@@ -1012,8 +1019,8 @@ parametric_polymorphism :: proc() {
|
||||
|
||||
table: Table(string, int);
|
||||
|
||||
for i in 0..36 do put(&table, "Hellope", i);
|
||||
for i in 0..42 do put(&table, "World!", i);
|
||||
for i in 0..36 { put(&table, "Hellope", i); }
|
||||
for i in 0..42 { put(&table, "World!", i); }
|
||||
|
||||
found, _ := find(&table, "Hellope");
|
||||
fmt.printf("`found` is %v\n", found);
|
||||
@@ -1597,7 +1604,9 @@ where_clauses :: proc() {
|
||||
}
|
||||
|
||||
|
||||
when ODIN_OS == "windows" do foreign import kernel32 "system:kernel32.lib"
|
||||
when ODIN_OS == "windows" {
|
||||
foreign import kernel32 "system:kernel32.lib"
|
||||
}
|
||||
|
||||
foreign_system :: proc() {
|
||||
fmt.println("\n#foreign system");
|
||||
@@ -1736,7 +1745,9 @@ range_statements_with_multiple_return_values :: proc() {
|
||||
it := make_my_iterator(data);
|
||||
for {
|
||||
val, _, cond := my_iterator(&it);
|
||||
if !cond do break;
|
||||
if !cond {
|
||||
break;
|
||||
}
|
||||
fmt.println(val);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user