Begin transition to Jai-like syntax

This commit is contained in:
Ginger Bill
2017-01-01 19:08:03 +00:00
parent 3f1195cd03
commit a48e0c7179
20 changed files with 2348 additions and 2365 deletions
+5 -2
View File
@@ -11,7 +11,7 @@ import {
win32 "sys/windows.odin";
}
const Thing = enum f64 {
Thing :: enum f64 {
_, // Ignore first value
A = 1<<(10*iota),
B,
@@ -19,6 +19,9 @@ const Thing = enum f64 {
D,
};
const main = proc() {
main :: proc() {
fmt.println(Thing.A, Thing.B, Thing.C, Thing.D);
x := 123;
fmt.println(x);
}
+15 -15
View File
@@ -83,7 +83,7 @@ proc type_info_base(info ^Type_Info) -> ^Type_Info {
if info == nil {
return nil;
}
var base = info;
base := info;
match type i : base {
case Type_Info.Named:
base = i.base;
@@ -140,14 +140,14 @@ type {
}
}
#thread_local var __context Context;
#thread_local __context: Context;
const DEFAULT_ALIGNMENT = align_of([vector 4]f32);
DEFAULT_ALIGNMENT :: align_of([vector 4]f32);
proc __check_context() {
var c = ^__context;
c := ^__context;
if c.allocator.procedure == nil {
c.allocator = default_allocator();
@@ -161,20 +161,20 @@ proc alloc(size int) -> rawptr #inline { return alloc_align(size, DEFAULT_ALIGNM
proc alloc_align(size, alignment int) -> rawptr #inline {
__check_context();
var a = context.allocator;
a := context.allocator;
return a.procedure(a.data, Allocator_Mode.ALLOC, size, alignment, nil, 0, 0);
}
proc free(ptr rawptr) #inline {
__check_context();
var a = context.allocator;
a := context.allocator;
if ptr != nil {
a.procedure(a.data, Allocator_Mode.FREE, 0, 0, ptr, 0, 0);
}
}
proc free_all() #inline {
__check_context();
var a = context.allocator;
a := context.allocator;
a.procedure(a.data, Allocator_Mode.FREE_ALL, 0, 0, nil, 0, 0);
}
@@ -182,7 +182,7 @@ proc free_all() #inline {
proc resize (ptr rawptr, old_size, new_size int) -> rawptr #inline { return resize_align(ptr, old_size, new_size, DEFAULT_ALIGNMENT); }
proc resize_align(ptr rawptr, old_size, new_size, alignment int) -> rawptr #inline {
__check_context();
var a = context.allocator;
a := context.allocator;
return a.procedure(a.data, Allocator_Mode.RESIZE, new_size, alignment, ptr, old_size, 0);
}
@@ -202,7 +202,7 @@ proc default_resize_align(old_memory rawptr, old_size, new_size, alignment int)
return old_memory;
}
var new_memory = alloc_align(new_size, alignment);
new_memory := alloc_align(new_size, alignment);
if new_memory == nil {
return nil;
}
@@ -221,9 +221,9 @@ proc default_allocator_proc(allocator_data rawptr, mode Allocator_Mode,
when false {
match mode {
case ALLOC:
var total_size = size + alignment + size_of(mem.AllocationHeader);
var ptr = os.heap_alloc(total_size);
var header = ptr as ^mem.AllocationHeader;
total_size := size + alignment + size_of(mem.AllocationHeader);
ptr := os.heap_alloc(total_size);
header := ptr as ^mem.AllocationHeader;
ptr = mem.align_forward(header+1, alignment);
mem.allocation_header_fill(header, ptr, size);
return mem.zero(ptr, size);
@@ -236,9 +236,9 @@ proc default_allocator_proc(allocator_data rawptr, mode Allocator_Mode,
// NOTE(bill): Does nothing
case RESIZE:
var total_size = size + alignment + size_of(mem.AllocationHeader);
var ptr = os.heap_resize(mem.allocation_header(old_memory), total_size);
var header = ptr as ^mem.AllocationHeader;
total_size := size + alignment + size_of(mem.AllocationHeader);
ptr := os.heap_resize(mem.allocation_header(old_memory), total_size);
header := ptr as ^mem.AllocationHeader;
ptr = mem.align_forward(header+1, alignment);
mem.allocation_header_fill(header, ptr, size);
return mem.zero(ptr, size);
+7 -7
View File
@@ -2,7 +2,7 @@
// Inline vs external file?
import win32 "sys/windows.odin" when ODIN_OS == "windows";
var _ = compile_assert(ODIN_ARCH == "amd64"); // TODO(bill): x86 version
_ := compile_assert(ODIN_ARCH == "amd64"); // TODO(bill): x86 version
proc yield_thread() { win32._mm_pause(); }
@@ -35,8 +35,8 @@ proc fetch_or32(a ^i32, operand i32) -> i32 {
return win32.InterlockedOr(a, operand);
}
proc spin_lock32(a ^i32, time_out int) -> bool { // NOTE(bill) time_out = -1 as default
var old_value = compare_exchange32(a, 1, 0);
var counter = 0;
old_value := compare_exchange32(a, 1, 0);
counter := 0;
for old_value != 0 && (time_out < 0 || counter < time_out) {
counter++;
yield_thread();
@@ -51,7 +51,7 @@ proc spin_unlock32(a ^i32) {
}
proc try_acquire_lock32(a ^i32) -> bool {
yield_thread();
var old_value = compare_exchange32(a, 1, 0);
old_value := compare_exchange32(a, 1, 0);
mfence();
return old_value == 0;
}
@@ -79,8 +79,8 @@ proc fetch_or64(a ^i64, operand i64) -> i64 {
return win32.InterlockedOr64(a, operand);
}
proc spin_lock64(a ^i64, time_out int) -> bool { // NOTE(bill) time_out = -1 as default
var old_value = compare_exchange64(a, 1, 0);
var counter = 0;
old_value := compare_exchange64(a, 1, 0);
counter := 0;
for old_value != 0 && (time_out < 0 || counter < time_out) {
counter++;
yield_thread();
@@ -95,7 +95,7 @@ proc spin_unlock64(a ^i64) {
}
proc try_acquire_lock64(a ^i64) -> bool {
yield_thread();
var old_value = compare_exchange64(a, 1, 0);
old_value := compare_exchange64(a, 1, 0);
mfence();
return old_value == 0;
}
+60 -60
View File
@@ -4,26 +4,26 @@ import {
"utf8.odin";
}
const PRINT_BUF_SIZE = 1<<12;
PRINT_BUF_SIZE :: 1<<12;
proc fprint(fd os.Handle, args ..any) -> int {
var data [PRINT_BUF_SIZE]byte;
var buf = data[:0];
data :[PRINT_BUF_SIZE]byte;
buf := data[:0];
bprint(^buf, ..args);
os.write(fd, buf);
return buf.count;
}
proc fprintln(fd os.Handle, args ..any) -> int {
var data [PRINT_BUF_SIZE]byte;
var buf = data[:0];
data :[PRINT_BUF_SIZE]byte;
buf := data[:0];
bprintln(^buf, ..args);
os.write(fd, buf);
return buf.count;
}
proc fprintf(fd os.Handle, fmt string, args ..any) -> int {
var data [PRINT_BUF_SIZE]byte;
var buf = data[:0];
data :[PRINT_BUF_SIZE]byte;
buf := data[:0];
bprintf(^buf, fmt, ..args);
os.write(fd, buf);
return buf.count;
@@ -43,8 +43,8 @@ proc printf(fmt string, args ..any) -> int {
proc fprint_type(fd os.Handle, info ^Type_Info) {
var data [PRINT_BUF_SIZE]byte;
var buf = data[:0];
data :[PRINT_BUF_SIZE]byte;
buf := data[:0];
bprint_type(^buf, info);
os.write(fd, buf);
}
@@ -53,7 +53,7 @@ proc fprint_type(fd os.Handle, info ^Type_Info) {
proc print_byte_buffer(buf ^[]byte, b []byte) {
if buf.count < buf.capacity {
var n = min(buf.capacity-buf.count, b.count);
n := min(buf.capacity-buf.count, b.count);
if n > 0 {
mem.copy(buf.data + buf.count, b.data, n);
buf.count += n;
@@ -67,21 +67,21 @@ proc bprint_string(buf ^[]byte, s string) {
proc byte_reverse(b []byte) {
var n = b.count;
for var i = 0; i < n/2; i++ {
n := b.count;
for i := 0; i < n/2; i++ {
b[i], b[n-1-i] = b[n-1-i], b[i];
}
}
proc bprint_rune(buf ^[]byte, r rune) {
var b, n = utf8.encode_rune(r);
b, n := utf8.encode_rune(r);
bprint_string(buf, b[:n] as string);
}
proc bprint_space(buf ^[]byte) { bprint_rune(buf, ' '); }
proc bprint_nl (buf ^[]byte) { bprint_rune(buf, '\n'); }
var __NUM_TO_CHAR_TABLE = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz@$";
__NUM_TO_CHAR_TABLE := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz@$";
proc bprint_bool(buffer ^[]byte, b bool) {
if b {
@@ -100,9 +100,9 @@ proc bprint_f16 (buffer ^[]byte, f f32) #inline { print__f64(buffer, f as f64,
proc bprint_f32 (buffer ^[]byte, f f32) #inline { print__f64(buffer, f as f64, 7); }
proc bprint_f64 (buffer ^[]byte, f f64) #inline { print__f64(buffer, f as f64, 16); }
proc bprint_u64(buffer ^[]byte, value u64) {
var i = value;
var buf [20]byte;
var len = 0;
i := value;
buf :[20]byte;
len := 0;
if i == 0 {
buf[len] = '0';
len++;
@@ -117,7 +117,7 @@ proc bprint_u64(buffer ^[]byte, value u64) {
}
proc bprint_i64(buffer ^[]byte, value i64) {
// TODO(bill): Cleanup printing
var i = value;
i := value;
if i < 0 {
i = -i;
bprint_rune(buffer, '-');
@@ -127,14 +127,14 @@ proc bprint_i64(buffer ^[]byte, value i64) {
/*
proc bprint_u128(buffer ^[]byte, value u128) {
var a = value transmute [2]u64;
a := value transmute [2]u64;
if a[1] != 0 {
bprint_u64(buffer, a[1]);
}
bprint_u64(buffer, a[0]);
}
proc bprint_i128(buffer ^[]byte, value i128) {
var i = value;
i := value;
if i < 0 {
i = -i;
bprint_rune(buffer, '-');
@@ -145,7 +145,7 @@ proc bprint_i128(buffer ^[]byte, value i128) {
proc print__f64(buffer ^[]byte, value f64, decimal_places int) {
var f = value;
f := value;
if f == 0 {
bprint_rune(buffer, '0');
return;
@@ -155,13 +155,13 @@ proc print__f64(buffer ^[]byte, value f64, decimal_places int) {
f = -f;
}
var i = f as u64;
i := f as u64;
bprint_u64(buffer, i);
f -= i as f64;
bprint_rune(buffer, '.');
var mult f64 = 10.0;
mult :f64 = 10.0;
for ; decimal_places >= 0; decimal_places-- {
i = (f * mult) as u64;
bprint_u64(buffer, i as u64);
@@ -214,7 +214,7 @@ proc bprint_type(buf ^[]byte, ti ^Type_Info) {
if info.params == nil {
bprint_string(buf, "()");
} else {
var count = (info.params as ^Tuple).fields.count;
count := (info.params as ^Tuple).fields.count;
if count == 1 { bprint_string(buf, "("); }
bprint_type(buf, info.params);
if count == 1 { bprint_string(buf, ")"); }
@@ -224,12 +224,12 @@ proc bprint_type(buf ^[]byte, ti ^Type_Info) {
bprint_type(buf, info.results);
}
case Tuple:
var count = info.fields.count;
count := info.fields.count;
if count != 1 { bprint_string(buf, "("); }
for var i = 0; i < count; i++ {
for i := 0; i < count; i++ {
if i > 0 { bprint_string(buf, ", "); }
var f = info.fields[i];
f := info.fields[i];
if f.name.count > 0 {
bprint_string(buf, f.name);
@@ -259,7 +259,7 @@ proc bprint_type(buf ^[]byte, ti ^Type_Info) {
if info.packed { bprint_string(buf, "#packed "); }
if info.ordered { bprint_string(buf, "#ordered "); }
bprint_string(buf, "{");
for var i = 0; i < info.fields.count; i++ {
for i := 0; i < info.fields.count; i++ {
if i > 0 {
bprint_string(buf, ", ");
}
@@ -271,7 +271,7 @@ proc bprint_type(buf ^[]byte, ti ^Type_Info) {
case Union:
bprint_string(buf, "union {");
for var i = 0; i < info.fields.count; i++ {
for i := 0; i < info.fields.count; i++ {
if i > 0 {
bprint_string(buf, ", ");
}
@@ -283,7 +283,7 @@ proc bprint_type(buf ^[]byte, ti ^Type_Info) {
case Raw_Union:
bprint_string(buf, "raw_union {");
for var i = 0; i < info.fields.count; i++ {
for i := 0; i < info.fields.count; i++ {
if i > 0 {
bprint_string(buf, ", ");
}
@@ -303,7 +303,7 @@ proc bprint_type(buf ^[]byte, ti ^Type_Info) {
proc make_any(type_info ^Type_Info, data rawptr) -> any {
var a any;
a :any;
a.type_info = type_info;
a.data = data;
return a;
@@ -323,20 +323,20 @@ proc bprint_any(buf ^[]byte, arg any) {
using Type_Info;
match type info : arg.type_info {
case Named:
var a = make_any(info.base, arg.data);
a := make_any(info.base, arg.data);
match type b : info.base {
case Struct:
bprint_string(buf, info.name);
bprint_string(buf, "{");
for var i = 0; i < b.fields.count; i++ {
var f = b.fields[i];
for i := 0; i < b.fields.count; i++ {
f := b.fields[i];
if i > 0 {
bprint_string(buf, ", ");
}
bprint_string(buf, f.name);
// bprint_any(buf, f.offset);
bprint_string(buf, " = ");
var data = arg.data as ^byte + f.offset;
data := arg.data as ^byte + f.offset;
bprint_any(buf, make_any(f.type_info, data));
}
bprint_string(buf, "}");
@@ -387,8 +387,8 @@ proc bprint_any(buf ^[]byte, arg any) {
}
case Maybe:
var size = mem.size_of_type_info(info.elem);
var data = slice_ptr(arg.data as ^byte, size+1);
size := mem.size_of_type_info(info.elem);
data := slice_ptr(arg.data as ^byte, size+1);
if data[size] != 0 {
bprint_any(buf, make_any(info.elem, arg.data));
} else {
@@ -399,26 +399,26 @@ proc bprint_any(buf ^[]byte, arg any) {
bprintf(buf, "[%]%{", info.count, info.elem);
defer bprint_string(buf, "}");
for var i = 0; i < info.count; i++ {
for i := 0; i < info.count; i++ {
if i > 0 {
bprint_string(buf, ", ");
}
var data = arg.data as ^byte + i*info.elem_size;
data := arg.data as ^byte + i*info.elem_size;
bprint_any(buf, make_any(info.elem, data));
}
case Slice:
var slice = arg.data as ^[]byte;
slice := arg.data as ^[]byte;
bprintf(buf, "[]%{", info.elem);
defer bprint_string(buf, "}");
for var i = 0; i < slice.count; i++ {
for i := 0; i < slice.count; i++ {
if i > 0 {
bprint_string(buf, ", ");
}
var data = slice.data + i*info.elem_size;
data := slice.data + i*info.elem_size;
bprint_any(buf, make_any(info.elem, data));
}
@@ -440,12 +440,12 @@ proc bprint_any(buf ^[]byte, arg any) {
return;
}
for var i = 0; i < info.count; i++ {
for i := 0; i < info.count; i++ {
if i > 0 {
bprint_string(buf, ", ");
}
var data = arg.data as ^byte + i*info.elem_size;
data := arg.data as ^byte + i*info.elem_size;
bprint_any(buf, make_any(info.elem, data));
}
@@ -454,14 +454,14 @@ proc bprint_any(buf ^[]byte, arg any) {
bprintf(buf, "%{", arg.type_info);
defer bprint_string(buf, "}");
for var i = 0; i < info.fields.count; i++ {
for i := 0; i < info.fields.count; i++ {
if i > 0 {
bprint_string(buf, ", ");
}
bprint_string(buf, info.fields[i].name);
bprint_string(buf, " = ");
var data = arg.data as ^byte + info.fields[i].offset;
var ti = info.fields[i].type_info;
data := arg.data as ^byte + info.fields[i].offset;
ti := info.fields[i].type_info;
bprint_any(buf, make_any(ti, data));
}
@@ -487,10 +487,10 @@ proc bprintf(buf ^[]byte, fmt string, args ..any) -> int {
}
proc parse_int(s string, offset int) -> (int, int) {
var result = 0;
result := 0;
for ; offset < s.count; offset++ {
var c = s[offset] as rune;
c := s[offset] as rune;
if !is_digit(c) {
break;
}
@@ -502,12 +502,12 @@ proc bprintf(buf ^[]byte, fmt string, args ..any) -> int {
return result, offset;
}
var prev = 0;
var implicit_index = 0;
prev := 0;
implicit_index := 0;
for var i = 0; i < fmt.count; i++ {
var r = fmt[i] as rune;
var index = implicit_index;
for i := 0; i < fmt.count; i++ {
r := fmt[i] as rune;
index := implicit_index;
if r != '%' {
continue;
@@ -516,7 +516,7 @@ proc bprintf(buf ^[]byte, fmt string, args ..any) -> int {
bprint_string(buf, fmt[prev:i]);
i++; // Skip %
if i < fmt.count {
var next = fmt[i] as rune;
next := fmt[i] as rune;
if next == '%' {
bprint_string(buf, "%");
@@ -561,10 +561,10 @@ proc bprint(buf ^[]byte, args ..any) -> int {
}
var prev_string = false;
for var i = 0; i < args.count; i++ {
var arg = args[i];
var is_string = arg.data != nil && is_type_string(arg.type_info);
prev_string := false;
for i := 0; i < args.count; i++ {
arg := args[i];
is_string := arg.data != nil && is_type_string(arg.type_info);
if i > 0 && !is_string && !prev_string {
bprint_space(buf);
}
@@ -575,7 +575,7 @@ proc bprint(buf ^[]byte, args ..any) -> int {
}
proc bprintln(buf ^[]byte, args ..any) -> int {
for var i = 0; i < args.count; i++ {
for i := 0; i < args.count; i++ {
if i > 0 {
append(buf, ' ');
}
+40 -40
View File
@@ -1,57 +1,57 @@
proc crc32(data rawptr, len int) -> u32 {
var result = ~(0 as u32);
var s = slice_ptr(data as ^u8, len);
for var i = 0; i < len; i++ {
var b = s[i] as u32;
result := ~(0 as u32);
s := slice_ptr(data as ^u8, len);
for i := 0; i < len; i++ {
b := s[i] as u32;
result = result>>8 ~ __CRC32_TABLE[(result ~ b) & 0xff];
}
return ~result;
}
proc crc64(data rawptr, len int) -> u64 {
var result = ~(0 as u64);
var s = slice_ptr(data as ^u8, len);
for var i = 0; i < len; i++ {
var b = s[i] as u64;
result := ~(0 as u64);
s := slice_ptr(data as ^u8, len);
for i := 0; i < len; i++ {
b := s[i] as u64;
result = result>>8 ~ __CRC64_TABLE[(result ~ b) & 0xff];
}
return ~result;
}
proc fnv32(data rawptr, len int) -> u32 {
var s = slice_ptr(data as ^u8, len);
s := slice_ptr(data as ^u8, len);
var h u32 = 0x811c9dc5;
for var i = 0; i < len; i++ {
h :u32 = 0x811c9dc5;
for i := 0; i < len; i++ {
h = (h * 0x01000193) ~ s[i] as u32;
}
return h;
}
proc fnv64(data rawptr, len int) -> u64 {
var s = slice_ptr(data as ^u8, len);
s := slice_ptr(data as ^u8, len);
var h u64 = 0xcbf29ce484222325;
for var i = 0; i < len; i++ {
h :u64 = 0xcbf29ce484222325;
for i := 0; i < len; i++ {
h = (h * 0x100000001b3) ~ s[i] as u64;
}
return h;
}
proc fnv32a(data rawptr, len int) -> u32 {
var s = slice_ptr(data as ^u8, len);
s := slice_ptr(data as ^u8, len);
var h u32 = 0x811c9dc5;
for var i = 0; i < len; i++ {
h :u32 = 0x811c9dc5;
for i := 0; i < len; i++ {
h = (h ~ s[i] as u32) * 0x01000193;
}
return h;
}
proc fnv64a(data rawptr, len int) -> u64 {
var s = slice_ptr(data as ^u8, len);
s := slice_ptr(data as ^u8, len);
var h u64 = 0xcbf29ce484222325;
for var i = 0; i < len; i++ {
h :u64 = 0xcbf29ce484222325;
for i := 0; i < len; i++ {
h = (h ~ s[i] as u64) * 0x100000001b3;
}
return h;
@@ -59,19 +59,19 @@ proc fnv64a(data rawptr, len int) -> u64 {
proc murmur64(data_ rawptr, len int) -> u64 {
const SEED = 0x9747b28c;
SEED :: 0x9747b28c;
when size_of(int) == 8 {
const m = 0xc6a4a7935bd1e995;
const r = 47;
m :: 0xc6a4a7935bd1e995;
r :: 47;
var h u64 = SEED ~ (len as u64 * m);
h: u64 = SEED ~ (len as u64 * m);
var data = slice_ptr(data_ as ^u64, len/size_of(u64));
var data2 = slice_ptr(data_ as ^u8, len);
data := slice_ptr(data_ as ^u64, len/size_of(u64));
data2 := slice_ptr(data_ as ^u8, len);
for var i = 0; i < data.count; i++ {
var k = data[i];
for i := 0; i < data.count; i++ {
k := data[i];
k *= m;
k ~= k>>r;
@@ -99,17 +99,17 @@ proc murmur64(data_ rawptr, len int) -> u64 {
return h;
} else {
const m = 0x5bd1e995;
const r = 24;
m :: 0x5bd1e995;
r :: 24;
var h1 u32 = SEED as u32 ~ len as u32;
var h2 u32 = SEED >> 32;
h1: u32 = SEED as u32 ~ len as u32;
h2: u32 = SEED >> 32;
var data = slice_ptr(data_ as ^u32, len/size_of(u32));
data := slice_ptr(data_ as ^u32, len/size_of(u32));
var i = 0;
i := 0;
for len >= 8 {
var k1, k2 u32;
k1, k2: u32;
k1 = data[i]; i++;
k1 *= m;
k1 ~= k1>>r;
@@ -128,7 +128,7 @@ proc murmur64(data_ rawptr, len int) -> u64 {
}
if (len >= 4) {
var k1 u32;
k1: u32;
k1 = data[i]; i++;
k1 *= m;
k1 ~= k1>>r;
@@ -138,7 +138,7 @@ proc murmur64(data_ rawptr, len int) -> u64 {
len -= 4;
}
var data8 = slice_ptr((data.data+i) as ^u8, 3); // NOTE(bill): This is unsafe
data8 := slice_ptr((data.data+i) as ^u8, 3); // NOTE(bill): This is unsafe
match len {
case 3: h2 ~= data8[2] as u32 << 16; fallthrough;
@@ -157,14 +157,14 @@ proc murmur64(data_ rawptr, len int) -> u64 {
h2 ~= h1>>19;
h2 *= m;
var h = (h1 as u64)<<32 | h2 as u64;
h := (h1 as u64)<<32 | h2 as u64;
return h;
}
}
var __CRC32_TABLE = [256]u32{
__CRC32_TABLE := [256]u32{
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
@@ -230,7 +230,7 @@ var __CRC32_TABLE = [256]u32{
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
};
var __CRC64_TABLE = [256]u64{
__CRC64_TABLE := [256]u64{
0x0000000000000000, 0x42f0e1eba9ea3693, 0x85e1c3d753d46d26, 0xc711223cfa3e5bb5,
0x493366450e42ecdf, 0x0bc387aea7a8da4c, 0xccd2a5925d9681f9, 0x8e224479f47cb76a,
0x9266cc8a1c85d9be, 0xd0962d61b56fef2d, 0x17870f5d4f51b498, 0x5577eeb6e6bb820b,
+87 -89
View File
@@ -1,22 +1,20 @@
const {
TAU = 6.28318530717958647692528676655900576;
PI = 3.14159265358979323846264338327950288;
ONE_OVER_TAU = 0.636619772367581343075535053490057448;
ONE_OVER_PI = 0.159154943091895335768883763372514362;
TAU :: 6.28318530717958647692528676655900576;
PI :: 3.14159265358979323846264338327950288;
ONE_OVER_TAU :: 0.636619772367581343075535053490057448;
ONE_OVER_PI :: 0.159154943091895335768883763372514362;
E = 2.71828182845904523536;
SQRT_TWO = 1.41421356237309504880168872420969808;
SQRT_THREE = 1.73205080756887729352744634150587236;
SQRT_FIVE = 2.23606797749978969640917366873127623;
E :: 2.71828182845904523536;
SQRT_TWO :: 1.41421356237309504880168872420969808;
SQRT_THREE :: 1.73205080756887729352744634150587236;
SQRT_FIVE :: 2.23606797749978969640917366873127623;
LOG_TWO = 0.693147180559945309417232121458176568;
LOG_TEN = 2.30258509299404568401799145468436421;
LOG_TWO :: 0.693147180559945309417232121458176568;
LOG_TEN :: 2.30258509299404568401799145468436421;
EPSILON = 1.19209290e-7;
EPSILON :: 1.19209290e-7;
τ = TAU;
π = PI;
}
τ :: TAU;
π :: PI;
type {
Vec2 [vector 2]f32;
@@ -49,8 +47,8 @@ proc sign64(x f64) -> f64 { if x >= 0 { return +1; } return -1; }
proc copy_sign32(x, y f32) -> f32 {
var ix = x transmute u32;
var iy = y transmute u32;
ix := x transmute u32;
iy := y transmute u32;
ix &= 0x7fffffff;
ix |= iy & 0x80000000;
return ix transmute f32;
@@ -80,7 +78,7 @@ proc remainder32(x, y f32) -> f32 {
proc fmod32(x, y f32) -> f32 {
y = abs(y);
var result = remainder32(abs(x), y);
result := remainder32(abs(x), y);
if sign32(result) < 0 {
result += y;
}
@@ -94,13 +92,13 @@ proc to_degrees(radians f32) -> f32 { return radians * 360 / TAU; }
proc dot2(a, b Vec2) -> f32 { var c = a*b; return c.x + c.y; }
proc dot3(a, b Vec3) -> f32 { var c = a*b; return c.x + c.y + c.z; }
proc dot4(a, b Vec4) -> f32 { var c = a*b; return c.x + c.y + c.z + c.w; }
proc dot2(a, b Vec2) -> f32 { c := a*b; return c.x + c.y; }
proc dot3(a, b Vec3) -> f32 { c := a*b; return c.x + c.y + c.z; }
proc dot4(a, b Vec4) -> f32 { c := a*b; return c.x + c.y + c.z + c.w; }
proc cross3(x, y Vec3) -> Vec3 {
var a = swizzle(x, 1, 2, 0) * swizzle(y, 2, 0, 1);
var b = swizzle(x, 2, 0, 1) * swizzle(y, 1, 2, 0);
a := swizzle(x, 1, 2, 0) * swizzle(y, 2, 0, 1);
b := swizzle(x, 2, 0, 1) * swizzle(y, 1, 2, 0);
return a - b;
}
@@ -114,7 +112,7 @@ proc vec3_norm(v Vec3) -> Vec3 { return v / Vec3{vec3_mag(v)}; }
proc vec4_norm(v Vec4) -> Vec4 { return v / Vec4{vec4_mag(v)}; }
proc vec2_norm0(v Vec2) -> Vec2 {
var m = vec2_mag(v);
m := vec2_mag(v);
if m == 0 {
return Vec2{0};
}
@@ -122,7 +120,7 @@ proc vec2_norm0(v Vec2) -> Vec2 {
}
proc vec3_norm0(v Vec3) -> Vec3 {
var m = vec3_mag(v);
m := vec3_mag(v);
if m == 0 {
return Vec3{0};
}
@@ -130,7 +128,7 @@ proc vec3_norm0(v Vec3) -> Vec3 {
}
proc vec4_norm0(v Vec4) -> Vec4 {
var m = vec4_mag(v);
m := vec4_mag(v);
if m == 0 {
return Vec4{0};
}
@@ -149,8 +147,8 @@ proc mat4_identity() -> Mat4 {
}
proc mat4_transpose(m Mat4) -> Mat4 {
for var j = 0; j < 4; j++ {
for var i = 0; i < 4; i++ {
for j := 0; j < 4; j++ {
for i := 0; i < 4; i++ {
m[i][j], m[j][i] = m[j][i], m[i][j];
}
}
@@ -158,9 +156,9 @@ proc mat4_transpose(m Mat4) -> Mat4 {
}
proc mat4_mul(a, b Mat4) -> Mat4 {
var c Mat4;
for var j = 0; j < 4; j++ {
for var i = 0; i < 4; i++ {
c: Mat4;
for j := 0; j < 4; j++ {
for i := 0; i < 4; i++ {
c[j][i] = a[0][i]*b[j][0] +
a[1][i]*b[j][1] +
a[2][i]*b[j][2] +
@@ -180,27 +178,27 @@ proc mat4_mul_vec4(m Mat4, v Vec4) -> Vec4 {
}
proc mat4_inverse(m Mat4) -> Mat4 {
var o Mat4;
o: Mat4;
var sf00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
var sf01 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
var sf02 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
var sf03 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
var sf04 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
var sf05 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
var sf06 = m[1][2] * m[3][3] - m[3][2] * m[1][3];
var sf07 = m[1][1] * m[3][3] - m[3][1] * m[1][3];
var sf08 = m[1][1] * m[3][2] - m[3][1] * m[1][2];
var sf09 = m[1][0] * m[3][3] - m[3][0] * m[1][3];
var sf10 = m[1][0] * m[3][2] - m[3][0] * m[1][2];
var sf11 = m[1][1] * m[3][3] - m[3][1] * m[1][3];
var sf12 = m[1][0] * m[3][1] - m[3][0] * m[1][1];
var sf13 = m[1][2] * m[2][3] - m[2][2] * m[1][3];
var sf14 = m[1][1] * m[2][3] - m[2][1] * m[1][3];
var sf15 = m[1][1] * m[2][2] - m[2][1] * m[1][2];
var sf16 = m[1][0] * m[2][3] - m[2][0] * m[1][3];
var sf17 = m[1][0] * m[2][2] - m[2][0] * m[1][2];
var sf18 = m[1][0] * m[2][1] - m[2][0] * m[1][1];
sf00 := m[2][2] * m[3][3] - m[3][2] * m[2][3];
sf01 := m[2][1] * m[3][3] - m[3][1] * m[2][3];
sf02 := m[2][1] * m[3][2] - m[3][1] * m[2][2];
sf03 := m[2][0] * m[3][3] - m[3][0] * m[2][3];
sf04 := m[2][0] * m[3][2] - m[3][0] * m[2][2];
sf05 := m[2][0] * m[3][1] - m[3][0] * m[2][1];
sf06 := m[1][2] * m[3][3] - m[3][2] * m[1][3];
sf07 := m[1][1] * m[3][3] - m[3][1] * m[1][3];
sf08 := m[1][1] * m[3][2] - m[3][1] * m[1][2];
sf09 := m[1][0] * m[3][3] - m[3][0] * m[1][3];
sf10 := m[1][0] * m[3][2] - m[3][0] * m[1][2];
sf11 := m[1][1] * m[3][3] - m[3][1] * m[1][3];
sf12 := m[1][0] * m[3][1] - m[3][0] * m[1][1];
sf13 := m[1][2] * m[2][3] - m[2][2] * m[1][3];
sf14 := m[1][1] * m[2][3] - m[2][1] * m[1][3];
sf15 := m[1][1] * m[2][2] - m[2][1] * m[1][2];
sf16 := m[1][0] * m[2][3] - m[2][0] * m[1][3];
sf17 := m[1][0] * m[2][2] - m[2][0] * m[1][2];
sf18 := m[1][0] * m[2][1] - m[2][0] * m[1][1];
o[0][0] = +(m[1][1] * sf00 - m[1][2] * sf01 + m[1][3] * sf02);
o[0][1] = -(m[1][0] * sf00 - m[1][2] * sf03 + m[1][3] * sf04);
@@ -222,7 +220,7 @@ proc mat4_inverse(m Mat4) -> Mat4 {
o[3][2] = -(m[0][0] * sf14 - m[0][1] * sf16 + m[0][3] * sf18);
o[3][3] = +(m[0][0] * sf15 - m[0][1] * sf17 + m[0][2] * sf18);
var ood = 1.0 / (m[0][0] * o[0][0] +
ood := 1.0 / (m[0][0] * o[0][0] +
m[0][1] * o[0][1] +
m[0][2] * o[0][2] +
m[0][3] * o[0][3]);
@@ -249,7 +247,7 @@ proc mat4_inverse(m Mat4) -> Mat4 {
proc mat4_translate(v Vec3) -> Mat4 {
var m = mat4_identity();
m := mat4_identity();
m[3][0] = v.x;
m[3][1] = v.y;
m[3][2] = v.z;
@@ -258,13 +256,13 @@ proc mat4_translate(v Vec3) -> Mat4 {
}
proc mat4_rotate(v Vec3, angle_radians f32) -> Mat4 {
var c = cos32(angle_radians);
var s = sin32(angle_radians);
c := cos32(angle_radians);
s := sin32(angle_radians);
var a = vec3_norm(v);
var t = a * Vec3{1-c};
a := vec3_norm(v);
t := a * Vec3{1-c};
var rot = mat4_identity();
rot := mat4_identity();
rot[0][0] = c + t.x*a.x;
rot[0][1] = 0 + t.x*a.y + s*a.z;
@@ -300,11 +298,11 @@ proc mat4_scalef(m Mat4, s f32) -> Mat4 {
proc mat4_look_at(eye, centre, up Vec3) -> Mat4 {
var f = vec3_norm(centre - eye);
var s = vec3_norm(cross3(f, up));
var u = cross3(s, f);
f := vec3_norm(centre - eye);
s := vec3_norm(cross3(f, up));
u := cross3(s, f);
var m Mat4;
m: Mat4;
m[0] = Vec4{+s.x, +s.y, +s.z, 0};
m[1] = Vec4{+u.x, +u.y, +u.z, 0};
@@ -314,8 +312,8 @@ proc mat4_look_at(eye, centre, up Vec3) -> Mat4 {
return m;
}
proc mat4_perspective(fovy, aspect, near, far f32) -> Mat4 {
var m Mat4;
var tan_half_fovy = tan32(0.5 * fovy);
m: Mat4;
tan_half_fovy := tan32(0.5 * fovy);
m[0][0] = 1.0 / (aspect*tan_half_fovy);
m[1][1] = 1.0 / (tan_half_fovy);
m[2][2] = -(far + near) / (far - near);
@@ -326,7 +324,7 @@ proc mat4_perspective(fovy, aspect, near, far f32) -> Mat4 {
proc mat4_ortho3d(left, right, bottom, top, near, far f32) -> Mat4 {
var m = mat4_identity();
m := mat4_identity();
m[0][0] = +2.0 / (right - left);
m[1][1] = +2.0 / (top - bottom);
m[2][2] = -2.0 / (far - near);
@@ -340,31 +338,31 @@ proc mat4_ortho3d(left, right, bottom, top, near, far f32) -> Mat4 {
const F32_DIG = 6;
const F32_EPSILON = 1.192092896e-07;
const F32_GUARD = 0;
const F32_MANT_DIG = 24;
const F32_MAX = 3.402823466e+38;
const F32_MAX_10_EXP = 38;
const F32_MAX_EXP = 128;
const F32_MIN = 1.175494351e-38;
const F32_MIN_10_EXP = -37;
const F32_MIN_EXP = -125;
const F32_NORMALIZE = 0;
const F32_RADIX = 2;
const F32_ROUNDS = 1;
F32_DIG :: 6;
F32_EPSILON :: 1.192092896e-07;
F32_GUARD :: 0;
F32_MANT_DIG :: 24;
F32_MAX :: 3.402823466e+38;
F32_MAX_10_EXP :: 38;
F32_MAX_EXP :: 128;
F32_MIN :: 1.175494351e-38;
F32_MIN_10_EXP :: -37;
F32_MIN_EXP :: -125;
F32_NORMALIZE :: 0;
F32_RADIX :: 2;
F32_ROUNDS :: 1;
const F64_DIG = 15; // # of decimal digits of precision
const F64_EPSILON = 2.2204460492503131e-016; // smallest such that 1.0+F64_EPSILON != 1.0
const F64_MANT_DIG = 53; // # of bits in mantissa
const F64_MAX = 1.7976931348623158e+308; // max value
const F64_MAX_10_EXP = 308; // max decimal exponent
const F64_MAX_EXP = 1024; // max binary exponent
const F64_MIN = 2.2250738585072014e-308; // min positive value
const F64_MIN_10_EXP = -307; // min decimal exponent
const F64_MIN_EXP = -1021; // min binary exponent
const F64_RADIX = 2; // exponent radix
const F64_ROUNDS = 1; // addition rounding: near
F64_DIG :: 15; // # of decimal digits of precision
F64_EPSILON :: 2.2204460492503131e-016; // smallest such that 1.0+F64_EPSILON != 1.0
F64_MANT_DIG :: 53; // # of bits in mantissa
F64_MAX :: 1.7976931348623158e+308; // max value
F64_MAX_10_EXP :: 308; // max decimal exponent
F64_MAX_EXP :: 1024; // max binary exponent
F64_MIN :: 2.2250738585072014e-308; // min positive value
F64_MIN_10_EXP :: -307; // min decimal exponent
F64_MIN_EXP :: -1021; // min binary exponent
F64_RADIX :: 2; // exponent radix
F64_ROUNDS :: 1; // addition rounding: near
+34 -34
View File
@@ -30,22 +30,22 @@ proc copy_non_overlapping(dst, src rawptr, len int) -> rawptr #link_name "__mem_
proc compare(dst, src rawptr, n int) -> int #link_name "__mem_compare" {
// Translation of http://mgronhol.github.io/fast-strcmp/
var a = slice_ptr(dst as ^byte, n);
var b = slice_ptr(src as ^byte, n);
a := slice_ptr(dst as ^byte, n);
b := slice_ptr(src as ^byte, n);
var fast = n/size_of(int) + 1;
var offset = (fast-1)*size_of(int);
var curr_block = 0;
fast := n/size_of(int) + 1;
offset := (fast-1)*size_of(int);
curr_block := 0;
if n <= size_of(int) {
fast = 0;
}
var la = slice_ptr(^a[0] as ^int, fast);
var lb = slice_ptr(^b[0] as ^int, fast);
la := slice_ptr(^a[0] as ^int, fast);
lb := slice_ptr(^b[0] as ^int, fast);
for ; curr_block < fast; curr_block++ {
if (la[curr_block] ~ lb[curr_block]) != 0 {
for var pos = curr_block*size_of(int); pos < n; pos++ {
for pos := curr_block*size_of(int); pos < n; pos++ {
if (a[pos] ~ b[pos]) != 0 {
return a[pos] as int - b[pos] as int;
}
@@ -80,9 +80,9 @@ proc is_power_of_two(x int) -> bool {
proc align_forward(ptr rawptr, align int) -> rawptr {
assert(is_power_of_two(align));
var a = align as uint;
var p = ptr as uint;
var modulo = p & (a-1);
a := align as uint;
p := ptr as uint;
modulo := p & (a-1);
if modulo != 0 {
p += a - modulo;
}
@@ -97,14 +97,14 @@ type Allocation_Header struct {
proc allocation_header_fill(header ^Allocation_Header, data rawptr, size int) {
header.size = size;
var ptr = (header+1) as ^int;
ptr := (header+1) as ^int;
for var i = 0; ptr as rawptr < data; i++ {
for i := 0; ptr as rawptr < data; i++ {
(ptr+i)^ = -1;
}
}
proc allocation_header(data rawptr) -> ^Allocation_Header {
var p = data as ^int;
p := data as ^int;
for (p-1)^ == -1 {
p = (p-1);
}
@@ -164,20 +164,20 @@ proc arena_allocator_proc(allocator_data rawptr, mode Allocator_Mode,
size, alignment int,
old_memory rawptr, old_size int, flags u64) -> rawptr {
using Allocator_Mode;
var arena = allocator_data as ^Arena;
arena := allocator_data as ^Arena;
match mode {
case ALLOC:
var total_size = size + alignment;
total_size := size + alignment;
if arena.memory.count + total_size > arena.memory.capacity {
fmt.fprintln(os.stderr, "Arena out of memory");
return nil;
}
#no_bounds_check var end = ^arena.memory[arena.memory.count];
#no_bounds_check end := ^arena.memory[arena.memory.count];
var ptr = align_forward(end, alignment);
ptr := align_forward(end, alignment);
arena.memory.count += total_size;
return zero(ptr, size);
@@ -196,7 +196,7 @@ proc arena_allocator_proc(allocator_data rawptr, mode Allocator_Mode,
}
proc begin_arena_temp_memory(a ^Arena) -> Arena_Temp_Memory {
var tmp Arena_Temp_Memory;
tmp: Arena_Temp_Memory;
tmp.arena = a;
tmp.original_count = a.memory.count;
a.temp_count++;
@@ -230,8 +230,8 @@ proc align_of_type_info(type_info ^Type_Info) -> int {
return n - (n >> 1);
}
const WORD_SIZE = size_of(int);
const MAX_ALIGN = size_of([vector 64]f64); // TODO(bill): Should these constants be builtin constants?
WORD_SIZE :: size_of(int);
MAX_ALIGN :: size_of([vector 64]f64); // TODO(bill): Should these constants be builtin constants?
using Type_Info;
match type info : type_info {
@@ -256,9 +256,9 @@ proc align_of_type_info(type_info ^Type_Info) -> int {
case Slice:
return WORD_SIZE;
case Vector:
var size = size_of_type_info(info.elem);
var count = max(prev_pow2(info.count as i64), 1) as int;
var total = size * count;
size := size_of_type_info(info.elem);
count := max(prev_pow2(info.count as i64), 1) as int;
total := size * count;
return clamp(total, 1, MAX_ALIGN);
case Struct:
return info.align;
@@ -272,12 +272,12 @@ proc align_of_type_info(type_info ^Type_Info) -> int {
}
proc align_formula(size, align int) -> int {
var result = size + align-1;
result := size + align-1;
return result - result%align;
}
proc size_of_type_info(type_info ^Type_Info) -> int {
const WORD_SIZE = size_of(int);
WORD_SIZE :: size_of(int);
using Type_Info;
match type info : type_info {
case Named:
@@ -299,13 +299,13 @@ proc size_of_type_info(type_info ^Type_Info) -> int {
case Procedure:
return WORD_SIZE;
case Array:
var count = info.count;
count := info.count;
if count == 0 {
return 0;
}
var size = size_of_type_info(info.elem);
var align = align_of_type_info(info.elem);
var alignment = align_formula(size, align);
size := size_of_type_info(info.elem);
align := align_of_type_info(info.elem);
alignment := align_formula(size, align);
return alignment*(count-1) + size;
case Slice:
return 3*WORD_SIZE;
@@ -320,18 +320,18 @@ proc size_of_type_info(type_info ^Type_Info) -> int {
return false;
}
var count = info.count;
count := info.count;
if count == 0 {
return 0;
}
var bit_size = 8*size_of_type_info(info.elem);
bit_size := 8*size_of_type_info(info.elem);
if is_bool(info.elem) {
// NOTE(bill): LLVM can store booleans as 1 bit because a boolean _is_ an `i1`
// Silly LLVM spec
bit_size = 1;
}
var total_size_in_bits = bit_size * count;
var total_size = (total_size_in_bits+7)/8;
total_size_in_bits := bit_size * count;
total_size := (total_size_in_bits+7)/8;
return total_size;
case Struct:
+48 -50
View File
@@ -30,76 +30,74 @@ proc GetIntegerv(name i32, v ^i32) #foreign "glGetIntegerv"
var _libgl = win32.LoadLibraryA(("opengl32.dll\x00" as string).data);
_libgl := win32.LoadLibraryA(("opengl32.dll\x00" as string).data);
proc GetProcAddress(name string) -> proc() #cc_c {
assert(name[name.count-1] == 0);
var res = win32.wglGetProcAddress(name.data);
res := win32.wglGetProcAddress(name.data);
if res == nil {
res = win32.GetProcAddress(_libgl, name.data);
}
return res;
}
var {
GenBuffers proc(count i32, buffers ^u32) #cc_c;
GenVertexArrays proc(count i32, buffers ^u32) #cc_c;
GenSamplers proc(count i32, buffers ^u32) #cc_c;
BindBuffer proc(target i32, buffer u32) #cc_c;
BindVertexArray proc(buffer u32) #cc_c;
BindSampler proc(position i32, sampler u32) #cc_c;
BufferData proc(target i32, size int, data rawptr, usage i32) #cc_c;
BufferSubData proc(target i32, offset, size int, data rawptr) #cc_c;
GenBuffers: proc(count i32, buffers ^u32) #cc_c;
GenVertexArrays: proc(count i32, buffers ^u32) #cc_c;
GenSamplers: proc(count i32, buffers ^u32) #cc_c;
BindBuffer: proc(target i32, buffer u32) #cc_c;
BindVertexArray: proc(buffer u32) #cc_c;
BindSampler: proc(position i32, sampler u32) #cc_c;
BufferData: proc(target i32, size int, data rawptr, usage i32) #cc_c;
BufferSubData: proc(target i32, offset, size int, data rawptr) #cc_c;
DrawArrays proc(mode, first i32, count u32) #cc_c;
DrawElements proc(mode i32, count u32, type_ i32, indices rawptr) #cc_c;
DrawArrays: proc(mode, first i32, count u32) #cc_c;
DrawElements: proc(mode i32, count u32, type_ i32, indices rawptr) #cc_c;
MapBuffer proc(target, access i32) -> rawptr #cc_c;
UnmapBuffer proc(target i32) #cc_c;
MapBuffer: proc(target, access i32) -> rawptr #cc_c;
UnmapBuffer: proc(target i32) #cc_c;
VertexAttribPointer proc(index u32, size, type_ i32, normalized i32, stride u32, pointer rawptr) #cc_c;
EnableVertexAttribArray proc(index u32) #cc_c;
VertexAttribPointer: proc(index u32, size, type_ i32, normalized i32, stride u32, pointer rawptr) #cc_c;
EnableVertexAttribArray: proc(index u32) #cc_c;
CreateShader proc(shader_type i32) -> u32 #cc_c;
ShaderSource proc(shader u32, count u32, str ^^byte, length ^i32) #cc_c;
CompileShader proc(shader u32) #cc_c;
CreateProgram proc() -> u32 #cc_c;
AttachShader proc(program, shader u32) #cc_c;
DetachShader proc(program, shader u32) #cc_c;
DeleteShader proc(shader u32) #cc_c;
LinkProgram proc(program u32) #cc_c;
UseProgram proc(program u32) #cc_c;
DeleteProgram proc(program u32) #cc_c;
CreateShader: proc(shader_type i32) -> u32 #cc_c;
ShaderSource: proc(shader u32, count u32, str ^^byte, length ^i32) #cc_c;
CompileShader: proc(shader u32) #cc_c;
CreateProgram: proc() -> u32 #cc_c;
AttachShader: proc(program, shader u32) #cc_c;
DetachShader: proc(program, shader u32) #cc_c;
DeleteShader: proc(shader u32) #cc_c;
LinkProgram: proc(program u32) #cc_c;
UseProgram: proc(program u32) #cc_c;
DeleteProgram: proc(program u32) #cc_c;
GetShaderiv proc(shader u32, pname i32, params ^i32) #cc_c;
GetProgramiv proc(program u32, pname i32, params ^i32) #cc_c;
GetShaderInfoLog proc(shader u32, max_length u32, length ^u32, info_long ^byte) #cc_c;
GetProgramInfoLog proc(program u32, max_length u32, length ^u32, info_long ^byte) #cc_c;
GetShaderiv: proc(shader u32, pname i32, params ^i32) #cc_c;
GetProgramiv: proc(program u32, pname i32, params ^i32) #cc_c;
GetShaderInfoLog: proc(shader u32, max_length u32, length ^u32, info_long ^byte) #cc_c;
GetProgramInfoLog: proc(program u32, max_length u32, length ^u32, info_long ^byte) #cc_c;
ActiveTexture proc(texture i32) #cc_c;
GenerateMipmap proc(target i32) #cc_c;
ActiveTexture: proc(texture i32) #cc_c;
GenerateMipmap: proc(target i32) #cc_c;
SamplerParameteri proc(sampler u32, pname i32, param i32) #cc_c;
SamplerParameterf proc(sampler u32, pname i32, param f32) #cc_c;
SamplerParameteriv proc(sampler u32, pname i32, params ^i32) #cc_c;
SamplerParameterfv proc(sampler u32, pname i32, params ^f32) #cc_c;
SamplerParameterIiv proc(sampler u32, pname i32, params ^i32) #cc_c;
SamplerParameterIuiv proc(sampler u32, pname i32, params ^u32) #cc_c;
SamplerParameteri: proc(sampler u32, pname i32, param i32) #cc_c;
SamplerParameterf: proc(sampler u32, pname i32, param f32) #cc_c;
SamplerParameteriv: proc(sampler u32, pname i32, params ^i32) #cc_c;
SamplerParameterfv: proc(sampler u32, pname i32, params ^f32) #cc_c;
SamplerParameterIiv: proc(sampler u32, pname i32, params ^i32) #cc_c;
SamplerParameterIuiv: proc(sampler u32, pname i32, params ^u32) #cc_c;
Uniform1i proc(loc i32, v0 i32) #cc_c;
Uniform2i proc(loc i32, v0, v1 i32) #cc_c;
Uniform3i proc(loc i32, v0, v1, v2 i32) #cc_c;
Uniform4i proc(loc i32, v0, v1, v2, v3 i32) #cc_c;
Uniform1f proc(loc i32, v0 f32) #cc_c;
Uniform2f proc(loc i32, v0, v1 f32) #cc_c;
Uniform3f proc(loc i32, v0, v1, v2 f32) #cc_c;
Uniform4f proc(loc i32, v0, v1, v2, v3 f32) #cc_c;
UniformMatrix4fv proc(loc i32, count u32, transpose i32, value ^f32) #cc_c;
Uniform1i: proc(loc i32, v0 i32) #cc_c;
Uniform2i: proc(loc i32, v0, v1 i32) #cc_c;
Uniform3i: proc(loc i32, v0, v1, v2 i32) #cc_c;
Uniform4i: proc(loc i32, v0, v1, v2, v3 i32) #cc_c;
Uniform1f: proc(loc i32, v0 f32) #cc_c;
Uniform2f: proc(loc i32, v0, v1 f32) #cc_c;
Uniform3f: proc(loc i32, v0, v1, v2 f32) #cc_c;
Uniform4f: proc(loc i32, v0, v1, v2, v3 f32) #cc_c;
UniformMatrix4fv: proc(loc i32, count u32, transpose i32, value ^f32) #cc_c;
GetUniformLocation proc(program u32, name ^byte) -> i32 #cc_c;
}
GetUniformLocation: proc(program u32, name ^byte) -> i32 #cc_c;
proc init() {
proc set_proc_address(p rawptr, name string) #inline { (p as ^(proc() #cc_c))^ = GetProcAddress(name); }
+1367 -1367
View File
File diff suppressed because it is too large Load Diff
+81 -86
View File
@@ -10,52 +10,48 @@ type {
Error int;
}
const INVALID_HANDLE Handle = ~(0 as Handle);
INVALID_HANDLE: Handle : ~(0 as Handle);
const {
O_RDONLY = 0x00000;
O_WRONLY = 0x00001;
O_RDWR = 0x00002;
O_CREAT = 0x00040;
O_EXCL = 0x00080;
O_NOCTTY = 0x00100;
O_TRUNC = 0x00200;
O_NONBLOCK = 0x00800;
O_APPEND = 0x00400;
O_SYNC = 0x01000;
O_ASYNC = 0x02000;
O_CLOEXEC = 0x80000;
}
const {
ERROR_NONE Error = 0;
ERROR_FILE_NOT_FOUND Error = 2;
ERROR_PATH_NOT_FOUND Error = 3;
ERROR_ACCESS_DENIED Error = 5;
ERROR_NO_MORE_FILES Error = 18;
ERROR_HANDLE_EOF Error = 38;
ERROR_NETNAME_DELETED Error = 64;
ERROR_FILE_EXISTS Error = 80;
ERROR_BROKEN_PIPE Error = 109;
ERROR_BUFFER_OVERFLOW Error = 111;
ERROR_INSUFFICIENT_BUFFER Error = 122;
ERROR_MOD_NOT_FOUND Error = 126;
ERROR_PROC_NOT_FOUND Error = 127;
ERROR_DIR_NOT_EMPTY Error = 145;
ERROR_ALREADY_EXISTS Error = 183;
ERROR_ENVVAR_NOT_FOUND Error = 203;
ERROR_MORE_DATA Error = 234;
ERROR_OPERATION_ABORTED Error = 995;
ERROR_IO_PENDING Error = 997;
ERROR_NOT_FOUND Error = 1168;
ERROR_PRIVILEGE_NOT_HELD Error = 1314;
WSAEACCES Error = 10013;
WSAECONNRESET Error = 10054;
}
O_RDONLY :: 0x00000;
O_WRONLY :: 0x00001;
O_RDWR :: 0x00002;
O_CREAT :: 0x00040;
O_EXCL :: 0x00080;
O_NOCTTY :: 0x00100;
O_TRUNC :: 0x00200;
O_NONBLOCK :: 0x00800;
O_APPEND :: 0x00400;
O_SYNC :: 0x01000;
O_ASYNC :: 0x02000;
O_CLOEXEC :: 0x80000;
const { // Windows reserves errors >= 1<<29 for application use
ERROR_FILE_IS_PIPE Error = 1<<29 + 0;
}
ERROR_NONE : Error : 0;
ERROR_FILE_NOT_FOUND : Error : 2;
ERROR_PATH_NOT_FOUND : Error : 3;
ERROR_ACCESS_DENIED : Error : 5;
ERROR_NO_MORE_FILES : Error : 18;
ERROR_HANDLE_EOF : Error : 38;
ERROR_NETNAME_DELETED : Error : 64;
ERROR_FILE_EXISTS : Error : 80;
ERROR_BROKEN_PIPE : Error : 109;
ERROR_BUFFER_OVERFLOW : Error : 111;
ERROR_INSUFFICIENT_BUFFER : Error : 122;
ERROR_MOD_NOT_FOUND : Error : 126;
ERROR_PROC_NOT_FOUND : Error : 127;
ERROR_DIR_NOT_EMPTY : Error : 145;
ERROR_ALREADY_EXISTS : Error : 183;
ERROR_ENVVAR_NOT_FOUND : Error : 203;
ERROR_MORE_DATA : Error : 234;
ERROR_OPERATION_ABORTED : Error : 995;
ERROR_IO_PENDING : Error : 997;
ERROR_NOT_FOUND : Error : 1168;
ERROR_PRIVILEGE_NOT_HELD : Error : 1314;
WSAEACCES : Error : 10013;
WSAECONNRESET : Error : 10054;
// Windows reserves errors >= 1<<29 for application use
ERROR_FILE_IS_PIPE : Error : 1<<29 + 0;
@@ -66,7 +62,7 @@ proc open(path string, mode int, perm u32) -> (Handle, Error) {
return INVALID_HANDLE, ERROR_FILE_NOT_FOUND;
}
var access u32;
access: u32;
match mode & (O_RDONLY|O_WRONLY|O_RDWR) {
case O_RDONLY: access = FILE_GENERIC_READ;
case O_WRONLY: access = FILE_GENERIC_WRITE;
@@ -81,14 +77,14 @@ proc open(path string, mode int, perm u32) -> (Handle, Error) {
access |= FILE_APPEND_DATA;
}
var share_mode = (FILE_SHARE_READ|FILE_SHARE_WRITE) as u32;
var sa ^SECURITY_ATTRIBUTES = nil;
var sa_inherit = SECURITY_ATTRIBUTES{length = size_of(SECURITY_ATTRIBUTES), inherit_handle = 1};
share_mode := (FILE_SHARE_READ|FILE_SHARE_WRITE) as u32;
sa: ^SECURITY_ATTRIBUTES = nil;
sa_inherit := SECURITY_ATTRIBUTES{length = size_of(SECURITY_ATTRIBUTES), inherit_handle = 1};
if mode&O_CLOEXEC == 0 {
sa = ^sa_inherit;
}
var create_mode u32;
create_mode: u32;
match {
case mode&(O_CREAT|O_EXCL) == (O_CREAT | O_EXCL):
create_mode = CREATE_NEW;
@@ -102,14 +98,14 @@ proc open(path string, mode int, perm u32) -> (Handle, Error) {
create_mode = OPEN_EXISTING;
}
var buf [300]byte;
buf: [300]byte;
copy(buf[:], path as []byte);
var handle = CreateFileA(^buf[0], access, share_mode, sa, create_mode, FILE_ATTRIBUTE_NORMAL, nil) as Handle;
handle := CreateFileA(^buf[0], access, share_mode, sa, create_mode, FILE_ATTRIBUTE_NORMAL, nil) as Handle;
if handle == INVALID_HANDLE {
return handle, ERROR_NONE;
}
var err = GetLastError();
err := GetLastError();
return INVALID_HANDLE, err as Error;
}
@@ -118,8 +114,8 @@ proc close(fd Handle) {
}
proc write(fd Handle, data []byte) -> (int, Error) {
var bytes_written i32;
var e = win32.WriteFile(fd as win32.HANDLE, data.data, data.count as i32, ^bytes_written, nil);
bytes_written: i32;
e := win32.WriteFile(fd as win32.HANDLE, data.data, data.count as i32, ^bytes_written, nil);
if e != 0 {
return 0, e as Error;
}
@@ -127,10 +123,10 @@ proc write(fd Handle, data []byte) -> (int, Error) {
}
proc read(fd Handle, data []byte) -> (int, Error) {
var bytes_read i32;
var e = win32.ReadFile(fd as win32.HANDLE, data.data, data.count as u32, ^bytes_read, nil);
bytes_read: i32;
e := win32.ReadFile(fd as win32.HANDLE, data.data, data.count as u32, ^bytes_read, nil);
if e != win32.FALSE {
var err = win32.GetLastError();
err := win32.GetLastError();
return 0, err as Error;
}
return bytes_read as int, ERROR_NONE;
@@ -138,21 +134,21 @@ proc read(fd Handle, data []byte) -> (int, Error) {
proc seek(fd Handle, offset i64, whence int) -> (i64, Error) {
using win32;
var w u32;
w: u32;
match whence {
case 0: w = FILE_BEGIN;
case 1: w = FILE_CURRENT;
case 2: w = FILE_END;
}
var hi = (offset>>32) as i32;
var lo = offset as i32;
var ft = GetFileType(fd as HANDLE);
hi := (offset>>32) as i32;
lo := offset as i32;
ft := GetFileType(fd as HANDLE);
if ft == FILE_TYPE_PIPE {
return 0, ERROR_FILE_IS_PIPE;
}
var dw_ptr = SetFilePointer(fd as HANDLE, lo, ^hi, w);
dw_ptr := SetFilePointer(fd as HANDLE, lo, ^hi, w);
if dw_ptr == INVALID_SET_FILE_POINTER {
var err = GetLastError();
err := GetLastError();
return 0, err as Error;
}
return (hi as i64)<<32 + (dw_ptr as i64), ERROR_NONE;
@@ -160,14 +156,13 @@ proc seek(fd Handle, offset i64, whence int) -> (i64, Error) {
// NOTE(bill): Uses startup to initialize it
var {
stdin = get_std_handle(win32.STD_INPUT_HANDLE);
stdout = get_std_handle(win32.STD_OUTPUT_HANDLE);
stderr = get_std_handle(win32.STD_ERROR_HANDLE);
}
stdin := get_std_handle(win32.STD_INPUT_HANDLE);
stdout := get_std_handle(win32.STD_OUTPUT_HANDLE);
stderr := get_std_handle(win32.STD_ERROR_HANDLE);
proc get_std_handle(h int) -> Handle {
var fd = win32.GetStdHandle(h as i32);
fd := win32.GetStdHandle(h as i32);
win32.SetHandleInformation(fd, win32.HANDLE_FLAG_INHERIT, 0);
return fd as Handle;
}
@@ -178,17 +173,17 @@ proc get_std_handle(h int) -> Handle {
proc last_write_time(fd Handle) -> File_Time {
var file_info win32.BY_HANDLE_FILE_INFORMATION;
file_info: win32.BY_HANDLE_FILE_INFORMATION;
win32.GetFileInformationByHandle(fd as win32.HANDLE, ^file_info);
var lo = file_info.last_write_time.lo as File_Time;
var hi = file_info.last_write_time.hi as File_Time;
lo := file_info.last_write_time.lo as File_Time;
hi := file_info.last_write_time.hi as File_Time;
return lo | hi << 32;
}
proc last_write_time_by_name(name string) -> File_Time {
var last_write_time win32.FILETIME;
var data win32.FILE_ATTRIBUTE_DATA;
var buf [1024]byte;
last_write_time: win32.FILETIME;
data: win32.FILE_ATTRIBUTE_DATA;
buf: [1024]byte;
assert(buf.count > name.count);
@@ -198,8 +193,8 @@ proc last_write_time_by_name(name string) -> File_Time {
last_write_time = data.last_write_time;
}
var l = last_write_time.lo as File_Time;
var h = last_write_time.hi as File_Time;
l := last_write_time.lo as File_Time;
h := last_write_time.hi as File_Time;
return l | h << 32;
}
@@ -208,33 +203,33 @@ proc last_write_time_by_name(name string) -> File_Time {
proc read_entire_file(name string) -> ([]byte, bool) {
var buf [300]byte;
buf: [300]byte;
copy(buf[:], name as []byte);
var fd, err = open(name, O_RDONLY, 0);
fd, err := open(name, O_RDONLY, 0);
if err != ERROR_NONE {
return nil, false;
}
defer close(fd);
var length i64;
var file_size_ok = win32.GetFileSizeEx(fd as win32.HANDLE, ^length) != 0;
length: i64;
file_size_ok := win32.GetFileSizeEx(fd as win32.HANDLE, ^length) != 0;
if !file_size_ok {
return nil, false;
}
var data = new_slice(u8, length);
data := new_slice(u8, length);
if data.data == nil {
return nil, false;
}
var single_read_length i32;
var total_read i64;
single_read_length: i32;
total_read: i64;
for total_read < length {
var remaining = length - total_read;
var to_read u32;
const MAX = 1<<32-1;
remaining := length - total_read;
to_read: u32;
MAX :: 1<<32-1;
if remaining <= MAX {
to_read = remaining as u32;
} else {
+5 -5
View File
@@ -49,7 +49,7 @@ proc mutex_destroy(m ^Mutex) {
semaphore_destroy(^m.semaphore);
}
proc mutex_lock(m ^Mutex) {
var thread_id = current_thread_id();
thread_id := current_thread_id();
if atomic.fetch_add32(^m.counter, 1) > 0 {
if thread_id != atomic.load32(^m.owner) {
semaphore_wait(^m.semaphore);
@@ -59,11 +59,11 @@ proc mutex_lock(m ^Mutex) {
m.recursion++;
}
proc mutex_try_lock(m ^Mutex) -> bool {
var thread_id = current_thread_id();
thread_id := current_thread_id();
if atomic.load32(^m.owner) == thread_id {
atomic.fetch_add32(^m.counter, 1);
} else {
var expected i32 = 0;
expected: i32 = 0;
if atomic.load32(^m.counter) != 0 {
return false;
}
@@ -76,8 +76,8 @@ proc mutex_try_lock(m ^Mutex) -> bool {
return true;
}
proc mutex_unlock(m ^Mutex) {
var recursion i32;
var thread_id = current_thread_id();
recursion: i32;
thread_id := current_thread_id();
assert(thread_id == atomic.load32(^m.owner));
m.recursion--;
+102 -115
View File
@@ -20,42 +20,42 @@ type {
WNDPROC proc(hwnd HWND, msg u32, wparam WPARAM, lparam LPARAM) -> LRESULT;
}
const {
INVALID_HANDLE_VALUE = (-1 as int) as HANDLE;
FALSE BOOL = 0;
TRUE BOOL = 1;
INVALID_HANDLE_VALUE :: (-1 as int) as HANDLE;
CS_VREDRAW = 0x0001;
CS_HREDRAW = 0x0002;
CS_OWNDC = 0x0020;
CW_USEDEFAULT = -0x80000000;
FALSE: BOOL : 0;
TRUE: BOOL : 1;
WS_OVERLAPPED = 0;
WS_MAXIMIZEBOX = 0x00010000;
WS_MINIMIZEBOX = 0x00020000;
WS_THICKFRAME = 0x00040000;
WS_SYSMENU = 0x00080000;
WS_CAPTION = 0x00C00000;
WS_VISIBLE = 0x10000000;
WS_OVERLAPPEDWINDOW = WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX;
CS_VREDRAW :: 0x0001;
CS_HREDRAW :: 0x0002;
CS_OWNDC :: 0x0020;
CW_USEDEFAULT :: -0x80000000;
WM_DESTROY = 0x0002;
WM_CLOSE = 0x0010;
WM_QUIT = 0x0012;
WM_KEYDOWN = 0x0100;
WM_KEYUP = 0x0101;
WS_OVERLAPPED :: 0;
WS_MAXIMIZEBOX :: 0x00010000;
WS_MINIMIZEBOX :: 0x00020000;
WS_THICKFRAME :: 0x00040000;
WS_SYSMENU :: 0x00080000;
WS_CAPTION :: 0x00C00000;
WS_VISIBLE :: 0x10000000;
WS_OVERLAPPEDWINDOW :: WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX;
PM_REMOVE = 1;
WM_DESTROY :: 0x0002;
WM_CLOSE :: 0x0010;
WM_QUIT :: 0x0012;
WM_KEYDOWN :: 0x0100;
WM_KEYUP :: 0x0101;
COLOR_BACKGROUND = 1 as HBRUSH;
BLACK_BRUSH = 4;
PM_REMOVE :: 1;
SM_CXSCREEN = 0;
SM_CYSCREEN = 1;
COLOR_BACKGROUND :: 1 as HBRUSH;
BLACK_BRUSH :: 4;
SM_CXSCREEN :: 0;
SM_CYSCREEN :: 1;
SW_SHOW :: 5;
SW_SHOW = 5;
}
type {
POINT struct #ordered {
@@ -118,10 +118,8 @@ type {
GET_FILEEX_INFO_LEVELS i32;
}
const {
GetFileExInfoStandard = 0 as GET_FILEEX_INFO_LEVELS;
GetFileExMaxInfoLevel = 1 as GET_FILEEX_INFO_LEVELS;
}
GetFileExInfoStandard: GET_FILEEX_INFO_LEVELS : 0;
GetFileExMaxInfoLevel: GET_FILEEX_INFO_LEVELS : 1;
proc GetLastError () -> i32 #foreign #dll_import
proc ExitProcess (exit_code u32) #foreign #dll_import
@@ -163,7 +161,7 @@ proc GetActiveWindow () -> HWND #foreign #dll_import
proc GetQueryPerformanceFrequency() -> i64 {
var r i64;
r: i64;
QueryPerformanceFrequency(^r);
return r;
}
@@ -191,60 +189,54 @@ proc SetFilePointer(file_handle HANDLE, distance_to_move i32, distance_to_move_h
proc SetHandleInformation(obj HANDLE, mask, flags u32) -> BOOL #foreign #dll_import
const {
HANDLE_FLAG_INHERIT = 1;
HANDLE_FLAG_PROTECT_FROM_CLOSE = 2;
}
HANDLE_FLAG_INHERIT :: 1;
HANDLE_FLAG_PROTECT_FROM_CLOSE :: 2;
const {
FILE_BEGIN = 0;
FILE_CURRENT = 1;
FILE_END = 2;
}
FILE_BEGIN :: 0;
FILE_CURRENT :: 1;
FILE_END :: 2;
const {
FILE_SHARE_READ = 0x00000001;
FILE_SHARE_WRITE = 0x00000002;
FILE_SHARE_DELETE = 0x00000004;
FILE_GENERIC_ALL = 0x10000000;
FILE_GENERIC_EXECUTE = 0x20000000;
FILE_GENERIC_WRITE = 0x40000000;
FILE_GENERIC_READ = 0x80000000;
FILE_SHARE_READ :: 0x00000001;
FILE_SHARE_WRITE :: 0x00000002;
FILE_SHARE_DELETE :: 0x00000004;
FILE_GENERIC_ALL :: 0x10000000;
FILE_GENERIC_EXECUTE :: 0x20000000;
FILE_GENERIC_WRITE :: 0x40000000;
FILE_GENERIC_READ :: 0x80000000;
FILE_APPEND_DATA = 0x0004;
FILE_APPEND_DATA :: 0x0004;
STD_INPUT_HANDLE = -10;
STD_OUTPUT_HANDLE = -11;
STD_ERROR_HANDLE = -12;
STD_INPUT_HANDLE :: -10;
STD_OUTPUT_HANDLE :: -11;
STD_ERROR_HANDLE :: -12;
CREATE_NEW = 1;
CREATE_ALWAYS = 2;
OPEN_EXISTING = 3;
OPEN_ALWAYS = 4;
TRUNCATE_EXISTING = 5;
CREATE_NEW :: 1;
CREATE_ALWAYS :: 2;
OPEN_EXISTING :: 3;
OPEN_ALWAYS :: 4;
TRUNCATE_EXISTING :: 5;
FILE_ATTRIBUTE_READONLY = 0x00000001;
FILE_ATTRIBUTE_HIDDEN = 0x00000002;
FILE_ATTRIBUTE_SYSTEM = 0x00000004;
FILE_ATTRIBUTE_DIRECTORY = 0x00000010;
FILE_ATTRIBUTE_ARCHIVE = 0x00000020;
FILE_ATTRIBUTE_DEVICE = 0x00000040;
FILE_ATTRIBUTE_NORMAL = 0x00000080;
FILE_ATTRIBUTE_TEMPORARY = 0x00000100;
FILE_ATTRIBUTE_SPARSE_FILE = 0x00000200;
FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400;
FILE_ATTRIBUTE_COMPRESSED = 0x00000800;
FILE_ATTRIBUTE_OFFLINE = 0x00001000;
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000;
FILE_ATTRIBUTE_ENCRYPTED = 0x00004000;
FILE_ATTRIBUTE_READONLY :: 0x00000001;
FILE_ATTRIBUTE_HIDDEN :: 0x00000002;
FILE_ATTRIBUTE_SYSTEM :: 0x00000004;
FILE_ATTRIBUTE_DIRECTORY :: 0x00000010;
FILE_ATTRIBUTE_ARCHIVE :: 0x00000020;
FILE_ATTRIBUTE_DEVICE :: 0x00000040;
FILE_ATTRIBUTE_NORMAL :: 0x00000080;
FILE_ATTRIBUTE_TEMPORARY :: 0x00000100;
FILE_ATTRIBUTE_SPARSE_FILE :: 0x00000200;
FILE_ATTRIBUTE_REPARSE_POINT :: 0x00000400;
FILE_ATTRIBUTE_COMPRESSED :: 0x00000800;
FILE_ATTRIBUTE_OFFLINE :: 0x00001000;
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED :: 0x00002000;
FILE_ATTRIBUTE_ENCRYPTED :: 0x00004000;
FILE_TYPE_DISK = 0x0001;
FILE_TYPE_CHAR = 0x0002;
FILE_TYPE_PIPE = 0x0003;
FILE_TYPE_DISK :: 0x0001;
FILE_TYPE_CHAR :: 0x0002;
FILE_TYPE_PIPE :: 0x0003;
INVALID_SET_FILE_POINTER = ~(0 as u32);
}
INVALID_SET_FILE_POINTER :: ~(0 as u32);
@@ -255,7 +247,7 @@ proc HeapFree (h HANDLE, flags u32, memory rawptr) -> BOOL #f
proc GetProcessHeap() -> HANDLE #foreign #dll_import
const HEAP_ZERO_MEMORY = 0x00000008;
HEAP_ZERO_MEMORY :: 0x00000008;
// Synchronization
@@ -265,7 +257,7 @@ type SECURITY_ATTRIBUTES struct #ordered {
inherit_handle BOOL;
}
const INFINITE = 0xffffffff;
INFINITE :: 0xffffffff;
proc CreateSemaphoreA (attributes ^SECURITY_ATTRIBUTES, initial_count, maximum_count i32, name ^byte) -> HANDLE #foreign #dll_import
proc ReleaseSemaphore (semaphore HANDLE, release_count i32, previous_count ^i32) -> BOOL #foreign #dll_import
@@ -314,11 +306,10 @@ type {
}
}
const {
BI_RGB = 0;
DIB_RGB_COLORS = 0x00;
SRCCOPY = 0x00cc0020 as u32;
}
BI_RGB :: 0;
DIB_RGB_COLORS :: 0x00;
SRCCOPY: u32 : 0x00cc0020;
proc StretchDIBits(hdc HDC,
x_dst, y_dst, width_dst, height_dst i32,
@@ -338,29 +329,27 @@ proc GetClientRect(hwnd HWND, rect ^RECT) -> BOOL #foreign
// Windows OpenGL
const {
PFD_TYPE_RGBA = 0;
PFD_TYPE_COLORINDEX = 1;
PFD_MAIN_PLANE = 0;
PFD_OVERLAY_PLANE = 1;
PFD_UNDERLAY_PLANE = -1;
PFD_DOUBLEBUFFER = 1;
PFD_STEREO = 2;
PFD_DRAW_TO_WINDOW = 4;
PFD_DRAW_TO_BITMAP = 8;
PFD_SUPPORT_GDI = 16;
PFD_SUPPORT_OPENGL = 32;
PFD_GENERIC_FORMAT = 64;
PFD_NEED_PALETTE = 128;
PFD_NEED_SYSTEM_PALETTE = 0x00000100;
PFD_SWAP_EXCHANGE = 0x00000200;
PFD_SWAP_COPY = 0x00000400;
PFD_SWAP_LAYER_BUFFERS = 0x00000800;
PFD_GENERIC_ACCELERATED = 0x00001000;
PFD_DEPTH_DONTCARE = 0x20000000;
PFD_DOUBLEBUFFER_DONTCARE = 0x40000000;
PFD_STEREO_DONTCARE = 0x80000000;
}
PFD_TYPE_RGBA :: 0;
PFD_TYPE_COLORINDEX :: 1;
PFD_MAIN_PLANE :: 0;
PFD_OVERLAY_PLANE :: 1;
PFD_UNDERLAY_PLANE :: -1;
PFD_DOUBLEBUFFER :: 1;
PFD_STEREO :: 2;
PFD_DRAW_TO_WINDOW :: 4;
PFD_DRAW_TO_BITMAP :: 8;
PFD_SUPPORT_GDI :: 16;
PFD_SUPPORT_OPENGL :: 32;
PFD_GENERIC_FORMAT :: 64;
PFD_NEED_PALETTE :: 128;
PFD_NEED_SYSTEM_PALETTE :: 0x00000100;
PFD_SWAP_EXCHANGE :: 0x00000200;
PFD_SWAP_COPY :: 0x00000400;
PFD_SWAP_LAYER_BUFFERS :: 0x00000800;
PFD_GENERIC_ACCELERATED :: 0x00001000;
PFD_DEPTH_DONTCARE :: 0x20000000;
PFD_DOUBLEBUFFER_DONTCARE :: 0x40000000;
PFD_STEREO_DONTCARE :: 0x80000000;
type {
HGLRC HANDLE;
@@ -406,13 +395,11 @@ proc ChoosePixelFormat(hdc HDC, pfd ^PIXELFORMATDESCRIPTOR) -> i32 #foreign #dll
proc SwapBuffers (hdc HDC) -> BOOL #foreign #dll_import
proc ReleaseDC (wnd HWND, hdc HDC) -> i32 #foreign #dll_import
const {
WGL_CONTEXT_MAJOR_VERSION_ARB = 0x2091;
WGL_CONTEXT_MINOR_VERSION_ARB = 0x2092;
WGL_CONTEXT_PROFILE_MASK_ARB = 0x9126;
WGL_CONTEXT_CORE_PROFILE_BIT_ARB = 0x0001;
WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB = 0x0002;
}
WGL_CONTEXT_MAJOR_VERSION_ARB :: 0x2091;
WGL_CONTEXT_MINOR_VERSION_ARB :: 0x2092;
WGL_CONTEXT_PROFILE_MASK_ARB :: 0x9126;
WGL_CONTEXT_CORE_PROFILE_BIT_ARB :: 0x0001;
WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB :: 0x0002;
proc wglCreateContext (hdc HDC) -> HGLRC #foreign #dll_import
proc wglMakeCurrent (hdc HDC, hglrc HGLRC) -> BOOL #foreign #dll_import
+68 -74
View File
@@ -1,53 +1,49 @@
const {
RUNE_ERROR = '\ufffd';
RUNE_SELF = 0x80;
RUNE_BOM = 0xfeff;
RUNE_EOF = ~(0 as rune);
MAX_RUNE = '\U0010ffff';
UTF_MAX = 4;
RUNE_ERROR :: '\ufffd';
RUNE_SELF :: 0x80;
RUNE_BOM :: 0xfeff;
RUNE_EOF :: ~(0 as rune);
MAX_RUNE :: '\U0010ffff';
UTF_MAX :: 4;
SURROGATE_MIN = 0xd800;
SURROGATE_MAX = 0xdfff;
}
SURROGATE_MIN :: 0xd800;
SURROGATE_MAX :: 0xdfff;
type Accept_Range struct {
lo, hi u8;
}
var {
accept_ranges = [5]Accept_Range{
{0x80, 0xbf},
{0xa0, 0xbf},
{0x80, 0x9f},
{0x90, 0xbf},
{0x80, 0x8f},
};
accept_ranges := [5]Accept_Range{
{0x80, 0xbf},
{0xa0, 0xbf},
{0x80, 0x9f},
{0x90, 0xbf},
{0x80, 0x8f},
};
accept_sizes = [256]byte{
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x00-0x0f
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x10-0x1f
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x20-0x2f
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x30-0x3f
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x40-0x4f
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x50-0x5f
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x60-0x6f
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x70-0x7f
accept_sizes := [256]byte{
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x00-0x0f
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x10-0x1f
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x20-0x2f
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x30-0x3f
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x40-0x4f
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x50-0x5f
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x60-0x6f
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x70-0x7f
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, // 0x80-0x8f
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, // 0x90-0x9f
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, // 0xa0-0xaf
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, // 0xb0-0xbf
0xf1, 0xf1, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, // 0xc0-0xcf
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, // 0xd0-0xdf
0x13, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x23, 0x03, 0x03, // 0xe0-0xef
0x34, 0x04, 0x04, 0x04, 0x44, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, // 0xf0-0xff
};
}
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, // 0x80-0x8f
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, // 0x90-0x9f
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, // 0xa0-0xaf
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, // 0xb0-0xbf
0xf1, 0xf1, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, // 0xc0-0xcf
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, // 0xd0-0xdf
0x13, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x23, 0x03, 0x03, // 0xe0-0xef
0x34, 0x04, 0x04, 0x04, 0x44, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, // 0xf0-0xff
};
proc encode_rune(r rune) -> ([4]byte, int) {
var buf [4]byte;
var i = r as u32;
const mask = 0x3f as byte;
buf: [4]byte;
i := r as u32;
mask: byte : 0x3f;
if i <= 1<<7-1 {
buf[0] = r as byte;
return buf, 1;
@@ -79,44 +75,42 @@ proc encode_rune(r rune) -> ([4]byte, int) {
}
proc decode_rune(s string) -> (rune, int) {
var n = s.count;
n := s.count;
if n < 1 {
return RUNE_ERROR, 0;
}
var b0 = s[0];
var x = accept_sizes[b0];
b0 := s[0];
x := accept_sizes[b0];
if x >= 0xf0 {
var mask = (x as rune << 31) >> 31; // all zeros or all ones
mask := (x as rune << 31) >> 31; // all zeros or all ones
return (b0 as rune) &~ mask | RUNE_ERROR&mask, 1;
}
var size = x & 7;
var ar = accept_ranges[x>>4];
size := x & 7;
ar := accept_ranges[x>>4];
if n < size as int {
return RUNE_ERROR, 1;
}
var b1 = s[1];
b1 := s[1];
if b1 < ar.lo || ar.hi < b1 {
return RUNE_ERROR, 1;
}
const {
MASK_X = 0b00111111;
MASK_2 = 0b00011111;
MASK_3 = 0b00001111;
MASK_4 = 0b00000111;
}
MASK_X :: 0b00111111;
MASK_2 :: 0b00011111;
MASK_3 :: 0b00001111;
MASK_4 :: 0b00000111;
if size == 2 {
return (b0&MASK_2) as rune <<6 | (b1&MASK_X) as rune, 2;
}
var b2 = s[2];
b2 := s[2];
if b2 < 0x80 || 0xbf < b2 {
return RUNE_ERROR, 1;
}
if size == 3 {
return (b0&MASK_3) as rune <<12 | (b1&MASK_X) as rune <<6 | (b2&MASK_X) as rune, 3;
}
var b3 = s[3];
b3 := s[3];
if b3 < 0x80 || 0xbf < b3 {
return RUNE_ERROR, 1;
}
@@ -137,31 +131,31 @@ proc valid_rune(r rune) -> bool {
}
proc valid_string(s string) -> bool {
var n = s.count;
for var i = 0; i < n; {
var si = s[i];
n := s.count;
for i := 0; i < n; {
si := s[i];
if si < RUNE_SELF { // ascii
i++;
continue;
}
var x = accept_sizes[si];
x := accept_sizes[si];
if x == 0xf1 {
return false;
}
var size = (x & 7) as int;
size := (x & 7) as int;
if i+size > n {
return false;
}
var ar = accept_ranges[x>>4];
if var b = s[i+1]; b < ar.lo || ar.hi < b {
ar := accept_ranges[x>>4];
if b := s[i+1]; b < ar.lo || ar.hi < b {
return false;
} else if size == 2 {
// Okay
} else if var b = s[i+2]; b < 0x80 || 0xbf < b {
} else if b := s[i+2]; b < 0x80 || 0xbf < b {
return false;
} else if size == 3 {
// Okay
} else if var b = s[i+3]; b < 0x80 || 0xbf < b {
} else if b := s[i+3]; b < 0x80 || 0xbf < b {
return false;
}
i += size;
@@ -170,34 +164,34 @@ proc valid_string(s string) -> bool {
}
proc rune_count(s string) -> int {
var count = 0;
var n = s.count;
for var i = 0; i < n; count++ {
var si = s[i];
count := 0;
n := s.count;
for i := 0; i < n; count++ {
si := s[i];
if si < RUNE_SELF { // ascii
i++;
continue;
}
var x = accept_sizes[si];
x := accept_sizes[si];
if x == 0xf1 {
i++;
continue;
}
var size = (x & 7) as int;
size := (x & 7) as int;
if i+size > n {
i++;
continue;
}
var ar = accept_ranges[x>>4];
if var b = s[i+1]; b < ar.lo || ar.hi < b {
ar := accept_ranges[x>>4];
if b := s[i+1]; b < ar.lo || ar.hi < b {
size = 1;
} else if size == 2 {
// Okay
} else if var b = s[i+2]; b < 0x80 || 0xbf < b {
} else if b := s[i+2]; b < 0x80 || 0xbf < b {
size = 1;
} else if size == 3 {
// Okay
} else if var b = s[i+3]; b < 0x80 || 0xbf < b {
} else if b := s[i+3]; b < 0x80 || 0xbf < b {
size = 1;
}
i += size;
+95 -111
View File
@@ -1075,36 +1075,33 @@ void init_preload(Checker *c) {
c->done_preload = true;
}
bool check_arity_match(Checker *c, AstNodeValueSpec *s, AstNodeValueSpec *init);
bool check_arity_match(Checker *c, AstNodeValueDecl *d);
#include "expr.c"
#include "decl.c"
#include "stmt.c"
bool check_arity_match(Checker *c, AstNodeValueSpec *s, AstNodeValueSpec *init) {
isize lhs = s->names.count;
isize rhs = s->values.count;
if (init != NULL) {
rhs = init->values.count;
}
bool check_arity_match(Checker *c, AstNodeValueDecl *d) {
isize lhs = d->names.count;
isize rhs = d->values.count;
if (init == NULL && rhs == 0) {
if (s->type == NULL) {
error_node(s->names.e[0], "Missing type or initial expression");
if (rhs == 0) {
if (d->type == NULL) {
error_node(d->names.e[0], "Missing type or initial expression");
return false;
}
} else if (lhs < rhs) {
if (lhs < s->values.count) {
AstNode *n = s->values.e[lhs];
if (lhs < d->values.count) {
AstNode *n = d->values.e[lhs];
gbString str = expr_to_string(n);
error_node(n, "Extra initial expression `%s`", str);
gb_string_free(str);
} else {
error_node(s->names.e[0], "Extra initial expression");
error_node(d->names.e[0], "Extra initial expression");
}
return false;
} else if (lhs > rhs && (init != NULL || rhs != 1)) {
AstNode *n = s->names.e[rhs];
} else if (lhs > rhs && rhs != 1) {
AstNode *n = d->names.e[rhs];
gbString str = expr_to_string(n);
error_node(n, "Missing expression for `%s`", str);
gb_string_free(str);
@@ -1160,15 +1157,95 @@ void check_global_collect_entities_from_file(Checker *c, Scope *parent_scope, As
switch (decl->kind) {
case_ast_node(bd, BadDecl, decl);
case_end;
case_ast_node(vd, ValueDecl, decl);
if (vd->is_var) {
// NOTE(bill): You need to store the entity information here unline a constant declaration
isize entity_count = vd->names.count;
isize entity_index = 0;
Entity **entities = gb_alloc_array(c->allocator, Entity *, entity_count);
DeclInfo *di = NULL;
if (vd->values.count > 0) {
di = make_declaration_info(heap_allocator(), parent_scope);
di->entities = entities;
di->entity_count = entity_count;
di->type_expr = vd->type;
di->init_expr = vd->values.e[0];
}
for_array(i, vd->names) {
AstNode *name = vd->names.e[i];
AstNode *value = NULL;
if (i < vd->values.count) {
value = vd->values.e[i];
}
if (name->kind != AstNode_Ident) {
error_node(name, "A declaration's name must be an identifier, got %.*s", LIT(ast_node_strings[name->kind]));
continue;
}
Entity *e = make_entity_variable(c->allocator, parent_scope, name->Ident, NULL);
e->identifier = name;
entities[entity_index++] = e;
DeclInfo *d = di;
if (d == NULL) {
AstNode *init_expr = value;
d = make_declaration_info(heap_allocator(), e->scope);
d->type_expr = vd->type;
d->init_expr = init_expr;
d->var_decl_tags = vd->tags;
}
add_entity_and_decl_info(c, name, e, d);
}
check_arity_match(c, vd);
} else {
for_array(i, vd->names) {
AstNode *name = vd->names.e[i];
if (name->kind != AstNode_Ident) {
error_node(name, "A declaration's name must be an identifier, got %.*s", LIT(ast_node_strings[name->kind]));
continue;
}
AstNode *init = NULL;
if (i < vd->values.count) {
init = vd->values.e[i];
}
DeclInfo *d = make_declaration_info(c->allocator, parent_scope);
Entity *e = NULL;
AstNode *up_init = unparen_expr(init);
if (init != NULL && is_ast_node_type(up_init)) {
e = make_entity_type_name(c->allocator, d->scope, name->Ident, NULL);
d->type_expr = init;
d->init_expr = init;
} else if (init != NULL && up_init->kind == AstNode_ProcLit) {
e = make_entity_procedure(c->allocator, d->scope, name->Ident, NULL, up_init->ProcLit.tags);
d->proc_decl = init;
} else {
e = make_entity_constant(c->allocator, d->scope, name->Ident, NULL, (ExactValue){0});
d->type_expr = vd->type;
d->init_expr = init;
}
GB_ASSERT(e != NULL);
e->identifier = name;
add_entity_and_decl_info(c, name, e, d);
}
check_arity_match(c, vd);
}
case_end;
case_ast_node(gd, GenericDecl, decl);
if (!parent_scope->is_file) {
// NOTE(bill): Within a procedure, variables must be in order
continue;
}
AstNodeValueSpec empty_spec_ = {0}, *empty_spec = &empty_spec_;
AstNodeValueSpec *prev_spec = NULL;
for_array(iota, gd->specs) {
AstNode *spec = gd->specs.e[iota];
switch (spec->kind) {
@@ -1183,99 +1260,6 @@ void check_global_collect_entities_from_file(Checker *c, Scope *parent_scope, As
DelayedDecl di = {parent_scope, spec};
array_add(&c->delayed_imports, di);
case_end;
case_ast_node(vs, ValueSpec, spec);
switch (vs->keyword) {
case Token_var: {
// NOTE(bill): You need to store the entity information here unline a constant declaration
isize entity_count = vs->names.count;
isize entity_index = 0;
Entity **entities = gb_alloc_array(c->allocator, Entity *, entity_count);
DeclInfo *di = NULL;
if (vs->values.count > 0) {
di = make_declaration_info(heap_allocator(), parent_scope);
di->entities = entities;
di->entity_count = entity_count;
di->type_expr = vs->type;
di->init_expr = vs->values.e[0];
}
for_array(i, vs->names) {
AstNode *name = vs->names.e[i];
AstNode *value = NULL;
if (i < vs->values.count) {
value = vs->values.e[i];
}
if (name->kind != AstNode_Ident) {
error_node(name, "A declaration's name must be an identifier, got %.*s", LIT(ast_node_strings[name->kind]));
continue;
}
Entity *e = make_entity_variable(c->allocator, parent_scope, name->Ident, NULL);
e->identifier = name;
entities[entity_index++] = e;
DeclInfo *d = di;
if (d == NULL) {
AstNode *init_expr = value;
d = make_declaration_info(heap_allocator(), e->scope);
d->type_expr = vs->type;
d->init_expr = init_expr;
d->var_decl_tags = gd->tags;
}
add_entity_and_decl_info(c, name, e, d);
}
check_arity_match(c, vs, NULL);
} break;
case Token_const: {
if (vs->type != NULL || vs->values.count > 0) {
prev_spec = vs;
} else if (prev_spec == NULL) {
prev_spec = empty_spec;
}
for_array(i, vs->names) {
AstNode *name = vs->names.e[i];
if (name->kind != AstNode_Ident) {
error_node(name, "A declaration's name must be an identifier, got %.*s", LIT(ast_node_strings[name->kind]));
continue;
}
AstNode *init = NULL;
if (i < prev_spec->values.count) {
init = prev_spec->values.e[i];
}
DeclInfo *d = make_declaration_info(c->allocator, parent_scope);
Entity *e = NULL;
ExactValue v_iota = make_exact_value_integer(iota);
AstNode *up_init = unparen_expr(init);
if (init != NULL && is_ast_node_type(up_init)) {
e = make_entity_type_name(c->allocator, d->scope, name->Ident, NULL);
d->type_expr = init;
d->init_expr = init;
} else if (init != NULL && up_init->kind == AstNode_ProcLit) {
e = make_entity_procedure(c->allocator, d->scope, name->Ident, NULL, up_init->ProcLit.tags);
d->proc_decl = init;
} else {
e = make_entity_constant(c->allocator, d->scope, name->Ident, NULL, v_iota);
d->type_expr = prev_spec->type;
d->init_expr = init;
}
GB_ASSERT(e != NULL);
e->identifier = name;
add_entity_and_decl_info(c, name, e, d);
}
check_arity_match(c, vs, prev_spec);
} break;
}
case_end;
case_ast_node(ts, TypeSpec, spec);
if (ts->name->kind != AstNode_Ident) {
+11 -11
View File
@@ -107,14 +107,14 @@ void check_init_variables(Checker *c, Entity **lhs, isize lhs_count, AstNodeArra
gb_temp_arena_memory_end(tmp);
}
void check_var_spec_node(Checker *c, AstNodeValueSpec *vs) {
GB_ASSERT(vs->keyword == Token_var);
isize entity_count = vs->names.count;
void check_var_decl_node(Checker *c, AstNodeValueDecl *vd) {
GB_ASSERT(vd->is_var == true);
isize entity_count = vd->names.count;
isize entity_index = 0;
Entity **entities = gb_alloc_array(c->allocator, Entity *, entity_count);
for_array(i, vs->names) {
AstNode *name = vs->names.e[i];
for_array(i, vd->names) {
AstNode *name = vd->names.e[i];
Entity *entity = NULL;
if (name->kind == AstNode_Ident) {
Token token = name->Ident;
@@ -145,8 +145,8 @@ void check_var_spec_node(Checker *c, AstNodeValueSpec *vs) {
}
Type *init_type = NULL;
if (vs->type) {
init_type = check_type_extra(c, vs->type, NULL);
if (vd->type) {
init_type = check_type_extra(c, vd->type, NULL);
if (init_type == NULL) {
init_type = t_invalid;
}
@@ -165,12 +165,12 @@ void check_var_spec_node(Checker *c, AstNodeValueSpec *vs) {
e->type = init_type;
}
check_arity_match(c, vs, NULL);
check_init_variables(c, entities, entity_count, vs->values, str_lit("variable declaration"));
check_arity_match(c, vd);
check_init_variables(c, entities, entity_count, vd->values, str_lit("variable declaration"));
for_array(i, vs->names) {
for_array(i, vd->names) {
if (entities[i] != NULL) {
add_entity(c, c->context.scope, vs->names.e[i], entities[i]);
add_entity(c, c->context.scope, vd->names.e[i], entities[i]);
}
}
+46 -59
View File
@@ -85,71 +85,58 @@ void check_local_collect_entities(Checker *c, AstNodeArray nodes, DelayedEntitie
case_ast_node(ws, WhenStmt, node);
// Will be handled later
case_end;
case_ast_node(gd, GenericDecl, node);
AstNodeValueSpec empty_spec_ = {0}, *empty_spec = &empty_spec_;
AstNodeValueSpec *last = NULL;
case_ast_node(vd, ValueDecl, node);
if (vd->is_var) {
// NOTE(bill): Handled later
} else {
for_array(i, vd->names) {
AstNode *name = vd->names.e[i];
if (name->kind != AstNode_Ident) {
error_node(name, "A declaration's name must be an identifier, got %.*s", LIT(ast_node_strings[name->kind]));
continue;
}
AstNode *init = NULL;
if (i < vd->values.count) {
init = vd->values.e[i];
}
DeclInfo *d = make_declaration_info(c->allocator, c->context.scope);
Entity *e = NULL;
AstNode *up_init = unparen_expr(init);
if (init != NULL && is_ast_node_type(up_init)) {
e = make_entity_type_name(c->allocator, d->scope, name->Ident, NULL);
d->type_expr = init;
d->init_expr = init;
} else if (init != NULL && up_init->kind == AstNode_ProcLit) {
e = make_entity_procedure(c->allocator, d->scope, name->Ident, NULL, up_init->ProcLit.tags);
d->proc_decl = init;
} else {
e = make_entity_constant(c->allocator, d->scope, name->Ident, NULL, (ExactValue){0});
d->type_expr = vd->type;
d->init_expr = init;
}
GB_ASSERT(e != NULL);
e->identifier = name;
add_entity_and_decl_info(c, name, e, d);
DelayedEntity delay = {name, e, d};
array_add(delayed_entities, delay);
}
check_arity_match(c, vd);
}
case_end;
case_ast_node(gd, GenericDecl, node);
for_array(iota, gd->specs) {
AstNode *spec = gd->specs.e[iota];
switch (spec->kind) {
case_ast_node(bd, BadDecl, spec);
case_end;
case_ast_node(vs, ValueSpec, spec);
switch (vs->keyword) {
case Token_var:
break;
case Token_const: {
if (vs->type != NULL || vs->values.count > 0) {
last = vs;
} else if (last == NULL) {
last = empty_spec;
}
for_array(i, vs->names) {
AstNode *name = vs->names.e[i];
if (name->kind != AstNode_Ident) {
error_node(name, "A declaration's name must be an identifier, got %.*s", LIT(ast_node_strings[name->kind]));
continue;
}
AstNode *init = NULL;
if (i < vs->values.count) {
init = vs->values.e[i];
}
DeclInfo *d = make_declaration_info(c->allocator, c->context.scope);
Entity *e = NULL;
ExactValue v_iota = make_exact_value_integer(iota);
AstNode *up_init = unparen_expr(init);
if (init != NULL && is_ast_node_type(up_init)) {
e = make_entity_type_name(c->allocator, d->scope, name->Ident, NULL);
d->type_expr = init;
d->init_expr = init;
} else if (init != NULL && up_init->kind == AstNode_ProcLit) {
e = make_entity_procedure(c->allocator, d->scope, name->Ident, NULL, up_init->ProcLit.tags);
d->proc_decl = init;
} else {
e = make_entity_constant(c->allocator, d->scope, name->Ident, NULL, v_iota);
d->type_expr = vs->type;
d->init_expr = init;
}
GB_ASSERT(e != NULL);
e->identifier = name;
add_entity_and_decl_info(c, name, e, d);
DelayedEntity delay = {name, e, d};
array_add(delayed_entities, delay);
}
check_arity_match(c, vs, last);
} break;
}
case_end;
case_ast_node(ts, TypeSpec, spec);
if (ts->name->kind != AstNode_Ident) {
error_node(ts->name, "A declaration's name must be an identifier, got %.*s", LIT(ast_node_strings[ts->name->kind]));
+102 -111
View File
@@ -1026,48 +1026,45 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
}
case_end;
case_ast_node(gd, GenericDecl, us->node);
for_array(spec_index, gd->specs) {
AstNode *spec = gd->specs.e[spec_index];
switch (spec->kind) {
case_ast_node(vs, ValueSpec, spec);
if (vs->keyword != Token_var) {
error_node(spec, "`using` can only be applied to a variable declaration");
return;
}
case_ast_node(vd, ValueDecl, us->node);
if (!vd->is_var) {
error_node(us->node, "`using` can only be applied to a variable declaration");
return;
}
if (vs->names.count > 1 && vs->type != NULL) {
error(us->token, "`using` can only be applied to one variable of the same type");
}
if (vd->names.count > 1 && vd->type != NULL) {
error(us->token, "`using` can only be applied to one variable of the same type");
}
check_var_spec_node(c, vs);
check_var_decl_node(c, vd);
for_array(name_index, vs->names) {
AstNode *item = vs->names.e[name_index];
ast_node(i, Ident, item);
String name = i->string;
Entity *e = scope_lookup_entity(c->context.scope, name);
Type *t = base_type(type_deref(e->type));
if (is_type_struct(t) || is_type_raw_union(t)) {
Scope **found = map_scope_get(&c->info.scopes, hash_pointer(t->Record.node));
GB_ASSERT(found != NULL);
for_array(i, (*found)->elements.entries) {
Entity *f = (*found)->elements.entries.e[i].value;
if (f->kind == Entity_Variable) {
Entity *uvar = make_entity_using_variable(c->allocator, e, f->token, f->type);
Entity *prev = scope_insert_entity(c->context.scope, uvar);
if (prev != NULL) {
error(us->token, "Namespace collision while `using` `%.*s` of: %.*s", LIT(name), LIT(prev->token.string));
return;
}
}
for_array(name_index, vd->names) {
AstNode *item = vd->names.e[name_index];
if (item->kind != AstNode_Ident) {
// TODO(bill): Handle error here???
continue;
}
ast_node(i, Ident, item);
String name = i->string;
Entity *e = scope_lookup_entity(c->context.scope, name);
Type *t = base_type(type_deref(e->type));
if (is_type_struct(t) || is_type_raw_union(t)) {
Scope **found = map_scope_get(&c->info.scopes, hash_pointer(t->Record.node));
GB_ASSERT(found != NULL);
for_array(i, (*found)->elements.entries) {
Entity *f = (*found)->elements.entries.e[i].value;
if (f->kind == Entity_Variable) {
Entity *uvar = make_entity_using_variable(c->allocator, e, f->token, f->type);
Entity *prev = scope_insert_entity(c->context.scope, uvar);
if (prev != NULL) {
error(us->token, "Namespace collision while `using` `%.*s` of: %.*s", LIT(name), LIT(prev->token.string));
return;
}
} else {
error(us->token, "`using` can only be applied to variables of type struct or raw_union");
return;
}
}
case_end;
} else {
error(us->token, "`using` can only be applied to variables of type struct or raw_union");
return;
}
}
case_end;
@@ -1096,7 +1093,76 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
case_end;
case_ast_node(vd, ValueDecl, node);
if (vd->is_var) {
isize entity_count = vd->names.count;
isize entity_index = 0;
Entity **entities = gb_alloc_array(c->allocator, Entity *, entity_count);
for_array(i, vd->names) {
AstNode *name = vd->names.e[i];
Entity *entity = NULL;
if (name->kind == AstNode_Ident) {
Token token = name->Ident;
String str = token.string;
Entity *found = NULL;
// NOTE(bill): Ignore assignments to `_`
if (str_ne(str, str_lit("_"))) {
found = current_scope_lookup_entity(c->context.scope, str);
}
if (found == NULL) {
entity = make_entity_variable(c->allocator, c->context.scope, token, NULL);
add_entity_definition(&c->info, name, entity);
} else {
TokenPos pos = found->token.pos;
error(token,
"Redeclaration of `%.*s` in this scope\n"
"\tat %.*s(%td:%td)",
LIT(str), LIT(pos.file), pos.line, pos.column);
entity = found;
}
} else {
error_node(name, "A variable declaration must be an identifier");
}
if (entity == NULL) {
entity = make_entity_dummy_variable(c->allocator, c->global_scope, ast_node_token(name));
}
entities[entity_index++] = entity;
}
Type *init_type = NULL;
if (vd->type) {
init_type = check_type_extra(c, vd->type, NULL);
if (init_type == NULL) {
init_type = t_invalid;
}
}
for (isize i = 0; i < entity_count; i++) {
Entity *e = entities[i];
GB_ASSERT(e != NULL);
if (e->flags & EntityFlag_Visited) {
e->type = t_invalid;
continue;
}
e->flags |= EntityFlag_Visited;
if (e->type == NULL)
e->type = init_type;
}
check_arity_match(c, vd);
check_init_variables(c, entities, entity_count, vd->values, str_lit("variable declaration"));
for_array(i, vd->names) {
if (entities[i] != NULL) {
add_entity(c, c->context.scope, vd->names.e[i], entities[i]);
}
}
} else {
// NOTE(bill): Handled elsewhere
}
case_end;
case_ast_node(gd, GenericDecl, node);
for_array(spec_index, gd->specs) {
@@ -1104,81 +1170,6 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
switch (spec->kind) {
case_ast_node(bd, BadDecl, spec);
case_end;
case_ast_node(vs, ValueSpec, spec);
switch (vs->keyword) {
case Token_var: {
isize entity_count = vs->names.count;
isize entity_index = 0;
Entity **entities = gb_alloc_array(c->allocator, Entity *, entity_count);
for_array(i, vs->names) {
AstNode *name = vs->names.e[i];
Entity *entity = NULL;
if (name->kind == AstNode_Ident) {
Token token = name->Ident;
String str = token.string;
Entity *found = NULL;
// NOTE(bill): Ignore assignments to `_`
if (str_ne(str, str_lit("_"))) {
found = current_scope_lookup_entity(c->context.scope, str);
}
if (found == NULL) {
entity = make_entity_variable(c->allocator, c->context.scope, token, NULL);
add_entity_definition(&c->info, name, entity);
} else {
TokenPos pos = found->token.pos;
error(token,
"Redeclaration of `%.*s` in this scope\n"
"\tat %.*s(%td:%td)",
LIT(str), LIT(pos.file), pos.line, pos.column);
entity = found;
}
} else {
error_node(name, "A variable declaration must be an identifier");
}
if (entity == NULL) {
entity = make_entity_dummy_variable(c->allocator, c->global_scope, ast_node_token(name));
}
entities[entity_index++] = entity;
}
Type *init_type = NULL;
if (vs->type) {
init_type = check_type_extra(c, vs->type, NULL);
if (init_type == NULL) {
init_type = t_invalid;
}
}
for (isize i = 0; i < entity_count; i++) {
Entity *e = entities[i];
GB_ASSERT(e != NULL);
if (e->flags & EntityFlag_Visited) {
e->type = t_invalid;
continue;
}
e->flags |= EntityFlag_Visited;
if (e->type == NULL)
e->type = init_type;
}
check_arity_match(c, vs, NULL);
check_init_variables(c, entities, entity_count, vs->values, str_lit("variable declaration"));
for_array(i, vs->names) {
if (entities[i] != NULL) {
add_entity(c, c->context.scope, vs->names.e[i], entities[i]);
}
}
} break;
case Token_const:
// NOTE(bill): Handled elsewhere
break;
}
case_end;
case_ast_node(ts, TypeSpec, spec);
// NOTE(bill): Handled elsewhere
case_end;
+117 -67
View File
@@ -251,12 +251,6 @@ AST_NODE_KIND(_ComplexStmtBegin, "", i32) \
AST_NODE_KIND(_ComplexStmtEnd, "", i32) \
AST_NODE_KIND(_StmtEnd, "", i32) \
AST_NODE_KIND(_SpecBegin, "", i32) \
AST_NODE_KIND(ValueSpec, "value specification", struct { \
TokenKind keyword; \
AstNodeArray names; \
AstNode * type; \
AstNodeArray values; \
}) \
AST_NODE_KIND(TypeSpec, "type specification", struct { \
AstNode *name; \
AstNode *type; \
@@ -280,6 +274,13 @@ AST_NODE_KIND(_DeclBegin, "", i32) \
u64 tags; \
bool is_using; \
}) \
AST_NODE_KIND(ValueDecl, "value declaration", struct { \
bool is_var; \
AstNodeArray names; \
AstNode * type; \
AstNodeArray values; \
u64 tags; \
}) \
AST_NODE_KIND(ProcDecl, "procedure declaration", struct { \
AstNode *name; \
AstNode *type; \
@@ -498,14 +499,14 @@ Token ast_node_token(AstNode *node) {
return node->BadDecl.begin;
case AstNode_GenericDecl:
return node->GenericDecl.token;
case AstNode_ValueDecl:
return ast_node_token(node->ValueDecl.names.e[0]);
case AstNode_ProcDecl:
return ast_node_token(node->ProcDecl.name);
case AstNode_ForeignLibrary:
return node->ForeignLibrary.token;
case AstNode_ValueSpec:
return ast_node_token(node->ValueSpec.names.e[0]);
case AstNode_TypeSpec:
return ast_node_token(node->TypeSpec.name);
case AstNode_ImportSpec:
@@ -1076,12 +1077,12 @@ AstNode *make_generic_decl(AstFile *f, Token token, Token open, Token close, Ast
return result;
}
AstNode *make_value_spec(AstFile *f, TokenKind keyword, AstNodeArray names, AstNode *type, AstNodeArray values) {
AstNode *result = make_node(f, AstNode_ValueSpec);
result->ValueSpec.keyword = keyword;
result->ValueSpec.names = names;
result->ValueSpec.type = type;
result->ValueSpec.values = values;
AstNode *make_value_decl(AstFile *f, bool is_var, AstNodeArray names, AstNode *type, AstNodeArray values) {
AstNode *result = make_node(f, AstNode_ValueDecl);
result->ValueDecl.is_var = is_var;
result->ValueDecl.names = names;
result->ValueDecl.type = type;
result->ValueDecl.values = values;
return result;
}
@@ -1210,8 +1211,8 @@ void fix_advance_to_next_stmt(AstFile *f) {
case Token_Semicolon:
return;
case Token_var:
case Token_const:
// case Token_var:
// case Token_const:
case Token_type:
case Token_proc:
case Token_import:
@@ -2139,42 +2140,42 @@ AstNode *parse_generic_decl(AstFile *f, TokenKind keyword, ParserSpecProc spec_p
return make_generic_decl(f, token, open, close, specs, 0, false);
}
PARSE_SPEC_PROC(parse_value_spec) {
AstNodeArray names = parse_identfier_list(f);
parse_check_name_list_for_reserves(f, names);
AstNode *type = parse_type_attempt(f);
AstNodeArray values = {0};
// PARSE_SPEC_PROC(parse_value_spec) {
// AstNodeArray names = parse_identfier_list(f);
// parse_check_name_list_for_reserves(f, names);
// AstNode *type = parse_type_attempt(f);
// AstNodeArray values = {0};
if (allow_token(f, Token_Eq)) {
values = parse_rhs_expr_list(f);
}
// if (allow_token(f, Token_Eq)) {
// values = parse_rhs_expr_list(f);
// }
if (values.count > names.count) {
syntax_error(f->curr_token, "Too many values on the right hand side of the declaration");
}
// if (values.count > names.count) {
// syntax_error(f->curr_token, "Too many values on the right hand side of the declaration");
// }
switch (keyword) {
case Token_var:
if (type == NULL && values.count == 0 && names.count > 0) {
syntax_error(f->curr_token, "Missing type or initialization");
return make_bad_decl(f, f->curr_token, f->curr_token);
}
break;
case Token_const:
if (values.count == 0 && (index == 0 || type != NULL)) {
syntax_error(f->curr_token, "Missing constant value");
return make_bad_decl(f, f->curr_token, f->curr_token);
}
break;
}
// switch (keyword) {
// case Token_var:
// if (type == NULL && values.count == 0 && names.count > 0) {
// syntax_error(f->curr_token, "Missing type or initialization");
// return make_bad_decl(f, f->curr_token, f->curr_token);
// }
// break;
// case Token_const:
// if (values.count == 0 && (index == 0 || type != NULL)) {
// syntax_error(f->curr_token, "Missing constant value");
// return make_bad_decl(f, f->curr_token, f->curr_token);
// }
// break;
// }
// TODO(bill): Fix this so it does not require it
if (values.e == NULL) {
values = make_ast_node_array(f);
}
// // TODO(bill): Fix this so it does not require it
// if (values.e == NULL) {
// values = make_ast_node_array(f);
// }
return make_value_spec(f, keyword, names, type, values);
}
// return make_value_spec(f, keyword, names, type, values);
// }
PARSE_SPEC_PROC(parse_type_spec) {
AstNode *name = parse_identifier(f);
AstNode *type = parse_type(f);
@@ -2239,9 +2240,9 @@ PARSE_SPEC_PROC(parse_include_spec) {
AstNode *parse_decl(AstFile *f) {
switch (f->curr_token.kind) {
case Token_var:
case Token_const:
return parse_generic_decl(f, f->curr_token.kind, parse_value_spec);
// case Token_var:
// case Token_const:
// return parse_generic_decl(f, f->curr_token.kind, parse_value_spec);
case Token_type:
return parse_generic_decl(f, f->curr_token.kind, parse_type_spec);
@@ -2266,12 +2267,7 @@ AstNode *parse_decl(AstFile *f) {
AstNode *parse_simple_stmt(AstFile *f) {
switch (f->curr_token.kind) {
case Token_var:
case Token_const:
return parse_decl(f);
}
Token start_token = f->curr_token;
AstNodeArray lhs = parse_lhs_expr_list(f);
Token token = f->curr_token;
switch (token.kind) {
@@ -2302,6 +2298,61 @@ AstNode *parse_simple_stmt(AstFile *f) {
}
return make_assign_stmt(f, token, lhs, rhs);
} break;
case Token_Colon: {
parse_check_name_list_for_reserves(f, lhs);
AstNode *type = NULL;
AstNodeArray values = {0};
bool is_mutable = true;
if (allow_token(f, Token_Colon)) {
if (!allow_token(f, Token_type)) {
type = parse_type_attempt(f);
}
} else if (f->curr_token.kind != Token_Eq &&
f->curr_token.kind != Token_Semicolon) {
syntax_error(f->curr_token, "Expected a type separator `:` or `=`");
}
switch (f->curr_token.kind) {
case Token_Colon:
is_mutable = false;
/*fallthrough*/
case Token_Eq:
next_token(f);
values = parse_rhs_expr_list(f);
if (values.count > lhs.count) {
syntax_error(f->curr_token, "Too many values on the right hand side of the declaration");
} else if (values.count < lhs.count && !is_mutable) {
syntax_error(f->curr_token, "All constant declarations must be defined");
} else if (values.count == 0) {
syntax_error(f->curr_token, "Expected an expression for this declaration");
}
break;
}
if (is_mutable) {
if (type == NULL && values.count == 0) {
syntax_error(f->curr_token, "Missing variable type or initialization");
return make_bad_decl(f, f->curr_token, f->curr_token);
}
} else {
if (type == NULL && values.count == 0 && lhs.count > 0) {
syntax_error(f->curr_token, "Missing constant value");
return make_bad_decl(f, f->curr_token, f->curr_token);
}
}
if (values.e == NULL) {
values = make_ast_node_array(f);
}
AstNodeArray specs = {0};
array_init_reserve(&specs, heap_allocator(), 1);
return make_value_decl(f, is_mutable, lhs, type, values);
} break;
}
if (lhs.count > 1) {
@@ -3025,8 +3076,8 @@ AstNode *parse_stmt(AstFile *f) {
expect_semicolon(f, s);
return s;
case Token_var:
case Token_const:
// case Token_var:
// case Token_const:
case Token_proc:
case Token_type:
case Token_import:
@@ -3063,14 +3114,12 @@ AstNode *parse_stmt(AstFile *f) {
while (e->kind == AstNode_SelectorExpr) {
e = unparen_expr(e->SelectorExpr.selector);
}
if (e->kind == AstNode_Ident) {
if (e->kind == AstNode_Ident) {
valid = true;
}
} break;
case AstNode_GenericDecl:
if (node->GenericDecl.token.kind == Token_var) {
valid = true;
}
case AstNode_ValueDecl:
valid = node->ValueDecl.is_var;
break;
}
@@ -3153,8 +3202,8 @@ AstNode *parse_stmt(AstFile *f) {
return s;
} else if (str_eq(tag, str_lit("thread_local"))) {
AstNode *decl = parse_simple_stmt(f);
if (decl->kind == AstNode_GenericDecl &&
decl->GenericDecl.token.kind != Token_var) {
if (decl->kind != AstNode_ValueDecl &&
!decl->ValueDecl.is_var) {
syntax_error(token, "#thread_local may only be applied to variable declarations");
return make_bad_decl(f, token, ast_node_token(decl));
}
@@ -3162,8 +3211,9 @@ AstNode *parse_stmt(AstFile *f) {
syntax_error(token, "#thread_local is only allowed at the file scope");
return make_bad_decl(f, token, ast_node_token(decl));
}
GB_ASSERT(decl->kind == AstNode_GenericDecl);
decl->GenericDecl.tags |= VarDeclTag_thread_local;
GB_ASSERT(decl->kind == AstNode_ValueDecl);
decl->ValueDecl.tags |= VarDeclTag_thread_local;
return decl;
} else if (str_eq(tag, str_lit("bounds_check"))) {
s = parse_stmt(f);
+56 -60
View File
@@ -3924,71 +3924,67 @@ void ssa_build_stmt_internal(ssaProcedure *proc, AstNode *node) {
ssa_build_when_stmt(proc, ws);
case_end;
case_ast_node(vd, ValueDecl, node);
if (vd->is_var) {
ssaModule *m = proc->module;
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&m->tmp_arena);
if (vd->values.count == 0) { // declared and zero-initialized
for_array(i, vd->names) {
AstNode *name = vd->names.e[i];
if (!ssa_is_blank_ident(name)) {
ssa_add_local_for_identifier(proc, name, true);
}
}
} else { // Tuple(s)
Array(ssaAddr) lvals;
ssaValueArray inits;
array_init_reserve(&lvals, m->tmp_allocator, vd->names.count);
array_init_reserve(&inits, m->tmp_allocator, vd->names.count);
for_array(i, vd->names) {
AstNode *name = vd->names.e[i];
ssaAddr lval = ssa_make_addr(NULL, NULL);
if (!ssa_is_blank_ident(name)) {
ssa_add_local_for_identifier(proc, name, false);
lval = ssa_build_addr(proc, name);
}
array_add(&lvals, lval);
}
for_array(i, vd->values) {
ssaValue *init = ssa_build_expr(proc, vd->values.e[i]);
Type *t = ssa_type(init);
if (t->kind == Type_Tuple) {
for (isize i = 0; i < t->Tuple.variable_count; i++) {
Entity *e = t->Tuple.variables[i];
ssaValue *v = ssa_emit_struct_ev(proc, init, i);
array_add(&inits, v);
}
} else {
array_add(&inits, init);
}
}
for_array(i, inits) {
if (lvals.e[i].addr == NULL) {
continue;
}
ssaValue *v = ssa_emit_conv(proc, inits.e[i], ssa_addr_type(lvals.e[i]));
ssa_addr_store(proc, lvals.e[i], v);
}
}
gb_temp_arena_memory_end(tmp);
}
case_end;
case_ast_node(gd, GenericDecl, node);
for_array(spec_index, gd->specs) {
AstNode *spec = gd->specs.e[spec_index];
switch (spec->kind) {
case_ast_node(vs, ValueSpec, spec);
switch (vs->keyword) {
case Token_const:
break;
case Token_var: {
ssaModule *m = proc->module;
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&m->tmp_arena);
if (vs->values.count == 0) { // declared and zero-initialized
for_array(i, vs->names) {
AstNode *name = vs->names.e[i];
if (!ssa_is_blank_ident(name)) {
ssa_add_local_for_identifier(proc, name, true);
}
}
} else { // Tuple(s)
Array(ssaAddr) lvals;
ssaValueArray inits;
array_init_reserve(&lvals, m->tmp_allocator, vs->names.count);
array_init_reserve(&inits, m->tmp_allocator, vs->names.count);
for_array(i, vs->names) {
AstNode *name = vs->names.e[i];
ssaAddr lval = ssa_make_addr(NULL, NULL);
if (!ssa_is_blank_ident(name)) {
ssa_add_local_for_identifier(proc, name, false);
lval = ssa_build_addr(proc, name);
}
array_add(&lvals, lval);
}
for_array(i, vs->values) {
ssaValue *init = ssa_build_expr(proc, vs->values.e[i]);
Type *t = ssa_type(init);
if (t->kind == Type_Tuple) {
for (isize i = 0; i < t->Tuple.variable_count; i++) {
Entity *e = t->Tuple.variables[i];
ssaValue *v = ssa_emit_struct_ev(proc, init, i);
array_add(&inits, v);
}
} else {
array_add(&inits, init);
}
}
for_array(i, inits) {
if (lvals.e[i].addr == NULL) {
continue;
}
ssaValue *v = ssa_emit_conv(proc, inits.e[i], ssa_addr_type(lvals.e[i]));
ssa_addr_store(proc, lvals.e[i], v);
}
}
gb_temp_arena_memory_end(tmp);
} break;
}
case_end;
case_ast_node(ts, TypeSpec, spec);
// NOTE(bill): Generate a new name
// parent_proc.name-guid
+2 -2
View File
@@ -84,8 +84,8 @@ TOKEN_KIND(Token__OperatorEnd, "_OperatorEnd"), \
TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \
TOKEN_KIND(Token_type, "type"), \
TOKEN_KIND(Token_proc, "proc"), \
TOKEN_KIND(Token_var, "var"), \
TOKEN_KIND(Token_const, "const"), \
/* TOKEN_KIND(Token_var, "var"), */\
/* TOKEN_KIND(Token_const, "const"), */\
TOKEN_KIND(Token_import, "import"), \
TOKEN_KIND(Token_include, "include"), \
TOKEN_KIND(Token_macro, "macro"), \