mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 15:18:49 +00:00
in keyword for for and match type
This commit is contained in:
+24
-20
@@ -1,5 +1,12 @@
|
|||||||
#import "fmt.odin";
|
#import "fmt.odin";
|
||||||
#import "utf8.odin";
|
#import "utf8.odin";
|
||||||
|
#import "atomic.odin";
|
||||||
|
#import "hash.odin";
|
||||||
|
#import "math.odin";
|
||||||
|
#import "mem.odin";
|
||||||
|
#import "opengl.odin";
|
||||||
|
#import "os.odin";
|
||||||
|
#import "sync.odin";
|
||||||
|
|
||||||
main :: proc() {
|
main :: proc() {
|
||||||
syntax();
|
syntax();
|
||||||
@@ -120,7 +127,6 @@ when_statements :: proc() {
|
|||||||
foreign_procedures();
|
foreign_procedures();
|
||||||
}
|
}
|
||||||
|
|
||||||
#import "atomic.odin" when ODIN_OS == "windows";
|
|
||||||
#foreign_system_library win32_user "user32.lib" when ODIN_OS == "windows";
|
#foreign_system_library win32_user "user32.lib" when ODIN_OS == "windows";
|
||||||
// NOTE: This is done on purpose for two reasons:
|
// NOTE: This is done on purpose for two reasons:
|
||||||
// * Makes it clear where the platform specific stuff is
|
// * Makes it clear where the platform specific stuff is
|
||||||
@@ -132,6 +138,8 @@ foreign_procedures :: proc() {
|
|||||||
// NOTE: If that library doesn't get used, it doesn't get linked with
|
// NOTE: If that library doesn't get used, it doesn't get linked with
|
||||||
// NOTE: There is not link checking yet to see if that procedure does come from that library
|
// NOTE: There is not link checking yet to see if that procedure does come from that library
|
||||||
|
|
||||||
|
// See sys/windows.odin for more examples
|
||||||
|
|
||||||
special_expressions();
|
special_expressions();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,8 +156,7 @@ special_expressions :: proc() {
|
|||||||
give x;
|
give x;
|
||||||
} else {
|
} else {
|
||||||
// TODO: Type cohesion is not yet finished
|
// TODO: Type cohesion is not yet finished
|
||||||
// E.g. this constant "number" should be able to be cast to a `f32` automatically
|
give 123;
|
||||||
give cast(f32)123;
|
|
||||||
}; // semicolon is required as it's an expression
|
}; // semicolon is required as it's an expression
|
||||||
|
|
||||||
|
|
||||||
@@ -176,24 +183,24 @@ loops :: proc() {
|
|||||||
for i := 0; i < 123; i += 1 {
|
for i := 0; i < 123; i += 1 {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
for i : 0..<123 {
|
for i in 0..<123 {
|
||||||
}
|
}
|
||||||
|
|
||||||
for i : 0...122 {
|
for i in 0..122 {
|
||||||
}
|
}
|
||||||
|
|
||||||
for val, idx : 12..<16 {
|
for val, idx in 12..<16 {
|
||||||
fmt.println(val, idx);
|
fmt.println(val, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
primes := [...]int{2, 3, 5, 7, 11, 13, 17, 19};
|
primes := [..]int{2, 3, 5, 7, 11, 13, 17, 19};
|
||||||
|
|
||||||
for p : primes {
|
for p in primes {
|
||||||
fmt.println(p);
|
fmt.println(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pointers to arrays, slices, or strings are allowed
|
// Pointers to arrays, slices, or strings are allowed
|
||||||
for _ : ^primes {
|
for _ in ^primes {
|
||||||
// ignore the value and just iterate across it
|
// ignore the value and just iterate across it
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,7 +208,7 @@ loops :: proc() {
|
|||||||
|
|
||||||
name := "你好,世界";
|
name := "你好,世界";
|
||||||
fmt.println(name);
|
fmt.println(name);
|
||||||
for r : name {
|
for r in name {
|
||||||
compile_assert(type_of_val(r) == rune);
|
compile_assert(type_of_val(r) == rune);
|
||||||
fmt.printf("%r\n", r);
|
fmt.printf("%r\n", r);
|
||||||
}
|
}
|
||||||
@@ -210,14 +217,12 @@ loops :: proc() {
|
|||||||
while i := 0; i < name.count {
|
while i := 0; i < name.count {
|
||||||
r, size := utf8.decode_rune(name[i:]);
|
r, size := utf8.decode_rune(name[i:]);
|
||||||
i += size;
|
i += size;
|
||||||
fmt.printf("%c\n", r);
|
fmt.printf("%r\n", r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Emulate a C-style loop (not exactly the same though)
|
// Emulate a C-style loop (not exactly the same though)
|
||||||
while x := 0; x < 10 {
|
while x := 0; x < 10 {
|
||||||
defer x += 2;
|
defer x += 2;
|
||||||
@@ -250,10 +255,8 @@ procedure_overloading :: proc() {
|
|||||||
|
|
||||||
foo();
|
foo();
|
||||||
foo(THINGF);
|
foo(THINGF);
|
||||||
// foo(THINGI);
|
// foo(THINGI); // 14451 is just a number so it could go to either procedures
|
||||||
foo(cast(int)THINGI);
|
foo(cast(int)THINGI);
|
||||||
fmt.println(THINGF);
|
|
||||||
fmt.println(THINGI);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -273,11 +276,12 @@ procedure_overloading :: proc() {
|
|||||||
fmt.println(foo(^a));
|
fmt.println(foo(^a));
|
||||||
foo(^b);
|
foo(^b);
|
||||||
foo(c);
|
foo(c);
|
||||||
// foo(nil);
|
// foo(nil); // nil could go to numerous types thus the ambiguity
|
||||||
atomic.store(^a, 1);
|
|
||||||
|
|
||||||
|
|
||||||
f: proc();
|
f: proc();
|
||||||
f = foo;
|
f = foo; // The correct `foo` to chosen
|
||||||
f();
|
f();
|
||||||
|
|
||||||
|
|
||||||
|
// See math.odin and atomic.odin for more examples
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -100,7 +100,7 @@ type_info_base :: proc(info: ^Type_Info) -> ^Type_Info {
|
|||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
base := info;
|
base := info;
|
||||||
match type i : base {
|
match type i in base {
|
||||||
case Type_Info.Named:
|
case Type_Info.Named:
|
||||||
base = i.base;
|
base = i.base;
|
||||||
}
|
}
|
||||||
|
|||||||
+45
-45
@@ -58,38 +58,38 @@ Fmt_Info :: struct {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
fprint :: proc(fd: os.Handle, args: ...any) -> int {
|
fprint :: proc(fd: os.Handle, args: ..any) -> int {
|
||||||
data: [DEFAULT_BUFFER_SIZE]byte;
|
data: [DEFAULT_BUFFER_SIZE]byte;
|
||||||
buf := Buffer{data[:], 0};
|
buf := Buffer{data[:], 0};
|
||||||
bprint(^buf, ...args);
|
bprint(^buf, ..args);
|
||||||
os.write(fd, buf.data[:buf.length]);
|
os.write(fd, buf.data[:buf.length]);
|
||||||
return buf.length;
|
return buf.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintln :: proc(fd: os.Handle, args: ...any) -> int {
|
fprintln :: proc(fd: os.Handle, args: ..any) -> int {
|
||||||
data: [DEFAULT_BUFFER_SIZE]byte;
|
data: [DEFAULT_BUFFER_SIZE]byte;
|
||||||
buf := Buffer{data[:], 0};
|
buf := Buffer{data[:], 0};
|
||||||
bprintln(^buf, ...args);
|
bprintln(^buf, ..args);
|
||||||
os.write(fd, buf.data[:buf.length]);
|
os.write(fd, buf.data[:buf.length]);
|
||||||
return buf.length;
|
return buf.length;
|
||||||
}
|
}
|
||||||
fprintf :: proc(fd: os.Handle, fmt: string, args: ...any) -> int {
|
fprintf :: proc(fd: os.Handle, fmt: string, args: ..any) -> int {
|
||||||
data: [DEFAULT_BUFFER_SIZE]byte;
|
data: [DEFAULT_BUFFER_SIZE]byte;
|
||||||
buf := Buffer{data[:], 0};
|
buf := Buffer{data[:], 0};
|
||||||
bprintf(^buf, fmt, ...args);
|
bprintf(^buf, fmt, ..args);
|
||||||
os.write(fd, buf.data[:buf.length]);
|
os.write(fd, buf.data[:buf.length]);
|
||||||
return buf.length;
|
return buf.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
print :: proc(args: ...any) -> int {
|
print :: proc(args: ..any) -> int {
|
||||||
return fprint(os.stdout, ...args);
|
return fprint(os.stdout, ..args);
|
||||||
}
|
}
|
||||||
println :: proc(args: ...any) -> int {
|
println :: proc(args: ..any) -> int {
|
||||||
return fprintln(os.stdout, ...args);
|
return fprintln(os.stdout, ..args);
|
||||||
}
|
}
|
||||||
printf :: proc(fmt: string, args: ...any) -> int {
|
printf :: proc(fmt: string, args: ..any) -> int {
|
||||||
return fprintf(os.stdout, fmt, ...args);
|
return fprintf(os.stdout, fmt, ..args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ buffer_write_type :: proc(buf: ^Buffer, ti: ^Type_Info) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
using Type_Info;
|
using Type_Info;
|
||||||
match type info : ti {
|
match type info in ti {
|
||||||
case Named:
|
case Named:
|
||||||
buffer_write_string(buf, info.name);
|
buffer_write_string(buf, info.name);
|
||||||
case Integer:
|
case Integer:
|
||||||
@@ -154,7 +154,7 @@ buffer_write_type :: proc(buf: ^Buffer, ti: ^Type_Info) {
|
|||||||
case Tuple:
|
case Tuple:
|
||||||
count := info.fields.count;
|
count := info.fields.count;
|
||||||
if count != 1 { buffer_write_string(buf, "("); }
|
if count != 1 { buffer_write_string(buf, "("); }
|
||||||
for i : 0..<count {
|
for i in 0..<count {
|
||||||
if i > 0 { buffer_write_string(buf, ", "); }
|
if i > 0 { buffer_write_string(buf, ", "); }
|
||||||
|
|
||||||
f := info.fields[i];
|
f := info.fields[i];
|
||||||
@@ -189,7 +189,7 @@ buffer_write_type :: proc(buf: ^Buffer, ti: ^Type_Info) {
|
|||||||
if info.packed { buffer_write_string(buf, "#packed "); }
|
if info.packed { buffer_write_string(buf, "#packed "); }
|
||||||
if info.ordered { buffer_write_string(buf, "#ordered "); }
|
if info.ordered { buffer_write_string(buf, "#ordered "); }
|
||||||
buffer_write_string(buf, "{");
|
buffer_write_string(buf, "{");
|
||||||
for field, i : info.fields {
|
for field, i in info.fields {
|
||||||
buffer_write_string(buf, field.name);
|
buffer_write_string(buf, field.name);
|
||||||
buffer_write_string(buf, ": ");
|
buffer_write_string(buf, ": ");
|
||||||
buffer_write_type(buf, field.type_info);
|
buffer_write_type(buf, field.type_info);
|
||||||
@@ -199,7 +199,7 @@ buffer_write_type :: proc(buf: ^Buffer, ti: ^Type_Info) {
|
|||||||
|
|
||||||
case Union:
|
case Union:
|
||||||
buffer_write_string(buf, "union {");
|
buffer_write_string(buf, "union {");
|
||||||
for field, i : info.fields {
|
for field, i in info.fields {
|
||||||
buffer_write_string(buf, field.name);
|
buffer_write_string(buf, field.name);
|
||||||
buffer_write_string(buf, ": ");
|
buffer_write_string(buf, ": ");
|
||||||
buffer_write_type(buf, field.type_info);
|
buffer_write_type(buf, field.type_info);
|
||||||
@@ -209,7 +209,7 @@ buffer_write_type :: proc(buf: ^Buffer, ti: ^Type_Info) {
|
|||||||
|
|
||||||
case Raw_Union:
|
case Raw_Union:
|
||||||
buffer_write_string(buf, "raw_union {");
|
buffer_write_string(buf, "raw_union {");
|
||||||
for field, i : info.fields {
|
for field, i in info.fields {
|
||||||
buffer_write_string(buf, field.name);
|
buffer_write_string(buf, field.name);
|
||||||
buffer_write_string(buf, ": ");
|
buffer_write_string(buf, ": ");
|
||||||
buffer_write_type(buf, field.type_info);
|
buffer_write_type(buf, field.type_info);
|
||||||
@@ -225,12 +225,12 @@ buffer_write_type :: proc(buf: ^Buffer, ti: ^Type_Info) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bprint :: proc(buf: ^Buffer, args: ...any) -> int {
|
bprint :: proc(buf: ^Buffer, args: ..any) -> int {
|
||||||
fi: Fmt_Info;
|
fi: Fmt_Info;
|
||||||
fi.buf = buf;
|
fi.buf = buf;
|
||||||
|
|
||||||
prev_string := false;
|
prev_string := false;
|
||||||
for arg, i : args {
|
for arg, i in args {
|
||||||
is_string := arg.data != nil && is_type_string(arg.type_info);
|
is_string := arg.data != nil && is_type_string(arg.type_info);
|
||||||
if i > 0 && !is_string && !prev_string {
|
if i > 0 && !is_string && !prev_string {
|
||||||
buffer_write_byte(buf, ' ');
|
buffer_write_byte(buf, ' ');
|
||||||
@@ -241,11 +241,11 @@ bprint :: proc(buf: ^Buffer, args: ...any) -> int {
|
|||||||
return buf.length;
|
return buf.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
bprintln :: proc(buf: ^Buffer, args: ...any) -> int {
|
bprintln :: proc(buf: ^Buffer, args: ..any) -> int {
|
||||||
fi: Fmt_Info;
|
fi: Fmt_Info;
|
||||||
fi.buf = buf;
|
fi.buf = buf;
|
||||||
|
|
||||||
for arg, i : args {
|
for arg, i in args {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
buffer_write_byte(buf, ' ');
|
buffer_write_byte(buf, ' ');
|
||||||
}
|
}
|
||||||
@@ -262,7 +262,7 @@ is_type_string :: proc(info: ^Type_Info) -> bool {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
match type i : type_info_base(info) {
|
match type i in type_info_base(info) {
|
||||||
case String:
|
case String:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -274,7 +274,7 @@ is_type_integer :: proc(info: ^Type_Info) -> bool {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
match type i : type_info_base(info) {
|
match type i in type_info_base(info) {
|
||||||
case Integer:
|
case Integer:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -286,7 +286,7 @@ is_type_float :: proc(info: ^Type_Info) -> bool {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
match type i : type_info_base(info) {
|
match type i in type_info_base(info) {
|
||||||
case Float:
|
case Float:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -305,7 +305,7 @@ parse_int :: proc(s: string, offset: int) -> (int, int, bool) {
|
|||||||
ok := true;
|
ok := true;
|
||||||
|
|
||||||
i := 0;
|
i := 0;
|
||||||
for o : offset..<s.count {
|
for o in offset..<s.count {
|
||||||
c := cast(rune)s[offset+i];
|
c := cast(rune)s[offset+i];
|
||||||
if !is_digit(c) {
|
if !is_digit(c) {
|
||||||
break;
|
break;
|
||||||
@@ -325,7 +325,7 @@ arg_number :: proc(fi: ^Fmt_Info, arg_index: int, format: string, offset: int, a
|
|||||||
return 0, 1, false;
|
return 0, 1, false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for i : 1..<format.count {
|
for i in 1..<format.count {
|
||||||
if format[i] == ']' {
|
if format[i] == ']' {
|
||||||
width, new_index, ok := parse_int(format, 1);
|
width, new_index, ok := parse_int(format, 1);
|
||||||
if !ok || new_index != i {
|
if !ok || new_index != i {
|
||||||
@@ -358,7 +358,7 @@ int_from_arg :: proc(args: []any, arg_index: int) -> (int, int, bool) {
|
|||||||
if arg_index < args.count {
|
if arg_index < args.count {
|
||||||
arg := args[arg_index];
|
arg := args[arg_index];
|
||||||
arg.type_info = type_info_base(arg.type_info);
|
arg.type_info = type_info_base(arg.type_info);
|
||||||
match type i : arg {
|
match type i in arg {
|
||||||
case int: num = i;
|
case int: num = i;
|
||||||
case i8: num = cast(int)i;
|
case i8: num = cast(int)i;
|
||||||
case i16: num = cast(int)i;
|
case i16: num = cast(int)i;
|
||||||
@@ -413,7 +413,7 @@ fmt_write_padding :: proc(fi: ^Fmt_Info, width: int) {
|
|||||||
|
|
||||||
count := min(width, fi.buf.data.count-fi.buf.length);
|
count := min(width, fi.buf.data.count-fi.buf.length);
|
||||||
start := fi.buf.length;
|
start := fi.buf.length;
|
||||||
for i : start..<count {
|
for i in start..<count {
|
||||||
fi.buf.data[i] = pad_byte;
|
fi.buf.data[i] = pad_byte;
|
||||||
}
|
}
|
||||||
fi.buf.length += count;
|
fi.buf.length += count;
|
||||||
@@ -581,7 +581,7 @@ fmt_float :: proc(fi: ^Fmt_Info, v: f64, bit_size: int, verb: rune) {
|
|||||||
arg := v - cast(f64)val;
|
arg := v - cast(f64)val;
|
||||||
mult: f64 = 10;
|
mult: f64 = 10;
|
||||||
buffer_write_byte(fi.buf, '.');
|
buffer_write_byte(fi.buf, '.');
|
||||||
for _ : 0..<prec {
|
for _ in 0..<prec {
|
||||||
val := cast(u64)(arg*mult);
|
val := cast(u64)(arg*mult);
|
||||||
buffer_write_byte(fi.buf, __DIGITS_LOWER[cast(u64)val]);
|
buffer_write_byte(fi.buf, __DIGITS_LOWER[cast(u64)val]);
|
||||||
arg -= cast(f64)val / mult;
|
arg -= cast(f64)val / mult;
|
||||||
@@ -638,7 +638,7 @@ fmt_enum :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
using Type_Info;
|
using Type_Info;
|
||||||
match type e : v.type_info {
|
match type e in v.type_info {
|
||||||
default:
|
default:
|
||||||
fmt_bad_verb(fi, verb);
|
fmt_bad_verb(fi, verb);
|
||||||
return;
|
return;
|
||||||
@@ -651,7 +651,7 @@ fmt_enum :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
|||||||
f: f64;
|
f: f64;
|
||||||
ok := false;
|
ok := false;
|
||||||
a := any{type_info_base(e.base), v.data};
|
a := any{type_info_base(e.base), v.data};
|
||||||
match type v : a {
|
match type v in a {
|
||||||
case i8: i = cast(i64)v;
|
case i8: i = cast(i64)v;
|
||||||
case i16: i = cast(i64)v;
|
case i16: i = cast(i64)v;
|
||||||
case i32: i = cast(i64)v;
|
case i32: i = cast(i64)v;
|
||||||
@@ -667,7 +667,7 @@ fmt_enum :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if is_type_integer(e.base) {
|
if is_type_integer(e.base) {
|
||||||
for it, idx : e.values {
|
for it, idx in e.values {
|
||||||
if it.i == i {
|
if it.i == i {
|
||||||
buffer_write_string(fi.buf, e.names[idx]);
|
buffer_write_string(fi.buf, e.names[idx]);
|
||||||
ok = true;
|
ok = true;
|
||||||
@@ -675,7 +675,7 @@ fmt_enum :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for it, idx : e.values {
|
for it, idx in e.values {
|
||||||
if it.f == f {
|
if it.f == f {
|
||||||
buffer_write_string(fi.buf, e.names[idx]);
|
buffer_write_string(fi.buf, e.names[idx]);
|
||||||
ok = true;
|
ok = true;
|
||||||
@@ -702,9 +702,9 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
using Type_Info;
|
using Type_Info;
|
||||||
match type info : v.type_info {
|
match type info in v.type_info {
|
||||||
case Named:
|
case Named:
|
||||||
match type b : info.base {
|
match type b in info.base {
|
||||||
case Struct:
|
case Struct:
|
||||||
if verb != 'v' {
|
if verb != 'v' {
|
||||||
fmt_bad_verb(fi, verb);
|
fmt_bad_verb(fi, verb);
|
||||||
@@ -712,7 +712,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
|||||||
}
|
}
|
||||||
buffer_write_string(fi.buf, info.name);
|
buffer_write_string(fi.buf, info.name);
|
||||||
buffer_write_byte(fi.buf, '{');
|
buffer_write_byte(fi.buf, '{');
|
||||||
for f, i : b.fields {
|
for f, i in b.fields {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
buffer_write_string(fi.buf, ", ");
|
buffer_write_string(fi.buf, ", ");
|
||||||
}
|
}
|
||||||
@@ -757,7 +757,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
|||||||
|
|
||||||
buffer_write_byte(fi.buf, '[');
|
buffer_write_byte(fi.buf, '[');
|
||||||
defer buffer_write_byte(fi.buf, ']');
|
defer buffer_write_byte(fi.buf, ']');
|
||||||
for i : 0..<info.count {
|
for i in 0..<info.count {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
buffer_write_string(fi.buf, ", ");
|
buffer_write_string(fi.buf, ", ");
|
||||||
}
|
}
|
||||||
@@ -774,7 +774,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
|||||||
buffer_write_byte(fi.buf, '[');
|
buffer_write_byte(fi.buf, '[');
|
||||||
defer buffer_write_byte(fi.buf, ']');
|
defer buffer_write_byte(fi.buf, ']');
|
||||||
slice := cast(^[]byte)v.data;
|
slice := cast(^[]byte)v.data;
|
||||||
for i : 0..<slice.count {
|
for i in 0..<slice.count {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
buffer_write_string(fi.buf, ", ");
|
buffer_write_string(fi.buf, ", ");
|
||||||
}
|
}
|
||||||
@@ -784,7 +784,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
|||||||
|
|
||||||
case Vector:
|
case Vector:
|
||||||
is_bool :: proc(type_info: ^Type_Info) -> bool {
|
is_bool :: proc(type_info: ^Type_Info) -> bool {
|
||||||
match type info : type_info {
|
match type info in type_info {
|
||||||
case Named:
|
case Named:
|
||||||
return is_bool(info.base);
|
return is_bool(info.base);
|
||||||
case Boolean:
|
case Boolean:
|
||||||
@@ -800,7 +800,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for i : 0..<info.count {
|
for i in 0..<info.count {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
buffer_write_string(fi.buf, ", ");
|
buffer_write_string(fi.buf, ", ");
|
||||||
}
|
}
|
||||||
@@ -813,7 +813,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
|||||||
buffer_write_byte(fi.buf, '{');
|
buffer_write_byte(fi.buf, '{');
|
||||||
defer buffer_write_byte(fi.buf, '}');
|
defer buffer_write_byte(fi.buf, '}');
|
||||||
|
|
||||||
for f, i : info.fields {
|
for f, i in info.fields {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
buffer_write_string(fi.buf, ", ");
|
buffer_write_string(fi.buf, ", ");
|
||||||
}
|
}
|
||||||
@@ -848,7 +848,7 @@ fmt_arg :: proc(fi: ^Fmt_Info, arg: any, verb: rune) {
|
|||||||
|
|
||||||
if verb == 'T' {
|
if verb == 'T' {
|
||||||
ti := arg.type_info;
|
ti := arg.type_info;
|
||||||
match type a : arg {
|
match type a in arg {
|
||||||
case ^Type_Info: ti = a;
|
case ^Type_Info: ti = a;
|
||||||
}
|
}
|
||||||
buffer_write_type(fi.buf, ti);
|
buffer_write_type(fi.buf, ti);
|
||||||
@@ -858,7 +858,7 @@ fmt_arg :: proc(fi: ^Fmt_Info, arg: any, verb: rune) {
|
|||||||
|
|
||||||
base_arg := arg;
|
base_arg := arg;
|
||||||
base_arg.type_info = type_info_base(base_arg.type_info);
|
base_arg.type_info = type_info_base(base_arg.type_info);
|
||||||
match type a : base_arg {
|
match type a in base_arg {
|
||||||
case bool: fmt_bool(fi, a, verb);
|
case bool: fmt_bool(fi, a, verb);
|
||||||
case f32: fmt_float(fi, cast(f64)a, 32, verb);
|
case f32: fmt_float(fi, cast(f64)a, 32, verb);
|
||||||
case f64: fmt_float(fi, a, 64, verb);
|
case f64: fmt_float(fi, a, 64, verb);
|
||||||
@@ -880,7 +880,7 @@ fmt_arg :: proc(fi: ^Fmt_Info, arg: any, verb: rune) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bprintf :: proc(b: ^Buffer, fmt: string, args: ...any) -> int {
|
bprintf :: proc(b: ^Buffer, fmt: string, args: ..any) -> int {
|
||||||
fi := Fmt_Info{};
|
fi := Fmt_Info{};
|
||||||
end := fmt.count;
|
end := fmt.count;
|
||||||
arg_index := 0;
|
arg_index := 0;
|
||||||
@@ -1004,7 +1004,7 @@ bprintf :: proc(b: ^Buffer, fmt: string, args: ...any) -> int {
|
|||||||
|
|
||||||
if !fi.reordered && arg_index < args.count {
|
if !fi.reordered && arg_index < args.count {
|
||||||
buffer_write_string(b, "%!(EXTRA ");
|
buffer_write_string(b, "%!(EXTRA ");
|
||||||
for arg, index : args[arg_index:] {
|
for arg, index in args[arg_index:] {
|
||||||
if index > 0 {
|
if index > 0 {
|
||||||
buffer_write_string(b, ", ");
|
buffer_write_string(b, ", ");
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-7
@@ -1,7 +1,7 @@
|
|||||||
crc32 :: proc(data: rawptr, len: int) -> u32 {
|
crc32 :: proc(data: rawptr, len: int) -> u32 {
|
||||||
result := ~cast(u32)0;
|
result := ~cast(u32)0;
|
||||||
s := slice_ptr(cast(^u8)data, len);
|
s := slice_ptr(cast(^u8)data, len);
|
||||||
for i : 0..<len {
|
for i in 0..<len {
|
||||||
b := cast(u32)s[i];
|
b := cast(u32)s[i];
|
||||||
result = result>>8 ~ __CRC32_TABLE[(result ~ b) & 0xff];
|
result = result>>8 ~ __CRC32_TABLE[(result ~ b) & 0xff];
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,7 @@ crc32 :: proc(data: rawptr, len: int) -> u32 {
|
|||||||
crc64 :: proc(data: rawptr, len: int) -> u64 {
|
crc64 :: proc(data: rawptr, len: int) -> u64 {
|
||||||
result := ~cast(u64)0;
|
result := ~cast(u64)0;
|
||||||
s := slice_ptr(cast(^u8)data, len);
|
s := slice_ptr(cast(^u8)data, len);
|
||||||
for i : 0..<len {
|
for i in 0..<len {
|
||||||
b := cast(u64)s[i];
|
b := cast(u64)s[i];
|
||||||
result = result>>8 ~ __CRC64_TABLE[(result ~ b) & 0xff];
|
result = result>>8 ~ __CRC64_TABLE[(result ~ b) & 0xff];
|
||||||
}
|
}
|
||||||
@@ -21,7 +21,7 @@ fnv32 :: proc(data: rawptr, len: int) -> u32 {
|
|||||||
s := slice_ptr(cast(^u8)data, len);
|
s := slice_ptr(cast(^u8)data, len);
|
||||||
|
|
||||||
h: u32 = 0x811c9dc5;
|
h: u32 = 0x811c9dc5;
|
||||||
for i : 0..<len {
|
for i in 0..<len {
|
||||||
h = (h * 0x01000193) ~ cast(u32)s[i];
|
h = (h * 0x01000193) ~ cast(u32)s[i];
|
||||||
}
|
}
|
||||||
return h;
|
return h;
|
||||||
@@ -31,7 +31,7 @@ fnv64 :: proc(data: rawptr, len: int) -> u64 {
|
|||||||
s := slice_ptr(cast(^u8)data, len);
|
s := slice_ptr(cast(^u8)data, len);
|
||||||
|
|
||||||
h: u64 = 0xcbf29ce484222325;
|
h: u64 = 0xcbf29ce484222325;
|
||||||
for i : 0..<len {
|
for i in 0..<len {
|
||||||
h = (h * 0x100000001b3) ~ cast(u64)s[i];
|
h = (h * 0x100000001b3) ~ cast(u64)s[i];
|
||||||
}
|
}
|
||||||
return h;
|
return h;
|
||||||
@@ -41,7 +41,7 @@ fnv32a :: proc(data: rawptr, len: int) -> u32 {
|
|||||||
s := slice_ptr(cast(^u8)data, len);
|
s := slice_ptr(cast(^u8)data, len);
|
||||||
|
|
||||||
h: u32 = 0x811c9dc5;
|
h: u32 = 0x811c9dc5;
|
||||||
for i : 0..<len {
|
for i in 0..<len {
|
||||||
h = (h ~ cast(u32)s[i]) * 0x01000193;
|
h = (h ~ cast(u32)s[i]) * 0x01000193;
|
||||||
}
|
}
|
||||||
return h;
|
return h;
|
||||||
@@ -51,7 +51,7 @@ fnv64a :: proc(data: rawptr, len: int) -> u64 {
|
|||||||
s := slice_ptr(cast(^u8)data, len);
|
s := slice_ptr(cast(^u8)data, len);
|
||||||
|
|
||||||
h :u64 = 0xcbf29ce484222325;
|
h :u64 = 0xcbf29ce484222325;
|
||||||
for i : 0..<len {
|
for i in 0..<len {
|
||||||
h = (h ~ cast(u64)s[i]) * 0x100000001b3;
|
h = (h ~ cast(u64)s[i]) * 0x100000001b3;
|
||||||
}
|
}
|
||||||
return h;
|
return h;
|
||||||
@@ -70,7 +70,7 @@ murmur64 :: proc(data_: rawptr, len: int) -> u64 {
|
|||||||
data := slice_ptr(cast(^u64)data_, len/size_of(u64));
|
data := slice_ptr(cast(^u64)data_, len/size_of(u64));
|
||||||
data2 := slice_ptr(cast(^u8)data_, len);
|
data2 := slice_ptr(cast(^u8)data_, len);
|
||||||
|
|
||||||
for i : 0 ..< data.count {
|
for i in 0 ..< data.count {
|
||||||
k := data[i];
|
k := data[i];
|
||||||
|
|
||||||
k *= m;
|
k *= m;
|
||||||
|
|||||||
+4
-4
@@ -155,8 +155,8 @@ mat4_identity :: proc() -> Mat4 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mat4_transpose :: proc(m: Mat4) -> Mat4 {
|
mat4_transpose :: proc(m: Mat4) -> Mat4 {
|
||||||
for j : 0..<4 {
|
for j in 0..<4 {
|
||||||
for i : 0..<4 {
|
for i in 0..<4 {
|
||||||
m[i][j], m[j][i] = m[j][i], m[i][j];
|
m[i][j], m[j][i] = m[j][i], m[i][j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -165,8 +165,8 @@ mat4_transpose :: proc(m: Mat4) -> Mat4 {
|
|||||||
|
|
||||||
mul :: proc(a, b: Mat4) -> Mat4 {
|
mul :: proc(a, b: Mat4) -> Mat4 {
|
||||||
c: Mat4;
|
c: Mat4;
|
||||||
for j : 0..<4 {
|
for j in 0..<4 {
|
||||||
for i : 0..<4 {
|
for i in 0..<4 {
|
||||||
c[j][i] = a[0][i]*b[j][0] +
|
c[j][i] = a[0][i]*b[j][0] +
|
||||||
a[1][i]*b[j][1] +
|
a[1][i]*b[j][1] +
|
||||||
a[2][i]*b[j][2] +
|
a[2][i]*b[j][2] +
|
||||||
|
|||||||
+4
-4
@@ -28,7 +28,7 @@ copy_non_overlapping :: proc(dst, src: rawptr, len: int) -> rawptr #link_name "_
|
|||||||
compare :: proc(dst, src: rawptr, n: int) -> int #link_name "__mem_compare" {
|
compare :: proc(dst, src: rawptr, n: int) -> int #link_name "__mem_compare" {
|
||||||
a := slice_ptr(cast(^byte)dst, n);
|
a := slice_ptr(cast(^byte)dst, n);
|
||||||
b := slice_ptr(cast(^byte)src, n);
|
b := slice_ptr(cast(^byte)src, n);
|
||||||
for i : 0..<n {
|
for i in 0..<n {
|
||||||
match {
|
match {
|
||||||
case a[i] < b[i]:
|
case a[i] < b[i]:
|
||||||
return -1;
|
return -1;
|
||||||
@@ -212,7 +212,7 @@ align_of_type_info :: proc(type_info: ^Type_Info) -> int {
|
|||||||
MAX_ALIGN :: size_of([vector 64]f64); // TODO(bill): Should these constants be builtin constants?
|
MAX_ALIGN :: size_of([vector 64]f64); // TODO(bill): Should these constants be builtin constants?
|
||||||
using Type_Info;
|
using Type_Info;
|
||||||
|
|
||||||
match type info : type_info {
|
match type info in type_info {
|
||||||
case Named:
|
case Named:
|
||||||
return align_of_type_info(info.base);
|
return align_of_type_info(info.base);
|
||||||
case Integer:
|
case Integer:
|
||||||
@@ -257,7 +257,7 @@ align_formula :: proc(size, align: int) -> int {
|
|||||||
size_of_type_info :: proc(type_info: ^Type_Info) -> int {
|
size_of_type_info :: proc(type_info: ^Type_Info) -> int {
|
||||||
WORD_SIZE :: size_of(int);
|
WORD_SIZE :: size_of(int);
|
||||||
using Type_Info;
|
using Type_Info;
|
||||||
match type info : type_info {
|
match type info in type_info {
|
||||||
case Named:
|
case Named:
|
||||||
return size_of_type_info(info.base);
|
return size_of_type_info(info.base);
|
||||||
case Integer:
|
case Integer:
|
||||||
@@ -289,7 +289,7 @@ size_of_type_info :: proc(type_info: ^Type_Info) -> int {
|
|||||||
return 3*WORD_SIZE;
|
return 3*WORD_SIZE;
|
||||||
case Vector:
|
case Vector:
|
||||||
is_bool :: proc(type_info: ^Type_Info) -> bool {
|
is_bool :: proc(type_info: ^Type_Info) -> bool {
|
||||||
match type info : type_info {
|
match type info in type_info {
|
||||||
case Named:
|
case Named:
|
||||||
return is_bool(info.base);
|
return is_bool(info.base);
|
||||||
case Boolean:
|
case Boolean:
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ void check_init_variables(Checker *c, Entity **lhs, isize lhs_count, AstNodeArra
|
|||||||
Array(Operand) operands;
|
Array(Operand) operands;
|
||||||
array_init_reserve(&operands, c->tmp_allocator, 2*lhs_count);
|
array_init_reserve(&operands, c->tmp_allocator, 2*lhs_count);
|
||||||
|
|
||||||
|
// TODO(bill): Allow for type hints from the entities
|
||||||
for_array(i, inits) {
|
for_array(i, inits) {
|
||||||
AstNode *rhs = inits.e[i];
|
AstNode *rhs = inits.e[i];
|
||||||
Operand o = {0};
|
Operand o = {0};
|
||||||
|
|||||||
+5
-3
@@ -4071,19 +4071,21 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
|
|||||||
error_node(ie->cond, "Non-boolean condition in if expression");
|
error_node(ie->cond, "Non-boolean condition in if expression");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Operand x = {Addressing_Invalid};
|
Operand x = {Addressing_Invalid};
|
||||||
Operand y = {Addressing_Invalid};
|
Operand y = {Addressing_Invalid};
|
||||||
Type *if_type = NULL;
|
Type *if_type = NULL;
|
||||||
Type *else_type = NULL;
|
Type *else_type = NULL;
|
||||||
check_expr(c, &x, ie->body);
|
if (type_hint) {
|
||||||
|
gb_printf_err("here\n");
|
||||||
|
}
|
||||||
|
check_expr_with_type_hint(c, &x, ie->body, type_hint);
|
||||||
if_type = x.type;
|
if_type = x.type;
|
||||||
|
|
||||||
if (ie->else_expr != NULL) {
|
if (ie->else_expr != NULL) {
|
||||||
switch (ie->else_expr->kind) {
|
switch (ie->else_expr->kind) {
|
||||||
case AstNode_IfExpr:
|
case AstNode_IfExpr:
|
||||||
case AstNode_BlockExpr:
|
case AstNode_BlockExpr:
|
||||||
check_expr(c, &y, ie->else_expr);
|
check_expr_with_type_hint(c, &y, ie->else_expr, if_type);
|
||||||
else_type = y.type;
|
else_type = y.type;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
+2
-2
@@ -2944,7 +2944,7 @@ AstNode *parse_for_stmt(AstFile *f) {
|
|||||||
Token token = expect_token(f, Token_for);
|
Token token = expect_token(f, Token_for);
|
||||||
AstNodeArray names = parse_ident_list(f);
|
AstNodeArray names = parse_ident_list(f);
|
||||||
parse_check_name_list_for_reserves(f, names);
|
parse_check_name_list_for_reserves(f, names);
|
||||||
Token colon = expect_token_after(f, Token_Colon, "for name list");
|
Token colon = expect_token_after(f, Token_in, "for name list");
|
||||||
|
|
||||||
isize prev_level = f->expr_level;
|
isize prev_level = f->expr_level;
|
||||||
f->expr_level = -1;
|
f->expr_level = -1;
|
||||||
@@ -3029,7 +3029,7 @@ AstNode *parse_match_stmt(AstFile *f) {
|
|||||||
f->expr_level = -1;
|
f->expr_level = -1;
|
||||||
|
|
||||||
AstNode *var = parse_identifier(f);
|
AstNode *var = parse_identifier(f);
|
||||||
expect_token(f, Token_Colon);
|
expect_token_after(f, Token_in, "match type name");
|
||||||
tag = parse_simple_stmt(f);
|
tag = parse_simple_stmt(f);
|
||||||
|
|
||||||
f->expr_level = prev_level;
|
f->expr_level = prev_level;
|
||||||
|
|||||||
+5
-8
@@ -75,7 +75,7 @@ TOKEN_KIND(Token__ComparisonEnd, "_ComparisonEnd"), \
|
|||||||
TOKEN_KIND(Token_Semicolon, ";"), \
|
TOKEN_KIND(Token_Semicolon, ";"), \
|
||||||
TOKEN_KIND(Token_Period, "."), \
|
TOKEN_KIND(Token_Period, "."), \
|
||||||
TOKEN_KIND(Token_Comma, ","), \
|
TOKEN_KIND(Token_Comma, ","), \
|
||||||
TOKEN_KIND(Token_Ellipsis, "..."), \
|
TOKEN_KIND(Token_Ellipsis, ".."), \
|
||||||
TOKEN_KIND(Token_HalfOpenRange, "..<"), \
|
TOKEN_KIND(Token_HalfOpenRange, "..<"), \
|
||||||
TOKEN_KIND(Token__OperatorEnd, "_OperatorEnd"), \
|
TOKEN_KIND(Token__OperatorEnd, "_OperatorEnd"), \
|
||||||
\
|
\
|
||||||
@@ -94,6 +94,7 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \
|
|||||||
TOKEN_KIND(Token_else, "else"), \
|
TOKEN_KIND(Token_else, "else"), \
|
||||||
TOKEN_KIND(Token_while, "while"), \
|
TOKEN_KIND(Token_while, "while"), \
|
||||||
TOKEN_KIND(Token_for, "for"), \
|
TOKEN_KIND(Token_for, "for"), \
|
||||||
|
TOKEN_KIND(Token_in, "in"), \
|
||||||
TOKEN_KIND(Token_when, "when"), \
|
TOKEN_KIND(Token_when, "when"), \
|
||||||
TOKEN_KIND(Token_range, "range"), \
|
TOKEN_KIND(Token_range, "range"), \
|
||||||
TOKEN_KIND(Token_defer, "defer"), \
|
TOKEN_KIND(Token_defer, "defer"), \
|
||||||
@@ -845,14 +846,10 @@ Token tokenizer_get_token(Tokenizer *t) {
|
|||||||
|
|
||||||
case '.':
|
case '.':
|
||||||
token.kind = Token_Period; // Default
|
token.kind = Token_Period; // Default
|
||||||
/* if (gb_is_between(t->curr_rune, '0', '9')) { // Might be a number
|
if (t->curr_rune == '.') { // Could be an ellipsis
|
||||||
token = scan_number_to_token(t, true);
|
|
||||||
} else */ if (t->curr_rune == '.') { // Could be an ellipsis
|
|
||||||
advance_to_next_rune(t);
|
advance_to_next_rune(t);
|
||||||
if (t->curr_rune == '.') {
|
token.kind = Token_Ellipsis;
|
||||||
advance_to_next_rune(t);
|
if (t->curr_rune == '<') {
|
||||||
token.kind = Token_Ellipsis;
|
|
||||||
} else if (t->curr_rune == '<') {
|
|
||||||
advance_to_next_rune(t);
|
advance_to_next_rune(t);
|
||||||
token.kind = Token_HalfOpenRange;
|
token.kind = Token_HalfOpenRange;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user