mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-24 22:54:59 -07:00
do keyword for inline statements instead of blocks
This commit is contained in:
+12
-17
@@ -1,8 +1,9 @@
|
||||
import (
|
||||
"fmt.odin";
|
||||
/*
|
||||
"atomics.odin";
|
||||
"bits.odin";
|
||||
"decimal.odin";
|
||||
"fmt.odin";
|
||||
"hash.odin";
|
||||
"math.odin";
|
||||
"mem.odin";
|
||||
@@ -15,6 +16,7 @@ import (
|
||||
"types.odin";
|
||||
"utf8.odin";
|
||||
"utf16.odin";
|
||||
*/
|
||||
)
|
||||
|
||||
general_stuff :: proc() {
|
||||
@@ -34,6 +36,8 @@ general_stuff :: proc() {
|
||||
// The variadic part allows for extra type checking too which C does not provide
|
||||
c_printf :: proc(fmt: ^u8, #c_vararg args: ..any) -> i32 #link_name "printf" ---;
|
||||
}
|
||||
str := "%d\n";
|
||||
c_printf(&str[0], i32(789456123));
|
||||
|
||||
|
||||
Foo :: struct {
|
||||
@@ -72,9 +76,7 @@ foreign_blocks :: proc() {
|
||||
}
|
||||
|
||||
default_arguments :: proc() {
|
||||
hello :: proc(a: int = 9, b: int = 9) {
|
||||
fmt.printf("a is %d; b is %d\n", a, b);
|
||||
}
|
||||
hello :: proc(a: int = 9, b: int = 9) do fmt.printf("a is %d; b is %d\n", a, b);
|
||||
fmt.println("\nTesting default arguments:");
|
||||
hello(1, 2);
|
||||
hello(1);
|
||||
@@ -179,7 +181,7 @@ default_return_values :: proc() {
|
||||
|
||||
some_thing :: proc(input: int) -> (result: ^Entity = nil, err := Error.None) {
|
||||
match {
|
||||
case input == 3: return err = Error.WhyTheNumberThree;
|
||||
case input == 3: return err = Error.WhyTheNumberThree;
|
||||
case input >= 10: return err = Error.TenIsTooBig;
|
||||
}
|
||||
|
||||
@@ -215,9 +217,7 @@ call_location :: proc() {
|
||||
|
||||
explicit_parametric_polymorphic_procedures :: proc() {
|
||||
// This is how `new` is actually implemented, see _preload.odin
|
||||
alloc_type :: proc(T: type) -> ^T {
|
||||
return ^T(alloc(size_of(T), align_of(T)));
|
||||
}
|
||||
alloc_type :: proc(T: type) -> ^T do return ^T(alloc(size_of(T), align_of(T)));
|
||||
|
||||
int_ptr := alloc_type(int);
|
||||
defer free(int_ptr);
|
||||
@@ -231,9 +231,7 @@ explicit_parametric_polymorphic_procedures :: proc() {
|
||||
|
||||
add :: proc(T: type, args: ..T) -> T {
|
||||
res: T;
|
||||
for arg in args {
|
||||
res += arg;
|
||||
}
|
||||
for arg in args do res += arg;
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -298,7 +296,7 @@ explicit_parametric_polymorphic_procedures :: proc() {
|
||||
|
||||
use_empty_slot :: proc(manager: ^EntityManager, batch: ^EntityBatch) -> ^Entity {
|
||||
for ok, i in batch.occupied {
|
||||
if ok -> continue;
|
||||
if ok do continue;
|
||||
batch.occupied[i] = true;
|
||||
|
||||
e := &batch.data[i];
|
||||
@@ -314,7 +312,7 @@ explicit_parametric_polymorphic_procedures :: proc() {
|
||||
gen_new_entity :: proc(manager: ^EntityManager) -> ^Entity {
|
||||
for b in manager.batches {
|
||||
e := use_empty_slot(manager, b);
|
||||
if e != nil -> return e;
|
||||
if e != nil do return e;
|
||||
}
|
||||
|
||||
new_batch := new(EntityBatch);
|
||||
@@ -366,12 +364,9 @@ explicit_parametric_polymorphic_procedures :: proc() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
main :: proc() {
|
||||
/*
|
||||
general_stuff();
|
||||
/*
|
||||
foreign_blocks();
|
||||
default_arguments();
|
||||
named_arguments();
|
||||
|
||||
+30
-49
@@ -118,7 +118,7 @@ __argc__: i32;
|
||||
|
||||
|
||||
type_info_base :: proc(info: ^TypeInfo) -> ^TypeInfo {
|
||||
if info == nil -> return nil;
|
||||
if info == nil do return nil;
|
||||
|
||||
base := info;
|
||||
match i in base {
|
||||
@@ -130,7 +130,7 @@ type_info_base :: proc(info: ^TypeInfo) -> ^TypeInfo {
|
||||
|
||||
|
||||
type_info_base_without_enum :: proc(info: ^TypeInfo) -> ^TypeInfo {
|
||||
if info == nil -> return nil;
|
||||
if info == nil do return nil;
|
||||
|
||||
base := info;
|
||||
match i in base {
|
||||
@@ -195,7 +195,7 @@ make_source_code_location :: proc(file: string, line, column: i64, procedure: st
|
||||
DEFAULT_ALIGNMENT :: align_of([vector 4]f32);
|
||||
|
||||
__init_context_from_ptr :: proc(c: ^Context, other: ^Context) #cc_contextless {
|
||||
if c == nil -> return;
|
||||
if c == nil do return;
|
||||
c^ = other^;
|
||||
|
||||
if c.allocator.procedure == nil {
|
||||
@@ -207,7 +207,7 @@ __init_context_from_ptr :: proc(c: ^Context, other: ^Context) #cc_contextless {
|
||||
}
|
||||
|
||||
__init_context :: proc(c: ^Context) #cc_contextless {
|
||||
if c == nil -> return;
|
||||
if c == nil do return;
|
||||
|
||||
if c.allocator.procedure == nil {
|
||||
c.allocator = default_allocator();
|
||||
@@ -259,30 +259,22 @@ resize :: proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_AL
|
||||
}
|
||||
|
||||
|
||||
new :: proc(T: type) -> ^T #inline {
|
||||
return ^T(alloc(size_of(T), align_of(T)));
|
||||
}
|
||||
new :: proc(T: type) -> ^T #inline do return ^T(alloc(size_of(T), align_of(T)));
|
||||
|
||||
|
||||
|
||||
default_resize_align :: proc(old_memory: rawptr, old_size, new_size, alignment: int) -> rawptr {
|
||||
if old_memory == nil {
|
||||
return alloc(new_size, alignment);
|
||||
}
|
||||
if old_memory == nil do return alloc(new_size, alignment);
|
||||
|
||||
if new_size == 0 {
|
||||
free(old_memory);
|
||||
return nil;
|
||||
}
|
||||
|
||||
if new_size == old_size {
|
||||
return old_memory;
|
||||
}
|
||||
if new_size == old_size do return old_memory;
|
||||
|
||||
new_memory := alloc(new_size, alignment);
|
||||
if new_memory == nil {
|
||||
return nil;
|
||||
}
|
||||
if new_memory == nil do return nil;
|
||||
|
||||
__mem_copy(new_memory, old_memory, min(old_size, new_size));;
|
||||
free(old_memory);
|
||||
@@ -326,9 +318,9 @@ default_allocator :: proc() -> Allocator {
|
||||
assert :: proc(condition: bool, message := "", using location := #caller_location) -> bool #cc_contextless {
|
||||
if !condition {
|
||||
if len(message) > 0 {
|
||||
fmt.printf("%s(%d:%d) Runtime assertion: %s\n", fully_pathed_filename, line, column, message);
|
||||
fmt.fprintf(os.stderr, "%s(%d:%d) Runtime assertion: %s\n", fully_pathed_filename, line, column, message);
|
||||
} else {
|
||||
fmt.printf("%s(%d:%d) Runtime assertion\n", fully_pathed_filename, line, column);
|
||||
fmt.fprintf(os.stderr, "%s(%d:%d) Runtime assertion\n", fully_pathed_filename, line, column);
|
||||
}
|
||||
__debug_trap();
|
||||
}
|
||||
@@ -337,9 +329,9 @@ assert :: proc(condition: bool, message := "", using location := #caller_locatio
|
||||
|
||||
panic :: proc(message := "", using location := #caller_location) #cc_contextless {
|
||||
if len(message) > 0 {
|
||||
fmt.printf("%s(%d:%d) Panic: %s\n", fully_pathed_filename, line, column, message);
|
||||
fmt.fprintf(os.stderr, "%s(%d:%d) Panic: %s\n", fully_pathed_filename, line, column, message);
|
||||
} else {
|
||||
fmt.printf("%s(%d:%d) Panic\n", fully_pathed_filename, line, column);
|
||||
fmt.fprintf(os.stderr, "%s(%d:%d) Panic\n", fully_pathed_filename, line, column);
|
||||
}
|
||||
__debug_trap();
|
||||
}
|
||||
@@ -348,14 +340,10 @@ panic :: proc(message := "", using location := #caller_location) #cc_contextless
|
||||
|
||||
|
||||
__string_eq :: proc(a, b: string) -> bool #cc_contextless {
|
||||
if len(a) != len(b) {
|
||||
return false;
|
||||
}
|
||||
if len(a) == 0 {
|
||||
return true;
|
||||
}
|
||||
if &a[0] == &b[0] {
|
||||
return true;
|
||||
match {
|
||||
case len(a) != len(b): return false;
|
||||
case len(a) == 0: return true;
|
||||
case &a[0] == &b[0]: return true;
|
||||
}
|
||||
return __string_cmp(a, b) == 0;
|
||||
}
|
||||
@@ -379,37 +367,30 @@ __complex128_ne :: proc(a, b: complex128) -> bool #cc_contextless #inline { retu
|
||||
|
||||
|
||||
__bounds_check_error :: proc(file: string, line, column: int, index, count: int) #cc_contextless {
|
||||
if 0 <= index && index < count {
|
||||
return;
|
||||
}
|
||||
if 0 <= index && index < count do return;
|
||||
fmt.fprintf(os.stderr, "%s(%d:%d) Index %d is out of bounds range 0..<%d\n",
|
||||
file, line, column, index, count);
|
||||
__debug_trap();
|
||||
}
|
||||
|
||||
__slice_expr_error :: proc(file: string, line, column: int, low, high, max: int) #cc_contextless {
|
||||
if 0 <= low && low <= high && high <= max {
|
||||
return;
|
||||
}
|
||||
if 0 <= low && low <= high && high <= max do return;
|
||||
fmt.fprintf(os.stderr, "%s(%d:%d) Invalid slice indices: [%d..<%d..<%d]\n",
|
||||
file, line, column, low, high, max);
|
||||
__debug_trap();
|
||||
}
|
||||
|
||||
__substring_expr_error :: proc(file: string, line, column: int, low, high: int) #cc_contextless {
|
||||
if 0 <= low && low <= high {
|
||||
return;
|
||||
}
|
||||
if 0 <= low && low <= high do return;
|
||||
fmt.fprintf(os.stderr, "%s(%d:%d) Invalid substring indices: [%d..<%d]\n",
|
||||
file, line, column, low, high);
|
||||
__debug_trap();
|
||||
}
|
||||
__type_assertion_check :: proc(ok: bool, file: string, line, column: int, from, to: ^TypeInfo) #cc_contextless {
|
||||
if !ok {
|
||||
fmt.fprintf(os.stderr, "%s(%d:%d) Invalid type_assertion from %T to %T\n",
|
||||
file, line, column, from, to);
|
||||
__debug_trap();
|
||||
}
|
||||
if ok do return;
|
||||
fmt.fprintf(os.stderr, "%s(%d:%d) Invalid type_assertion from %T to %T\n",
|
||||
file, line, column, from, to);
|
||||
__debug_trap();
|
||||
}
|
||||
|
||||
__string_decode_rune :: proc(s: string) -> (rune, int) #cc_contextless #inline {
|
||||
@@ -499,7 +480,7 @@ __dynamic_array_make :: proc(array_: rawptr, elem_size, elem_align: int, len, ca
|
||||
__dynamic_array_reserve :: proc(array_: rawptr, elem_size, elem_align: int, cap: int) -> bool {
|
||||
array := ^raw.DynamicArray(array_);
|
||||
|
||||
if cap <= array.cap -> return true;
|
||||
if cap <= array.cap do return true;
|
||||
|
||||
// __check_context();
|
||||
if array.allocator.procedure == nil {
|
||||
@@ -512,7 +493,7 @@ __dynamic_array_reserve :: proc(array_: rawptr, elem_size, elem_align: int, cap:
|
||||
allocator := array.allocator;
|
||||
|
||||
new_data := allocator.procedure(allocator.data, AllocatorMode.Resize, new_size, elem_align, array.data, old_size, 0);
|
||||
if new_data == nil -> return false;
|
||||
if new_data == nil do return false;
|
||||
|
||||
array.data = new_data;
|
||||
array.cap = cap;
|
||||
@@ -523,7 +504,7 @@ __dynamic_array_resize :: proc(array_: rawptr, elem_size, elem_align: int, len:
|
||||
array := ^raw.DynamicArray(array_);
|
||||
|
||||
ok := __dynamic_array_reserve(array_, elem_size, elem_align, len);
|
||||
if ok -> array.len = len;
|
||||
if ok do array.len = len;
|
||||
return ok;
|
||||
}
|
||||
|
||||
@@ -543,7 +524,7 @@ __dynamic_array_append :: proc(array_: rawptr, elem_size, elem_align: int,
|
||||
ok = __dynamic_array_reserve(array, elem_size, elem_align, cap);
|
||||
}
|
||||
// TODO(bill): Better error handling for failed reservation
|
||||
if !ok -> return array.len;
|
||||
if !ok do return array.len;
|
||||
|
||||
data := ^u8(array.data);
|
||||
assert(data != nil);
|
||||
@@ -561,7 +542,7 @@ __dynamic_array_append_nothing :: proc(array_: rawptr, elem_size, elem_align: in
|
||||
ok = __dynamic_array_reserve(array, elem_size, elem_align, cap);
|
||||
}
|
||||
// TODO(bill): Better error handling for failed reservation
|
||||
if !ok -> return array.len;
|
||||
if !ok do return array.len;
|
||||
|
||||
data := ^u8(array.data);
|
||||
assert(data != nil);
|
||||
@@ -650,7 +631,7 @@ __dynamic_map_rehash :: proc(using header: __MapHeader, new_count: int) {
|
||||
|
||||
__dynamic_array_resize(nm_hashes, size_of(int), align_of(int), new_count);
|
||||
__dynamic_array_reserve(&nm.entries, entry_size, entry_align, m.entries.len);
|
||||
for i in 0..<new_count -> nm.hashes[i] = -1;
|
||||
for i in 0..<new_count do nm.hashes[i] = -1;
|
||||
|
||||
for i := 0; i < m.entries.len; i++ {
|
||||
if len(nm.hashes) == 0 {
|
||||
@@ -740,7 +721,7 @@ __dynamic_map_full :: proc(using h: __MapHeader) -> bool {
|
||||
|
||||
__dynamic_map_hash_equal :: proc(h: __MapHeader, a, b: __MapKey) -> bool {
|
||||
if a.hash == b.hash {
|
||||
if h.is_key_string -> return a.str == b.str;
|
||||
if h.is_key_string do return a.str == b.str;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -98,7 +98,7 @@ __u128_quo_mod :: proc(a, b: u128, rem: ^u128) -> (quo: u128) #cc_c #link_name "
|
||||
d >>= 1;
|
||||
}
|
||||
|
||||
if rem != nil { rem^ = r; }
|
||||
if rem != nil do rem^ = r;
|
||||
return q;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@ Decimal :: struct {
|
||||
|
||||
decimal_to_string :: proc(buf: []u8, a: ^Decimal) -> string {
|
||||
digit_zero :: proc(buf: []u8) -> int {
|
||||
for _, i in buf -> buf[i] = '0';
|
||||
for _, i in buf do buf[i] = '0';
|
||||
return len(buf);
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ shift :: proc(a: ^Decimal, k: 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 -> return true;
|
||||
if a.trunc do return true;
|
||||
return nd > 0 && (a.digits[nd-1]-'0')%2 != 0;
|
||||
}
|
||||
|
||||
|
||||
+33
-33
@@ -189,7 +189,7 @@ fprint_type :: proc(fd: os.Handle, info: ^TypeInfo) {
|
||||
}
|
||||
|
||||
write_type :: proc(buf: ^StringBuffer, ti: ^TypeInfo) {
|
||||
if ti == nil -> return;
|
||||
if ti == nil do return;
|
||||
|
||||
using TypeInfo;
|
||||
match info in ti {
|
||||
@@ -240,7 +240,7 @@ write_type :: proc(buf: ^StringBuffer, ti: ^TypeInfo) {
|
||||
t := info.params.(^Tuple);
|
||||
write_string(buf, "(");
|
||||
for t, i in t.types {
|
||||
if i > 0 -> write_string(buf, ", ");
|
||||
if i > 0 do write_string(buf, ", ");
|
||||
write_type(buf, t);
|
||||
}
|
||||
write_string(buf, ")");
|
||||
@@ -251,9 +251,9 @@ write_type :: proc(buf: ^StringBuffer, ti: ^TypeInfo) {
|
||||
}
|
||||
case Tuple:
|
||||
count := len(info.names);
|
||||
if count != 1 -> write_string(buf, "(");
|
||||
if count != 1 do write_string(buf, "(");
|
||||
for name, i in info.names {
|
||||
if i > 0 -> write_string(buf, ", ");
|
||||
if i > 0 do write_string(buf, ", ");
|
||||
|
||||
t := info.types[i];
|
||||
|
||||
@@ -263,7 +263,7 @@ write_type :: proc(buf: ^StringBuffer, ti: ^TypeInfo) {
|
||||
}
|
||||
write_type(buf, t);
|
||||
}
|
||||
if count != 1 -> write_string(buf, ")");
|
||||
if count != 1 do write_string(buf, ")");
|
||||
|
||||
case Array:
|
||||
write_string(buf, "[");
|
||||
@@ -291,8 +291,8 @@ write_type :: proc(buf: ^StringBuffer, ti: ^TypeInfo) {
|
||||
|
||||
case Struct:
|
||||
write_string(buf, "struct ");
|
||||
if info.packed -> write_string(buf, "#packed ");
|
||||
if info.ordered -> write_string(buf, "#ordered ");
|
||||
if info.packed do write_string(buf, "#packed ");
|
||||
if info.ordered do write_string(buf, "#ordered ");
|
||||
if info.custom_align {
|
||||
write_string(buf, "#align ");
|
||||
write_int(buf, i64(info.align), 10);
|
||||
@@ -300,7 +300,7 @@ write_type :: proc(buf: ^StringBuffer, ti: ^TypeInfo) {
|
||||
}
|
||||
write_byte(buf, '{');
|
||||
for name, i in info.names {
|
||||
if i > 0 -> write_string(buf, ", ");
|
||||
if i > 0 do write_string(buf, ", ");
|
||||
write_string(buf, name);
|
||||
write_string(buf, ": ");
|
||||
write_type(buf, info.types[i]);
|
||||
@@ -312,14 +312,14 @@ write_type :: proc(buf: ^StringBuffer, ti: ^TypeInfo) {
|
||||
cf := info.common_fields;
|
||||
total_count := 0;
|
||||
for name, i in cf.names {
|
||||
if i > 0 -> write_string(buf, ", ");
|
||||
if i > 0 do write_string(buf, ", ");
|
||||
write_string(buf, name);
|
||||
write_string(buf, ": ");
|
||||
write_type(buf, cf.types[i]);
|
||||
total_count++;
|
||||
}
|
||||
for name, i in info.variant_names {
|
||||
if total_count > 0 || i > 0 -> write_string(buf, ", ");
|
||||
if total_count > 0 || i > 0 do write_string(buf, ", ");
|
||||
write_string(buf, name);
|
||||
write_byte(buf, '{');
|
||||
defer write_byte(buf, '}');
|
||||
@@ -329,7 +329,7 @@ write_type :: proc(buf: ^StringBuffer, ti: ^TypeInfo) {
|
||||
|
||||
vc := len(variant.names)-len(cf.names);
|
||||
for j in 0..<vc {
|
||||
if j > 0 -> write_string(buf, ", ");
|
||||
if j > 0 do write_string(buf, ", ");
|
||||
index := j + len(cf.names);
|
||||
write_string(buf, variant.names[index]);
|
||||
write_string(buf, ": ");
|
||||
@@ -341,7 +341,7 @@ write_type :: proc(buf: ^StringBuffer, ti: ^TypeInfo) {
|
||||
case RawUnion:
|
||||
write_string(buf, "raw_union {");
|
||||
for name, i in info.names {
|
||||
if i > 0 -> write_string(buf, ", ");
|
||||
if i > 0 do write_string(buf, ", ");
|
||||
write_string(buf, name);
|
||||
write_string(buf, ": ");
|
||||
write_type(buf, info.types[i]);
|
||||
@@ -353,7 +353,7 @@ write_type :: proc(buf: ^StringBuffer, ti: ^TypeInfo) {
|
||||
write_type(buf, info.base);
|
||||
write_string(buf, " {");
|
||||
for name, i in info.names {
|
||||
if i > 0 -> write_string(buf, ", ");
|
||||
if i > 0 do write_string(buf, ", ");
|
||||
write_string(buf, name);
|
||||
}
|
||||
write_string(buf, "}");
|
||||
@@ -366,7 +366,7 @@ write_type :: proc(buf: ^StringBuffer, ti: ^TypeInfo) {
|
||||
}
|
||||
write_string(buf, " {");
|
||||
for name, i in info.names {
|
||||
if i > 0 -> write_string(buf, ", ");
|
||||
if i > 0 do write_string(buf, ", ");
|
||||
write_string(buf, name);
|
||||
write_string(buf, ": ");
|
||||
write_int(buf, i64(info.bits[i]), 10);
|
||||
@@ -388,7 +388,7 @@ _parse_int :: proc(s: string, offset: int) -> (result: int, offset: int, ok: boo
|
||||
i := 0;
|
||||
for i < len(s[offset..]) {
|
||||
c := rune(s[offset+i]);
|
||||
if !is_digit(c) -> break;
|
||||
if !is_digit(c) do break;
|
||||
i++;
|
||||
|
||||
result *= 10;
|
||||
@@ -482,13 +482,13 @@ fmt_bool :: proc(using fi: ^FmtInfo, b: bool, verb: rune) {
|
||||
|
||||
|
||||
fmt_write_padding :: proc(fi: ^FmtInfo, width: int) {
|
||||
if width <= 0 -> return;
|
||||
if width <= 0 do return;
|
||||
|
||||
pad_byte: u8 = fi.space ? ' ' : '0';
|
||||
|
||||
data := string_buffer_data(fi.buf^);
|
||||
count := min(width, cap(data)-len(data));
|
||||
for _ in 0..<count -> write_byte(fi.buf, pad_byte);
|
||||
for _ in 0..<count do write_byte(fi.buf, pad_byte);
|
||||
}
|
||||
|
||||
_fmt_int :: proc(fi: ^FmtInfo, u: u128, base: int, is_signed: bool, bit_size: int, digits: string) {
|
||||
@@ -533,9 +533,9 @@ _fmt_int :: proc(fi: ^FmtInfo, u: u128, base: int, is_signed: bool, bit_size: in
|
||||
|
||||
|
||||
flags: strconv.IntFlag;
|
||||
if fi.hash && !fi.zero -> flags |= strconv.IntFlag.Prefix;
|
||||
if fi.plus -> flags |= strconv.IntFlag.Plus;
|
||||
if fi.space -> flags |= strconv.IntFlag.Space;
|
||||
if fi.hash && !fi.zero do flags |= strconv.IntFlag.Prefix;
|
||||
if fi.plus do flags |= strconv.IntFlag.Plus;
|
||||
if fi.space do flags |= strconv.IntFlag.Space;
|
||||
s := strconv.append_bits(buf[start..<start], u128(u), base, is_signed, bit_size, digits, flags);
|
||||
|
||||
if fi.hash && fi.zero {
|
||||
@@ -664,7 +664,7 @@ fmt_string :: proc(fi: ^FmtInfo, s: string, verb: rune) {
|
||||
defer fi.space = space;
|
||||
|
||||
for i in 0..<len(s) {
|
||||
if i > 0 && space -> write_byte(fi.buf, ' ');
|
||||
if i > 0 && space do write_byte(fi.buf, ' ');
|
||||
_fmt_int(fi, u128(s[i]), 16, false, 8, verb == 'x' ? __DIGITS_LOWER : __DIGITS_UPPER);
|
||||
}
|
||||
|
||||
@@ -777,7 +777,7 @@ fmt_value :: proc(fi: ^FmtInfo, v: any, verb: rune) {
|
||||
write_string(fi.buf, info.name);
|
||||
write_byte(fi.buf, '{');
|
||||
for _, i in b.names {
|
||||
if i > 0 -> write_string(fi.buf, ", ");
|
||||
if i > 0 do write_string(fi.buf, ", ");
|
||||
write_string(fi.buf, b.names[i]);
|
||||
write_string(fi.buf, " = ");
|
||||
|
||||
@@ -811,7 +811,7 @@ fmt_value :: proc(fi: ^FmtInfo, v: any, verb: rune) {
|
||||
write_byte(fi.buf, '[');
|
||||
defer write_byte(fi.buf, ']');
|
||||
for i in 0..<info.count {
|
||||
if i > 0 -> write_string(fi.buf, ", ");
|
||||
if i > 0 do write_string(fi.buf, ", ");
|
||||
|
||||
data := ^u8(v.data) + i*info.elem_size;
|
||||
fmt_arg(fi, any{rawptr(data), info.elem}, verb);
|
||||
@@ -822,7 +822,7 @@ fmt_value :: proc(fi: ^FmtInfo, v: any, verb: rune) {
|
||||
defer write_byte(fi.buf, ']');
|
||||
array := ^raw.DynamicArray(v.data);
|
||||
for i in 0..<array.len {
|
||||
if i > 0 -> write_string(fi.buf, ", ");
|
||||
if i > 0 do write_string(fi.buf, ", ");
|
||||
|
||||
data := ^u8(array.data) + i*info.elem_size;
|
||||
fmt_arg(fi, any{rawptr(data), info.elem}, verb);
|
||||
@@ -833,7 +833,7 @@ fmt_value :: proc(fi: ^FmtInfo, v: any, verb: rune) {
|
||||
defer write_byte(fi.buf, ']');
|
||||
slice := ^[]u8(v.data);
|
||||
for _, i in slice {
|
||||
if i > 0 -> write_string(fi.buf, ", ");
|
||||
if i > 0 do write_string(fi.buf, ", ");
|
||||
|
||||
data := &slice[0] + i*info.elem_size;
|
||||
fmt_arg(fi, any{rawptr(data), info.elem}, verb);
|
||||
@@ -844,7 +844,7 @@ fmt_value :: proc(fi: ^FmtInfo, v: any, verb: rune) {
|
||||
defer write_byte(fi.buf, '>');
|
||||
|
||||
for i in 0..<info.count {
|
||||
if i > 0 -> write_string(fi.buf, ", ");
|
||||
if i > 0 do write_string(fi.buf, ", ");
|
||||
|
||||
data := ^u8(v.data) + i*info.elem_size;
|
||||
fmt_value(fi, any{rawptr(data), info.elem}, verb);
|
||||
@@ -866,7 +866,7 @@ fmt_value :: proc(fi: ^FmtInfo, v: any, verb: rune) {
|
||||
entry_size := ed.elem_size;
|
||||
|
||||
for i in 0..<entries.len {
|
||||
if i > 0 -> write_string(fi.buf, ", ");
|
||||
if i > 0 do write_string(fi.buf, ", ");
|
||||
|
||||
data := ^u8(entries.data) + i*entry_size;
|
||||
header := ^__MapEntryHeader(data);
|
||||
@@ -891,7 +891,7 @@ fmt_value :: proc(fi: ^FmtInfo, v: any, verb: rune) {
|
||||
defer write_byte(fi.buf, '}');
|
||||
|
||||
for _, i in info.names {
|
||||
if i > 0 -> write_string(fi.buf, ", ");
|
||||
if i > 0 do write_string(fi.buf, ", ");
|
||||
|
||||
write_string(fi.buf, info.names[i]);
|
||||
write_string(fi.buf, " = ");
|
||||
@@ -905,7 +905,7 @@ fmt_value :: proc(fi: ^FmtInfo, v: any, verb: rune) {
|
||||
|
||||
cf := info.common_fields;
|
||||
for _, i in cf.names {
|
||||
if i > 0 -> write_string(fi.buf, ", ");
|
||||
if i > 0 do write_string(fi.buf, ", ");
|
||||
|
||||
write_string(fi.buf, cf.names[i]);
|
||||
write_string(fi.buf, " = ");
|
||||
@@ -1028,7 +1028,7 @@ sbprintln :: proc(buf: ^StringBuffer, args: ..any) -> string {
|
||||
fi.buf = buf;
|
||||
|
||||
for arg, i in args {
|
||||
if i > 0 -> write_byte(buf, ' ');
|
||||
if i > 0 do write_byte(buf, ' ');
|
||||
|
||||
fmt_value(&fi, args[i], 'v');
|
||||
}
|
||||
@@ -1155,10 +1155,10 @@ sbprintf :: proc(b: ^StringBuffer, fmt: string, args: ..any) -> string {
|
||||
if !fi.reordered && arg_index < len(args) {
|
||||
write_string(b, "%!(EXTRA ");
|
||||
for arg, index in args[arg_index..] {
|
||||
if index > 0 -> write_string(b, ", ");
|
||||
if index > 0 do write_string(b, ", ");
|
||||
|
||||
if arg == nil -> write_string(b, "<nil>");
|
||||
else -> fmt_arg(&fi, args[index], 'v');
|
||||
if arg == nil do write_string(b, "<nil>");
|
||||
else do fmt_arg(&fi, args[index], 'v');
|
||||
}
|
||||
write_string(b, ")");
|
||||
}
|
||||
|
||||
+40
-23
@@ -1073,7 +1073,7 @@ void check_bit_field_type(Checker *c, Type *bit_field_type, Type *named_type, As
|
||||
}
|
||||
}
|
||||
|
||||
bool is_polymorphic_type_assignable(Checker *c, Type *poly, Type *source, bool compound) {
|
||||
bool is_polymorphic_type_assignable(Checker *c, Type *poly, Type *source, bool compound, bool modify_type) {
|
||||
Operand o = {Addressing_Value};
|
||||
o.type = source;
|
||||
switch (poly->kind) {
|
||||
@@ -1085,40 +1085,42 @@ bool is_polymorphic_type_assignable(Checker *c, Type *poly, Type *source, bool c
|
||||
return check_is_assignable_to(c, &o, poly);
|
||||
|
||||
case Type_Generic: {
|
||||
Type *ds = default_type(source);
|
||||
gb_memmove(poly, ds, gb_size_of(Type));
|
||||
if (modify_type) {
|
||||
Type *ds = default_type(source);
|
||||
gb_memmove(poly, ds, gb_size_of(Type));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case Type_Pointer:
|
||||
if (source->kind == Type_Pointer) {
|
||||
return is_polymorphic_type_assignable(c, poly->Pointer.elem, source->Pointer.elem, true);
|
||||
return is_polymorphic_type_assignable(c, poly->Pointer.elem, source->Pointer.elem, true, modify_type);
|
||||
}
|
||||
return false;
|
||||
case Type_Atomic:
|
||||
if (source->kind == Type_Atomic) {
|
||||
return is_polymorphic_type_assignable(c, poly->Atomic.elem, source->Atomic.elem, true);
|
||||
return is_polymorphic_type_assignable(c, poly->Atomic.elem, source->Atomic.elem, true, modify_type);
|
||||
}
|
||||
return false;
|
||||
case Type_Array:
|
||||
if (source->kind == Type_Array &&
|
||||
poly->Array.count == source->Array.count) {
|
||||
return is_polymorphic_type_assignable(c, poly->Array.elem, source->Array.elem, true);
|
||||
return is_polymorphic_type_assignable(c, poly->Array.elem, source->Array.elem, true, modify_type);
|
||||
}
|
||||
return false;
|
||||
case Type_DynamicArray:
|
||||
if (source->kind == Type_DynamicArray) {
|
||||
return is_polymorphic_type_assignable(c, poly->DynamicArray.elem, source->DynamicArray.elem, true);
|
||||
return is_polymorphic_type_assignable(c, poly->DynamicArray.elem, source->DynamicArray.elem, true, modify_type);
|
||||
}
|
||||
return false;
|
||||
case Type_Vector:
|
||||
if (source->kind == Type_Vector &&
|
||||
poly->Vector.count == source->Vector.count) {
|
||||
return is_polymorphic_type_assignable(c, poly->Vector.elem, source->Vector.elem, true);
|
||||
return is_polymorphic_type_assignable(c, poly->Vector.elem, source->Vector.elem, true, modify_type);
|
||||
}
|
||||
return false;
|
||||
case Type_Slice:
|
||||
if (source->kind == Type_Slice) {
|
||||
return is_polymorphic_type_assignable(c, poly->Slice.elem, source->Slice.elem, true);
|
||||
return is_polymorphic_type_assignable(c, poly->Slice.elem, source->Slice.elem, true, modify_type);
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -1137,8 +1139,8 @@ bool is_polymorphic_type_assignable(Checker *c, Type *poly, Type *source, bool c
|
||||
return false;
|
||||
case Type_Map:
|
||||
if (source->kind == Type_Map) {
|
||||
bool key = is_polymorphic_type_assignable(c, poly->Map.key, source->Map.key, true);
|
||||
bool value = is_polymorphic_type_assignable(c, poly->Map.value, source->Map.value, true);
|
||||
bool key = is_polymorphic_type_assignable(c, poly->Map.key, source->Map.key, true, modify_type);
|
||||
bool value = is_polymorphic_type_assignable(c, poly->Map.value, source->Map.value, true, modify_type);
|
||||
return key || value;
|
||||
}
|
||||
return false;
|
||||
@@ -1147,21 +1149,26 @@ bool is_polymorphic_type_assignable(Checker *c, Type *poly, Type *source, bool c
|
||||
}
|
||||
|
||||
Type *determine_type_from_polymorphic(Checker *c, Type *poly_type, Operand operand) {
|
||||
bool modify_type = !c->context.no_polymorphic_errors;
|
||||
if (!is_operand_value(operand)) {
|
||||
error(operand.expr, "Cannot determine polymorphic type from parameter");
|
||||
if (modify_type) {
|
||||
error(operand.expr, "Cannot determine polymorphic type from parameter");
|
||||
}
|
||||
return t_invalid;
|
||||
}
|
||||
if (is_polymorphic_type_assignable(c, poly_type, operand.type, false)) {
|
||||
if (is_polymorphic_type_assignable(c, poly_type, operand.type, false, modify_type)) {
|
||||
return poly_type;
|
||||
}
|
||||
gbString pts = type_to_string(poly_type);
|
||||
gbString ots = type_to_string(operand.type);
|
||||
defer (gb_string_free(pts));
|
||||
defer (gb_string_free(ots));
|
||||
error(operand.expr,
|
||||
"Cannot determine polymorphic type from parameter: `%s` to `%s`\n"
|
||||
"\tNote: Record and procedure types are not yet supported",
|
||||
ots, pts);
|
||||
if (modify_type) {
|
||||
gbString pts = type_to_string(poly_type);
|
||||
gbString ots = type_to_string(operand.type);
|
||||
defer (gb_string_free(pts));
|
||||
defer (gb_string_free(ots));
|
||||
error(operand.expr,
|
||||
"Cannot determine polymorphic type from parameter: `%s` to `%s`\n"
|
||||
"\tNote: Record and procedure types are not yet supported",
|
||||
ots, pts);
|
||||
}
|
||||
return t_invalid;
|
||||
}
|
||||
|
||||
@@ -1332,7 +1339,10 @@ Type *check_get_params(Checker *c, Scope *scope, AstNode *_params, bool *is_vari
|
||||
if (o.mode == Addressing_Type) {
|
||||
type = o.type;
|
||||
} else {
|
||||
error(o.expr, "Expected a type to assign to the type parameter");
|
||||
if (!c->context.no_polymorphic_errors) {
|
||||
error(o.expr, "Expected a type to assign to the type parameter");
|
||||
}
|
||||
success = false;
|
||||
type = t_invalid;
|
||||
}
|
||||
}
|
||||
@@ -5338,7 +5348,9 @@ CALL_ARGUMENT_CHECKER(check_call_arguments_internal) {
|
||||
if (o.mode == Addressing_Invalid) {
|
||||
continue;
|
||||
} else if (o.mode != Addressing_Type) {
|
||||
error(o.expr, "Expected a type for the argument `%.*s`", LIT(e->token.string));
|
||||
if (show_error) {
|
||||
error(o.expr, "Expected a type for the argument `%.*s`", LIT(e->token.string));
|
||||
}
|
||||
err = CallArgumentError_WrongTypes;
|
||||
}
|
||||
|
||||
@@ -5641,6 +5653,7 @@ CallArgumentData check_call_arguments(Checker *c, Operand *operand, Type *proc_t
|
||||
|
||||
for (isize i = 0; i < overload_count; i++) {
|
||||
Entity *e = procs[i];
|
||||
GB_ASSERT(e->token.string == name);
|
||||
DeclInfo *d = decl_info_of_entity(&c->info, e);
|
||||
GB_ASSERT(d != NULL);
|
||||
check_entity_decl(c, e, d, NULL);
|
||||
@@ -5651,7 +5664,11 @@ CallArgumentData check_call_arguments(Checker *c, Operand *operand, Type *proc_t
|
||||
Type *pt = base_type(p->type);
|
||||
if (pt != NULL && is_type_proc(pt)) {
|
||||
CallArgumentData data = {};
|
||||
bool prev = c->context.no_polymorphic_errors;
|
||||
defer (c->context.no_polymorphic_errors = prev);
|
||||
c->context.no_polymorphic_errors = true;
|
||||
CallArgumentError err = call_checker(c, call, pt, p, operands, CallArgumentMode_NoErrors, &data);
|
||||
|
||||
if (err == CallArgumentError_None) {
|
||||
valids[valid_count].index = i;
|
||||
valids[valid_count].score = data.score;
|
||||
|
||||
+8
-1
@@ -262,6 +262,7 @@ struct CheckerContext {
|
||||
u32 stmt_state_flags;
|
||||
bool in_defer; // TODO(bill): Actually handle correctly
|
||||
bool allow_polymorphic_types;
|
||||
bool no_polymorphic_errors;
|
||||
String proc_name;
|
||||
Type * type_hint;
|
||||
DeclInfo * curr_proc_decl;
|
||||
@@ -1474,8 +1475,10 @@ void check_procedure_overloading(Checker *c, Entity *e) {
|
||||
is_invalid = true;
|
||||
break;
|
||||
case ProcOverload_Polymorphic:
|
||||
#if 1
|
||||
error(p->token, "Overloaded procedure `%.*s` has a polymorphic counterpart in this scope which is not allowed", LIT(name));
|
||||
is_invalid = true;
|
||||
#endif
|
||||
break;
|
||||
case ProcOverload_ParamCount:
|
||||
case ProcOverload_ParamTypes:
|
||||
@@ -1705,7 +1708,11 @@ void check_collect_entities(Checker *c, Array<AstNode *> nodes, bool is_file_sco
|
||||
e->identifier = name;
|
||||
|
||||
if (fl != NULL && e->kind != Entity_Procedure) {
|
||||
error(name, "Only procedures and variables are allowed to be in a foreign block, got %.*s", LIT(ast_node_strings[init->kind]));
|
||||
AstNodeKind kind = init->kind;
|
||||
error(name, "Only procedures and variables are allowed to be in a foreign block, got %.*s", LIT(ast_node_strings[kind]));
|
||||
if (kind == AstNode_ProcType) {
|
||||
gb_printf_err("\tDid you forget to append `---` to the procedure?\n");
|
||||
}
|
||||
// continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -92,6 +92,7 @@ struct Entity {
|
||||
bool is_foreign;
|
||||
Entity * foreign_library;
|
||||
AstNode * foreign_library_ident;
|
||||
String link_name;
|
||||
} Variable;
|
||||
struct {
|
||||
bool is_type_alias;
|
||||
|
||||
+36
-12
@@ -882,9 +882,13 @@ AstNode *clone_ast_node(gbAllocator a, AstNode *node) {
|
||||
|
||||
|
||||
void error(AstNode *node, char *fmt, ...) {
|
||||
Token token = {};
|
||||
if (node != NULL) {
|
||||
token = ast_node_token(node);
|
||||
}
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
error_va(ast_node_token(node), fmt, va);
|
||||
error_va(token, fmt, va);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
@@ -2265,6 +2269,26 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
|
||||
body = parse_body(f);
|
||||
f->curr_proc = curr_proc;
|
||||
|
||||
return ast_proc_lit(f, type, body, tags, link_name);
|
||||
} else if (allow_token(f, Token_do)) {
|
||||
if ((tags & ProcTag_foreign) != 0) {
|
||||
syntax_error(token, "A procedure tagged as `#foreign` cannot have a body");
|
||||
}
|
||||
AstNode *curr_proc = f->curr_proc;
|
||||
AstNode *body = NULL;
|
||||
f->curr_proc = type;
|
||||
body = parse_stmt(f);
|
||||
if (body->kind == AstNode_BlockStmt) {
|
||||
syntax_error(body, "Expected a normal statement rather than a block statement");
|
||||
} else {
|
||||
Token open = ast_node_token(body);
|
||||
Token close = ast_node_token(body);
|
||||
Array<AstNode *> stmts = make_ast_node_array(f, 1);
|
||||
array_add(&stmts, body);
|
||||
body = ast_block_stmt(f, stmts, open, close);
|
||||
}
|
||||
f->curr_proc = curr_proc;
|
||||
|
||||
return ast_proc_lit(f, type, body, tags, link_name);
|
||||
}
|
||||
|
||||
@@ -3787,7 +3811,7 @@ AstNode *parse_if_stmt(AstFile *f) {
|
||||
syntax_error(f->curr_token, "Expected condition for if statement");
|
||||
}
|
||||
|
||||
if (allow_token(f, Token_ArrowRight)) {
|
||||
if (allow_token(f, Token_do)) {
|
||||
body = parse_stmt(f);
|
||||
if (body->kind == AstNode_BlockStmt) {
|
||||
syntax_error(body, "Expected a normal statement rather than a block statement");
|
||||
@@ -3804,8 +3828,8 @@ AstNode *parse_if_stmt(AstFile *f) {
|
||||
case Token_OpenBrace:
|
||||
else_stmt = parse_block_stmt(f, false);
|
||||
break;
|
||||
case Token_ArrowRight: {
|
||||
Token arrow = expect_token(f, Token_ArrowRight);
|
||||
case Token_do: {
|
||||
Token arrow = expect_token(f, Token_do);
|
||||
body = parse_stmt(f);
|
||||
if (body->kind == AstNode_BlockStmt) {
|
||||
syntax_error(body, "Expected a normal statement rather than a block statement");
|
||||
@@ -3838,7 +3862,7 @@ AstNode *parse_when_stmt(AstFile *f) {
|
||||
syntax_error(f->curr_token, "Expected condition for when statement");
|
||||
}
|
||||
|
||||
if (allow_token(f, Token_ArrowRight)) {
|
||||
if (allow_token(f, Token_do)) {
|
||||
body = parse_stmt(f);
|
||||
if (body->kind == AstNode_BlockStmt) {
|
||||
syntax_error(body, "Expected a normal statement rather than a block statement");
|
||||
@@ -3855,8 +3879,8 @@ AstNode *parse_when_stmt(AstFile *f) {
|
||||
case Token_OpenBrace:
|
||||
else_stmt = parse_block_stmt(f, true);
|
||||
break;
|
||||
case Token_ArrowRight: {
|
||||
Token arrow = expect_token(f, Token_ArrowRight);
|
||||
case Token_do: {
|
||||
Token arrow = expect_token(f, Token_do);
|
||||
body = parse_stmt(f);
|
||||
if (body->kind == AstNode_BlockStmt) {
|
||||
syntax_error(body, "Expected a normal statement rather than a block statement");
|
||||
@@ -3958,7 +3982,7 @@ AstNode *parse_for_stmt(AstFile *f) {
|
||||
}
|
||||
|
||||
if (!is_range && (f->curr_token.kind == Token_Semicolon ||
|
||||
f->curr_token.kind == Token_ArrowRight)) {
|
||||
f->curr_token.kind == Token_do)) {
|
||||
next_token(f);
|
||||
init = cond;
|
||||
cond = NULL;
|
||||
@@ -3967,7 +3991,7 @@ AstNode *parse_for_stmt(AstFile *f) {
|
||||
}
|
||||
expect_semicolon(f, cond);
|
||||
if (f->curr_token.kind != Token_OpenBrace &&
|
||||
f->curr_token.kind != Token_ArrowRight) {
|
||||
f->curr_token.kind != Token_do) {
|
||||
post = parse_simple_stmt(f, StmtAllowFlag_None);
|
||||
}
|
||||
}
|
||||
@@ -3975,7 +3999,7 @@ AstNode *parse_for_stmt(AstFile *f) {
|
||||
f->expr_level = prev_level;
|
||||
}
|
||||
|
||||
if (allow_token(f, Token_ArrowRight)) {
|
||||
if (allow_token(f, Token_do)) {
|
||||
body = parse_stmt(f);
|
||||
if (body->kind == AstNode_BlockStmt) {
|
||||
syntax_error(body, "Expected a normal statement rather than a block statement");
|
||||
@@ -4236,7 +4260,7 @@ AstNode *parse_stmt(AstFile *f) {
|
||||
AstNode *expr = parse_expr(f, false);
|
||||
f->expr_level = prev_level;
|
||||
|
||||
if (allow_token(f, Token_ArrowRight)) {
|
||||
if (allow_token(f, Token_do)) {
|
||||
body = parse_stmt(f);
|
||||
if (body->kind == AstNode_BlockStmt) {
|
||||
syntax_error(body, "Expected a normal statement rather than a block statement");
|
||||
@@ -4256,7 +4280,7 @@ AstNode *parse_stmt(AstFile *f) {
|
||||
AstNode *expr = parse_expr(f, false);
|
||||
f->expr_level = prev_level;
|
||||
|
||||
if (allow_token(f, Token_ArrowRight)) {
|
||||
if (allow_token(f, Token_do)) {
|
||||
body = parse_stmt(f);
|
||||
if (body->kind == AstNode_BlockStmt) {
|
||||
syntax_error(body, "Expected a normal statement rather than a block statement");
|
||||
|
||||
+30
-23
@@ -36,27 +36,28 @@ TOKEN_KIND(Token__OperatorBegin, "_OperatorBegin"), \
|
||||
TOKEN_KIND(Token_CmpAnd, "&&"), \
|
||||
TOKEN_KIND(Token_CmpOr, "||"), \
|
||||
\
|
||||
TOKEN_KIND(Token__AssignOpBegin, "_AssignOpBegin"), \
|
||||
TOKEN_KIND(Token_AddEq, "+="), \
|
||||
TOKEN_KIND(Token_SubEq, "-="), \
|
||||
TOKEN_KIND(Token_MulEq, "*="), \
|
||||
TOKEN_KIND(Token_QuoEq, "/="), \
|
||||
TOKEN_KIND(Token_ModEq, "%="), \
|
||||
TOKEN_KIND(Token_ModModEq, "%%="), \
|
||||
TOKEN_KIND(Token_AndEq, "&="), \
|
||||
TOKEN_KIND(Token_OrEq, "|="), \
|
||||
TOKEN_KIND(Token_XorEq, "~="), \
|
||||
TOKEN_KIND(Token_AndNotEq, "&~="), \
|
||||
TOKEN_KIND(Token_ShlEq, "<<="), \
|
||||
TOKEN_KIND(Token_ShrEq, ">>="), \
|
||||
TOKEN_KIND(Token_CmpAndEq, "&&="), \
|
||||
TOKEN_KIND(Token_CmpOrEq, "||="), \
|
||||
TOKEN_KIND(Token__AssignOpEnd, "_AssignOpEnd"), \
|
||||
TOKEN_KIND(Token_ArrowRight, "->"), \
|
||||
TOKEN_KIND(Token_ThickArrowRight, "=>"), \
|
||||
TOKEN_KIND(Token_Inc, "++"), \
|
||||
TOKEN_KIND(Token_Dec, "--"), \
|
||||
TOKEN_KIND(Token_Undef, "---"), \
|
||||
TOKEN_KIND(Token__AssignOpBegin, "_AssignOpBegin"), \
|
||||
TOKEN_KIND(Token_AddEq, "+="), \
|
||||
TOKEN_KIND(Token_SubEq, "-="), \
|
||||
TOKEN_KIND(Token_MulEq, "*="), \
|
||||
TOKEN_KIND(Token_QuoEq, "/="), \
|
||||
TOKEN_KIND(Token_ModEq, "%="), \
|
||||
TOKEN_KIND(Token_ModModEq, "%%="), \
|
||||
TOKEN_KIND(Token_AndEq, "&="), \
|
||||
TOKEN_KIND(Token_OrEq, "|="), \
|
||||
TOKEN_KIND(Token_XorEq, "~="), \
|
||||
TOKEN_KIND(Token_AndNotEq, "&~="), \
|
||||
TOKEN_KIND(Token_ShlEq, "<<="), \
|
||||
TOKEN_KIND(Token_ShrEq, ">>="), \
|
||||
TOKEN_KIND(Token_CmpAndEq, "&&="), \
|
||||
TOKEN_KIND(Token_CmpOrEq, "||="), \
|
||||
TOKEN_KIND(Token__AssignOpEnd, "_AssignOpEnd"), \
|
||||
TOKEN_KIND(Token_ArrowRight, "->"), \
|
||||
TOKEN_KIND(Token_ArrowLeft, "<-"), \
|
||||
TOKEN_KIND(Token_DoubleArrowRight, "=>"), \
|
||||
TOKEN_KIND(Token_Inc, "++"), \
|
||||
TOKEN_KIND(Token_Dec, "--"), \
|
||||
TOKEN_KIND(Token_Undef, "---"), \
|
||||
\
|
||||
TOKEN_KIND(Token__ComparisonBegin, "_ComparisonBegin"), \
|
||||
TOKEN_KIND(Token_CmpEq, "=="), \
|
||||
@@ -100,6 +101,7 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \
|
||||
TOKEN_KIND(Token_continue, "continue"), \
|
||||
TOKEN_KIND(Token_fallthrough, "fallthrough"), \
|
||||
TOKEN_KIND(Token_defer, "defer"), \
|
||||
TOKEN_KIND(Token_do, "do"), \
|
||||
TOKEN_KIND(Token_return, "return"), \
|
||||
TOKEN_KIND(Token_proc, "proc"), \
|
||||
TOKEN_KIND(Token_macro, "macro"), \
|
||||
@@ -914,7 +916,7 @@ Token tokenizer_get_token(Tokenizer *t) {
|
||||
token.kind = Token_Eq;
|
||||
if (t->curr_rune == '>') {
|
||||
advance_to_next_rune(t);
|
||||
token.kind = Token_ThickArrowRight;
|
||||
token.kind = Token_DoubleArrowRight;
|
||||
} else if (t->curr_rune == '=') {
|
||||
advance_to_next_rune(t);
|
||||
token.kind = Token_CmpEq;
|
||||
@@ -976,7 +978,12 @@ Token tokenizer_get_token(Tokenizer *t) {
|
||||
} break;
|
||||
|
||||
case '<':
|
||||
token.kind = token_kind_dub_eq(t, '<', Token_Lt, Token_LtEq, Token_Shl, Token_ShlEq);
|
||||
if (t->curr_rune == '-') {
|
||||
advance_to_next_rune(t);
|
||||
token.kind = Token_ArrowLeft;
|
||||
} else {
|
||||
token.kind = token_kind_dub_eq(t, '<', Token_Lt, Token_LtEq, Token_Shl, Token_ShlEq);
|
||||
}
|
||||
break;
|
||||
case '>': token.kind = token_kind_dub_eq(t, '>', Token_Gt, Token_GtEq, Token_Shr, Token_ShrEq); break;
|
||||
|
||||
|
||||
+5
-3
@@ -1353,14 +1353,16 @@ ProcTypeOverloadKind are_proc_types_overload_safe(Type *x, Type *y) {
|
||||
TypeProc px = base_type(x)->Proc;
|
||||
TypeProc py = base_type(y)->Proc;
|
||||
|
||||
// if (px.calling_convention != py.calling_convention) {
|
||||
// return ProcOverload_CallingConvention;
|
||||
// }
|
||||
|
||||
if (px.is_polymorphic != py.is_polymorphic) {
|
||||
return ProcOverload_Polymorphic;
|
||||
}
|
||||
|
||||
|
||||
// if (px.calling_convention != py.calling_convention) {
|
||||
// return ProcOverload_CallingConvention;
|
||||
// }
|
||||
|
||||
if (px.param_count != py.param_count) {
|
||||
return ProcOverload_ParamCount;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user