match to switch; Optional semicolons after "import" statements

This commit is contained in:
Ginger Bill
2017-10-01 17:09:57 +01:00
parent f38c8875b2
commit c1e720a49b
33 changed files with 641 additions and 451 deletions

View File

@@ -1,9 +1,9 @@
#shared_global_scope;
#shared_global_scope
import "core:os.odin";
import "core:fmt.odin"; // TODO(bill): Remove the need for `fmt` here
import "core:utf8.odin";
import "core:raw.odin";
import "core:os.odin"
import "core:fmt.odin" // TODO(bill): Remove the need for `fmt` here
import "core:utf8.odin"
import "core:raw.odin"
// Naming Conventions:
// In general, Ada_Case for types and snake_case for values
@@ -43,7 +43,6 @@ Type_Info_Enum_Value :: union {
f32, f64,
};
// Variant Types
Type_Info_Named :: struct #ordered {name: string, base: ^Type_Info};
Type_Info_Integer :: struct #ordered {signed: bool};
@@ -106,7 +105,6 @@ Type_Info_Bit_Field :: struct #ordered {
Type_Info :: struct #ordered {
// Fields
size: int,
align: int,
@@ -217,7 +215,7 @@ type_info_base :: proc(info: ^Type_Info) -> ^Type_Info {
if info == nil do return nil;
base := info;
match i in base.variant {
switch i in base.variant {
case Type_Info_Named: base = i.base;
}
return base;
@@ -228,7 +226,7 @@ type_info_base_without_enum :: proc(info: ^Type_Info) -> ^Type_Info {
if info == nil do return nil;
base := info;
match i in base.variant {
switch i in base.variant {
case Type_Info_Named: base = i.base;
case Type_Info_Enum: base = i.base;
}
@@ -444,9 +442,9 @@ __get_map_header :: proc(m: ^$T/map[$K]$V) -> __Map_Header #cc_contextless {
__get_map_key :: proc(key: $K) -> __Map_Key #cc_contextless {
map_key: __Map_Key;
ti := type_info_base_without_enum(type_info_of(K));
match _ in ti.variant {
switch _ in ti.variant {
case Type_Info_Integer:
match 8*size_of(key) {
switch 8*size_of(key) {
case 8: map_key.hash = u128(( ^u8)(&key)^);
case 16: map_key.hash = u128(( ^u16)(&key)^);
case 32: map_key.hash = u128(( ^u32)(&key)^);
@@ -459,7 +457,7 @@ __get_map_key :: proc(key: $K) -> __Map_Key #cc_contextless {
case Type_Info_Pointer:
map_key.hash = u128(uint((^rawptr)(&key)^));
case Type_Info_Float:
match 8*size_of(key) {
switch 8*size_of(key) {
case 32: map_key.hash = u128((^u32)(&key)^);
case 64: map_key.hash = u128((^u64)(&key)^);
case: panic("Unhandled float size");
@@ -575,7 +573,7 @@ default_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
old_memory: rawptr, old_size: int, flags: u64) -> rawptr {
using Allocator_Mode;
match mode {
switch mode {
case Alloc:
return os.heap_alloc(size);
@@ -626,7 +624,7 @@ panic :: proc(message := "", using location := #caller_location) #cc_contextless
__string_eq :: proc(a, b: string) -> bool #cc_contextless {
match {
switch {
case len(a) != len(b): return false;
case len(a) == 0: return true;
case &a[0] == &b[0]: return true;
@@ -731,7 +729,7 @@ __mem_copy_non_overlapping :: proc(dst, src: rawptr, len: int) -> rawptr #cc_con
__mem_compare :: proc(a, b: ^u8, n: int) -> int #cc_contextless {
for i in 0..n {
match {
switch {
case (a+i)^ < (b+i)^: return -1;
case (a+i)^ > (b+i)^: return +1;
}

View File

@@ -1,4 +1,4 @@
#shared_global_scope;
#shared_global_scope
__multi3 :: proc(a, b: u128) -> u128 #cc_c #link_name "__multi3" {
bits_in_dword_2 :: size_of(i64) * 4;

View File

@@ -2,7 +2,7 @@
// Inline vs external file?
when ODIN_OS == "windows" {
import win32 "core:sys/windows.odin";
import win32 "core:sys/windows.odin"
}
_ :: compile_assert(ODIN_ARCH == "amd64"); // TODO(bill): x86 version

View File

@@ -171,7 +171,7 @@ shift :: proc(a: ^Decimal, k: int) {
uint_size :: 8*size_of(uint);
max_shift :: uint_size-4;
match {
switch {
case a.count == 0:
// no need to update
case k > 0:

View File

@@ -1,9 +1,9 @@
import "core:os.odin";
import "core:mem.odin";
import "core:utf8.odin";
import "core:types.odin";
import "core:strconv.odin";
import "core:raw.odin";
import "core:os.odin"
import "core:mem.odin"
import "core:utf8.odin"
import "core:types.odin"
import "core:strconv.odin"
import "core:raw.odin"
_BUFFER_SIZE :: 1<<12;
@@ -36,14 +36,14 @@ Fmt_Info :: struct {
string_buffer_data :: proc(buf: ^String_Buffer) -> []u8 {
match b in buf {
switch b in buf {
case []u8: return b[..];
case [dynamic]u8: return b[..];
}
return nil;
}
string_buffer_data :: proc(buf: String_Buffer) -> []u8 {
match b in buf {
switch b in buf {
case []u8: return b[..];
case [dynamic]u8: return b[..];
}
@@ -58,13 +58,13 @@ write_string :: proc(buf: ^String_Buffer, s: string) {
write_bytes(buf, cast([]u8)s);
}
write_bytes :: proc(buf: ^String_Buffer, data: []u8) {
match b in buf {
switch b in buf {
case []u8: append(b, ...data);
case [dynamic]u8: append(b, ...data);
}
}
write_byte :: proc(buf: ^String_Buffer, data: u8) {
match b in buf {
switch b in buf {
case []u8: append(b, data);
case [dynamic]u8: append(b, data);
}
@@ -179,11 +179,11 @@ write_type :: proc(buf: ^String_Buffer, ti: ^Type_Info) {
return;
}
match info in ti.variant {
switch info in ti.variant {
case Type_Info_Named:
write_string(buf, info.name);
case Type_Info_Integer:
match {
switch {
case ti == type_info_of(int): write_string(buf, "int");
case ti == type_info_of(uint): write_string(buf, "uint");
case:
@@ -194,13 +194,13 @@ write_type :: proc(buf: ^String_Buffer, ti: ^Type_Info) {
case Type_Info_Rune:
write_string(buf, "rune");
case Type_Info_Float:
match ti.size {
switch ti.size {
case 2: write_string(buf, "f16");
case 4: write_string(buf, "f32");
case 8: write_string(buf, "f64");
}
case Type_Info_Complex:
match ti.size {
switch ti.size {
case 4: write_string(buf, "complex32");
case 8: write_string(buf, "complex64");
case 16: write_string(buf, "complex128");
@@ -388,7 +388,7 @@ int_from_arg :: proc(args: []any, arg_index: int) -> (int, int, bool) {
if arg_index < len(args) {
arg := args[arg_index];
arg.type_info = type_info_base(arg.type_info);
match i in arg {
switch i in arg {
case int: num = i;
case i8: num = int(i);
case i16: num = int(i);
@@ -423,7 +423,7 @@ fmt_bad_verb :: proc(using fi: ^Fmt_Info, verb: rune) {
}
fmt_bool :: proc(using fi: ^Fmt_Info, b: bool, verb: rune) {
match verb {
switch verb {
case 't', 'v':
s := "false";
if b do s = "true";
@@ -475,7 +475,7 @@ _fmt_int :: proc(fi: ^Fmt_Info, u: u128, base: int, is_signed: bool, bit_size: i
}
}
match base {
switch base {
case 2, 8, 10, 12, 16:
break;
case:
@@ -493,7 +493,7 @@ _fmt_int :: proc(fi: ^Fmt_Info, u: u128, base: int, is_signed: bool, bit_size: i
if fi.hash && fi.zero {
c: u8;
match base {
switch base {
case 2: c = 'b';
case 8: c = 'o';
case 10: c = 'd';
@@ -517,7 +517,7 @@ __DIGITS_LOWER := "0123456789abcdefx";
__DIGITS_UPPER := "0123456789ABCDEFX";
fmt_rune :: proc(fi: ^Fmt_Info, r: rune, verb: rune) {
match verb {
switch verb {
case 'c', 'r', 'v':
write_rune(fi.buf, r);
case:
@@ -526,7 +526,7 @@ fmt_rune :: proc(fi: ^Fmt_Info, r: rune, verb: rune) {
}
fmt_int :: proc(fi: ^Fmt_Info, u: u128, is_signed: bool, bit_size: int, verb: rune) {
match verb {
switch verb {
case 'v': _fmt_int(fi, u, 10, is_signed, bit_size, __DIGITS_LOWER);
case 'b': _fmt_int(fi, u, 2, is_signed, bit_size, __DIGITS_LOWER);
case 'o': _fmt_int(fi, u, 8, is_signed, bit_size, __DIGITS_LOWER);
@@ -568,7 +568,7 @@ _pad :: proc(fi: ^Fmt_Info, s: string) {
}
fmt_float :: proc(fi: ^Fmt_Info, v: f64, bit_size: int, verb: rune) {
match verb {
switch verb {
// case 'e', 'E', 'f', 'F', 'g', 'G', 'v':
// case 'f', 'F', 'v':
@@ -611,7 +611,7 @@ fmt_float :: proc(fi: ^Fmt_Info, v: f64, bit_size: int, verb: rune) {
}
}
fmt_string :: proc(fi: ^Fmt_Info, s: string, verb: rune) {
match verb {
switch verb {
case 's', 'v':
write_string(fi.buf, s);
@@ -633,7 +633,7 @@ fmt_string :: proc(fi: ^Fmt_Info, s: string, verb: rune) {
}
fmt_pointer :: proc(fi: ^Fmt_Info, p: rawptr, verb: rune) {
match verb {
switch verb {
case 'p', 'v':
// Okay
case:
@@ -650,7 +650,7 @@ fmt_pointer :: proc(fi: ^Fmt_Info, p: rawptr, verb: rune) {
enum_value_to_string :: proc(v: any) -> (string, bool) {
v.type_info = type_info_base(v.type_info);
match e in v.type_info.variant {
switch e in v.type_info.variant {
case: return "", false;
case Type_Info_Enum:
get_str :: proc(i: $T, e: Type_Info_Enum) -> (string, bool) {
@@ -673,7 +673,7 @@ enum_value_to_string :: proc(v: any) -> (string, bool) {
}
a := any{v.data, type_info_base(e.base)};
match v in a {
switch v in a {
case rune: return get_str(v, e);
case i8: return get_str(v, e);
case i16: return get_str(v, e);
@@ -716,10 +716,10 @@ fmt_enum :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
return;
}
match e in v.type_info.variant {
switch e in v.type_info.variant {
case: fmt_bad_verb(fi, verb);
case Type_Info_Enum:
match verb {
switch verb {
case: fmt_bad_verb(fi, verb);
case 'd', 'f':
fmt_arg(fi, any{v.data, type_info_base(e.base)}, verb);
@@ -738,9 +738,9 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
return;
}
match info in v.type_info.variant {
switch info in v.type_info.variant {
case Type_Info_Named:
match b in info.base.variant {
switch b in info.base.variant {
case Type_Info_Struct:
if verb != 'v' {
fmt_bad_verb(fi, verb);
@@ -939,7 +939,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
}
fmt_complex :: proc(fi: ^Fmt_Info, c: complex128, bits: int, verb: rune) {
match verb {
switch verb {
case 'f', 'F', 'v':
r, i := real(c), imag(c);
fmt_float(fi, r, bits/2, verb);
@@ -972,7 +972,7 @@ fmt_arg :: proc(fi: ^Fmt_Info, arg: any, verb: rune) {
if verb == 'T' {
ti := arg.type_info;
match a in arg {
switch a in arg {
case ^Type_Info: ti = a;
}
write_type(fi.buf, ti);
@@ -982,7 +982,7 @@ fmt_arg :: proc(fi: ^Fmt_Info, arg: any, verb: rune) {
base_arg := arg;
base_arg.type_info = type_info_base(base_arg.type_info);
match a in base_arg {
switch a in base_arg {
case any: fmt_arg(fi, a, verb);
case bool: fmt_bool(fi, a, verb);
case rune: fmt_rune(fi, a, verb);
@@ -1073,7 +1073,7 @@ sbprintf :: proc(b: ^String_Buffer, fmt: string, args: ...any) -> string {
i += 1;
prefix_loop: for ; i < end; i += 1 {
match fmt[i] {
switch fmt[i] {
case '+':
fi.plus = true;
case '-':

View File

@@ -1,4 +1,4 @@
import "core:mem.odin";
import "core:mem.odin"
adler32 :: proc(data: []u8) -> u32 {
ADLER_CONST :: 65521;
@@ -80,7 +80,7 @@ murmur32 :: proc(data: []u8) -> u32 {
tail := data[nblocks*4 ..];
k1: u32;
match len(tail)&3 {
switch len(tail)&3 {
case 3:
k1 ~= u32(tail[2]) << 16;
fallthrough;
@@ -127,7 +127,7 @@ murmur64 :: proc(data: []u8) -> u64 {
h *= m;
}
match len(data)&7 {
switch len(data)&7 {
case 7: h ~= u64(data[6]) << 48; fallthrough;
case 6: h ~= u64(data[5]) << 40; fallthrough;
case 5: h ~= u64(data[4]) << 32; fallthrough;
@@ -186,7 +186,7 @@ murmur64 :: proc(data: []u8) -> u64 {
// TODO(bill): Fix this
#no_bounds_check data8 := slice_to_bytes(data32[i..])[..3];
match len {
switch len {
case 3:
h2 ~= u32(data8[2]) << 16;
fallthrough;

View File

@@ -1,4 +1,4 @@
import "core:raw.odin";
import "core:raw.odin"
foreign __llvm_core {
swap :: proc(b: u16) -> u16 #link_name "llvm.bswap.i16" ---;
@@ -137,7 +137,7 @@ arena_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
using Allocator_Mode;
arena := cast(^Arena)allocator_data;
match mode {
switch mode {
case Alloc:
total_size := size + alignment;
@@ -200,7 +200,7 @@ align_of_type_info :: proc(type_info: ^Type_Info) -> int {
WORD_SIZE :: size_of(int);
MAX_ALIGN :: size_of([vector 64]f64); // TODO(bill): Should these constants be builtin constants?
match info in type_info.variant {
switch info in type_info.variant {
case Type_Info_Named:
return align_of_type_info(info.base);
case Type_Info_Integer:
@@ -252,7 +252,7 @@ align_formula :: proc(size, align: int) -> int {
size_of_type_info :: proc(type_info: ^Type_Info) -> int {
WORD_SIZE :: size_of(int);
match info in type_info.variant {
switch info in type_info.variant {
case Type_Info_Named:
return size_of_type_info(info.base);
case Type_Info_Integer:

View File

@@ -1,12 +1,12 @@
when ODIN_OS == "windows" do foreign_system_library lib "opengl32.lib";
when ODIN_OS == "linux" do foreign_system_library lib "gl";
when ODIN_OS == "windows" {
import win32 "core:sys/windows.odin";
import "core:sys/wgl.odin";
foreign_system_library lib "opengl32.lib"
import win32 "core:sys/windows.odin"
import "core:sys/wgl.odin"
} else when ODIN_OS == "linux" {
foreign_system_library lib "gl"
}
export "core:opengl_constants.odin";
export "core:opengl_constants.odin"
_ := compile_assert(ODIN_OS != "osx");

View File

@@ -1,7 +1,7 @@
foreign_system_library dl "dl";
foreign_system_library libc "c";
foreign_system_library dl "dl"
foreign_system_library libc "c"
import "core:strings.odin";
import "core:strings.odin"
Handle :: i32;
File_Time :: u64;

View File

@@ -1,5 +1,5 @@
import win32 "core:sys/windows.odin";
import "core:mem.odin";
import win32 "core:sys/windows.odin"
import "core:mem.odin"
Handle :: int;
File_Time :: u64;
@@ -60,7 +60,7 @@ open :: proc(path: string, mode: int = O_RDONLY, perm: u32 = 0) -> (Handle, Errn
if len(path) == 0 do return INVALID_HANDLE, ERROR_FILE_NOT_FOUND;
access: u32;
match mode & (O_RDONLY|O_WRONLY|O_RDWR) {
switch mode & (O_RDONLY|O_WRONLY|O_RDWR) {
case O_RDONLY: access = win32.FILE_GENERIC_READ;
case O_WRONLY: access = win32.FILE_GENERIC_WRITE;
case O_RDWR: access = win32.FILE_GENERIC_READ | win32.FILE_GENERIC_WRITE;
@@ -82,7 +82,7 @@ open :: proc(path: string, mode: int = O_RDONLY, perm: u32 = 0) -> (Handle, Errn
}
create_mode: u32;
match {
switch {
case mode&(O_CREAT|O_EXCL) == (O_CREAT | O_EXCL):
create_mode = win32.CREATE_NEW;
case mode&(O_CREAT|O_TRUNC) == (O_CREAT | O_TRUNC):
@@ -156,7 +156,7 @@ read :: proc(fd: Handle, data: []u8) -> (int, Errno) {
seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {
w: u32;
match whence {
switch whence {
case 0: w = win32.FILE_BEGIN;
case 1: w = win32.FILE_CURRENT;
case 2: w = win32.FILE_END;
@@ -272,7 +272,7 @@ _alloc_command_line_arguments :: proc() -> []string {
i, j := 0, 0;
for str[j] != 0 {
match {
switch {
case str[j] < 0x80:
if i+1 > len do return "";
buf[i] = u8(str[j]); i += 1;

View File

@@ -1,7 +1,7 @@
foreign_system_library dl "dl";
foreign_system_library libc "c";
foreign_system_library dl "dl"
foreign_system_library libc "c"
import "core:strings.odin";
import "core:strings.odin"
Handle :: i32;
File_Time :: u64;

View File

@@ -187,7 +187,7 @@ merge_sort :: proc(array: $A/[]$T) {
compare_ints :: proc(a, b: int) -> int {
match delta := a - b; {
switch delta := a - b; {
case delta < 0: return -1;
case delta > 0: return +1;
}
@@ -195,14 +195,14 @@ compare_ints :: proc(a, b: int) -> int {
}
compare_f32s :: proc(a, b: f32) -> int {
match delta := a - b; {
switch delta := a - b; {
case delta < 0: return -1;
case delta > 0: return +1;
}
return 0;
}
compare_f64s :: proc(a, b: f64) -> int {
match delta := a - b; {
switch delta := a - b; {
case delta < 0: return -1;
case delta > 0: return +1;
}

View File

@@ -1,4 +1,4 @@
using import "core:decimal.odin";
using import "core:decimal.odin"
Int_Flag :: enum {
Prefix = 1<<0,
@@ -8,7 +8,7 @@ Int_Flag :: enum {
parse_bool :: proc(s: string) -> (result: bool = false, ok: bool) {
match s {
switch s {
case "1", "t", "T", "true", "TRUE", "True":
return true, true;
case "0", "f", "F", "false", "FALSE", "False":
@@ -20,7 +20,7 @@ parse_bool :: proc(s: string) -> (result: bool = false, ok: bool) {
_digit_value :: proc(r: rune) -> int {
ri := int(r);
v: int = 16;
match r {
switch r {
case '0'...'9': v = ri-'0';
case 'a'...'z': v = ri-'a'+10;
case 'A'...'Z': v = ri-'A'+10;
@@ -31,7 +31,7 @@ _digit_value :: proc(r: rune) -> int {
parse_i128 :: proc(s: string) -> i128 {
neg := false;
if len(s) > 1 {
match s[0] {
switch s[0] {
case '-':
neg = true;
s = s[1..];
@@ -43,7 +43,7 @@ parse_i128 :: proc(s: string) -> i128 {
base: i128 = 10;
if len(s) > 2 && s[0] == '0' {
match s[1] {
switch s[1] {
case 'b': base = 2; s = s[2..];
case 'o': base = 8; s = s[2..];
case 'd': base = 10; s = s[2..];
@@ -80,7 +80,7 @@ parse_u128 :: proc(s: string) -> u128 {
base := u128(10);
if len(s) > 2 && s[0] == '0' {
match s[1] {
switch s[1] {
case 'b': base = 2; s = s[2..];
case 'o': base = 8; s = s[2..];
case 'd': base = 10; s = s[2..];
@@ -115,7 +115,7 @@ parse_f64 :: proc(s: string) -> f64 {
i := 0;
sign: f64 = 1;
match s[i] {
switch s[i] {
case '-': i += 1; sign = -1;
case '+': i += 1;
}
@@ -153,7 +153,7 @@ parse_f64 :: proc(s: string) -> f64 {
i += 1;
if i < len(s) {
match s[i] {
switch s[i] {
case '-': i += 1; frac = true;
case '+': i += 1;
}
@@ -223,7 +223,7 @@ _f64_info := FloatInfo{52, 11, -1023};
generic_ftoa :: proc(buf: []u8, val: f64, fmt: u8, prec, bit_size: int) -> []u8 {
bits: u64;
flt: ^FloatInfo;
match bit_size {
switch bit_size {
case 32:
bits = u64(transmute(u32)f32(val));
flt = &_f32_info;
@@ -238,7 +238,7 @@ generic_ftoa :: proc(buf: []u8, val: f64, fmt: u8, prec, bit_size: int) -> []u8
exp := int(bits>>flt.mantbits) & (1<<flt.expbits - 1);
mant := bits & (u64(1) << flt.mantbits - 1);
match exp {
switch exp {
case 1<<flt.expbits - 1:
s: string;
if mant != 0 {
@@ -269,13 +269,13 @@ generic_ftoa :: proc(buf: []u8, val: f64, fmt: u8, prec, bit_size: int) -> []u8
if shortest {
round_shortest(d, mant, exp, flt);
digs = DecimalSlice{digits = d.digits[..], count = d.count, decimal_point = d.decimal_point};
match fmt {
switch fmt {
case 'e', 'E': prec = digs.count-1;
case 'f', 'F': prec = max(digs.count-digs.decimal_point, 0);
case 'g', 'G': prec = digs.count;
}
} else {
match fmt {
switch fmt {
case 'e', 'E': round(d, prec+1);
case 'f', 'F': round(d, d.decimal_point+prec);
case 'g', 'G':
@@ -293,7 +293,7 @@ generic_ftoa :: proc(buf: []u8, val: f64, fmt: u8, prec, bit_size: int) -> []u8
format_digits :: proc(buf: []u8, shortest: bool, neg: bool, digs: DecimalSlice, prec: int, fmt: u8) -> []u8 {
match fmt {
switch fmt {
case 'f', 'F':
append(&buf, neg ? '-' : '+');
@@ -410,7 +410,7 @@ digits := "0123456789abcdefghijklmnopqrstuvwxyz";
is_integer_negative :: proc(u: u128, is_signed: bool, bit_size: int) -> (unsigned: u128, neg: bool) {
neg := false;
if is_signed {
match bit_size {
switch bit_size {
case 8:
i := i8(u);
neg = i < 0;
@@ -456,7 +456,7 @@ append_bits :: proc(buf: []u8, u: u128, base: int, is_signed: bool, bit_size: in
if flags&Int_Flag.Prefix != 0 {
ok := true;
match base {
switch base {
case 2: i-=1; a[i] = 'b';
case 8: i-=1; a[i] = 'o';
case 10: i-=1; a[i] = 'd';

View File

@@ -1,4 +1,4 @@
import "core:mem.odin";
import "core:mem.odin"
new_string :: proc(s: string) -> string {
c := make([]u8, len(s)+1);

View File

@@ -1,5 +1,5 @@
import "core:atomics.odin";
import "core:os.odin";
import "core:atomics.odin"
import "core:os.odin"
Semaphore :: struct {
// _handle: win32.Handle,

View File

@@ -1,5 +1,7 @@
when ODIN_OS == "windows" do import win32 "core:sys/windows.odin";
import "core:atomics.odin";
when ODIN_OS == "windows" {
import win32 "core:sys/windows.odin";
}
import "core:atomics.odin"
Semaphore :: struct {
_handle: win32.Handle,

View File

@@ -1,5 +1,7 @@
when ODIN_OS == "windows" do foreign_system_library "opengl32.lib";
using import "core:sys/windows.odin";
when ODIN_OS == "windows" {
foreign_system_library "opengl32.lib"
}
using import "core:sys/windows.odin"
CONTEXT_MAJOR_VERSION_ARB :: 0x2091;

View File

@@ -1,9 +1,9 @@
when ODIN_OS == "windows" {
foreign_system_library "kernel32.lib";
foreign_system_library "user32.lib";
foreign_system_library "gdi32.lib";
foreign_system_library "winmm.lib";
foreign_system_library "shell32.lib";
foreign_system_library "kernel32.lib"
foreign_system_library "user32.lib"
foreign_system_library "gdi32.lib"
foreign_system_library "winmm.lib"
foreign_system_library "shell32.lib"
}
Handle :: rawptr;

View File

@@ -1,7 +1,7 @@
_ :: compile_assert(ODIN_OS == "windows");
when ODIN_OS == "windows" {
import win32 "core:sys/windows.odin";
import win32 "core:sys/windows.odin"
}
Thread_Proc :: #type proc(^Thread) -> int;

View File

@@ -1,6 +1,6 @@
is_signed :: proc(info: ^Type_Info) -> bool {
if info == nil do return false;
match i in type_info_base(info).variant {
switch i in type_info_base(info).variant {
case Type_Info_Integer: return i.signed;
case Type_Info_Float: return true;
}

View File

@@ -35,7 +35,7 @@ encode :: proc(d: []u16, s: []rune) {
n = 0;
for r in s {
match r {
switch r {
case 0.._surr1, _surr3.._surr_self:
d[n] = u16(r);
n += 1;

View File

@@ -254,7 +254,7 @@ rune_count :: proc(s: []u8) -> int {
rune_size :: proc(r: rune) -> int {
match {
switch {
case r < 0: return -1;
case r <= 1<<7 - 1: return 1;
case r <= 1<<11 - 1: return 2;

View File

@@ -150,7 +150,7 @@ union_type :: proc() {
val = nil;
match v in val {
switch v in val {
case int: fmt.println("int", v);
case bool: fmt.println("bool", v);
case: fmt.println("nil");
@@ -171,7 +171,7 @@ union_type :: proc() {
val = nil;
match v in val {
switch v in val {
case int: fmt.println("int", v);
case bool: fmt.println("bool", v);
case: fmt.println("nil");
@@ -218,7 +218,7 @@ union_type :: proc() {
entity := new_entity(Monster);
match e in entity.derived {
switch e in entity.derived {
case Frog:
fmt.println("Ribbit");
case Monster:
@@ -262,7 +262,7 @@ union_type :: proc() {
entity := new_entity(Monster);
match e in entity.derived {
switch e in entity.derived {
case Frog:
fmt.println("Ribbit");
case Monster:

View File

@@ -234,7 +234,7 @@ void check_const_decl(Checker *c, Entity *e, AstNode *type_expr, AstNode *init,
d->type_expr = d->init_expr;
check_type_decl(c, e, d->type_expr, named_type);
return;
} break;
}
// NOTE(bill): Check to see if the expression it to be aliases
#if 1
@@ -446,6 +446,13 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
error(e->token, "Procedure `main` cannot have a custom calling convention");
}
pt->calling_convention = ProcCC_Contextless;
if (d->scope->is_init) {
if (c->info.entry_point != nullptr) {
error(e->token, "Redeclaration of the entry pointer procedure `main`");
} else {
c->info.entry_point = e;
}
}
}
if (is_inline && is_no_inline) {

View File

@@ -2469,7 +2469,8 @@ Type *type_to_abi_compat_param_type(gbAllocator a, Type *original_type) {
if (sz > 8 && build_context.word_size < 8) {
new_type = make_type_pointer(a, original_type);
}
} break;
break;
}
case Type_Pointer: break;
case Type_Proc: break; // NOTE(bill): Just a pointer
@@ -2495,7 +2496,9 @@ Type *type_to_abi_compat_param_type(gbAllocator a, Type *original_type) {
new_type = make_type_pointer(a, original_type);
break;
}
} break;
break;
}
}
} else if (build_context.ODIN_OS == "linux" ||
build_context.ODIN_OS == "osx") {
@@ -2508,7 +2511,9 @@ Type *type_to_abi_compat_param_type(gbAllocator a, Type *original_type) {
if (sz > 8 && build_context.word_size < 8) {
new_type = make_type_pointer(a, original_type);
}
} break;
break;
}
case Type_Pointer: break;
case Type_Proc: break; // NOTE(bill): Just a pointer
@@ -2528,7 +2533,9 @@ Type *type_to_abi_compat_param_type(gbAllocator a, Type *original_type) {
if (8*size > 16) {
new_type = make_type_pointer(a, original_type);
}
} break;
break;
}
}
} else {
// IMPORTANT TODO(bill): figure out the ABI settings for Linux, OSX etc. for
@@ -2579,7 +2586,9 @@ Type *type_to_abi_compat_result_type(gbAllocator a, Type *original_type) {
case 64: new_type = t_u64; break;
#endif
}
} break;
break;
}
}
} else if (build_context.ODIN_OS == "linux") {
@@ -3031,26 +3040,29 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
switch (e->kind) {
case_ast_node(i, Ident, e);
Operand o = {};
check_ident(c, &o, e, named_type, nullptr, false);
gbString err_str;
switch (o.mode) {
case Addressing_Invalid:
break;
case Addressing_Type: {
case Addressing_Type:
*type = o.type;
return true;
} break;
case Addressing_NoValue: {
gbString err_str = expr_to_string(e);
case Addressing_NoValue:
err_str = expr_to_string(e);
error(e, "`%s` used as a type", err_str);
gb_string_free(err_str);
} break;
default: {
gbString err_str = expr_to_string(e);
break;
default:
err_str = expr_to_string(e);
error(e, "`%s` used as a type when not a type", err_str);
gb_string_free(err_str);
} break;
break;
}
case_end;
@@ -3104,6 +3116,7 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
Operand o = {};
check_selector(c, &o, e, nullptr);
gbString err_str;
switch (o.mode) {
case Addressing_Invalid:
break;
@@ -3111,16 +3124,16 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
GB_ASSERT(o.type != nullptr);
*type = o.type;
return true;
case Addressing_NoValue: {
gbString err_str = expr_to_string(e);
case Addressing_NoValue:
err_str = expr_to_string(e);
error(e, "`%s` used as a type", err_str);
gb_string_free(err_str);
} break;
default: {
gbString err_str = expr_to_string(e);
break;
default:
err_str = expr_to_string(e);
error(e, "`%s` is not a type", err_str);
gb_string_free(err_str);
} break;
break;
}
case_end;
@@ -3533,7 +3546,8 @@ bool check_representable_as_constant(Checker *c, ExactValue in_value, Type *type
if (out_value) *out_value = exact_binary_operator_value(Token_Add, real, exact_value_make_imag(imag));
return true;
}
} break;
break;
}
case Basic_UntypedComplex:
return true;
@@ -3724,9 +3738,9 @@ void check_comparison(Checker *c, Operand *x, Operand *y, TokenKind op) {
case Token_Lt:
case Token_Gt:
case Token_LtEq:
case Token_GtEq: {
case Token_GtEq:
defined = is_type_ordered(x->type);
} break;
break;
}
if (!defined) {
@@ -4176,7 +4190,9 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
if (xt) error_operand_not_expression(x);
if (yt) error_operand_not_expression(y);
}
} break;
break;
}
default:
check_expr(c, x, be->left);
@@ -4522,7 +4538,9 @@ void convert_to_typed(Checker *c, Operand *operand, Type *target_type, i32 level
convert_untyped_error(c, operand, target_type);
return;
}
} break;
break;
}
case Type_Union:
if (!is_operand_nil(*operand) && !is_operand_undef(*operand)) {
@@ -5112,7 +5130,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
operand->type = t_source_code_location;
operand->mode = Addressing_Value;
} break;
break;
}
case BuiltinProc_len:
case BuiltinProc_cap: {
@@ -5159,7 +5179,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
operand->mode = mode;
operand->value = value;
operand->type = type;
} break;
break;
}
#if 0
case BuiltinProc_new: {
@@ -5173,7 +5195,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
}
operand->mode = Addressing_Value;
operand->type = make_type_pointer(c->allocator, type);
} break;
break;
}
#endif
#if 0
case BuiltinProc_new_slice: {
@@ -5212,7 +5236,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
operand->mode = Addressing_Value;
operand->type = make_type_slice(c->allocator, type);
} break;
break;
}
#endif
case BuiltinProc_make: {
// proc make(Type, len: int) -> Type
@@ -5268,7 +5294,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
operand->mode = Addressing_Value;
operand->type = type;
} break;
break;
}
#if 0
case BuiltinProc_free: {
@@ -5299,7 +5327,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
operand->mode = Addressing_NoValue;
} break;
break;
}
#endif
@@ -5329,7 +5359,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
operand->type = nullptr;
operand->mode = Addressing_NoValue;
} break;
break;
}
#endif
#if 0
case BuiltinProc_clear: {
@@ -5345,7 +5377,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
operand->type = nullptr;
operand->mode = Addressing_NoValue;
} break;
break;
}
#endif
#if 0
case BuiltinProc_append: {
@@ -5394,7 +5428,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
}
operand->mode = Addressing_Value;
operand->type = t_int;
} break;
break;
}
#endif
#if 0
case BuiltinProc_delete: {
@@ -5426,7 +5462,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
}
operand->mode = Addressing_NoValue;
} break;
break;
}
#endif
@@ -5447,7 +5485,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
operand->mode = Addressing_Constant;
operand->value = exact_value_i64(type_size_of(c->allocator, t));
operand->type = t_untyped_integer;
} break;
break;
}
case BuiltinProc_align_of: {
// proc align_of(Type or expr) -> untyped int
@@ -5466,7 +5506,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
operand->mode = Addressing_Constant;
operand->value = exact_value_i64(type_align_of(c->allocator, t));
operand->type = t_untyped_integer;
} break;
break;
}
case BuiltinProc_offset_of: {
@@ -5511,7 +5553,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
operand->mode = Addressing_Constant;
operand->value = exact_value_i64(type_offset_of_from_selection(c->allocator, type, sel));
operand->type = t_untyped_integer;
} break;
break;
}
case BuiltinProc_type_of:
@@ -5557,7 +5601,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
operand->mode = Addressing_Value;
operand->type = t_type_info_ptr;
} break;
break;
}
case BuiltinProc_compile_assert:
// proc compile_assert(cond: bool) -> bool
@@ -5630,7 +5676,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
Type *elem_type = vector_type->Vector.elem;
operand->type = make_type_vector(c->allocator, elem_type, arg_count);
operand->mode = Addressing_Value;
} break;
break;
}
case BuiltinProc_complex: {
// proc complex(real, imag: float_type) -> complex_type
@@ -5689,7 +5737,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
case Basic_UntypedFloat: operand->type = t_untyped_complex; break;
default: GB_PANIC("Invalid type"); break;
}
} break;
break;
}
case BuiltinProc_real:
case BuiltinProc_imag: {
@@ -5733,7 +5783,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
case Basic_UntypedComplex: x->type = t_untyped_float; break;
default: GB_PANIC("Invalid type"); break;
}
} break;
break;
}
case BuiltinProc_conj: {
// proc conj(x: type) -> type
@@ -5755,7 +5807,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
return false;
}
} break;
break;
}
#if 0
case BuiltinProc_slice_ptr: {
@@ -5799,7 +5853,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
}
operand->type = make_type_slice(c->allocator, ptr_type->Pointer.elem);
operand->mode = Addressing_Value;
} break;
break;
}
case BuiltinProc_slice_to_bytes: {
// proc slice_to_bytes(a: []T) -> []u8
@@ -5813,7 +5869,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
operand->type = t_u8_slice;
operand->mode = Addressing_Value;
} break;
break;
}
#endif
case BuiltinProc_expand_to_tuple: {
Type *type = base_type(operand->type);
@@ -5834,7 +5892,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
operand->type = tuple;
operand->mode = Addressing_Value;
} break;
break;
}
case BuiltinProc_min: {
// proc min(a, b: ordered) -> ordered
@@ -5900,7 +5960,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
}
}
} break;
break;
}
case BuiltinProc_max: {
// proc min(a, b: ordered) -> ordered
@@ -5968,7 +6030,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
}
}
} break;
break;
}
case BuiltinProc_abs: {
// proc abs(n: numeric) -> numeric
@@ -5991,7 +6055,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
f64 r = operand->value.value_complex.real;
f64 i = operand->value.value_complex.imag;
operand->value = exact_value_float(gb_sqrt(r*r + i*i));
} break;
break;
}
default:
GB_PANIC("Invalid numeric constant");
break;
@@ -6004,7 +6070,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
operand->type = base_complex_elem_type(operand->type);
}
GB_ASSERT(!is_type_complex(operand->type));
} break;
break;
}
case BuiltinProc_clamp: {
// proc clamp(a, min, max: ordered) -> ordered
@@ -6092,7 +6160,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
return false;
}
}
} break;
break;
}
#if 0
case BuiltinProc_transmute: {
@@ -6143,7 +6213,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
o->mode = Addressing_Value;
o->type = t;
} break;
break;
}
#endif
}
@@ -7103,7 +7175,9 @@ ExprKind check_call_expr(Checker *c, Operand *operand, AstNode *call) {
if (operand->mode != Addressing_Invalid) {
check_cast(c, operand, t);
}
} break;
break;
}
}
}
return Expr_Expr;
@@ -7330,7 +7404,9 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
switch (r) {
case 'i': t = t_untyped_complex; break;
}
} break;
break;
}
default: GB_PANIC("Unknown literal"); break;
}
o->mode = Addressing_Constant;
@@ -7663,7 +7739,8 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
}
}
}
} break;
break;
}
case Type_Slice:
case Type_Array:
@@ -7740,7 +7817,9 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
if (t->kind == Type_Array && is_to_be_determined_array_count) {
t->Array.count = max;
}
} break;
break;
}
case Type_Basic: {
if (!is_type_any(t)) {
@@ -7819,7 +7898,9 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
}
}
}
} break;
break;
}
case Type_Map: {
if (cl->elems.count == 0) {
@@ -7844,7 +7925,9 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
check_assignment(c, o, t->Map.value, str_lit("map literal"));
}
}
} break;
break;
}
default: {
if (cl->elems.count == 0) {
@@ -7855,7 +7938,7 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
error(node, "Invalid compound literal type `%s`", str);
gb_string_free(str);
return kind;
} break;
}
}
if (is_constant) {

View File

@@ -138,10 +138,10 @@ bool check_is_terminating(AstNode *node) {
return false;
case_end;
case_ast_node(ms, MatchStmt, node);
case_ast_node(ss, SwitchStmt, node);
bool has_default = false;
for_array(i, ms->body->BlockStmt.stmts) {
AstNode *clause = ms->body->BlockStmt.stmts[i];
for_array(i, ss->body->BlockStmt.stmts) {
AstNode *clause = ss->body->BlockStmt.stmts[i];
ast_node(cc, CaseClause, clause);
if (cc->list.count == 0) {
has_default = true;
@@ -154,10 +154,10 @@ bool check_is_terminating(AstNode *node) {
return has_default;
case_end;
case_ast_node(ms, TypeMatchStmt, node);
case_ast_node(ss, TypeSwitchStmt, node);
bool has_default = false;
for_array(i, ms->body->BlockStmt.stmts) {
AstNode *clause = ms->body->BlockStmt.stmts[i];
for_array(i, ss->body->BlockStmt.stmts) {
AstNode *clause = ss->body->BlockStmt.stmts[i];
ast_node(cc, CaseClause, clause);
if (cc->list.count == 0) {
has_default = true;
@@ -309,7 +309,9 @@ Type *check_assignment_variable(Checker *c, Operand *rhs, AstNode *lhs_node) {
}
}
}
} break;
break;
}
default: {
if (lhs.expr->kind == AstNode_SelectorExpr) {
@@ -332,7 +334,9 @@ Type *check_assignment_variable(Checker *c, Operand *rhs, AstNode *lhs_node) {
error(lhs.expr, "Cannot assign to `%s`", str);
}
gb_string_free(str);
} break;
break;
}
}
check_assignment(c, rhs, assignment_type, str_lit("assignment"));
@@ -490,7 +494,9 @@ bool check_using_stmt_entity(Checker *c, AstNodeUsingStmt *us, AstNode *expr, bo
} else {
error(us->token, "`using` can be only applied to enum type entities");
}
} break;
break;
}
case Entity_ImportName: {
Scope *scope = e->ImportName.scope;
@@ -511,7 +517,9 @@ bool check_using_stmt_entity(Checker *c, AstNodeUsingStmt *us, AstNode *expr, bo
return false;
}
}
} break;
break;
}
case Entity_Variable: {
Type *t = base_type(type_deref(e->type));
@@ -538,7 +546,9 @@ bool check_using_stmt_entity(Checker *c, AstNodeUsingStmt *us, AstNode *expr, bo
error(us->token, "`using` can only be applied to variables of type struct or raw_union");
return false;
}
} break;
break;
}
case Entity_Constant:
error(us->token, "`using` cannot be applied to a constant");
@@ -583,7 +593,9 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
gbString str = type_to_string(operand.type);
error(node, "`%s` is not an expression", str);
gb_string_free(str);
} break;
break;
}
case Addressing_NoValue:
return;
default: {
@@ -605,7 +617,9 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
gbString expr_str = expr_to_string(operand.expr);
error(node, "Expression is not used: `%s`", expr_str);
gb_string_free(expr_str);
} break;
break;
}
}
case_end;
@@ -695,7 +709,9 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
error(as->lhs[0], "Assignment count mismatch `%td` = `%td`", lhs_count, rhs_count);
}
} break;
break;
}
default: {
// a += 1; // Single-sided
@@ -723,7 +739,9 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
}
// NOTE(bill): Only use the first one will be used
check_assignment_variable(c, &operand, as->lhs[0]);
} break;
break;
}
}
case_end;
@@ -1161,18 +1179,18 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
check_close_scope(c);
case_end;
case_ast_node(ms, MatchStmt, node);
case_ast_node(ss, SwitchStmt, node);
Operand x = {};
mod_flags |= Stmt_BreakAllowed;
check_open_scope(c, node);
check_label(c, ms->label); // TODO(bill): What should the label's "scope" be?
check_label(c, ss->label); // TODO(bill): What should the label's "scope" be?
if (ms->init != nullptr) {
check_stmt(c, ms->init, 0);
if (ss->init != nullptr) {
check_stmt(c, ss->init, 0);
}
if (ms->tag != nullptr) {
check_expr(c, &x, ms->tag);
if (ss->tag != nullptr) {
check_expr(c, &x, ss->tag);
check_assignment(c, &x, nullptr, str_lit("match expression"));
} else {
x.mode = Addressing_Constant;
@@ -1180,7 +1198,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
x.value = exact_value_bool(true);
Token token = {};
token.pos = ast_node_token(ms->body).pos;
token.pos = ast_node_token(ss->body).pos;
token.string = str_lit("true");
x.expr = ast_ident(c->curr_ast_file, token);
}
@@ -1194,7 +1212,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
// NOTE(bill): Check for multiple defaults
AstNode *first_default = nullptr;
ast_node(bs, BlockStmt, ms->body);
ast_node(bs, BlockStmt, ss->body);
for_array(i, bs->stmts) {
AstNode *stmt = bs->stmts[i];
AstNode *default_stmt = nullptr;
@@ -1365,22 +1383,22 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
check_close_scope(c);
case_end;
case_ast_node(ms, TypeMatchStmt, node);
case_ast_node(ss, TypeSwitchStmt, node);
Operand x = {};
mod_flags |= Stmt_BreakAllowed;
check_open_scope(c, node);
check_label(c, ms->label); // TODO(bill): What should the label's "scope" be?
check_label(c, ss->label); // TODO(bill): What should the label's "scope" be?
MatchTypeKind match_type_kind = MatchType_Invalid;
if (ms->tag->kind != AstNode_AssignStmt) {
error(ms->tag, "Expected an `in` assignment for this type match statement");
if (ss->tag->kind != AstNode_AssignStmt) {
error(ss->tag, "Expected an `in` assignment for this type match statement");
break;
}
ast_node(as, AssignStmt, ms->tag);
Token as_token = ast_node_token(ms->tag);
ast_node(as, AssignStmt, ss->tag);
Token as_token = ast_node_token(ss->tag);
if (as->lhs.count != 1) {
syntax_error(as_token, "Expected 1 name before `in`");
break;
@@ -1406,7 +1424,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
// NOTE(bill): Check for multiple defaults
AstNode *first_default = nullptr;
ast_node(bs, BlockStmt, ms->body);
ast_node(bs, BlockStmt, ss->body);
for_array(i, bs->stmts) {
AstNode *stmt = bs->stmts[i];
AstNode *default_stmt = nullptr;

View File

@@ -448,8 +448,9 @@ struct CheckerInfo {
Map<isize> type_info_map; // Key: Type *
isize type_info_count;
Scope * init_scope;
Entity * entry_point;
PtrSet<Entity *> minimum_dependency_map;
PtrSet<Entity *> minimum_dependency_set;
};
@@ -1293,7 +1294,7 @@ void add_type_info_type(Checker *c, Type *t) {
add_type_info_type(c, bt);
switch (bt->kind) {
case Type_Basic: {
case Type_Basic:
switch (bt->Basic.kind) {
case Basic_string:
add_type_info_type(c, t_u8_ptr);
@@ -1313,7 +1314,7 @@ void add_type_info_type(Checker *c, Type *t) {
add_type_info_type(c, t_f64);
break;
}
} break;
break;
case Type_Pointer:
add_type_info_type(c, bt->Pointer.elem);
@@ -1352,7 +1353,7 @@ void add_type_info_type(Checker *c, Type *t) {
}
break;
case Type_Struct: {
case Type_Struct:
if (bt->Struct.scope != nullptr) {
for_array(i, bt->Struct.scope->elements.entries) {
Entity *e = bt->Struct.scope->elements.entries[i].value;
@@ -1363,14 +1364,14 @@ void add_type_info_type(Checker *c, Type *t) {
Entity *f = bt->Struct.fields[i];
add_type_info_type(c, f->type);
}
} break;
break;
case Type_Map: {
case Type_Map:
generate_map_internal_types(c->allocator, bt);
add_type_info_type(c, bt->Map.key);
add_type_info_type(c, bt->Map.value);
add_type_info_type(c, bt->Map.generated_struct_type);
} break;
break;
case Type_Tuple:
for_array(i, bt->Tuple.variables) {
@@ -1457,7 +1458,7 @@ void add_dependency_to_map(PtrSet<Entity *> *map, CheckerInfo *info, Entity *ent
}
}
PtrSet<Entity *> generate_minimum_dependency_map(CheckerInfo *info, Entity *start) {
PtrSet<Entity *> generate_minimum_dependency_set(CheckerInfo *info, Entity *start) {
PtrSet<Entity *> map = {}; // Key: Entity *
ptr_set_init(&map, heap_allocator());
@@ -2360,7 +2361,9 @@ void add_import_dependency_node(Checker *c, AstNode *decl, Map<ImportGraphNode *
for_array(i, stmts) {
add_import_dependency_node(c, stmts[i], M);
}
} break;
break;
}
case AstNode_WhenStmt:
add_import_dependency_node(c, ws->else_stmt, M);
break;
@@ -2839,17 +2842,15 @@ void check_import_entities(Checker *c) {
};
if (path.count > 0) {
Scope *s = path[path.count-1];
Token token = mt(s);
error(token, "Cyclic importation of `%.*s`", LIT(token.string));
for (isize i = 0; i < path.count; i++) {
gb_printf_err("\t`%.*s` refers to\n", LIT(token.string));
s = path[i];
token = mt(s);
}
gb_printf_err("\t`%.*s`\n", LIT(token.string));
Scope *s = path[path.count-1];
Token token = mt(s);
error(token, "Cyclic importation of `%.*s`", LIT(token.string));
for (isize i = 0; i < path.count; i++) {
gb_printf_err("\t`%.*s` refers to\n", LIT(token.string));
s = path[i];
token = mt(s);
}
gb_printf_err("\t`%.*s`\n", LIT(token.string));
}
}
@@ -3059,11 +3060,14 @@ void check_parsed_files(Checker *c) {
for_array(i, c->parser->files) {
AstFile *f = c->parser->files[i];
Scope *scope = create_scope_from_file(c, f);
f->decl_info = make_declaration_info(c->allocator, f->scope, c->context.decl);
HashKey key = hash_string(f->tokenizer.fullpath);
map_set(&c->file_scopes, key, scope);
map_set(&c->info.files, key, f);
if (scope->is_init) {
c->info.init_scope = scope;
}
}
// Collect Entities
@@ -3077,7 +3081,7 @@ void check_parsed_files(Checker *c) {
check_import_entities(c);
check_all_global_entities(c);
init_preload(c); // NOTE(bill): This could be setup previously through the use of `type_info(_of_val)`
init_preload(c); // NOTE(bill): This could be setup previously through the use of `type_info_of`
// Check procedure bodies
// NOTE(bill): Nested procedures bodies will be added to this "queue"
@@ -3112,25 +3116,12 @@ void check_parsed_files(Checker *c) {
check_proc_body(c, pi->token, pi->decl, pi->type, pi->body);
}
{
for_array(i, c->info.entities.entries) {
auto *entry = &c->info.entities.entries[i];
Entity *e = cast(Entity *)entry->key.ptr;
String name = e->token.string;
if (e->kind == Entity_Procedure && !e->scope->is_global) {
if (e->scope->is_init && name == "main") {
c->info.entry_point = e;
break;
}
}
}
c->info.minimum_dependency_map = generate_minimum_dependency_map(&c->info, c->info.entry_point);
}
c->info.minimum_dependency_set = generate_minimum_dependency_set(&c->info, c->info.entry_point);
// Calculate initialization order of global variables
calculate_global_init_order(c);
// Add untyped expression values
for_array(i, c->info.untyped.entries) {
auto *entry = &c->info.untyped.entries[i];
@@ -3148,8 +3139,6 @@ void check_parsed_files(Checker *c) {
// TODO(bill): Check for unused imports (and remove) or even warn/err
// TODO(bill): Any other checks?
#if 1
// Add "Basic" type information
for (isize i = 0; i < gb_count_of(basic_types)-1; i++) {
Type *t = &basic_types[i];
@@ -3158,53 +3147,34 @@ void check_parsed_files(Checker *c) {
}
}
/*
for (isize i = 0; i < gb_count_of(basic_type_aliases)-1; i++) {
Type *t = &basic_type_aliases[i];
if (t->Basic.size > 0) {
add_type_info_type(c, t);
}
}
*/
#endif
// NOTE(bill): Check for illegal cyclic type declarations
for_array(i, c->info.definitions.entries) {
Entity *e = c->info.definitions.entries[i].value;
if (e->kind == Entity_TypeName) {
if (e->type != nullptr) {
// i64 size = type_size_of(c->sizes, c->allocator, e->type);
i64 align = type_align_of(c->allocator, e->type);
if (align > 0) {
add_type_info_type(c, e->type);
}
if (e->kind == Entity_TypeName && e->type != nullptr) {
// i64 size = type_size_of(c->sizes, c->allocator, e->type);
i64 align = type_align_of(c->allocator, e->type);
if (align > 0) {
add_type_info_type(c, e->type);
}
}
}
// gb_printf_err("Count: %td\n", c->info.type_info_count++);
if (!build_context.is_dll) {
for_array(i, c->file_scopes.entries) {
Scope *s = c->file_scopes.entries[i].value;
if (s->is_init) {
Entity *e = current_scope_lookup_entity(s, str_lit("main"));
if (e == nullptr) {
Token token = {};
if (s->file->tokens.count > 0) {
token = s->file->tokens[0];
} else {
token.pos.file = s->file->tokenizer.fullpath;
token.pos.line = 1;
token.pos.column = 1;
}
error(token, "Undefined entry point procedure `main`");
}
break;
Scope *s = c->info.init_scope;
GB_ASSERT(s != nullptr);
GB_ASSERT(s->is_init);
Entity *e = current_scope_lookup_entity(s, str_lit("main"));
if (e == nullptr) {
Token token = {};
if (s->file->tokens.count > 0) {
token = s->file->tokens[0];
} else {
token.pos.file = s->file->tokenizer.fullpath;
token.pos.line = 1;
token.pos.column = 1;
}
error(token, "Undefined entry point procedure `main`");
}
}
}

View File

@@ -50,16 +50,19 @@ GB_ALLOCATOR_PROC(heap_allocator_proc) {
if (flags & gbAllocatorFlag_ClearToZero) {
gb_zero_size(ptr, size);
}
} break;
break;
}
case gbAllocation_Free: {
free(old_memory);
} break;
break;
}
case gbAllocation_Resize: {
// ptr = realloc(old_memory, size);
ptr = gb_default_resize_align(heap_allocator(), old_memory, old_size, size, alignment);
} break;
break;
}
#else
// TODO(bill): *nix version that's decent
case gbAllocation_Alloc: {
@@ -68,15 +71,18 @@ GB_ALLOCATOR_PROC(heap_allocator_proc) {
if (flags & gbAllocatorFlag_ClearToZero) {
gb_zero_size(ptr, size);
}
} break;
break;
}
case gbAllocation_Free: {
free(old_memory);
} break;
break;
}
case gbAllocation_Resize: {
ptr = gb_default_resize_align(heap_allocator(), old_memory, old_size, size, alignment);
} break;
break;
}
#endif
case gbAllocation_FreeAll:

View File

@@ -270,7 +270,8 @@ ExactValue exact_value_to_integer(ExactValue v) {
if (f == v.value_float) {
return exact_value_i128(i);
}
} break;
break;
}
case ExactValue_Pointer:
return exact_value_i64(cast(i64)cast(intptr)v.value_pointer);
@@ -352,7 +353,8 @@ ExactValue exact_unary_operator_value(TokenKind op, ExactValue v, i32 precision)
case ExactValue_Complex:
return v;
}
} break;
break;
}
case Token_Sub: {
switch (v.kind) {
@@ -374,7 +376,8 @@ ExactValue exact_unary_operator_value(TokenKind op, ExactValue v, i32 precision)
return exact_value_complex(-real, -imag);
}
}
} break;
break;
}
case Token_Xor: {
i128 i = I128_ZERO;
@@ -396,7 +399,8 @@ ExactValue exact_unary_operator_value(TokenKind op, ExactValue v, i32 precision)
}
return exact_value_i128(i);
} break;
break;
}
case Token_Not: {
switch (v.kind) {
@@ -404,7 +408,8 @@ ExactValue exact_unary_operator_value(TokenKind op, ExactValue v, i32 precision)
case ExactValue_Bool:
return exact_value_bool(!v.value_bool);
}
} break;
break;
}
}
failure:
@@ -521,7 +526,8 @@ ExactValue exact_binary_operator_value(TokenKind op, ExactValue x, ExactValue y)
}
return exact_value_i128(c);
} break;
break;
}
case ExactValue_Float: {
f64 a = x.value_float;
@@ -533,7 +539,8 @@ ExactValue exact_binary_operator_value(TokenKind op, ExactValue x, ExactValue y)
case Token_Quo: return exact_value_float(a / b);
default: goto error;
}
} break;
break;
}
case ExactValue_Complex: {
y = exact_value_to_complex(y);
@@ -560,11 +567,13 @@ ExactValue exact_binary_operator_value(TokenKind op, ExactValue x, ExactValue y)
f64 s = c*c + d*d;
real = (a*c + b*d)/s;
imag = (b*c - a*d)/s;
} break;
break;
}
default: goto error;
}
return exact_value_complex(real, imag);
} break;
break;
}
case ExactValue_String: {
if (op != Token_Add) goto error;
@@ -577,7 +586,8 @@ ExactValue exact_binary_operator_value(TokenKind op, ExactValue x, ExactValue y)
gb_memmove(data, sx.text, sx.len);
gb_memmove(data+sx.len, sy.text, sy.len);
return exact_value_string(make_string(data, len));
} break;
break;
}
}
error:; // NOTE(bill): MSVC accepts this??? apparently you cannot declare variables immediately after labels...
@@ -620,7 +630,8 @@ bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y) {
case Token_Gt: return a > b;
case Token_GtEq: return a >= b;
}
} break;
break;
}
case ExactValue_Float: {
f64 a = x.value_float;
@@ -633,7 +644,8 @@ bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y) {
case Token_Gt: return cmp_f64(a, b) > 0;
case Token_GtEq: return cmp_f64(a, b) >= 0;
}
} break;
break;
}
case ExactValue_Complex: {
f64 a = x.value_complex.real;
@@ -644,7 +656,8 @@ bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y) {
case Token_CmpEq: return cmp_f64(a, c) == 0 && cmp_f64(b, d) == 0;
case Token_NotEq: return cmp_f64(a, c) != 0 || cmp_f64(b, d) != 0;
}
} break;
break;
}
case ExactValue_String: {
String a = x.value_string;
@@ -658,7 +671,8 @@ bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y) {
case Token_Gt: return a > b;
case Token_GtEq: return a >= b;
}
} break;
break;
}
case ExactValue_Type:
switch (op) {

View File

@@ -19,7 +19,7 @@ struct irModule {
String layout;
// String triple;
PtrSet<Entity *> min_dep_map;
PtrSet<Entity *> min_dep_set;
Map<irValue *> values; // Key: Entity *
Map<irValue *> members; // Key: String
Map<String> entity_names; // Key: Entity * of the typename
@@ -623,7 +623,7 @@ Type *ir_instr_type(irInstr *instr) {
return pt;
}
return nullptr;
} break;
}
}
return nullptr;
}
@@ -741,7 +741,8 @@ Array<irValue *> *ir_value_referrers(irValue *v) {
case irInstr_Local:
return &i->Local.referrers;
}
} break;
break;
}
}
return nullptr;
@@ -2107,7 +2108,8 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue *
irValue *z = ir_emit_arith(proc, Token_Mul, b, c, ft);
irValue *w = ir_emit_arith(proc, Token_Mul, a, d, ft);
imag = ir_emit_arith(proc, Token_Add, z, w, ft);
} break;
break;
}
case Token_Quo: {
irValue *s1 = ir_emit_arith(proc, Token_Mul, c, c, ft);
irValue *s2 = ir_emit_arith(proc, Token_Mul, d, d, ft);
@@ -2122,7 +2124,8 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue *
irValue *w = ir_emit_arith(proc, Token_Mul, a, d, ft);
imag = ir_emit_arith(proc, Token_Sub, z, w, ft);
imag = ir_emit_arith(proc, Token_Quo, imag, s, ft);
} break;
break;
}
}
ir_emit_store(proc, ir_emit_struct_ep(proc, res, 0), real);
@@ -2473,7 +2476,8 @@ irValue *ir_emit_struct_ev(irProcedure *proc, irValue *s, i32 index) {
case 0: result_type = ft; break;
case 1: result_type = ft; break;
}
} break;
break;
}
}
break;
case Type_Struct:
@@ -2509,7 +2513,8 @@ irValue *ir_emit_struct_ev(irProcedure *proc, irValue *s, i32 index) {
case 0: result_type = gst->Struct.fields[0]->type; break;
case 1: result_type = gst->Struct.fields[1]->type; break;
}
} break;
break;
}
default:
GB_PANIC("TODO(bill): struct_ev type: %s, %d", type_to_string(ir_type(s)), index);
@@ -2558,7 +2563,8 @@ irValue *ir_emit_deep_field_gep(irProcedure *proc, irValue *e, Selection sel) {
type = t_type_info_ptr;
}
e = ir_emit_struct_ep(proc, e, index);
} break;
break;
}
case Basic_string:
e = ir_emit_struct_ep(proc, e, index);
@@ -2924,12 +2930,14 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) {
irValue **args = gb_alloc_array(a, irValue *, 1);
args[0] = value;
return ir_emit_global_call(proc, "__gnu_h2f_ieee", args, 1);
} break;
break;
}
case 8: {
irValue **args = gb_alloc_array(a, irValue *, 1);
args[0] = value;
return ir_emit_global_call(proc, "__f16_to_f64", args, 1);
} break;
break;
}
}
} else if (dz == 2) {
switch (sz) {
@@ -2938,12 +2946,14 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) {
irValue **args = gb_alloc_array(a, irValue *, 1);
args[0] = value;
return ir_emit_global_call(proc, "__gnu_f2h_ieee", args, 1);
} break;
break;
}
case 8: {
irValue **args = gb_alloc_array(a, irValue *, 1);
args[0] = value;
return ir_emit_global_call(proc, "__truncdfhf2", args, 1);
} break;
break;
}
}
}
@@ -3897,12 +3907,14 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
}
return ir_emit_source_code_location(proc, procedure, pos);
} break;
break;
}
case BuiltinProc_type_info_of: {
Type *t = default_type(type_of_expr(proc->module->info, ce->args[0]));
return ir_type_info(proc, t);
} break;
break;
}
case BuiltinProc_len: {
irValue *v = ir_build_expr(proc, ce->args[0]);
@@ -3929,7 +3941,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
}
GB_PANIC("Unreachable");
} break;
break;
}
case BuiltinProc_cap: {
irValue *v = ir_build_expr(proc, ce->args[0]);
@@ -3956,7 +3969,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
GB_PANIC("Unreachable");
} break;
break;
}
#if 0
case BuiltinProc_new: {
@@ -3993,7 +4007,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
ir_emit_store(proc, tag_ptr, ir_const_int(a, variant_index));
}
return v;
} break;
break;
}
#endif
case BuiltinProc_make: {
@@ -4079,7 +4094,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
return ir_emit_load(proc, array);
}
} break;
break;
}
#if 0
case BuiltinProc_free: {
@@ -4154,7 +4170,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
irValue **args = gb_alloc_array(a, irValue *, 1);
args[0] = ptr;
return ir_emit_global_call(proc, "free_ptr", args, 1);
} break;
break;
}
#endif
#if 0
case BuiltinProc_reserve: {
@@ -4190,7 +4207,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
} else {
GB_PANIC("Unknown type for `reserve`");
}
} break;
break;
}
#endif
#if 0
case BuiltinProc_clear: {
@@ -4217,7 +4235,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
GB_PANIC("TODO(bill): ir clear for `%s`", type_to_string(t));
}
return nullptr;
} break;
break;
}
#endif
#if 0
case BuiltinProc_append: {
@@ -4327,7 +4346,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
return ir_emit_global_call(proc, "__slice_append", daa_args, 5);
}
return ir_emit_global_call(proc, "__dynamic_array_append", daa_args, 5);
} break;
break;
}
#endif
#if 0
case BuiltinProc_delete: {
@@ -4345,7 +4365,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
args[0] = ir_gen_map_header(proc, addr, map_type);
args[1] = ir_gen_map_key(proc, key, key_type);
return ir_emit_global_call(proc, "__dynamic_map_delete", args, 2);
} break;
break;
}
#endif
case BuiltinProc_swizzle: {
@@ -4374,7 +4395,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
ir_emit_comment(proc, str_lit("swizzle.end"));
return ir_emit_load(proc, dst);
// return ir_emit(proc, ir_instr_vector_shuffle(proc, vector, indices, index_count));
} break;
break;
}
case BuiltinProc_complex: {
ir_emit_comment(proc, str_lit("complex"));
@@ -4389,20 +4411,23 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
ir_emit_store(proc, ir_emit_struct_ep(proc, dst, 1), imag);
return ir_emit_load(proc, dst);
} break;
break;
}
case BuiltinProc_real: {
ir_emit_comment(proc, str_lit("real"));
irValue *val = ir_build_expr(proc, ce->args[0]);
irValue *real = ir_emit_struct_ev(proc, val, 0);
return ir_emit_conv(proc, real, tv.type);
} break;
break;
}
case BuiltinProc_imag: {
ir_emit_comment(proc, str_lit("imag"));
irValue *val = ir_build_expr(proc, ce->args[0]);
irValue *imag = ir_emit_struct_ev(proc, val, 1);
return ir_emit_conv(proc, imag, tv.type);
} break;
break;
}
case BuiltinProc_conj: {
ir_emit_comment(proc, str_lit("conj"));
@@ -4418,7 +4443,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
ir_emit_store(proc, ir_emit_struct_ep(proc, res, 1), imag);
}
return ir_emit_load(proc, res);
} break;
break;
}
#if 0
case BuiltinProc_slice_ptr: {
@@ -4436,7 +4462,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
irValue *slice = ir_add_local_generated(proc, slice_type);
ir_fill_slice(proc, slice, ptr, count, capacity);
return ir_emit_load(proc, slice);
} break;
break;
}
case BuiltinProc_slice_to_bytes: {
ir_emit_comment(proc, str_lit("slice_to_bytes"));
@@ -4455,7 +4482,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
capacity = ir_emit_arith(proc, Token_Mul, capacity, ir_const_int(proc->module->allocator, elem_size), t_int);
ir_fill_slice(proc, slice, ptr, count, capacity);
return ir_emit_load(proc, slice);
} break;
break;
}
#endif
case BuiltinProc_expand_to_tuple: {
@@ -4475,7 +4503,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
ir_emit_store(proc, ep, f);
}
return ir_emit_load(proc, tuple);
} break;
break;
}
case BuiltinProc_min: {
ir_emit_comment(proc, str_lit("min"));
@@ -4484,7 +4513,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
irValue *y = ir_emit_conv(proc, ir_build_expr(proc, ce->args[1]), t);
irValue *cond = ir_emit_comp(proc, Token_Lt, x, y);
return ir_emit_select(proc, cond, x, y);
} break;
break;
}
case BuiltinProc_max: {
ir_emit_comment(proc, str_lit("max"));
@@ -4493,7 +4523,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
irValue *y = ir_emit_conv(proc, ir_build_expr(proc, ce->args[1]), t);
irValue *cond = ir_emit_comp(proc, Token_Gt, x, y);
return ir_emit_select(proc, cond, x, y);
} break;
break;
}
case BuiltinProc_abs: {
ir_emit_comment(proc, str_lit("abs"));
@@ -4514,7 +4545,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
irValue *cond = ir_emit_comp(proc, Token_Lt, x, zero);
irValue *neg = ir_emit(proc, ir_instr_unary_op(proc, Token_Sub, x, t));
return ir_emit_select(proc, cond, neg, x);
} break;
break;
}
case BuiltinProc_clamp: {
ir_emit_comment(proc, str_lit("clamp"));
@@ -4523,7 +4555,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
ir_build_expr(proc, ce->args[0]),
ir_build_expr(proc, ce->args[1]),
ir_build_expr(proc, ce->args[2]));
} break;
break;
}
}
GB_PANIC("Unhandled built-in procedure");
@@ -4775,7 +4808,8 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
irValue *right = ir_build_expr(proc, be->right);
irValue *cmp = ir_emit_comp(proc, be->op.kind, left, right);
return ir_emit_conv(proc, cmp, type);
} break;
break;
}
case Token_CmpAnd:
case Token_CmpOr:
@@ -5307,7 +5341,8 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
irValue *len = ir_const_int(a, t->Vector.count);
ir_emit_bounds_check(proc, ast_node_token(ie->index), index, len);
return ir_addr(elem);
} break;
break;
}
case Type_Array: {
irValue *array = nullptr;
@@ -5324,7 +5359,8 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
irValue *len = ir_const_int(a, t->Vector.count);
ir_emit_bounds_check(proc, ast_node_token(ie->index), index, len);
return ir_addr(elem);
} break;
break;
}
case Type_Slice: {
irValue *slice = nullptr;
@@ -5342,7 +5378,8 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
ir_emit_bounds_check(proc, ast_node_token(ie->index), index, len);
irValue *v = ir_emit_ptr_offset(proc, elem, index);
return ir_addr(v);
} break;
break;
}
case Type_DynamicArray: {
irValue *dynamic_array = nullptr;
@@ -5360,7 +5397,8 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
ir_emit_bounds_check(proc, ast_node_token(ie->index), index, len);
irValue *v = ir_emit_ptr_offset(proc, elem, index);
return ir_addr(v);
} break;
break;
}
case Type_Basic: { // Basic_string
@@ -5384,7 +5422,8 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
ir_emit_bounds_check(proc, ast_node_token(ie->index), index, len);
return ir_addr(ir_emit_ptr_offset(proc, elem, index));
} break;
break;
}
}
case_end;
@@ -5485,7 +5524,8 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
irValue *str = ir_add_local_generated(proc, t_string);
ir_fill_string(proc, str, elem, len);
return ir_addr(str);
} break;
break;
}
}
GB_PANIC("Unknown slicable type");
@@ -5544,7 +5584,8 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
ir_emit_store(proc, gep, ev);
}
}
} break;
break;
}
case Type_Struct: {
// TODO(bill): "constant" unions are not initialized constantly at the moment.
@@ -5590,7 +5631,8 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
ir_emit_store(proc, gep, fv);
}
}
} break;
break;
}
case Type_Map: {
if (cl->elems.count == 0) {
@@ -5611,7 +5653,8 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
irValue *value = ir_build_expr(proc, fv->value);
ir_insert_dynamic_map_key_and_value(proc, v, type, key, value);
}
} break;
break;
}
case Type_DynamicArray: {
if (cl->elems.count == 0) {
@@ -5649,7 +5692,8 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
args[4] = ir_const_int(a, item_count);
ir_emit_global_call(proc, "__dynamic_array_append", args, 5);
}
} break;
break;
}
case Type_Array: {
if (cl->elems.count > 0) {
@@ -5667,7 +5711,8 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
ir_emit_store(proc, gep, ev);
}
}
} break;
break;
}
case Type_Slice: {
if (cl->elems.count > 0) {
Type *elem_type = bt->Slice.elem;
@@ -5695,7 +5740,8 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
irValue *count = ir_const_int(proc->module->allocator, slice->ConstantSlice.count);
ir_fill_slice(proc, v, data, count, count);
}
} break;
break;
}
case Type_Basic: {
GB_ASSERT(is_type_any(bt));
@@ -5814,7 +5860,7 @@ irValue *ir_build_cond(irProcedure *proc, AstNode *cond, irBlock *true_block, ir
void ir_build_poly_proc(irProcedure *proc, AstNodeProcLit *pd, Entity *e) {
GB_ASSERT(pd->body != nullptr);
if (ptr_set_exists(&proc->module->min_dep_map, e) == false) {
if (ptr_set_exists(&proc->module->min_dep_set, e) == false) {
// NOTE(bill): Nothing depends upon it so doesn't need to be built
return;
}
@@ -5876,7 +5922,7 @@ void ir_build_constant_value_decl(irProcedure *proc, AstNodeValueDecl *vd) {
}
}
if (!polymorphic_struct && !ptr_set_exists(&proc->module->min_dep_map, e)) {
if (!polymorphic_struct && !ptr_set_exists(&proc->module->min_dep_set, e)) {
continue;
}
@@ -5905,7 +5951,7 @@ void ir_build_constant_value_decl(irProcedure *proc, AstNodeValueDecl *vd) {
auto procs = *found;
for_array(i, procs) {
Entity *e = procs[i];
if (!ptr_set_exists(&proc->module->min_dep_map, e)) {
if (!ptr_set_exists(&proc->module->min_dep_set, e)) {
continue;
}
DeclInfo *d = decl_info_of_entity(info, e);
@@ -6061,19 +6107,23 @@ void ir_build_range_indexed(irProcedure *proc, irValue *expr, Type *val_type, ir
switch (expr_type->kind) {
case Type_Array: {
val = ir_emit_load(proc, ir_emit_array_ep(proc, expr, idx));
} break;
break;
}
case Type_Vector: {
val = ir_emit_load(proc, ir_emit_array_ep(proc, expr, idx));
} break;
break;
}
case Type_Slice: {
irValue *elem = ir_slice_elem(proc, expr);
val = ir_emit_load(proc, ir_emit_ptr_offset(proc, elem, idx));
} break;
break;
}
case Type_DynamicArray: {
irValue *elem = ir_emit_struct_ep(proc, expr, 0);
elem = ir_emit_load(proc, elem);
val = ir_emit_load(proc, ir_emit_ptr_offset(proc, elem, idx));
} break;
break;
}
case Type_Map: {
irValue *entries = ir_emit_struct_ep(proc, expr, 1);
irValue *elem = ir_emit_struct_ep(proc, entries, 0);
@@ -6093,7 +6143,8 @@ void ir_build_range_indexed(irProcedure *proc, irValue *expr, Type *val_type, ir
}
} break;
break;
}
default:
GB_PANIC("Cannot do range_indexed of %s", type_to_string(expr_type));
break;
@@ -6393,7 +6444,8 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
}
}
} break;
break;
}
default: {
// NOTE(bill): Only 1 += 1 is allowed, no tuples
@@ -6403,7 +6455,8 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
irAddr lhs = ir_build_addr(proc, as->lhs[0]);
irValue *value = ir_build_expr(proc, as->rhs[0]);
ir_build_assign_op(proc, lhs, value, cast(TokenKind)op);
} break;
break;
}
}
gb_temp_arena_memory_end(tmp);
@@ -6726,7 +6779,8 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
irValue *entries_ptr = ir_emit_struct_ep(proc, map, 1);
irValue *count_ptr = ir_emit_struct_ep(proc, entries_ptr, 1);
ir_build_range_indexed(proc, map, val_type, count_ptr, &val, &index, &loop, &done);
} break;
break;
}
case Type_Array: {
irValue *count_ptr = nullptr;
irValue *array = ir_build_addr(proc, rs->expr).addr;
@@ -6736,7 +6790,8 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
count_ptr = ir_add_local_generated(proc, t_int);
ir_emit_store(proc, count_ptr, ir_const_int(proc->module->allocator, et->Array.count));
ir_build_range_indexed(proc, array, val_type, count_ptr, &val, &index, &loop, &done);
} break;
break;
}
case Type_Vector: {
irValue *count_ptr = nullptr;
irValue *vector = ir_build_addr(proc, rs->expr).addr;
@@ -6746,7 +6801,8 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
count_ptr = ir_add_local_generated(proc, t_int);
ir_emit_store(proc, count_ptr, ir_const_int(proc->module->allocator, et->Vector.count));
ir_build_range_indexed(proc, vector, val_type, count_ptr, &val, &index, &loop, &done);
} break;
break;
}
case Type_DynamicArray: {
irValue *count_ptr = nullptr;
irValue *array = ir_build_addr(proc, rs->expr).addr;
@@ -6755,7 +6811,8 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
}
count_ptr = ir_emit_struct_ep(proc, array, 1);
ir_build_range_indexed(proc, array, val_type, count_ptr, &val, &index, &loop, &done);
} break;
break;
}
case Type_Slice: {
irValue *count_ptr = nullptr;
irValue *slice = ir_build_expr(proc, rs->expr);
@@ -6767,7 +6824,8 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
ir_emit_store(proc, count_ptr, ir_slice_count(proc, slice));
}
ir_build_range_indexed(proc, slice, val_type, count_ptr, &val, &index, &loop, &done);
} break;
break;
}
case Type_Basic: {
irValue *string = ir_build_expr(proc, rs->expr);
if (is_type_pointer(ir_type(string))) {
@@ -6779,7 +6837,8 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
string = ir_emit_load(proc, s);
}
ir_build_range_string(proc, string, val_type, &val, &index, &loop, &done);
} break;
break;
}
default:
GB_PANIC("Cannot range over %s", type_to_string(expr_type));
break;
@@ -6812,18 +6871,18 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
ir_start_block(proc, done);
case_end;
case_ast_node(ms, MatchStmt, node);
ir_emit_comment(proc, str_lit("MatchStmt"));
if (ms->init != nullptr) {
ir_build_stmt(proc, ms->init);
case_ast_node(ss, SwitchStmt, node);
ir_emit_comment(proc, str_lit("SwitchStmt"));
if (ss->init != nullptr) {
ir_build_stmt(proc, ss->init);
}
irValue *tag = v_true;
if (ms->tag != nullptr) {
tag = ir_build_expr(proc, ms->tag);
if (ss->tag != nullptr) {
tag = ir_build_expr(proc, ss->tag);
}
irBlock *done = ir_new_block(proc, node, "match.done"); // NOTE(bill): Append later
irBlock *done = ir_new_block(proc, node, "switch.done"); // NOTE(bill): Append later
ast_node(body, BlockStmt, ms->body);
ast_node(body, BlockStmt, ss->body);
Array<AstNode *> default_stmts = {};
irBlock *default_fall = nullptr;
@@ -6841,9 +6900,9 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
if (body == nullptr) {
if (cc->list.count == 0) {
body = ir_new_block(proc, clause, "match.dflt.body");
body = ir_new_block(proc, clause, "switch.dflt.body");
} else {
body = ir_new_block(proc, clause, "match.case.body");
body = ir_new_block(proc, clause, "switch.case.body");
}
}
if (append_fall && body == fall) {
@@ -6853,7 +6912,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
fall = done;
if (i+1 < case_count) {
append_fall = true;
fall = ir_new_block(proc, clause, "match.fall.body");
fall = ir_new_block(proc, clause, "switch.fall.body");
}
if (cc->list.count == 0) {
@@ -6867,7 +6926,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
irBlock *next_cond = nullptr;
for_array(j, cc->list) {
AstNode *expr = unparen_expr(cc->list[j]);
next_cond = ir_new_block(proc, clause, "match.case.next");
next_cond = ir_new_block(proc, clause, "switch.case.next");
irValue *cond = v_false;
if (is_ast_node_a_range(expr)) {
ast_node(ie, BinaryExpr, expr);
@@ -6891,7 +6950,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
}
ir_start_block(proc, body);
ir_push_target_list(proc, ms->label, done, nullptr, fall);
ir_push_target_list(proc, ss->label, done, nullptr, fall);
ir_open_scope(proc);
ir_build_stmt_list(proc, cc->stmts);
ir_close_scope(proc, irDeferExit_Default, body);
@@ -6906,7 +6965,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
ir_emit_jump(proc, default_block);
ir_start_block(proc, default_block);
ir_push_target_list(proc, ms->label, done, nullptr, default_fall);
ir_push_target_list(proc, ss->label, done, nullptr, default_fall);
ir_open_scope(proc);
ir_build_stmt_list(proc, default_stmts);
ir_close_scope(proc, irDeferExit_Default, default_block);
@@ -6918,11 +6977,11 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
case_end;
case_ast_node(ms, TypeMatchStmt, node);
ir_emit_comment(proc, str_lit("TypeMatchStmt"));
case_ast_node(ss, TypeSwitchStmt, node);
ir_emit_comment(proc, str_lit("TypeSwitchStmt"));
gbAllocator allocator = proc->module->allocator;
ast_node(as, AssignStmt, ms->tag);
ast_node(as, AssignStmt, ss->tag);
GB_ASSERT(as->lhs.count == 1);
GB_ASSERT(as->rhs.count == 1);
@@ -6948,15 +7007,15 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
union_data = ir_emit_conv(proc, parent_ptr, t_rawptr);
}
irBlock *start_block = ir_new_block(proc, node, "typematch.case.first");
irBlock *start_block = ir_new_block(proc, node, "typeswitch.case.first");
ir_emit_jump(proc, start_block);
ir_start_block(proc, start_block);
// NOTE(bill): Append this later
irBlock *done = ir_new_block(proc, node, "typematch.done");
irBlock *done = ir_new_block(proc, node, "typeswitch.done");
AstNode *default_ = nullptr;
ast_node(body, BlockStmt, ms->body);
ast_node(body, BlockStmt, ss->body);
gb_local_persist i32 weird_count = 0;
@@ -6968,11 +7027,11 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
continue;
}
irBlock *body = ir_new_block(proc, clause, "typematch.body");
irBlock *body = ir_new_block(proc, clause, "typeswitch.body");
irBlock *next = nullptr;
Type *case_type = nullptr;
for_array(type_index, cc->list) {
next = ir_new_block(proc, nullptr, "typematch.next");
next = ir_new_block(proc, nullptr, "typeswitch.next");
case_type = type_of_expr(proc->module->info, cc->list[type_index]);
irValue *cond = nullptr;
if (match_type_kind == MatchType_Union) {
@@ -7028,13 +7087,13 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
}
ir_store_type_case_implicit(proc, clause, value);
ir_type_case_body(proc, ms->label, clause, body, done);
ir_type_case_body(proc, ss->label, clause, body, done);
ir_start_block(proc, next);
}
if (default_ != nullptr) {
ir_store_type_case_implicit(proc, default_, parent_value);
ir_type_case_body(proc, ms->label, default_, proc->curr_block, done);
ir_type_case_body(proc, ss->label, default_, proc->curr_block, done);
} else {
ir_emit_jump(proc, done);
}
@@ -7635,7 +7694,7 @@ void ir_gen_tree(irGen *s) {
array_init(&global_variables, m->tmp_allocator, global_variable_max_count);
m->entry_point_entity = entry_point;
m->min_dep_map = info->minimum_dependency_map;
m->min_dep_set = info->minimum_dependency_set;
for_array(i, info->variable_init_order) {
DeclInfo *d = info->variable_init_order[i];
@@ -7647,7 +7706,7 @@ void ir_gen_tree(irGen *s) {
continue;
}
if (!ptr_set_exists(&m->min_dep_map, e)) {
if (!ptr_set_exists(&m->min_dep_set, e)) {
continue;
}
DeclInfo *decl = decl_info_of_entity(info, e);
@@ -7717,7 +7776,7 @@ void ir_gen_tree(irGen *s) {
}
}
if (!polymorphic_struct && !ptr_set_exists(&m->min_dep_map, e)) {
if (!polymorphic_struct && !ptr_set_exists(&m->min_dep_set, e)) {
// NOTE(bill): Nothing depends upon it so doesn't need to be built
continue;
}
@@ -7766,7 +7825,8 @@ void ir_gen_tree(irGen *s) {
if (map_get(&m->members, hash_name) == nullptr) {
multi_map_insert(&m->members, hash_name, p);
}
} break;
break;
}
}
}
@@ -8068,7 +8128,8 @@ void ir_gen_tree(irGen *s) {
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), name);
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 1), gtip);
} break;
break;
}
case Type_Basic:
ir_emit_comment(proc, str_lit("TypeInfoBasic"));
@@ -8092,7 +8153,8 @@ void ir_gen_tree(irGen *s) {
tag = ir_emit_conv(proc, variant_ptr, t_type_info_integer_ptr);
irValue *is_signed = ir_const_bool(a, (t->Basic.flags & BasicFlag_Unsigned) == 0);
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), is_signed);
} break;
break;
}
case Basic_rune:
tag = ir_emit_conv(proc, variant_ptr, t_type_info_rune_ptr);
@@ -8129,7 +8191,8 @@ void ir_gen_tree(irGen *s) {
tag = ir_emit_conv(proc, variant_ptr, t_type_info_pointer_ptr);
irValue *gep = ir_get_type_info_ptr(proc, t->Pointer.elem);
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
} break;
break;
}
case Type_Array: {
ir_emit_comment(proc, str_lit("TypeInfoArray"));
tag = ir_emit_conv(proc, variant_ptr, t_type_info_array_ptr);
@@ -8143,7 +8206,8 @@ void ir_gen_tree(irGen *s) {
irValue *count = ir_emit_struct_ep(proc, tag, 2);
ir_emit_store(proc, count, ir_const_int(a, t->Array.count));
} break;
break;
}
case Type_DynamicArray: {
ir_emit_comment(proc, str_lit("TypeInfoDynamicArray"));
tag = ir_emit_conv(proc, variant_ptr, t_type_info_dynamic_array_ptr);
@@ -8153,7 +8217,8 @@ void ir_gen_tree(irGen *s) {
isize ez = type_size_of(a, t->DynamicArray.elem);
irValue *elem_size = ir_emit_struct_ep(proc, tag, 1);
ir_emit_store(proc, elem_size, ir_const_int(a, ez));
} break;
break;
}
case Type_Slice: {
ir_emit_comment(proc, str_lit("TypeInfoSlice"));
tag = ir_emit_conv(proc, variant_ptr, t_type_info_slice_ptr);
@@ -8163,7 +8228,8 @@ void ir_gen_tree(irGen *s) {
isize ez = type_size_of(a, t->Slice.elem);
irValue *elem_size = ir_emit_struct_ep(proc, tag, 1);
ir_emit_store(proc, elem_size, ir_const_int(a, ez));
} break;
break;
}
case Type_Vector: {
ir_emit_comment(proc, str_lit("TypeInfoVector"));
tag = ir_emit_conv(proc, variant_ptr, t_type_info_vector_ptr);
@@ -8174,7 +8240,8 @@ void ir_gen_tree(irGen *s) {
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 1), ir_const_int(a, ez));
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 2), ir_const_int(a, t->Vector.count));
} break;
break;
}
case Type_Proc: {
ir_emit_comment(proc, str_lit("TypeInfoProc"));
tag = ir_emit_conv(proc, variant_ptr, t_type_info_procedure_ptr);
@@ -8194,7 +8261,8 @@ void ir_gen_tree(irGen *s) {
ir_emit_store(proc, convention, ir_const_int(a, t->Proc.calling_convention));
// TODO(bill): TypeInfo for procedures
} break;
break;
}
case Type_Tuple: {
ir_emit_comment(proc, str_lit("TypeInfoTuple"));
tag = ir_emit_conv(proc, variant_ptr, t_type_info_tuple_ptr);
@@ -8219,7 +8287,8 @@ void ir_gen_tree(irGen *s) {
irValue *count = ir_const_int(a, t->Tuple.variables.count);
ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 0), memory_types, count, count);
ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 1), memory_names, count, count);
} break;
break;
}
case Type_Enum:
ir_emit_comment(proc, str_lit("TypeInfoEnum"));
tag = ir_emit_conv(proc, variant_ptr, t_type_info_enum_ptr);
@@ -8293,7 +8362,8 @@ void ir_gen_tree(irGen *s) {
ir_emit_store(proc, tag_offset_ptr, ir_const_int(a, tag_offset));
}
} break;
break;
}
case Type_Struct: {
ir_emit_comment(proc, str_lit("TypeInfoStruct"));
@@ -8347,7 +8417,8 @@ void ir_gen_tree(irGen *s) {
ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 1), memory_names, cv, cv);
ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 2), memory_offsets, cv, cv);
ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 3), memory_usings, cv, cv);
} break;
break;
}
case Type_Map: {
ir_emit_comment(proc, str_lit("TypeInfoMap"));
tag = ir_emit_conv(proc, variant_ptr, t_type_info_map_ptr);
@@ -8360,7 +8431,8 @@ void ir_gen_tree(irGen *s) {
ir_emit_store(proc, key, ir_get_type_info_ptr(proc, t->Map.key));
ir_emit_store(proc, value, ir_get_type_info_ptr(proc, t->Map.value));
ir_emit_store(proc, generated_struct, ir_get_type_info_ptr(proc, t->Map.generated_struct_type));
} break;
break;
}
case Type_BitField: {
ir_emit_comment(proc, str_lit("TypeInfoBitField"));
@@ -8403,7 +8475,8 @@ void ir_gen_tree(irGen *s) {
irValue *offset_array_elem = ir_array_elem(proc, offset_array);
ir_fill_slice(proc, offsets, offset_array_elem, v_count, v_count);
}
} break;
break;
}
}

View File

@@ -281,14 +281,14 @@ AST_NODE_KIND(_ComplexStmtBegin, "", i32) \
Array<AstNode *> list; \
Array<AstNode *> stmts; \
}) \
AST_NODE_KIND(MatchStmt, "match statement", struct { \
AST_NODE_KIND(SwitchStmt, "switch statement", struct { \
Token token; \
AstNode *label; \
AstNode *init; \
AstNode *tag; \
AstNode *body; \
}) \
AST_NODE_KIND(TypeMatchStmt, "type match statement", struct { \
AST_NODE_KIND(TypeSwitchStmt, "type switch statement", struct { \
Token token; \
AstNode *label; \
AstNode *tag; \
@@ -575,8 +575,8 @@ Token ast_node_token(AstNode *node) {
case AstNode_ForStmt: return node->ForStmt.token;
case AstNode_RangeStmt: return node->RangeStmt.token;
case AstNode_CaseClause: return node->CaseClause.token;
case AstNode_MatchStmt: return node->MatchStmt.token;
case AstNode_TypeMatchStmt: return node->TypeMatchStmt.token;
case AstNode_SwitchStmt: return node->SwitchStmt.token;
case AstNode_TypeSwitchStmt: return node->TypeSwitchStmt.token;
case AstNode_DeferStmt: return node->DeferStmt.token;
case AstNode_BranchStmt: return node->BranchStmt.token;
case AstNode_UsingStmt: return node->UsingStmt.token;
@@ -783,16 +783,16 @@ AstNode *clone_ast_node(gbAllocator a, AstNode *node) {
n->CaseClause.list = clone_ast_node_array(a, n->CaseClause.list);
n->CaseClause.stmts = clone_ast_node_array(a, n->CaseClause.stmts);
break;
case AstNode_MatchStmt:
n->MatchStmt.label = clone_ast_node(a, n->MatchStmt.label);
n->MatchStmt.init = clone_ast_node(a, n->MatchStmt.init);
n->MatchStmt.tag = clone_ast_node(a, n->MatchStmt.tag);
n->MatchStmt.body = clone_ast_node(a, n->MatchStmt.body);
case AstNode_SwitchStmt:
n->SwitchStmt.label = clone_ast_node(a, n->SwitchStmt.label);
n->SwitchStmt.init = clone_ast_node(a, n->SwitchStmt.init);
n->SwitchStmt.tag = clone_ast_node(a, n->SwitchStmt.tag);
n->SwitchStmt.body = clone_ast_node(a, n->SwitchStmt.body);
break;
case AstNode_TypeMatchStmt:
n->TypeMatchStmt.label = clone_ast_node(a, n->TypeMatchStmt.label);
n->TypeMatchStmt.tag = clone_ast_node(a, n->TypeMatchStmt.tag);
n->TypeMatchStmt.body = clone_ast_node(a, n->TypeMatchStmt.body);
case AstNode_TypeSwitchStmt:
n->TypeSwitchStmt.label = clone_ast_node(a, n->TypeSwitchStmt.label);
n->TypeSwitchStmt.tag = clone_ast_node(a, n->TypeSwitchStmt.tag);
n->TypeSwitchStmt.body = clone_ast_node(a, n->TypeSwitchStmt.body);
break;
case AstNode_DeferStmt:
n->DeferStmt.stmt = clone_ast_node(a, n->DeferStmt.stmt);
@@ -1266,20 +1266,20 @@ AstNode *ast_range_stmt(AstFile *f, Token token, AstNode *value, AstNode *index,
}
AstNode *ast_match_stmt(AstFile *f, Token token, AstNode *init, AstNode *tag, AstNode *body) {
AstNode *result = make_ast_node(f, AstNode_MatchStmt);
result->MatchStmt.token = token;
result->MatchStmt.init = init;
result->MatchStmt.tag = tag;
result->MatchStmt.body = body;
AstNode *result = make_ast_node(f, AstNode_SwitchStmt);
result->SwitchStmt.token = token;
result->SwitchStmt.init = init;
result->SwitchStmt.tag = tag;
result->SwitchStmt.body = body;
return result;
}
AstNode *ast_type_match_stmt(AstFile *f, Token token, AstNode *tag, AstNode *body) {
AstNode *result = make_ast_node(f, AstNode_TypeMatchStmt);
result->TypeMatchStmt.token = token;
result->TypeMatchStmt.tag = tag;
result->TypeMatchStmt.body = body;
AstNode *result = make_ast_node(f, AstNode_TypeSwitchStmt);
result->TypeSwitchStmt.token = token;
result->TypeSwitchStmt.tag = tag;
result->TypeSwitchStmt.body = body;
return result;
}
@@ -1774,7 +1774,7 @@ void fix_advance_to_next_stmt(AstFile *f) {
case Token_for:
case Token_when:
case Token_return:
case Token_match:
case Token_switch:
case Token_defer:
case Token_asm:
case Token_using:
@@ -1823,12 +1823,15 @@ bool is_semicolon_optional_for_node(AstFile *f, AstNode *s) {
}
switch (s->kind) {
case AstNode_EmptyStmt:
return true;
case AstNode_IfStmt:
case AstNode_WhenStmt:
case AstNode_ForStmt:
case AstNode_RangeStmt:
case AstNode_MatchStmt:
case AstNode_TypeMatchStmt:
case AstNode_SwitchStmt:
case AstNode_TypeSwitchStmt:
return true;
case AstNode_PointerType:
@@ -1842,6 +1845,11 @@ bool is_semicolon_optional_for_node(AstFile *f, AstNode *s) {
case AstNode_ProcLit:
return s->ProcLit.body != nullptr;
case AstNode_ImportDecl:
case AstNode_ExportDecl:
case AstNode_ForeignLibraryDecl:
return true;
case AstNode_ValueDecl:
if (s->ValueDecl.is_mutable) {
return false;
@@ -3176,7 +3184,7 @@ AstNode *parse_simple_stmt(AstFile *f, StmtAllowFlag flags) {
TokenKind next = look_ahead_token_kind(f, 1);
switch (next) {
case Token_for:
case Token_match: {
case Token_switch: {
expect_token_after(f, Token_Colon, "identifier list");
AstNode *name = lhs[0];
AstNode *label = ast_label_decl(f, ast_node_token(name), name);
@@ -3185,8 +3193,8 @@ AstNode *parse_simple_stmt(AstFile *f, StmtAllowFlag flags) {
switch (stmt->kind) {
_SET_LABEL(ForStmt, label);
_SET_LABEL(RangeStmt, label);
_SET_LABEL(MatchStmt, label);
_SET_LABEL(TypeMatchStmt, label);
_SET_LABEL(SwitchStmt, label);
_SET_LABEL(TypeSwitchStmt, label);
default:
syntax_error(token, "Labels can only be applied to a loop or match statement");
break;
@@ -4238,7 +4246,7 @@ AstNode *parse_match_stmt(AstFile *f) {
return ast_bad_stmt(f, f->curr_token, f->curr_token);
}
Token token = expect_token(f, Token_match);
Token token = expect_token(f, Token_switch);
AstNode *init = nullptr;
AstNode *tag = nullptr;
AstNode *body = nullptr;
@@ -4366,12 +4374,15 @@ AstNode *parse_import_decl(AstFile *f, bool is_using) {
cond = parse_expr(f, false);
}
expect_semicolon(f, nullptr);
AstNode *s = nullptr;
if (f->curr_proc != nullptr) {
syntax_error(import_name, "You cannot use `import` within a procedure. This must be done at the file scope");
return ast_bad_decl(f, import_name, file_path);
s = ast_bad_decl(f, import_name, file_path);
} else {
s = ast_import_decl(f, token, is_using, file_path, import_name, cond, docs, f->line_comment);
}
return ast_import_decl(f, token, is_using, file_path, import_name, cond, docs, f->line_comment);
expect_semicolon(f, s);
return s;
}
AstNode *parse_export_decl(AstFile *f) {
@@ -4383,12 +4394,16 @@ AstNode *parse_export_decl(AstFile *f) {
if (allow_token(f, Token_when)) {
cond = parse_expr(f, false);
}
expect_semicolon(f, nullptr);
AstNode *s = nullptr;
if (f->curr_proc != nullptr) {
syntax_error(token, "You cannot use `export` within a procedure. This must be done at the file scope");
return ast_bad_decl(f, token, file_path);
s = ast_bad_decl(f, token, file_path);
} else {
s = ast_export_decl(f, token, file_path, cond, docs, f->line_comment);
}
return ast_export_decl(f, token, file_path, cond, docs, f->line_comment);
expect_semicolon(f, s);
return s;
}
AstNode *parse_foreign_decl(AstFile *f) {
@@ -4425,14 +4440,16 @@ AstNode *parse_foreign_decl(AstFile *f) {
cond = parse_expr(f, false);
}
expect_semicolon(f, nullptr);
AstNode *s = nullptr;
if (f->curr_proc != nullptr) {
syntax_error(lib_name, "You cannot use foreign_system_library within a procedure. This must be done at the file scope");
return ast_bad_decl(f, lib_name, file_path);
s = ast_bad_decl(f, lib_name, file_path);
} else {
s = ast_foreign_library_decl(f, token, file_path, lib_name, cond, docs, f->line_comment);
}
return ast_foreign_library_decl(f, token, file_path, lib_name, cond, docs, f->line_comment);
expect_semicolon(f, s);
return s;
}
@@ -4478,7 +4495,7 @@ AstNode *parse_stmt(AstFile *f) {
case Token_if: return parse_if_stmt(f);
case Token_when: return parse_when_stmt(f);
case Token_for: return parse_for_stmt(f);
case Token_match: return parse_match_stmt(f);
case Token_switch: return parse_match_stmt(f);
case Token_defer: return parse_defer_stmt(f);
case Token_asm: return parse_asm_stmt(f);
case Token_return: return parse_return_stmt(f);

View File

@@ -2138,12 +2138,12 @@ void ssa_build_stmt_internal(ssaProc *p, AstNode *node) {
GB_PANIC("TODO: RangeStmt");
case_end;
case_ast_node(rs, MatchStmt, node);
GB_PANIC("TODO: MatchStmt");
case_ast_node(rs, SwitchStmt, node);
GB_PANIC("TODO: SwitchStmt");
case_end;
case_ast_node(rs, TypeMatchStmt, node);
GB_PANIC("TODO: TypeMatchStmt");
case_ast_node(rs, TypeSwitchStmt, node);
GB_PANIC("TODO: TypeSwitchStmt");
case_end;
case_ast_node(bs, BranchStmt, node);
@@ -2445,7 +2445,7 @@ bool ssa_generate(Parser *parser, CheckerInfo *info) {
m.entry_point_entity = entry_point;
m.min_dep_map = generate_minimum_dependency_map(info, entry_point);
m.min_dep_map = generate_minimum_dependency_set(info, entry_point);
for_array(i, info->entities.entries) {
auto *entry = &info->entities.entries[i];

View File

@@ -94,7 +94,7 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \
TOKEN_KIND(Token_if, "if"), \
TOKEN_KIND(Token_else, "else"), \
TOKEN_KIND(Token_for, "for"), \
TOKEN_KIND(Token_match, "match"), \
TOKEN_KIND(Token_switch, "switch"), \
TOKEN_KIND(Token_in, "in"), \
TOKEN_KIND(Token_do, "do"), \
TOKEN_KIND(Token_case, "case"), \