var/const decl; remove : from parameter lists

This commit is contained in:
Ginger Bill
2016-12-18 21:50:14 +00:00
parent 5217eb55b4
commit e370337f97
15 changed files with 2009 additions and 1989 deletions
+36 -39
View File
@@ -77,7 +77,7 @@ type Type_Info union {
}; };
}; };
proc type_info_base(info: ^Type_Info) -> ^Type_Info { proc type_info_base(info ^Type_Info) -> ^Type_Info {
if info == nil { if info == nil {
return nil; return nil;
} }
@@ -91,22 +91,22 @@ proc type_info_base(info: ^Type_Info) -> ^Type_Info {
proc assume(cond: bool) #foreign "llvm.assume" proc assume(cond bool) #foreign "llvm.assume"
proc __debug_trap () #foreign "llvm.debugtrap" proc __debug_trap () #foreign "llvm.debugtrap"
proc __trap () #foreign "llvm.trap" proc __trap () #foreign "llvm.trap"
proc read_cycle_counter() -> u64 #foreign "llvm.readcyclecounter" proc read_cycle_counter() -> u64 #foreign "llvm.readcyclecounter"
proc bit_reverse16(b: u16) -> u16 #foreign "llvm.bitreverse.i16" proc bit_reverse16(b u16) -> u16 #foreign "llvm.bitreverse.i16"
proc bit_reverse32(b: u32) -> u32 #foreign "llvm.bitreverse.i32" proc bit_reverse32(b u32) -> u32 #foreign "llvm.bitreverse.i32"
proc bit_reverse64(b: u64) -> u64 #foreign "llvm.bitreverse.i64" proc bit_reverse64(b u64) -> u64 #foreign "llvm.bitreverse.i64"
proc byte_swap16(b: u16) -> u16 #foreign "llvm.bswap.i16" proc byte_swap16(b u16) -> u16 #foreign "llvm.bswap.i16"
proc byte_swap32(b: u32) -> u32 #foreign "llvm.bswap.i32" proc byte_swap32(b u32) -> u32 #foreign "llvm.bswap.i32"
proc byte_swap64(b: u64) -> u64 #foreign "llvm.bswap.i64" proc byte_swap64(b u64) -> u64 #foreign "llvm.bswap.i64"
proc fmuladd32(a, b, c: f32) -> f32 #foreign "llvm.fmuladd.f32" proc fmuladd32(a, b, c f32) -> f32 #foreign "llvm.fmuladd.f32"
proc fmuladd64(a, b, c: f64) -> f64 #foreign "llvm.fmuladd.f64" proc fmuladd64(a, b, c f64) -> f64 #foreign "llvm.fmuladd.f64"
@@ -119,9 +119,9 @@ type Allocator_Mode enum {
FREE_ALL, FREE_ALL,
RESIZE, RESIZE,
} }
type Allocator_Proc proc(allocator_data: rawptr, mode: Allocator_Mode, type Allocator_Proc proc(allocator_data rawptr, mode Allocator_Mode,
size, alignment: int, size, alignment int,
old_memory: rawptr, old_size: int, flags: u64) -> rawptr; old_memory rawptr, old_size int, flags u64) -> rawptr;
@@ -140,10 +140,10 @@ type Context struct #ordered {
user_index: int; user_index: int;
} }
#thread_local __context: Context; #thread_local var __context Context;
DEFAULT_ALIGNMENT :: align_of([vector 4]f32); const DEFAULT_ALIGNMENT = align_of([vector 4]f32);
proc __check_context() { proc __check_context() {
@@ -157,15 +157,15 @@ proc __check_context() {
} }
} }
proc alloc(size: int) -> rawptr #inline { return alloc_align(size, DEFAULT_ALIGNMENT); } proc alloc(size int) -> rawptr #inline { return alloc_align(size, DEFAULT_ALIGNMENT); }
proc alloc_align(size, alignment: int) -> rawptr #inline { proc alloc_align(size, alignment int) -> rawptr #inline {
__check_context(); __check_context();
a := context.allocator; a := context.allocator;
return a.procedure(a.data, Allocator_Mode.ALLOC, size, alignment, nil, 0, 0); return a.procedure(a.data, Allocator_Mode.ALLOC, size, alignment, nil, 0, 0);
} }
proc free(ptr: rawptr) #inline { proc free(ptr rawptr) #inline {
__check_context(); __check_context();
a := context.allocator; a := context.allocator;
if ptr != nil { if ptr != nil {
@@ -179,8 +179,8 @@ 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 (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 { proc resize_align(ptr rawptr, old_size, new_size, alignment int) -> rawptr #inline {
__check_context(); __check_context();
a := context.allocator; a := context.allocator;
return a.procedure(a.data, Allocator_Mode.RESIZE, new_size, alignment, ptr, old_size, 0); return a.procedure(a.data, Allocator_Mode.RESIZE, new_size, alignment, ptr, old_size, 0);
@@ -188,7 +188,7 @@ proc resize_align(ptr: rawptr, old_size, new_size, alignment: int) -> rawptr #in
proc default_resize_align(old_memory: rawptr, old_size, new_size, alignment: int) -> rawptr { proc default_resize_align(old_memory rawptr, old_size, new_size, alignment int) -> rawptr {
if old_memory == nil { if old_memory == nil {
return alloc_align(new_size, alignment); return alloc_align(new_size, alignment);
} }
@@ -213,9 +213,9 @@ proc default_resize_align(old_memory: rawptr, old_size, new_size, alignment: int
} }
proc default_allocator_proc(allocator_data: rawptr, mode: Allocator_Mode, proc default_allocator_proc(allocator_data rawptr, mode Allocator_Mode,
size, alignment: int, size, alignment int,
old_memory: rawptr, old_size: int, flags: u64) -> rawptr { old_memory rawptr, old_size int, flags u64) -> rawptr {
using Allocator_Mode; using Allocator_Mode;
when false { when false {
match mode { match mode {
@@ -279,7 +279,7 @@ proc default_allocator() -> Allocator {
proc __string_eq(a, b: string) -> bool { proc __string_eq(a, b string) -> bool {
if a.count != b.count { if a.count != b.count {
return false; return false;
} }
@@ -289,25 +289,24 @@ proc __string_eq(a, b: string) -> bool {
return mem.compare(a.data, b.data, a.count) == 0; return mem.compare(a.data, b.data, a.count) == 0;
} }
proc __string_cmp(a, b : string) -> int { proc __string_cmp(a, b string) -> int {
return mem.compare(a.data, b.data, min(a.count, b.count)); return mem.compare(a.data, b.data, min(a.count, b.count));
} }
proc __string_ne(a, b: string) -> bool #inline { return !__string_eq(a, b); } proc __string_ne(a, b string) -> bool #inline { return !__string_eq(a, b); }
proc __string_lt(a, b: string) -> bool #inline { return __string_cmp(a, b) < 0; } proc __string_lt(a, b string) -> bool #inline { return __string_cmp(a, b) < 0; }
proc __string_gt(a, b: string) -> bool #inline { return __string_cmp(a, b) > 0; } proc __string_gt(a, b string) -> bool #inline { return __string_cmp(a, b) > 0; }
proc __string_le(a, b: string) -> bool #inline { return __string_cmp(a, b) <= 0; } proc __string_le(a, b string) -> bool #inline { return __string_cmp(a, b) <= 0; }
proc __string_ge(a, b: string) -> bool #inline { return __string_cmp(a, b) >= 0; } proc __string_ge(a, b string) -> bool #inline { return __string_cmp(a, b) >= 0; }
proc __assert(file: string, line, column: int, msg: string) #inline { proc __assert(file string, line, column int, msg string) #inline {
fmt.fprintf(os.stderr, "%(%:%) Runtime assertion: %\n", fmt.fprintf(os.stderr, "%(%:%) Runtime assertion: %\n",
file, line, column, msg); file, line, column, msg);
__debug_trap(); __debug_trap();
} }
proc __bounds_check_error(file: string, line, column: int, proc __bounds_check_error(file string, line, column int, index, count int) {
index, count: int) {
if 0 <= index && index < count { if 0 <= index && index < count {
return; return;
} }
@@ -316,8 +315,7 @@ proc __bounds_check_error(file: string, line, column: int,
__debug_trap(); __debug_trap();
} }
proc __slice_expr_error(file: string, line, column: int, proc __slice_expr_error(file string, line, column int, low, high, max int) {
low, high, max: int) {
if 0 <= low && low <= high && high <= max { if 0 <= low && low <= high && high <= max {
return; return;
} }
@@ -325,8 +323,7 @@ proc __slice_expr_error(file: string, line, column: int,
file, line, column, low, high, max); file, line, column, low, high, max);
__debug_trap(); __debug_trap();
} }
proc __substring_expr_error(file: string, line, column: int, proc __substring_expr_error(file string, line, column int, low, high int) {
low, high: int) {
if 0 <= low && low <= high { if 0 <= low && low <= high {
return; return;
} }
@@ -335,7 +332,7 @@ proc __substring_expr_error(file: string, line, column: int,
__debug_trap(); __debug_trap();
} }
proc __enum_to_string(info: ^Type_Info, value: i64) -> string { proc __enum_to_string(info ^Type_Info, value i64) -> string {
match type ti : type_info_base(info) { match type ti : type_info_base(info) {
case Type_Info.Enum: case Type_Info.Enum:
// TODO(bill): Search faster than linearly // TODO(bill): Search faster than linearly
+20 -20
View File
@@ -11,30 +11,30 @@ proc sfence () { win32.WriteBarrier(); }
proc lfence () { win32.ReadBarrier(); } proc lfence () { win32.ReadBarrier(); }
proc load32(a: ^i32) -> i32 { proc load32(a ^i32) -> i32 {
return a^; return a^;
} }
proc store32(a: ^i32, value: i32) { proc store32(a ^i32, value i32) {
a^ = value; a^ = value;
} }
proc compare_exchange32(a: ^i32, expected, desired: i32) -> i32 { proc compare_exchange32(a ^i32, expected, desired i32) -> i32 {
return win32.InterlockedCompareExchange(a, desired, expected); return win32.InterlockedCompareExchange(a, desired, expected);
} }
proc exchanged32(a: ^i32, desired: i32) -> i32 { proc exchanged32(a ^i32, desired i32) -> i32 {
return win32.InterlockedExchange(a, desired); return win32.InterlockedExchange(a, desired);
} }
proc fetch_add32(a: ^i32, operand: i32) -> i32 { proc fetch_add32(a ^i32, operand i32) -> i32 {
return win32.InterlockedExchangeAdd(a, operand); return win32.InterlockedExchangeAdd(a, operand);
} }
proc fetch_and32(a: ^i32, operand: i32) -> i32 { proc fetch_and32(a ^i32, operand i32) -> i32 {
return win32.InterlockedAnd(a, operand); return win32.InterlockedAnd(a, operand);
} }
proc fetch_or32(a: ^i32, operand: i32) -> i32 { proc fetch_or32(a ^i32, operand i32) -> i32 {
return win32.InterlockedOr(a, operand); return win32.InterlockedOr(a, operand);
} }
proc spin_lock32(a: ^i32, time_out: int) -> bool { // NOTE(bill): time_out = -1 as default proc spin_lock32(a ^i32, time_out int) -> bool { // NOTE(bill) time_out = -1 as default
old_value := compare_exchange32(a, 1, 0); old_value := compare_exchange32(a, 1, 0);
counter := 0; counter := 0;
for old_value != 0 && (time_out < 0 || counter < time_out) { for old_value != 0 && (time_out < 0 || counter < time_out) {
@@ -45,11 +45,11 @@ proc spin_lock32(a: ^i32, time_out: int) -> bool { // NOTE(bill): time_out = -1
} }
return old_value == 0; return old_value == 0;
} }
proc spin_unlock32(a: ^i32) { proc spin_unlock32(a ^i32) {
store32(a, 0); store32(a, 0);
mfence(); mfence();
} }
proc try_acquire_lock32(a: ^i32) -> bool { proc try_acquire_lock32(a ^i32) -> bool {
yield_thread(); yield_thread();
old_value := compare_exchange32(a, 1, 0); old_value := compare_exchange32(a, 1, 0);
mfence(); mfence();
@@ -57,28 +57,28 @@ proc try_acquire_lock32(a: ^i32) -> bool {
} }
proc load64(a: ^i64) -> i64 { proc load64(a ^i64) -> i64 {
return a^; return a^;
} }
proc store64(a: ^i64, value: i64) { proc store64(a ^i64, value i64) {
a^ = value; a^ = value;
} }
proc compare_exchange64(a: ^i64, expected, desired: i64) -> i64 { proc compare_exchange64(a ^i64, expected, desired i64) -> i64 {
return win32.InterlockedCompareExchange64(a, desired, expected); return win32.InterlockedCompareExchange64(a, desired, expected);
} }
proc exchanged64(a: ^i64, desired: i64) -> i64 { proc exchanged64(a ^i64, desired i64) -> i64 {
return win32.InterlockedExchange64(a, desired); return win32.InterlockedExchange64(a, desired);
} }
proc fetch_add64(a: ^i64, operand: i64) -> i64 { proc fetch_add64(a ^i64, operand i64) -> i64 {
return win32.InterlockedExchangeAdd64(a, operand); return win32.InterlockedExchangeAdd64(a, operand);
} }
proc fetch_and64(a: ^i64, operand: i64) -> i64 { proc fetch_and64(a ^i64, operand i64) -> i64 {
return win32.InterlockedAnd64(a, operand); return win32.InterlockedAnd64(a, operand);
} }
proc fetch_or64(a: ^i64, operand: i64) -> i64 { proc fetch_or64(a ^i64, operand i64) -> i64 {
return win32.InterlockedOr64(a, operand); return win32.InterlockedOr64(a, operand);
} }
proc spin_lock64(a: ^i64, time_out: int) -> bool { // NOTE(bill): time_out = -1 as default proc spin_lock64(a ^i64, time_out int) -> bool { // NOTE(bill) time_out = -1 as default
old_value := compare_exchange64(a, 1, 0); old_value := compare_exchange64(a, 1, 0);
counter := 0; counter := 0;
for old_value != 0 && (time_out < 0 || counter < time_out) { for old_value != 0 && (time_out < 0 || counter < time_out) {
@@ -89,11 +89,11 @@ proc spin_lock64(a: ^i64, time_out: int) -> bool { // NOTE(bill): time_out = -1
} }
return old_value == 0; return old_value == 0;
} }
proc spin_unlock64(a: ^i64) { proc spin_unlock64(a ^i64) {
store64(a, 0); store64(a, 0);
mfence(); mfence();
} }
proc try_acquire_lock64(a: ^i64) -> bool { proc try_acquire_lock64(a ^i64) -> bool {
yield_thread(); yield_thread();
old_value := compare_exchange64(a, 1, 0); old_value := compare_exchange64(a, 1, 0);
mfence(); mfence();
+34 -34
View File
@@ -2,9 +2,9 @@
#import "mem.odin"; #import "mem.odin";
#import "utf8.odin"; #import "utf8.odin";
PRINT_BUF_SIZE :: 1<<12; const PRINT_BUF_SIZE = 1<<12;
proc fprint(f: ^os.File, args: ..any) -> int { proc fprint(f ^os.File, args ..any) -> int {
data: [PRINT_BUF_SIZE]byte; data: [PRINT_BUF_SIZE]byte;
buf := data[:0]; buf := data[:0];
bprint(^buf, ..args); bprint(^buf, ..args);
@@ -12,14 +12,14 @@ proc fprint(f: ^os.File, args: ..any) -> int {
return buf.count; return buf.count;
} }
proc fprintln(f: ^os.File, args: ..any) -> int { proc fprintln(f ^os.File, args ..any) -> int {
data: [PRINT_BUF_SIZE]byte; data: [PRINT_BUF_SIZE]byte;
buf := data[:0]; buf := data[:0];
bprintln(^buf, ..args); bprintln(^buf, ..args);
os.write(f, buf); os.write(f, buf);
return buf.count; return buf.count;
} }
proc fprintf(f: ^os.File, fmt: string, args: ..any) -> int { proc fprintf(f ^os.File, fmt string, args ..any) -> int {
data: [PRINT_BUF_SIZE]byte; data: [PRINT_BUF_SIZE]byte;
buf := data[:0]; buf := data[:0];
bprintf(^buf, fmt, ..args); bprintf(^buf, fmt, ..args);
@@ -28,19 +28,19 @@ proc fprintf(f: ^os.File, fmt: string, args: ..any) -> int {
} }
proc print(args: ..any) -> int { proc print(args ..any) -> int {
return fprint(os.stdout, ..args); return fprint(os.stdout, ..args);
} }
proc println(args: ..any) -> int { proc println(args ..any) -> int {
return fprintln(os.stdout, ..args); return fprintln(os.stdout, ..args);
} }
proc printf(fmt: string, args: ..any) -> int { proc printf(fmt string, args ..any) -> int {
return fprintf(os.stdout, fmt, ..args); return fprintf(os.stdout, fmt, ..args);
} }
proc fprint_type(f: ^os.File, info: ^Type_Info) { proc fprint_type(f ^os.File, info ^Type_Info) {
data: [PRINT_BUF_SIZE]byte; data: [PRINT_BUF_SIZE]byte;
buf := data[:0]; buf := data[:0];
bprint_type(^buf, info); bprint_type(^buf, info);
@@ -49,7 +49,7 @@ proc fprint_type(f: ^os.File, info: ^Type_Info) {
proc print_byte_buffer(buf: ^[]byte, b: []byte) { proc print_byte_buffer(buf ^[]byte, b []byte) {
if buf.count < buf.capacity { if buf.count < buf.capacity {
n := min(buf.capacity-buf.count, b.count); n := min(buf.capacity-buf.count, b.count);
if n > 0 { if n > 0 {
@@ -59,29 +59,29 @@ proc print_byte_buffer(buf: ^[]byte, b: []byte) {
} }
} }
proc bprint_string(buf: ^[]byte, s: string) { proc bprint_string(buf ^[]byte, s string) {
print_byte_buffer(buf, s as []byte); print_byte_buffer(buf, s as []byte);
} }
proc byte_reverse(b: []byte) { proc byte_reverse(b []byte) {
n := b.count; n := b.count;
for i := 0; i < n/2; i++ { for i := 0; i < n/2; i++ {
b[i], b[n-1-i] = b[n-1-i], b[i]; b[i], b[n-1-i] = b[n-1-i], b[i];
} }
} }
proc bprint_rune(buf: ^[]byte, r: rune) { proc bprint_rune(buf ^[]byte, r rune) {
b, n := utf8.encode_rune(r); b, n := utf8.encode_rune(r);
bprint_string(buf, b[:n] as string); bprint_string(buf, b[:n] as string);
} }
proc bprint_space(buf: ^[]byte) { bprint_rune(buf, ' '); } proc bprint_space(buf ^[]byte) { bprint_rune(buf, ' '); }
proc bprint_nl (buf: ^[]byte) { bprint_rune(buf, '\n'); } proc bprint_nl (buf ^[]byte) { bprint_rune(buf, '\n'); }
__NUM_TO_CHAR_TABLE := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz@$"; __NUM_TO_CHAR_TABLE := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz@$";
proc bprint_bool(buffer: ^[]byte, b : bool) { proc bprint_bool(buffer ^[]byte, b bool) {
if b { if b {
bprint_string(buffer, "true"); bprint_string(buffer, "true");
} else { } else {
@@ -89,15 +89,15 @@ proc bprint_bool(buffer: ^[]byte, b : bool) {
} }
} }
proc bprint_pointer(buffer: ^[]byte, p: rawptr) #inline { proc bprint_pointer(buffer ^[]byte, p rawptr) #inline {
bprint_string(buffer, "0x"); bprint_string(buffer, "0x");
bprint_u64(buffer, p as uint as u64); bprint_u64(buffer, p as uint as u64);
} }
proc bprint_f16 (buffer: ^[]byte, f: f32) #inline { print__f64(buffer, f as f64, 4); } proc bprint_f16 (buffer ^[]byte, f f32) #inline { print__f64(buffer, f as f64, 4); }
proc bprint_f32 (buffer: ^[]byte, f: f32) #inline { print__f64(buffer, f as f64, 7); } 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_f64 (buffer ^[]byte, f f64) #inline { print__f64(buffer, f as f64, 16); }
proc bprint_u64(buffer: ^[]byte, value: u64) { proc bprint_u64(buffer ^[]byte, value u64) {
i := value; i := value;
buf: [20]byte; buf: [20]byte;
len := 0; len := 0;
@@ -113,7 +113,7 @@ proc bprint_u64(buffer: ^[]byte, value: u64) {
byte_reverse(buf[:len]); byte_reverse(buf[:len]);
bprint_string(buffer, buf[:len] as string); bprint_string(buffer, buf[:len] as string);
} }
proc bprint_i64(buffer: ^[]byte, value: i64) { proc bprint_i64(buffer ^[]byte, value i64) {
// TODO(bill): Cleanup printing // TODO(bill): Cleanup printing
i := value; i := value;
if i < 0 { if i < 0 {
@@ -124,14 +124,14 @@ proc bprint_i64(buffer: ^[]byte, value: i64) {
} }
/* /*
proc bprint_u128(buffer: ^[]byte, value: u128) { proc bprint_u128(buffer ^[]byte, value u128) {
a := value transmute [2]u64; a := value transmute [2]u64;
if a[1] != 0 { if a[1] != 0 {
bprint_u64(buffer, a[1]); bprint_u64(buffer, a[1]);
} }
bprint_u64(buffer, a[0]); bprint_u64(buffer, a[0]);
} }
proc bprint_i128(buffer: ^[]byte, value: i128) { proc bprint_i128(buffer ^[]byte, value i128) {
i := value; i := value;
if i < 0 { if i < 0 {
i = -i; i = -i;
@@ -142,7 +142,7 @@ proc bprint_i128(buffer: ^[]byte, value: i128) {
*/ */
proc print__f64(buffer: ^[]byte, value: f64, decimal_places: int) { proc print__f64(buffer ^[]byte, value f64, decimal_places int) {
f := value; f := value;
if f == 0 { if f == 0 {
bprint_rune(buffer, '0'); bprint_rune(buffer, '0');
@@ -168,7 +168,7 @@ proc print__f64(buffer: ^[]byte, value: f64, decimal_places: int) {
} }
} }
proc bprint_type(buf: ^[]byte, ti: ^Type_Info) { proc bprint_type(buf ^[]byte, ti ^Type_Info) {
if ti == nil { if ti == nil {
return; return;
} }
@@ -299,14 +299,14 @@ proc bprint_type(buf: ^[]byte, ti: ^Type_Info) {
} }
proc make_any(type_info: ^Type_Info, data: rawptr) -> any { proc make_any(type_info ^Type_Info, data rawptr) -> any {
a: any; a: any;
a.type_info = type_info; a.type_info = type_info;
a.data = data; a.data = data;
return a; return a;
} }
proc bprint_any(buf: ^[]byte, arg: any) { proc bprint_any(buf ^[]byte, arg any) {
if arg.type_info == nil { if arg.type_info == nil {
bprint_string(buf, "<nil>"); bprint_string(buf, "<nil>");
return; return;
@@ -435,7 +435,7 @@ proc bprint_any(buf: ^[]byte, arg: any) {
} }
case Vector: case Vector:
proc is_bool(type_info: ^Type_Info) -> bool { proc is_bool(type_info ^Type_Info) -> bool {
match type info : type_info { match type info : type_info {
case Named: case Named:
return is_bool(info.base); return is_bool(info.base);
@@ -489,12 +489,12 @@ proc bprint_any(buf: ^[]byte, arg: any) {
} }
proc bprintf(buf: ^[]byte, fmt: string, args: ..any) -> int { proc bprintf(buf ^[]byte, fmt string, args ..any) -> int {
proc is_digit(r: rune) -> bool #inline { proc is_digit(r rune) -> bool #inline {
return '0' <= r && r <= '9'; return '0' <= r && r <= '9';
} }
proc parse_int(s: string, offset: int) -> (int, int) { proc parse_int(s string, offset int) -> (int, int) {
result := 0; result := 0;
for ; offset < s.count; offset++ { for ; offset < s.count; offset++ {
@@ -554,8 +554,8 @@ proc bprintf(buf: ^[]byte, fmt: string, args: ..any) -> int {
} }
proc bprint(buf: ^[]byte, args: ..any) -> int { proc bprint(buf ^[]byte, args ..any) -> int {
proc is_type_string(info: ^Type_Info) -> bool { proc is_type_string(info ^Type_Info) -> bool {
using Type_Info; using Type_Info;
if info == nil { if info == nil {
return false; return false;
@@ -582,7 +582,7 @@ proc bprint(buf: ^[]byte, args: ..any) -> int {
return buf.count; return buf.count;
} }
proc bprintln(buf: ^[]byte, args: ..any) -> int { proc bprintln(buf ^[]byte, args ..any) -> int {
for i := 0; i < args.count; i++ { for i := 0; i < args.count; i++ {
if i > 0 { if i > 0 {
append(buf, ' '); append(buf, ' ');
+12 -12
View File
@@ -1,4 +1,4 @@
proc crc32(data: rawptr, len: int) -> u32 { proc crc32(data rawptr, len int) -> u32 {
result := ~(0 as u32); result := ~(0 as u32);
s := slice_ptr(data as ^u8, len); s := slice_ptr(data as ^u8, len);
for i := 0; i < len; i++ { for i := 0; i < len; i++ {
@@ -7,7 +7,7 @@ proc crc32(data: rawptr, len: int) -> u32 {
} }
return ~result; return ~result;
} }
proc crc64(data: rawptr, len: int) -> u64 { proc crc64(data rawptr, len int) -> u64 {
result := ~(0 as u64); result := ~(0 as u64);
s := slice_ptr(data as ^u8, len); s := slice_ptr(data as ^u8, len);
for i := 0; i < len; i++ { for i := 0; i < len; i++ {
@@ -17,7 +17,7 @@ proc crc64(data: rawptr, len: int) -> u64 {
return ~result; return ~result;
} }
proc fnv32(data: rawptr, len: int) -> u32 { proc fnv32(data rawptr, len int) -> u32 {
s := slice_ptr(data as ^u8, len); s := slice_ptr(data as ^u8, len);
h: u32 = 0x811c9dc5; h: u32 = 0x811c9dc5;
@@ -27,7 +27,7 @@ proc fnv32(data: rawptr, len: int) -> u32 {
return h; return h;
} }
proc fnv64(data: rawptr, len: int) -> u64 { proc fnv64(data rawptr, len int) -> u64 {
s := slice_ptr(data as ^u8, len); s := slice_ptr(data as ^u8, len);
h: u64 = 0xcbf29ce484222325; h: u64 = 0xcbf29ce484222325;
@@ -37,7 +37,7 @@ proc fnv64(data: rawptr, len: int) -> u64 {
return h; return h;
} }
proc fnv32a(data: rawptr, len: int) -> u32 { proc fnv32a(data rawptr, len int) -> u32 {
s := slice_ptr(data as ^u8, len); s := slice_ptr(data as ^u8, len);
h: u32 = 0x811c9dc5; h: u32 = 0x811c9dc5;
@@ -47,7 +47,7 @@ proc fnv32a(data: rawptr, len: int) -> u32 {
return h; return h;
} }
proc fnv64a(data: rawptr, len: int) -> u64 { proc fnv64a(data rawptr, len int) -> u64 {
s := slice_ptr(data as ^u8, len); s := slice_ptr(data as ^u8, len);
h: u64 = 0xcbf29ce484222325; h: u64 = 0xcbf29ce484222325;
@@ -58,12 +58,12 @@ proc fnv64a(data: rawptr, len: int) -> u64 {
} }
proc murmur64(data_: rawptr, len: int) -> u64 { proc murmur64(data_ rawptr, len int) -> u64 {
SEED :: 0x9747b28c; const SEED = 0x9747b28c;
when size_of(int) == 8 { when size_of(int) == 8 {
m :: 0xc6a4a7935bd1e995; const m = 0xc6a4a7935bd1e995;
r :: 47; const r = 47;
h: u64 = SEED ~ (len as u64 * m); h: u64 = SEED ~ (len as u64 * m);
@@ -99,8 +99,8 @@ proc murmur64(data_: rawptr, len: int) -> u64 {
return h; return h;
} else { } else {
m :: 0x5bd1e995; const m = 0x5bd1e995;
r :: 24; const r = 24;
h1: u32 = SEED as u32 ~ len as u32; h1: u32 = SEED as u32 ~ len as u32;
h2: u32 = SEED >> 32; h2: u32 = SEED >> 32;
+81 -81
View File
@@ -1,20 +1,20 @@
TAU :: 6.28318530717958647692528676655900576; const TAU = 6.28318530717958647692528676655900576;
PI :: 3.14159265358979323846264338327950288; const PI = 3.14159265358979323846264338327950288;
ONE_OVER_TAU :: 0.636619772367581343075535053490057448; const ONE_OVER_TAU = 0.636619772367581343075535053490057448;
ONE_OVER_PI :: 0.159154943091895335768883763372514362; const ONE_OVER_PI = 0.159154943091895335768883763372514362;
E :: 2.71828182845904523536; const E = 2.71828182845904523536;
SQRT_TWO :: 1.41421356237309504880168872420969808; const SQRT_TWO = 1.41421356237309504880168872420969808;
SQRT_THREE :: 1.73205080756887729352744634150587236; const SQRT_THREE = 1.73205080756887729352744634150587236;
SQRT_FIVE :: 2.23606797749978969640917366873127623; const SQRT_FIVE = 2.23606797749978969640917366873127623;
LOG_TWO :: 0.693147180559945309417232121458176568; const LOG_TWO = 0.693147180559945309417232121458176568;
LOG_TEN :: 2.30258509299404568401799145468436421; const LOG_TEN = 2.30258509299404568401799145468436421;
EPSILON :: 1.19209290e-7; const EPSILON = 1.19209290e-7;
τ :: TAU; const τ = TAU;
π :: PI; const π = PI;
type Vec2 [vector 2]f32; type Vec2 [vector 2]f32;
@@ -26,57 +26,57 @@ type Mat3 [3]Vec3;
type Mat4 [4]Vec4; type Mat4 [4]Vec4;
proc sqrt32(x: f32) -> f32 #foreign "llvm.sqrt.f32" proc sqrt32(x f32) -> f32 #foreign "llvm.sqrt.f32"
proc sqrt64(x: f64) -> f64 #foreign "llvm.sqrt.f64" proc sqrt64(x f64) -> f64 #foreign "llvm.sqrt.f64"
proc sin32(x: f32) -> f32 #foreign "llvm.sin.f32" proc sin32(x f32) -> f32 #foreign "llvm.sin.f32"
proc sin64(x: f64) -> f64 #foreign "llvm.sin.f64" proc sin64(x f64) -> f64 #foreign "llvm.sin.f64"
proc cos32(x: f32) -> f32 #foreign "llvm.cos.f32" proc cos32(x f32) -> f32 #foreign "llvm.cos.f32"
proc cos64(x: f64) -> f64 #foreign "llvm.cos.f64" proc cos64(x f64) -> f64 #foreign "llvm.cos.f64"
proc tan32(x: f32) -> f32 #inline { return sin32(x)/cos32(x); } proc tan32(x f32) -> f32 #inline { return sin32(x)/cos32(x); }
proc tan64(x: f64) -> f64 #inline { return sin64(x)/cos64(x); } proc tan64(x f64) -> f64 #inline { return sin64(x)/cos64(x); }
proc lerp32(a, b, t: f32) -> f32 { return a*(1-t) + b*t; } proc lerp32(a, b, t f32) -> f32 { return a*(1-t) + b*t; }
proc lerp64(a, b, t: f64) -> f64 { return a*(1-t) + b*t; } proc lerp64(a, b, t f64) -> f64 { return a*(1-t) + b*t; }
proc sign32(x: f32) -> f32 { if x >= 0 { return +1; } return -1; } proc sign32(x f32) -> f32 { if x >= 0 { return +1; } return -1; }
proc sign64(x: f64) -> f64 { if x >= 0 { return +1; } return -1; } proc sign64(x f64) -> f64 { if x >= 0 { return +1; } return -1; }
proc copy_sign32(x, y: f32) -> f32 { proc copy_sign32(x, y f32) -> f32 {
ix := x transmute u32; ix := x transmute u32;
iy := y transmute u32; iy := y transmute u32;
ix &= 0x7fffffff; ix &= 0x7fffffff;
ix |= iy & 0x80000000; ix |= iy & 0x80000000;
return ix transmute f32; return ix transmute f32;
} }
proc round32(x: f32) -> f32 { proc round32(x f32) -> f32 {
if x >= 0 { if x >= 0 {
return floor32(x + 0.5); return floor32(x + 0.5);
} }
return ceil32(x - 0.5); return ceil32(x - 0.5);
} }
proc floor32(x: f32) -> f32 { proc floor32(x f32) -> f32 {
if x >= 0 { if x >= 0 {
return x as int as f32; return x as int as f32;
} }
return (x-0.5) as int as f32; return (x-0.5) as int as f32;
} }
proc ceil32(x: f32) -> f32 { proc ceil32(x f32) -> f32 {
if x < 0 { if x < 0 {
return x as int as f32; return x as int as f32;
} }
return ((x as int)+1) as f32; return ((x as int)+1) as f32;
} }
proc remainder32(x, y: f32) -> f32 { proc remainder32(x, y f32) -> f32 {
return x - round32(x/y) * y; return x - round32(x/y) * y;
} }
proc fmod32(x, y: f32) -> f32 { proc fmod32(x, y f32) -> f32 {
y = abs(y); y = abs(y);
result := remainder32(abs(x), y); result := remainder32(abs(x), y);
if sign32(result) < 0 { if sign32(result) < 0 {
@@ -86,32 +86,32 @@ proc fmod32(x, y: f32) -> f32 {
} }
proc to_radians(degrees: f32) -> f32 { return degrees * TAU / 360; } proc to_radians(degrees f32) -> f32 { return degrees * TAU / 360; }
proc to_degrees(radians: f32) -> f32 { return radians * 360 / TAU; } proc to_degrees(radians f32) -> f32 { return radians * 360 / TAU; }
proc dot2(a, b: Vec2) -> f32 { c := a*b; return c.x + c.y; } 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 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 dot4(a, b Vec4) -> f32 { c := a*b; return c.x + c.y + c.z + c.w; }
proc cross3(x, y: Vec3) -> Vec3 { proc cross3(x, y Vec3) -> Vec3 {
a := swizzle(x, 1, 2, 0) * swizzle(y, 2, 0, 1); a := swizzle(x, 1, 2, 0) * swizzle(y, 2, 0, 1);
b := swizzle(x, 2, 0, 1) * swizzle(y, 1, 2, 0); b := swizzle(x, 2, 0, 1) * swizzle(y, 1, 2, 0);
return a - b; return a - b;
} }
proc vec2_mag(v: Vec2) -> f32 { return sqrt32(dot2(v, v)); } proc vec2_mag(v Vec2) -> f32 { return sqrt32(dot2(v, v)); }
proc vec3_mag(v: Vec3) -> f32 { return sqrt32(dot3(v, v)); } proc vec3_mag(v Vec3) -> f32 { return sqrt32(dot3(v, v)); }
proc vec4_mag(v: Vec4) -> f32 { return sqrt32(dot4(v, v)); } proc vec4_mag(v Vec4) -> f32 { return sqrt32(dot4(v, v)); }
proc vec2_norm(v: Vec2) -> Vec2 { return v / Vec2{vec2_mag(v)}; } proc vec2_norm(v Vec2) -> Vec2 { return v / Vec2{vec2_mag(v)}; }
proc vec3_norm(v: Vec3) -> Vec3 { return v / Vec3{vec3_mag(v)}; } 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 vec4_norm(v Vec4) -> Vec4 { return v / Vec4{vec4_mag(v)}; }
proc vec2_norm0(v: Vec2) -> Vec2 { proc vec2_norm0(v Vec2) -> Vec2 {
m := vec2_mag(v); m := vec2_mag(v);
if m == 0 { if m == 0 {
return Vec2{0}; return Vec2{0};
@@ -119,7 +119,7 @@ proc vec2_norm0(v: Vec2) -> Vec2 {
return v / Vec2{m}; return v / Vec2{m};
} }
proc vec3_norm0(v: Vec3) -> Vec3 { proc vec3_norm0(v Vec3) -> Vec3 {
m := vec3_mag(v); m := vec3_mag(v);
if m == 0 { if m == 0 {
return Vec3{0}; return Vec3{0};
@@ -127,7 +127,7 @@ proc vec3_norm0(v: Vec3) -> Vec3 {
return v / Vec3{m}; return v / Vec3{m};
} }
proc vec4_norm0(v: Vec4) -> Vec4 { proc vec4_norm0(v Vec4) -> Vec4 {
m := vec4_mag(v); m := vec4_mag(v);
if m == 0 { if m == 0 {
return Vec4{0}; return Vec4{0};
@@ -146,7 +146,7 @@ proc mat4_identity() -> Mat4 {
}; };
} }
proc mat4_transpose(m: Mat4) -> Mat4 { proc mat4_transpose(m Mat4) -> Mat4 {
for j := 0; j < 4; j++ { for j := 0; j < 4; j++ {
for i := 0; i < 4; i++ { for i := 0; i < 4; i++ {
m[i][j], m[j][i] = m[j][i], m[i][j]; m[i][j], m[j][i] = m[j][i], m[i][j];
@@ -155,7 +155,7 @@ proc mat4_transpose(m: Mat4) -> Mat4 {
return m; return m;
} }
proc mat4_mul(a, b: Mat4) -> Mat4 { proc mat4_mul(a, b Mat4) -> Mat4 {
c: Mat4; c: Mat4;
for j := 0; j < 4; j++ { for j := 0; j < 4; j++ {
for i := 0; i < 4; i++ { for i := 0; i < 4; i++ {
@@ -168,7 +168,7 @@ proc mat4_mul(a, b: Mat4) -> Mat4 {
return c; return c;
} }
proc mat4_mul_vec4(m: Mat4, v: Vec4) -> Vec4 { proc mat4_mul_vec4(m Mat4, v Vec4) -> Vec4 {
return Vec4{ return Vec4{
m[0][0]*v.x + m[1][0]*v.y + m[2][0]*v.z + m[3][0]*v.w, m[0][0]*v.x + m[1][0]*v.y + m[2][0]*v.z + m[3][0]*v.w,
m[0][1]*v.x + m[1][1]*v.y + m[2][1]*v.z + m[3][1]*v.w, m[0][1]*v.x + m[1][1]*v.y + m[2][1]*v.z + m[3][1]*v.w,
@@ -177,7 +177,7 @@ proc mat4_mul_vec4(m: Mat4, v: Vec4) -> Vec4 {
}; };
} }
proc mat4_inverse(m: Mat4) -> Mat4 { proc mat4_inverse(m Mat4) -> Mat4 {
o: Mat4; o: Mat4;
sf00 := m[2][2] * m[3][3] - m[3][2] * m[2][3]; sf00 := m[2][2] * m[3][3] - m[3][2] * m[2][3];
@@ -246,7 +246,7 @@ proc mat4_inverse(m: Mat4) -> Mat4 {
} }
proc mat4_translate(v: Vec3) -> Mat4 { proc mat4_translate(v Vec3) -> Mat4 {
m := mat4_identity(); m := mat4_identity();
m[3][0] = v.x; m[3][0] = v.x;
m[3][1] = v.y; m[3][1] = v.y;
@@ -255,7 +255,7 @@ proc mat4_translate(v: Vec3) -> Mat4 {
return m; return m;
} }
proc mat4_rotate(v: Vec3, angle_radians: f32) -> Mat4 { proc mat4_rotate(v Vec3, angle_radians f32) -> Mat4 {
c := cos32(angle_radians); c := cos32(angle_radians);
s := sin32(angle_radians); s := sin32(angle_radians);
@@ -282,14 +282,14 @@ proc mat4_rotate(v: Vec3, angle_radians: f32) -> Mat4 {
return rot; return rot;
} }
proc mat4_scale(m: Mat4, v: Vec3) -> Mat4 { proc mat4_scale(m Mat4, v Vec3) -> Mat4 {
m[0][0] *= v.x; m[0][0] *= v.x;
m[1][1] *= v.y; m[1][1] *= v.y;
m[2][2] *= v.z; m[2][2] *= v.z;
return m; return m;
} }
proc mat4_scalef(m: Mat4, s: f32) -> Mat4 { proc mat4_scalef(m Mat4, s f32) -> Mat4 {
m[0][0] *= s; m[0][0] *= s;
m[1][1] *= s; m[1][1] *= s;
m[2][2] *= s; m[2][2] *= s;
@@ -297,7 +297,7 @@ proc mat4_scalef(m: Mat4, s: f32) -> Mat4 {
} }
proc mat4_look_at(eye, centre, up: Vec3) -> Mat4 { proc mat4_look_at(eye, centre, up Vec3) -> Mat4 {
f := vec3_norm(centre - eye); f := vec3_norm(centre - eye);
s := vec3_norm(cross3(f, up)); s := vec3_norm(cross3(f, up));
u := cross3(s, f); u := cross3(s, f);
@@ -311,7 +311,7 @@ proc mat4_look_at(eye, centre, up: Vec3) -> Mat4 {
return m; return m;
} }
proc mat4_perspective(fovy, aspect, near, far: f32) -> Mat4 { proc mat4_perspective(fovy, aspect, near, far f32) -> Mat4 {
m: Mat4; m: Mat4;
tan_half_fovy := tan32(0.5 * fovy); tan_half_fovy := tan32(0.5 * fovy);
m[0][0] = 1.0 / (aspect*tan_half_fovy); m[0][0] = 1.0 / (aspect*tan_half_fovy);
@@ -323,7 +323,7 @@ proc mat4_perspective(fovy, aspect, near, far: f32) -> Mat4 {
} }
proc mat4_ortho3d(left, right, bottom, top, near, far: f32) -> Mat4 { proc mat4_ortho3d(left, right, bottom, top, near, far f32) -> Mat4 {
m := mat4_identity(); m := mat4_identity();
m[0][0] = +2.0 / (right - left); m[0][0] = +2.0 / (right - left);
m[1][1] = +2.0 / (top - bottom); m[1][1] = +2.0 / (top - bottom);
@@ -338,31 +338,31 @@ proc mat4_ortho3d(left, right, bottom, top, near, far: f32) -> Mat4 {
F32_DIG :: 6; const F32_DIG = 6;
F32_EPSILON :: 1.192092896e-07; const F32_EPSILON = 1.192092896e-07;
F32_GUARD :: 0; const F32_GUARD = 0;
F32_MANT_DIG :: 24; const F32_MANT_DIG = 24;
F32_MAX :: 3.402823466e+38; const F32_MAX = 3.402823466e+38;
F32_MAX_10_EXP :: 38; const F32_MAX_10_EXP = 38;
F32_MAX_EXP :: 128; const F32_MAX_EXP = 128;
F32_MIN :: 1.175494351e-38; const F32_MIN = 1.175494351e-38;
F32_MIN_10_EXP :: -37; const F32_MIN_10_EXP = -37;
F32_MIN_EXP :: -125; const F32_MIN_EXP = -125;
F32_NORMALIZE :: 0; const F32_NORMALIZE = 0;
F32_RADIX :: 2; const F32_RADIX = 2;
F32_ROUNDS :: 1; const F32_ROUNDS = 1;
F64_DIG :: 15; // # of decimal digits of precision const F64_DIG = 15; // # of decimal digits of precision
F64_EPSILON :: 2.2204460492503131e-016; // smallest such that 1.0+F64_EPSILON != 1.0 const F64_EPSILON = 2.2204460492503131e-016; // smallest such that 1.0+F64_EPSILON != 1.0
F64_MANT_DIG :: 53; // # of bits in mantissa const F64_MANT_DIG = 53; // # of bits in mantissa
F64_MAX :: 1.7976931348623158e+308; // max value const F64_MAX = 1.7976931348623158e+308; // max value
F64_MAX_10_EXP :: 308; // max decimal exponent const F64_MAX_10_EXP = 308; // max decimal exponent
F64_MAX_EXP :: 1024; // max binary exponent const F64_MAX_EXP = 1024; // max binary exponent
F64_MIN :: 2.2250738585072014e-308; // min positive value const F64_MIN = 2.2250738585072014e-308; // min positive value
F64_MIN_10_EXP :: -307; // min decimal exponent const F64_MIN_10_EXP = -307; // min decimal exponent
F64_MIN_EXP :: -1021; // min binary exponent const F64_MIN_EXP = -1021; // min binary exponent
F64_RADIX :: 2; // exponent radix const F64_RADIX = 2; // exponent radix
F64_ROUNDS :: 1; // addition rounding: near const F64_ROUNDS = 1; // addition rounding: near
+33 -33
View File
@@ -1,32 +1,32 @@
#import "fmt.odin"; #import "fmt.odin";
#import "os.odin"; #import "os.odin";
proc set(data: rawptr, value: i32, len: int) -> rawptr #link_name "__mem_set" { proc set(data rawptr, value i32, len int) -> rawptr #link_name "__mem_set" {
proc llvm_memset_64bit(dst: rawptr, val: byte, len: int, align: i32, is_volatile: bool) #foreign "llvm.memset.p0i8.i64" proc llvm_memset_64bit(dst rawptr, val byte, len int, align i32, is_volatile bool) #foreign "llvm.memset.p0i8.i64"
llvm_memset_64bit(data, value as byte, len, 1, false); llvm_memset_64bit(data, value as byte, len, 1, false);
return data; return data;
} }
proc zero(data: rawptr, len: int) -> rawptr #link_name "__mem_zero" { proc zero(data rawptr, len int) -> rawptr #link_name "__mem_zero" {
return set(data, 0, len); return set(data, 0, len);
} }
proc copy(dst, src: rawptr, len: int) -> rawptr #link_name "__mem_copy" { proc copy(dst, src rawptr, len int) -> rawptr #link_name "__mem_copy" {
// NOTE(bill): This _must_ implemented like C's memmove // NOTE(bill): This _must_ implemented like C's memmove
proc llvm_memmove_64bit(dst, src: rawptr, len: int, align: i32, is_volatile: bool) #foreign "llvm.memmove.p0i8.p0i8.i64" proc llvm_memmove_64bit(dst, src rawptr, len int, align i32, is_volatile bool) #foreign "llvm.memmove.p0i8.p0i8.i64"
llvm_memmove_64bit(dst, src, len, 1, false); llvm_memmove_64bit(dst, src, len, 1, false);
return dst; return dst;
} }
proc copy_non_overlapping(dst, src: rawptr, len: int) -> rawptr #link_name "__mem_copy_non_overlapping" { proc copy_non_overlapping(dst, src rawptr, len int) -> rawptr #link_name "__mem_copy_non_overlapping" {
// NOTE(bill): This _must_ implemented like C's memcpy // NOTE(bill): This _must_ implemented like C's memcpy
proc llvm_memcpy_64bit(dst, src: rawptr, len: int, align: i32, is_volatile: bool) #foreign "llvm.memcpy.p0i8.p0i8.i64" proc llvm_memcpy_64bit(dst, src rawptr, len int, align i32, is_volatile bool) #foreign "llvm.memcpy.p0i8.p0i8.i64"
llvm_memcpy_64bit(dst, src, len, 1, false); llvm_memcpy_64bit(dst, src, len, 1, false);
return dst; return dst;
} }
proc compare(dst, src: rawptr, n: int) -> int #link_name "__mem_compare" { proc compare(dst, src rawptr, n int) -> int #link_name "__mem_compare" {
// Translation of http://mgronhol.github.io/fast-strcmp/ // Translation of http://mgronhol.github.io/fast-strcmp/
a := slice_ptr(dst as ^byte, n); a := slice_ptr(dst as ^byte, n);
b := slice_ptr(src as ^byte, n); b := slice_ptr(src as ^byte, n);
@@ -63,19 +63,19 @@ proc compare(dst, src: rawptr, n: int) -> int #link_name "__mem_compare" {
proc kilobytes(x: int) -> int #inline { return (x) * 1024; } proc kilobytes(x int) -> int #inline { return (x) * 1024; }
proc megabytes(x: int) -> int #inline { return kilobytes(x) * 1024; } proc megabytes(x int) -> int #inline { return kilobytes(x) * 1024; }
proc gigabytes(x: int) -> int #inline { return gigabytes(x) * 1024; } proc gigabytes(x int) -> int #inline { return gigabytes(x) * 1024; }
proc terabytes(x: int) -> int #inline { return terabytes(x) * 1024; } proc terabytes(x int) -> int #inline { return terabytes(x) * 1024; }
proc is_power_of_two(x: int) -> bool { proc is_power_of_two(x int) -> bool {
if x <= 0 { if x <= 0 {
return false; return false;
} }
return (x & (x-1)) == 0; return (x & (x-1)) == 0;
} }
proc align_forward(ptr: rawptr, align: int) -> rawptr { proc align_forward(ptr rawptr, align int) -> rawptr {
assert(is_power_of_two(align)); assert(is_power_of_two(align));
a := align as uint; a := align as uint;
@@ -92,7 +92,7 @@ proc align_forward(ptr: rawptr, align: int) -> rawptr {
type Allocation_Header struct { type Allocation_Header struct {
size: int; size: int;
} }
proc allocation_header_fill(header: ^Allocation_Header, data: rawptr, size: int) { proc allocation_header_fill(header ^Allocation_Header, data rawptr, size int) {
header.size = size; header.size = size;
ptr := (header+1) as ^int; ptr := (header+1) as ^int;
@@ -100,7 +100,7 @@ proc allocation_header_fill(header: ^Allocation_Header, data: rawptr, size: int)
(ptr+i)^ = -1; (ptr+i)^ = -1;
} }
} }
proc allocation_header(data: rawptr) -> ^Allocation_Header { proc allocation_header(data rawptr) -> ^Allocation_Header {
p := data as ^int; p := data as ^int;
for (p-1)^ == -1 { for (p-1)^ == -1 {
p = (p-1); p = (p-1);
@@ -129,19 +129,19 @@ type Arena_Temp_Memory struct {
proc init_arena_from_memory(using a: ^Arena, data: []byte) { proc init_arena_from_memory(using a ^Arena, data []byte) {
backing = Allocator{}; backing = Allocator{};
memory = data[:0]; memory = data[:0];
temp_count = 0; temp_count = 0;
} }
proc init_arena_from_context(using a: ^Arena, size: int) { proc init_arena_from_context(using a ^Arena, size int) {
backing = context.allocator; backing = context.allocator;
memory = new_slice(byte, 0, size); memory = new_slice(byte, 0, size);
temp_count = 0; temp_count = 0;
} }
proc free_arena(using a: ^Arena) { proc free_arena(using a ^Arena) {
if backing.procedure != nil { if backing.procedure != nil {
push_allocator backing { push_allocator backing {
free(memory.data); free(memory.data);
@@ -150,16 +150,16 @@ proc free_arena(using a: ^Arena) {
} }
} }
proc arena_allocator(arena: ^Arena) -> Allocator { proc arena_allocator(arena ^Arena) -> Allocator {
return Allocator{ return Allocator{
procedure = arena_allocator_proc, procedure = arena_allocator_proc,
data = arena, data = arena,
}; };
} }
proc arena_allocator_proc(allocator_data: rawptr, mode: Allocator_Mode, proc arena_allocator_proc(allocator_data rawptr, mode Allocator_Mode,
size, alignment: int, size, alignment int,
old_memory: rawptr, old_size: int, flags: u64) -> rawptr { old_memory rawptr, old_size int, flags u64) -> rawptr {
arena := allocator_data as ^Arena; arena := allocator_data as ^Arena;
using Allocator_Mode; using Allocator_Mode;
@@ -192,7 +192,7 @@ proc arena_allocator_proc(allocator_data: rawptr, mode: Allocator_Mode,
return nil; return nil;
} }
proc begin_arena_temp_memory(a: ^Arena) -> Arena_Temp_Memory { proc begin_arena_temp_memory(a ^Arena) -> Arena_Temp_Memory {
tmp: Arena_Temp_Memory; tmp: Arena_Temp_Memory;
tmp.arena = a; tmp.arena = a;
tmp.original_count = a.memory.count; tmp.original_count = a.memory.count;
@@ -200,7 +200,7 @@ proc begin_arena_temp_memory(a: ^Arena) -> Arena_Temp_Memory {
return tmp; return tmp;
} }
proc end_arena_temp_memory(using tmp: Arena_Temp_Memory) { proc end_arena_temp_memory(using tmp Arena_Temp_Memory) {
assert(arena.memory.count >= original_count); assert(arena.memory.count >= original_count);
assert(arena.temp_count > 0); assert(arena.temp_count > 0);
arena.memory.count = original_count; arena.memory.count = original_count;
@@ -213,8 +213,8 @@ proc end_arena_temp_memory(using tmp: Arena_Temp_Memory) {
proc align_of_type_info(type_info: ^Type_Info) -> int { proc align_of_type_info(type_info ^Type_Info) -> int {
proc prev_pow2(n: i64) -> i64 { proc prev_pow2(n i64) -> i64 {
if n <= 0 { if n <= 0 {
return 0; return 0;
} }
@@ -227,8 +227,8 @@ proc align_of_type_info(type_info: ^Type_Info) -> int {
return n - (n >> 1); return n - (n >> 1);
} }
WORD_SIZE :: size_of(int); const WORD_SIZE = size_of(int);
MAX_ALIGN :: size_of([vector 64]f64); // TODO(bill): Should these constants be builtin constants? const MAX_ALIGN = size_of([vector 64]f64); // TODO(bill): Should these constants be builtin constants?
using Type_Info; using Type_Info;
match type info : type_info { match type info : type_info {
@@ -270,13 +270,13 @@ proc align_of_type_info(type_info: ^Type_Info) -> int {
return 0; return 0;
} }
proc align_formula(size, align: int) -> int { proc align_formula(size, align int) -> int {
result := size + align-1; result := size + align-1;
return result - result%align; return result - result%align;
}; };
proc size_of_type_info(type_info: ^Type_Info) -> int { proc size_of_type_info(type_info ^Type_Info) -> int {
WORD_SIZE :: size_of(int); const WORD_SIZE = size_of(int);
using Type_Info; using Type_Info;
match type info : type_info { match type info : type_info {
case Named: case Named:
@@ -309,7 +309,7 @@ proc size_of_type_info(type_info: ^Type_Info) -> int {
case Slice: case Slice:
return 3*WORD_SIZE; return 3*WORD_SIZE;
case Vector: case Vector:
proc is_bool(type_info: ^Type_Info) -> bool { proc is_bool(type_info ^Type_Info) -> bool {
match type info : type_info { match type info : type_info {
case Named: case Named:
return is_bool(info.base); return is_bool(info.base);
+68 -68
View File
@@ -2,37 +2,37 @@
#import win32 "sys/windows.odin" when ODIN_OS == "windows"; #import win32 "sys/windows.odin" when ODIN_OS == "windows";
#include "opengl_constants.odin"; #include "opengl_constants.odin";
proc Clear (mask: u32) #foreign "glClear" proc Clear (mask u32) #foreign "glClear"
proc ClearColor (r, g, b, a: f32) #foreign "glClearColor" proc ClearColor (r, g, b, a f32) #foreign "glClearColor"
proc Begin (mode: i32) #foreign "glBegin" proc Begin (mode i32) #foreign "glBegin"
proc End () #foreign "glEnd" proc End () #foreign "glEnd"
proc Finish () #foreign "glFinish" proc Finish () #foreign "glFinish"
proc BlendFunc (sfactor, dfactor: i32) #foreign "glBlendFunc" proc BlendFunc (sfactor, dfactor i32) #foreign "glBlendFunc"
proc Enable (cap: i32) #foreign "glEnable" proc Enable (cap i32) #foreign "glEnable"
proc Disable (cap: i32) #foreign "glDisable" proc Disable (cap i32) #foreign "glDisable"
proc GenTextures (count: i32, result: ^u32) #foreign "glGenTextures" proc GenTextures (count i32, result ^u32) #foreign "glGenTextures"
proc DeleteTextures(count: i32, result: ^u32) #foreign "glDeleteTextures" proc DeleteTextures(count i32, result ^u32) #foreign "glDeleteTextures"
proc TexParameteri (target, pname, param: i32) #foreign "glTexParameteri" proc TexParameteri (target, pname, param i32) #foreign "glTexParameteri"
proc TexParameterf (target: i32, pname: i32, param: f32) #foreign "glTexParameterf" proc TexParameterf (target i32, pname i32, param f32) #foreign "glTexParameterf"
proc BindTexture (target: i32, texture: u32) #foreign "glBindTexture" proc BindTexture (target i32, texture u32) #foreign "glBindTexture"
proc LoadIdentity () #foreign "glLoadIdentity" proc LoadIdentity () #foreign "glLoadIdentity"
proc Viewport (x, y, width, height: i32) #foreign "glViewport" proc Viewport (x, y, width, height i32) #foreign "glViewport"
proc Ortho (left, right, bottom, top, near, far: f64) #foreign "glOrtho" proc Ortho (left, right, bottom, top, near, far f64) #foreign "glOrtho"
proc Color3f (r, g, b: f32) #foreign "glColor3f" proc Color3f (r, g, b f32) #foreign "glColor3f"
proc Vertex3f (x, y, z: f32) #foreign "glVertex3f" proc Vertex3f (x, y, z f32) #foreign "glVertex3f"
proc TexImage2D (target, level, internal_format, proc TexImage2D (target, level, internal_format,
width, height, border, width, height, border,
format, _type: i32, pixels: rawptr) #foreign "glTexImage2D" format, _type i32, pixels rawptr) #foreign "glTexImage2D"
proc GetError () -> i32 #foreign "glGetError" proc GetError () -> i32 #foreign "glGetError"
proc GetString (name: i32) -> ^byte #foreign "glGetString" proc GetString (name i32) -> ^byte #foreign "glGetString"
proc GetIntegerv(name: i32, v: ^i32) #foreign "glGetIntegerv" proc GetIntegerv(name i32, v ^i32) #foreign "glGetIntegerv"
_libgl := win32.LoadLibraryA(("opengl32.dll\x00" as string).data); _libgl := win32.LoadLibraryA(("opengl32.dll\x00" as string).data);
proc GetProcAddress(name: string) -> proc() { proc GetProcAddress(name string) -> proc() {
assert(name[name.count-1] == 0); assert(name[name.count-1] == 0);
res := win32.wglGetProcAddress(name.data); res := win32.wglGetProcAddress(name.data);
if res == nil { if res == nil {
@@ -42,66 +42,66 @@ proc GetProcAddress(name: string) -> proc() {
} }
GenBuffers: proc(count: i32, buffers: ^u32); GenBuffers: proc(count i32, buffers ^u32);
GenVertexArrays: proc(count: i32, buffers: ^u32); GenVertexArrays: proc(count i32, buffers ^u32);
GenSamplers: proc(count: i32, buffers: ^u32); GenSamplers: proc(count i32, buffers ^u32);
BindBuffer: proc(target: i32, buffer: u32); BindBuffer: proc(target i32, buffer u32);
BindVertexArray: proc(buffer: u32); BindVertexArray: proc(buffer u32);
BindSampler: proc(position: i32, sampler: u32); BindSampler: proc(position i32, sampler u32);
BufferData: proc(target: i32, size: int, data: rawptr, usage: i32); BufferData: proc(target i32, size int, data rawptr, usage i32);
BufferSubData: proc(target: i32, offset, size: int, data: rawptr); BufferSubData: proc(target i32, offset, size int, data rawptr);
DrawArrays: proc(mode, first: i32, count: u32); DrawArrays: proc(mode, first i32, count u32);
DrawElements: proc(mode: i32, count: u32, type_: i32, indices: rawptr); DrawElements: proc(mode i32, count u32, type_ i32, indices rawptr);
MapBuffer: proc(target, access: i32) -> rawptr; MapBuffer: proc(target, access i32) -> rawptr;
UnmapBuffer: proc(target: i32); UnmapBuffer: proc(target i32);
VertexAttribPointer: proc(index: u32, size, type_: i32, normalized: i32, stride: u32, pointer: rawptr); VertexAttribPointer: proc(index u32, size, type_ i32, normalized i32, stride u32, pointer rawptr);
EnableVertexAttribArray: proc(index: u32); EnableVertexAttribArray: proc(index u32);
CreateShader: proc(shader_type: i32) -> u32; CreateShader: proc(shader_type i32) -> u32;
ShaderSource: proc(shader: u32, count: u32, string: ^^byte, length: ^i32); ShaderSource: proc(shader u32, count u32, str ^^byte, length ^i32);
CompileShader: proc(shader: u32); CompileShader: proc(shader u32);
CreateProgram: proc() -> u32; CreateProgram: proc() -> u32;
AttachShader: proc(program, shader: u32); AttachShader: proc(program, shader u32);
DetachShader: proc(program, shader: u32); DetachShader: proc(program, shader u32);
DeleteShader: proc(shader: u32); DeleteShader: proc(shader u32);
LinkProgram: proc(program: u32); LinkProgram: proc(program u32);
UseProgram: proc(program: u32); UseProgram: proc(program u32);
DeleteProgram: proc(program: u32); DeleteProgram: proc(program u32);
GetShaderiv: proc(shader: u32, pname: i32, params: ^i32); GetShaderiv: proc(shader u32, pname i32, params ^i32);
GetProgramiv: proc(program: u32, pname: i32, params: ^i32); GetProgramiv: proc(program u32, pname i32, params ^i32);
GetShaderInfoLog: proc(shader: u32, max_length: u32, length: ^u32, info_long: ^byte); GetShaderInfoLog: proc(shader u32, max_length u32, length ^u32, info_long ^byte);
GetProgramInfoLog: proc(program: u32, max_length: u32, length: ^u32, info_long: ^byte); GetProgramInfoLog: proc(program u32, max_length u32, length ^u32, info_long ^byte);
ActiveTexture: proc(texture: i32); ActiveTexture: proc(texture i32);
GenerateMipmap: proc(target: i32); GenerateMipmap: proc(target i32);
SamplerParameteri: proc(sampler: u32, pname: i32, param: i32); SamplerParameteri: proc(sampler u32, pname i32, param i32);
SamplerParameterf: proc(sampler: u32, pname: i32, param: f32); SamplerParameterf: proc(sampler u32, pname i32, param f32);
SamplerParameteriv: proc(sampler: u32, pname: i32, params: ^i32); SamplerParameteriv: proc(sampler u32, pname i32, params ^i32);
SamplerParameterfv: proc(sampler: u32, pname: i32, params: ^f32); SamplerParameterfv: proc(sampler u32, pname i32, params ^f32);
SamplerParameterIiv: proc(sampler: u32, pname: i32, params: ^i32); SamplerParameterIiv: proc(sampler u32, pname i32, params ^i32);
SamplerParameterIuiv: proc(sampler: u32, pname: i32, params: ^u32); SamplerParameterIuiv: proc(sampler u32, pname i32, params ^u32);
Uniform1i: proc(loc: i32, v0: i32); Uniform1i: proc(loc i32, v0 i32);
Uniform2i: proc(loc: i32, v0, v1: i32); Uniform2i: proc(loc i32, v0, v1 i32);
Uniform3i: proc(loc: i32, v0, v1, v2: i32); Uniform3i: proc(loc i32, v0, v1, v2 i32);
Uniform4i: proc(loc: i32, v0, v1, v2, v3: i32); Uniform4i: proc(loc i32, v0, v1, v2, v3 i32);
Uniform1f: proc(loc: i32, v0: f32); Uniform1f: proc(loc i32, v0 f32);
Uniform2f: proc(loc: i32, v0, v1: f32); Uniform2f: proc(loc i32, v0, v1 f32);
Uniform3f: proc(loc: i32, v0, v1, v2: f32); Uniform3f: proc(loc i32, v0, v1, v2 f32);
Uniform4f: proc(loc: i32, v0, v1, v2, v3: f32); Uniform4f: proc(loc i32, v0, v1, v2, v3 f32);
UniformMatrix4fv: proc(loc: i32, count: u32, transpose: i32, value: ^f32); UniformMatrix4fv: proc(loc i32, count u32, transpose i32, value ^f32);
GetUniformLocation: proc(program: u32, name: ^byte) -> i32; GetUniformLocation: proc(program u32, name ^byte) -> i32;
proc init() { proc init() {
proc set_proc_address(p: rawptr, name: string) #inline { (p as ^proc())^ = GetProcAddress(name); } proc set_proc_address(p rawptr, name string) #inline { (p as ^proc())^ = GetProcAddress(name); }
set_proc_address(^GenBuffers, "glGenBuffers\x00"); set_proc_address(^GenBuffers, "glGenBuffers\x00");
set_proc_address(^GenVertexArrays, "glGenVertexArrays\x00"); set_proc_address(^GenVertexArrays, "glGenVertexArrays\x00");
+1365 -1365
View File
File diff suppressed because it is too large Load Diff
+13 -13
View File
@@ -13,7 +13,7 @@ type File struct {
last_write_time: File_Time; last_write_time: File_Time;
} }
proc open(name: string) -> (File, bool) { proc open(name string) -> (File, bool) {
using win32; using win32;
buf: [300]byte; buf: [300]byte;
copy(buf[:], name as []byte); copy(buf[:], name as []byte);
@@ -24,7 +24,7 @@ proc open(name: string) -> (File, bool) {
return f, success; return f, success;
} }
proc create(name: string) -> (File, bool) { proc create(name string) -> (File, bool) {
using win32; using win32;
buf: [300]byte; buf: [300]byte;
copy(buf[:], name as []byte); copy(buf[:], name as []byte);
@@ -35,16 +35,16 @@ proc create(name: string) -> (File, bool) {
return f, success; return f, success;
} }
proc close(using f: ^File) { proc close(using f ^File) {
win32.CloseHandle(handle.p as win32.HANDLE); win32.CloseHandle(handle.p as win32.HANDLE);
} }
proc write(using f: ^File, buf: []byte) -> bool { proc write(using f ^File, buf []byte) -> bool {
bytes_written: i32; bytes_written: i32;
return win32.WriteFile(handle.p as win32.HANDLE, buf.data, buf.count as i32, ^bytes_written, nil) != 0; return win32.WriteFile(handle.p as win32.HANDLE, buf.data, buf.count as i32, ^bytes_written, nil) != 0;
} }
proc file_has_changed(f: ^File) -> bool { proc file_has_changed(f ^File) -> bool {
last_write_time := last_write_time(f); last_write_time := last_write_time(f);
if f.last_write_time != last_write_time { if f.last_write_time != last_write_time {
f.last_write_time = last_write_time; f.last_write_time = last_write_time;
@@ -55,7 +55,7 @@ proc file_has_changed(f: ^File) -> bool {
proc last_write_time(f: ^File) -> File_Time { proc last_write_time(f ^File) -> File_Time {
file_info: win32.BY_HANDLE_FILE_INFORMATION; file_info: win32.BY_HANDLE_FILE_INFORMATION;
win32.GetFileInformationByHandle(f.handle.p as win32.HANDLE, ^file_info); win32.GetFileInformationByHandle(f.handle.p as win32.HANDLE, ^file_info);
l := file_info.last_write_time.low_date_time as File_Time; l := file_info.last_write_time.low_date_time as File_Time;
@@ -63,7 +63,7 @@ proc last_write_time(f: ^File) -> File_Time {
return l | h << 32; return l | h << 32;
} }
proc last_write_time_by_name(name: string) -> File_Time { proc last_write_time_by_name(name string) -> File_Time {
last_write_time: win32.FILETIME; last_write_time: win32.FILETIME;
data: win32.WIN32_FILE_ATTRIBUTE_DATA; data: win32.WIN32_FILE_ATTRIBUTE_DATA;
buf: [1024]byte; buf: [1024]byte;
@@ -103,7 +103,7 @@ stderr := ^__std_files[File_Standard.ERROR];
proc read_entire_file(name: string) -> ([]byte, bool) { proc read_entire_file(name string) -> ([]byte, bool) {
buf: [300]byte; buf: [300]byte;
copy(buf[:], name as []byte); copy(buf[:], name as []byte);
@@ -130,7 +130,7 @@ proc read_entire_file(name: string) -> ([]byte, bool) {
for total_read < length { for total_read < length {
remaining := length - total_read; remaining := length - total_read;
to_read: u32; to_read: u32;
MAX :: 1<<32-1; const MAX = 1<<32-1;
if remaining <= MAX { if remaining <= MAX {
to_read = remaining as u32; to_read = remaining as u32;
} else { } else {
@@ -151,18 +151,18 @@ proc read_entire_file(name: string) -> ([]byte, bool) {
proc heap_alloc(size: int) -> rawptr { proc heap_alloc(size int) -> rawptr {
return win32.HeapAlloc(win32.GetProcessHeap(), win32.HEAP_ZERO_MEMORY, size); return win32.HeapAlloc(win32.GetProcessHeap(), win32.HEAP_ZERO_MEMORY, size);
} }
proc heap_resize(ptr: rawptr, new_size: int) -> rawptr { proc heap_resize(ptr rawptr, new_size int) -> rawptr {
return win32.HeapReAlloc(win32.GetProcessHeap(), win32.HEAP_ZERO_MEMORY, ptr, new_size); return win32.HeapReAlloc(win32.GetProcessHeap(), win32.HEAP_ZERO_MEMORY, ptr, new_size);
} }
proc heap_free(ptr: rawptr) { proc heap_free(ptr rawptr) {
win32.HeapFree(win32.GetProcessHeap(), 0, ptr); win32.HeapFree(win32.GetProcessHeap(), 0, ptr);
} }
proc exit(code: int) { proc exit(code int) {
win32.ExitProcess(code as u32); win32.ExitProcess(code as u32);
} }
+10 -10
View File
@@ -17,35 +17,35 @@ proc current_thread_id() -> i32 {
return win32.GetCurrentThreadId() as i32; return win32.GetCurrentThreadId() as i32;
} }
proc semaphore_init(s: ^Semaphore) { proc semaphore_init(s ^Semaphore) {
s.handle = win32.CreateSemaphoreA(nil, 0, 1<<31-1, nil); s.handle = win32.CreateSemaphoreA(nil, 0, 1<<31-1, nil);
} }
proc semaphore_destroy(s: ^Semaphore) { proc semaphore_destroy(s ^Semaphore) {
win32.CloseHandle(s.handle); win32.CloseHandle(s.handle);
} }
proc semaphore_post(s: ^Semaphore, count: int) { proc semaphore_post(s ^Semaphore, count int) {
win32.ReleaseSemaphore(s.handle, count as i32, nil); win32.ReleaseSemaphore(s.handle, count as i32, nil);
} }
proc semaphore_release(s: ^Semaphore) #inline { semaphore_post(s, 1); } proc semaphore_release(s ^Semaphore) #inline { semaphore_post(s, 1); }
proc semaphore_wait(s: ^Semaphore) { proc semaphore_wait(s ^Semaphore) {
win32.WaitForSingleObject(s.handle, win32.INFINITE); win32.WaitForSingleObject(s.handle, win32.INFINITE);
} }
proc mutex_init(m: ^Mutex) { proc mutex_init(m ^Mutex) {
atomic.store32(^m.counter, 0); atomic.store32(^m.counter, 0);
atomic.store32(^m.owner, current_thread_id()); atomic.store32(^m.owner, current_thread_id());
semaphore_init(^m.semaphore); semaphore_init(^m.semaphore);
m.recursion = 0; m.recursion = 0;
} }
proc mutex_destroy(m: ^Mutex) { proc mutex_destroy(m ^Mutex) {
semaphore_destroy(^m.semaphore); semaphore_destroy(^m.semaphore);
} }
proc mutex_lock(m: ^Mutex) { proc mutex_lock(m ^Mutex) {
thread_id := current_thread_id(); thread_id := current_thread_id();
if atomic.fetch_add32(^m.counter, 1) > 0 { if atomic.fetch_add32(^m.counter, 1) > 0 {
if thread_id != atomic.load32(^m.owner) { if thread_id != atomic.load32(^m.owner) {
@@ -55,7 +55,7 @@ proc mutex_lock(m: ^Mutex) {
atomic.store32(^m.owner, thread_id); atomic.store32(^m.owner, thread_id);
m.recursion++; m.recursion++;
} }
proc mutex_try_lock(m: ^Mutex) -> bool { proc mutex_try_lock(m ^Mutex) -> bool {
thread_id := current_thread_id(); thread_id := current_thread_id();
if atomic.load32(^m.owner) == thread_id { if atomic.load32(^m.owner) == thread_id {
atomic.fetch_add32(^m.counter, 1); atomic.fetch_add32(^m.counter, 1);
@@ -72,7 +72,7 @@ proc mutex_try_lock(m: ^Mutex) -> bool {
m.recursion++; m.recursion++;
return true; return true;
} }
proc mutex_unlock(m: ^Mutex) { proc mutex_unlock(m ^Mutex) {
recursion: i32; recursion: i32;
thread_id := current_thread_id(); thread_id := current_thread_id();
assert(thread_id == atomic.load32(^m.owner)); assert(thread_id == atomic.load32(^m.owner));
+150 -150
View File
@@ -16,39 +16,39 @@ type LPARAM int;
type LRESULT int; type LRESULT int;
type ATOM i16; type ATOM i16;
type BOOL i32; type BOOL i32;
type WNDPROC proc(hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT; type WNDPROC proc(hwnd HWND, msg u32, wparam WPARAM, lparam LPARAM) -> LRESULT;
INVALID_HANDLE_VALUE :: (-1 as int) as HANDLE; const INVALID_HANDLE_VALUE = (-1 as int) as HANDLE;
CS_VREDRAW :: 0x0001; const CS_VREDRAW = 0x0001;
CS_HREDRAW :: 0x0002; const CS_HREDRAW = 0x0002;
CS_OWNDC :: 0x0020; const CS_OWNDC = 0x0020;
CW_USEDEFAULT :: -0x80000000; const CW_USEDEFAULT = -0x80000000;
WS_OVERLAPPED :: 0; const WS_OVERLAPPED = 0;
WS_MAXIMIZEBOX :: 0x00010000; const WS_MAXIMIZEBOX = 0x00010000;
WS_MINIMIZEBOX :: 0x00020000; const WS_MINIMIZEBOX = 0x00020000;
WS_THICKFRAME :: 0x00040000; const WS_THICKFRAME = 0x00040000;
WS_SYSMENU :: 0x00080000; const WS_SYSMENU = 0x00080000;
WS_CAPTION :: 0x00C00000; const WS_CAPTION = 0x00C00000;
WS_VISIBLE :: 0x10000000; const WS_VISIBLE = 0x10000000;
WS_OVERLAPPEDWINDOW :: WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX; const WS_OVERLAPPEDWINDOW = WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX;
WM_DESTROY :: 0x0002; const WM_DESTROY = 0x0002;
WM_CLOSE :: 0x0010; const WM_CLOSE = 0x0010;
WM_QUIT :: 0x0012; const WM_QUIT = 0x0012;
WM_KEYDOWN :: 0x0100; const WM_KEYDOWN = 0x0100;
WM_KEYUP :: 0x0101; const WM_KEYUP = 0x0101;
PM_REMOVE :: 1; const PM_REMOVE = 1;
COLOR_BACKGROUND :: 1 as HBRUSH; const COLOR_BACKGROUND = 1 as HBRUSH;
BLACK_BRUSH :: 4; const BLACK_BRUSH = 4;
SM_CXSCREEN :: 0; const SM_CXSCREEN = 0;
SM_CYSCREEN :: 1; const SM_CYSCREEN = 1;
SW_SHOW :: 5; const SW_SHOW = 5;
type POINT struct #ordered { type POINT struct #ordered {
x, y: i32; x, y: i32;
@@ -110,101 +110,101 @@ type WIN32_FILE_ATTRIBUTE_DATA struct #ordered {
} }
type GET_FILEEX_INFO_LEVELS i32; type GET_FILEEX_INFO_LEVELS i32;
GetFileExInfoStandard :: 0 as GET_FILEEX_INFO_LEVELS; const GetFileExInfoStandard = 0 as GET_FILEEX_INFO_LEVELS;
GetFileExMaxInfoLevel :: 1 as GET_FILEEX_INFO_LEVELS; const GetFileExMaxInfoLevel = 1 as GET_FILEEX_INFO_LEVELS;
proc GetLastError () -> i32 #foreign #dll_import proc GetLastError () -> i32 #foreign #dll_import
proc ExitProcess (exit_code: u32) #foreign #dll_import proc ExitProcess (exit_code u32) #foreign #dll_import
proc GetDesktopWindow() -> HWND #foreign #dll_import proc GetDesktopWindow() -> HWND #foreign #dll_import
proc GetCursorPos (p: ^POINT) -> i32 #foreign #dll_import proc GetCursorPos (p ^POINT) -> i32 #foreign #dll_import
proc ScreenToClient (h: HWND, p: ^POINT) -> i32 #foreign #dll_import proc ScreenToClient (h HWND, p ^POINT) -> i32 #foreign #dll_import
proc GetModuleHandleA(module_name: ^u8) -> HINSTANCE #foreign #dll_import proc GetModuleHandleA(module_name ^u8) -> HINSTANCE #foreign #dll_import
proc GetStockObject (fn_object: i32) -> HGDIOBJ #foreign #dll_import proc GetStockObject (fn_object i32) -> HGDIOBJ #foreign #dll_import
proc PostQuitMessage (exit_code: i32) #foreign #dll_import proc PostQuitMessage (exit_code i32) #foreign #dll_import
proc SetWindowTextA (hwnd: HWND, c_string: ^u8) -> BOOL #foreign #dll_import proc SetWindowTextA (hwnd HWND, c_string ^u8) -> BOOL #foreign #dll_import
proc QueryPerformanceFrequency(result: ^i64) -> i32 #foreign #dll_import proc QueryPerformanceFrequency(result ^i64) -> i32 #foreign #dll_import
proc QueryPerformanceCounter (result: ^i64) -> i32 #foreign #dll_import proc QueryPerformanceCounter (result ^i64) -> i32 #foreign #dll_import
proc Sleep(ms: i32) -> i32 #foreign #dll_import proc Sleep(ms i32) -> i32 #foreign #dll_import
proc OutputDebugStringA(c_str: ^u8) #foreign #dll_import proc OutputDebugStringA(c_str ^u8) #foreign #dll_import
proc RegisterClassExA(wc: ^WNDCLASSEXA) -> ATOM #foreign #dll_import proc RegisterClassExA(wc ^WNDCLASSEXA) -> ATOM #foreign #dll_import
proc CreateWindowExA (ex_style: u32, proc CreateWindowExA (ex_style u32,
class_name, title: ^u8, class_name, title ^u8,
style: u32, style u32,
x, y, w, h: i32, x, y, w, h i32,
parent: HWND, menu: HMENU, instance: HINSTANCE, parent HWND, menu HMENU, instance HINSTANCE,
param: rawptr) -> HWND #foreign #dll_import param rawptr) -> HWND #foreign #dll_import
proc ShowWindow (hwnd: HWND, cmd_show: i32) -> BOOL #foreign #dll_import proc ShowWindow (hwnd HWND, cmd_show i32) -> BOOL #foreign #dll_import
proc TranslateMessage(msg: ^MSG) -> BOOL #foreign #dll_import proc TranslateMessage(msg ^MSG) -> BOOL #foreign #dll_import
proc DispatchMessageA(msg: ^MSG) -> LRESULT #foreign #dll_import proc DispatchMessageA(msg ^MSG) -> LRESULT #foreign #dll_import
proc UpdateWindow (hwnd: HWND) -> BOOL #foreign #dll_import proc UpdateWindow (hwnd HWND) -> BOOL #foreign #dll_import
proc PeekMessageA (msg: ^MSG, hwnd: HWND, proc PeekMessageA (msg ^MSG, hwnd HWND,
msg_filter_min, msg_filter_max, remove_msg: u32) -> BOOL #foreign #dll_import msg_filter_min, msg_filter_max, remove_msg u32) -> BOOL #foreign #dll_import
proc DefWindowProcA (hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT #foreign #dll_import proc DefWindowProcA (hwnd HWND, msg u32, wparam WPARAM, lparam LPARAM) -> LRESULT #foreign #dll_import
proc AdjustWindowRect(rect: ^RECT, style: u32, menu: BOOL) -> BOOL #foreign #dll_import proc AdjustWindowRect(rect ^RECT, style u32, menu BOOL) -> BOOL #foreign #dll_import
proc GetActiveWindow () -> HWND #foreign #dll_import proc GetActiveWindow () -> HWND #foreign #dll_import
proc GetQueryPerformanceFrequency() -> i64 { proc GetQueryPerformanceFrequency() -> i64 {
r: i64; var r i64;
QueryPerformanceFrequency(^r); QueryPerformanceFrequency(^r);
return r; return r;
} }
proc GetCommandLineA() -> ^u8 #foreign #dll_import proc GetCommandLineA() -> ^u8 #foreign #dll_import
proc GetSystemMetrics(index: i32) -> i32 #foreign #dll_import proc GetSystemMetrics(index i32) -> i32 #foreign #dll_import
proc GetCurrentThreadId() -> u32 #foreign #dll_import proc GetCurrentThreadId() -> u32 #foreign #dll_import
// File Stuff // File Stuff
proc CloseHandle (h: HANDLE) -> i32 #foreign #dll_import proc CloseHandle (h HANDLE) -> i32 #foreign #dll_import
proc GetStdHandle(h: i32) -> HANDLE #foreign #dll_import proc GetStdHandle(h i32) -> HANDLE #foreign #dll_import
proc CreateFileA (filename: ^u8, desired_access, share_mode: u32, proc CreateFileA (filename ^u8, desired_access, share_mode u32,
security: rawptr, security rawptr,
creation, flags_and_attribs: u32, template_file: HANDLE) -> HANDLE #foreign #dll_import creation, flags_and_attribs u32, template_file HANDLE) -> HANDLE #foreign #dll_import
proc ReadFile (h: HANDLE, buf: rawptr, to_read: u32, bytes_read: ^i32, overlapped: rawptr) -> BOOL #foreign #dll_import proc ReadFile (h HANDLE, buf rawptr, to_read u32, bytes_read ^i32, overlapped rawptr) -> BOOL #foreign #dll_import
proc WriteFile (h: HANDLE, buf: rawptr, len: i32, written_result: ^i32, overlapped: rawptr) -> i32 #foreign #dll_import proc WriteFile (h HANDLE, buf rawptr, len i32, written_result ^i32, overlapped rawptr) -> i32 #foreign #dll_import
proc GetFileSizeEx (file_handle: HANDLE, file_size: ^i64) -> BOOL #foreign #dll_import proc GetFileSizeEx (file_handle HANDLE, file_size ^i64) -> BOOL #foreign #dll_import
proc GetFileAttributesExA (filename: ^u8, info_level_id: GET_FILEEX_INFO_LEVELS, file_info: rawptr) -> BOOL #foreign #dll_import proc GetFileAttributesExA (filename ^u8, info_level_id GET_FILEEX_INFO_LEVELS, file_info rawptr) -> BOOL #foreign #dll_import
proc GetFileInformationByHandle(file_handle: HANDLE, file_info: ^BY_HANDLE_FILE_INFORMATION) -> BOOL #foreign #dll_import proc GetFileInformationByHandle(file_handle HANDLE, file_info ^BY_HANDLE_FILE_INFORMATION) -> BOOL #foreign #dll_import
FILE_SHARE_READ :: 0x00000001; const FILE_SHARE_READ = 0x00000001;
FILE_SHARE_WRITE :: 0x00000002; const FILE_SHARE_WRITE = 0x00000002;
FILE_SHARE_DELETE :: 0x00000004; const FILE_SHARE_DELETE = 0x00000004;
FILE_GENERIC_ALL :: 0x10000000; const FILE_GENERIC_ALL = 0x10000000;
FILE_GENERIC_EXECUTE :: 0x20000000; const FILE_GENERIC_EXECUTE = 0x20000000;
FILE_GENERIC_WRITE :: 0x40000000; const FILE_GENERIC_WRITE = 0x40000000;
FILE_GENERIC_READ :: 0x80000000; const FILE_GENERIC_READ = 0x80000000;
STD_INPUT_HANDLE :: -10; const STD_INPUT_HANDLE = -10;
STD_OUTPUT_HANDLE :: -11; const STD_OUTPUT_HANDLE = -11;
STD_ERROR_HANDLE :: -12; const STD_ERROR_HANDLE = -12;
CREATE_NEW :: 1; const CREATE_NEW = 1;
CREATE_ALWAYS :: 2; const CREATE_ALWAYS = 2;
OPEN_EXISTING :: 3; const OPEN_EXISTING = 3;
OPEN_ALWAYS :: 4; const OPEN_ALWAYS = 4;
TRUNCATE_EXISTING :: 5; const TRUNCATE_EXISTING = 5;
proc HeapAlloc (h: HANDLE, flags: u32, bytes: int) -> rawptr #foreign #dll_import proc HeapAlloc (h HANDLE, flags u32, bytes int) -> rawptr #foreign #dll_import
proc HeapReAlloc (h: HANDLE, flags: u32, memory: rawptr, bytes: int) -> rawptr #foreign #dll_import proc HeapReAlloc (h HANDLE, flags u32, memory rawptr, bytes int) -> rawptr #foreign #dll_import
proc HeapFree (h: HANDLE, flags: u32, memory: rawptr) -> BOOL #foreign #dll_import proc HeapFree (h HANDLE, flags u32, memory rawptr) -> BOOL #foreign #dll_import
proc GetProcessHeap() -> HANDLE #foreign #dll_import proc GetProcessHeap() -> HANDLE #foreign #dll_import
HEAP_ZERO_MEMORY :: 0x00000008; const HEAP_ZERO_MEMORY = 0x00000008;
// Synchronization // Synchronization
@@ -214,24 +214,24 @@ type SECURITY_ATTRIBUTES struct #ordered {
inherit_handle: BOOL; inherit_handle: BOOL;
} }
INFINITE :: 0xffffffff; const INFINITE = 0xffffffff;
proc CreateSemaphoreA (attributes: ^SECURITY_ATTRIBUTES, initial_count, maximum_count: i32, name: ^byte) -> HANDLE #foreign #dll_import 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 proc ReleaseSemaphore (semaphore HANDLE, release_count i32, previous_count ^i32) -> BOOL #foreign #dll_import
proc WaitForSingleObject(handle: HANDLE, milliseconds: u32) -> u32 #foreign #dll_import proc WaitForSingleObject(handle HANDLE, milliseconds u32) -> u32 #foreign #dll_import
proc InterlockedCompareExchange(dst: ^i32, exchange, comparand: i32) -> i32 #foreign proc InterlockedCompareExchange(dst ^i32, exchange, comparand i32) -> i32 #foreign
proc InterlockedExchange (dst: ^i32, desired: i32) -> i32 #foreign proc InterlockedExchange (dst ^i32, desired i32) -> i32 #foreign
proc InterlockedExchangeAdd (dst: ^i32, desired: i32) -> i32 #foreign proc InterlockedExchangeAdd (dst ^i32, desired i32) -> i32 #foreign
proc InterlockedAnd (dst: ^i32, desired: i32) -> i32 #foreign proc InterlockedAnd (dst ^i32, desired i32) -> i32 #foreign
proc InterlockedOr (dst: ^i32, desired: i32) -> i32 #foreign proc InterlockedOr (dst ^i32, desired i32) -> i32 #foreign
proc InterlockedCompareExchange64(dst: ^i64, exchange, comparand: i64) -> i64 #foreign proc InterlockedCompareExchange64(dst ^i64, exchange, comparand i64) -> i64 #foreign
proc InterlockedExchange64 (dst: ^i64, desired: i64) -> i64 #foreign proc InterlockedExchange64 (dst ^i64, desired i64) -> i64 #foreign
proc InterlockedExchangeAdd64 (dst: ^i64, desired: i64) -> i64 #foreign proc InterlockedExchangeAdd64 (dst ^i64, desired i64) -> i64 #foreign
proc InterlockedAnd64 (dst: ^i64, desired: i64) -> i64 #foreign proc InterlockedAnd64 (dst ^i64, desired i64) -> i64 #foreign
proc InterlockedOr64 (dst: ^i64, desired: i64) -> i64 #foreign proc InterlockedOr64 (dst ^i64, desired i64) -> i64 #foreign
proc _mm_pause () #foreign proc _mm_pause () #foreign
proc ReadWriteBarrier() #foreign proc ReadWriteBarrier() #foreign
@@ -262,54 +262,54 @@ type RGBQUAD struct #ordered {
blue, green, red, reserved: byte; blue, green, red, reserved: byte;
} }
BI_RGB :: 0; const BI_RGB = 0;
DIB_RGB_COLORS :: 0x00; const DIB_RGB_COLORS = 0x00;
SRCCOPY :: 0x00cc0020 as u32; const SRCCOPY = 0x00cc0020 as u32;
proc StretchDIBits(hdc: HDC, proc StretchDIBits(hdc HDC,
x_dst, y_dst, width_dst, height_dst: i32, x_dst, y_dst, width_dst, height_dst i32,
x_src, y_src, width_src, header_src: i32, x_src, y_src, width_src, header_src i32,
bits: rawptr, bits_info: ^BITMAPINFO, bits rawptr, bits_info ^BITMAPINFO,
usage: u32, usage u32,
rop: u32) -> i32 #foreign #dll_import rop u32) -> i32 #foreign #dll_import
proc LoadLibraryA (c_str: ^u8) -> HMODULE #foreign proc LoadLibraryA (c_str ^u8) -> HMODULE #foreign
proc FreeLibrary (h: HMODULE) #foreign proc FreeLibrary (h HMODULE) #foreign
proc GetProcAddress(h: HMODULE, c_str: ^u8) -> PROC #foreign proc GetProcAddress(h HMODULE, c_str ^u8) -> PROC #foreign
proc GetClientRect(hwnd: HWND, rect: ^RECT) -> BOOL #foreign proc GetClientRect(hwnd HWND, rect ^RECT) -> BOOL #foreign
// Windows OpenGL // Windows OpenGL
PFD_TYPE_RGBA :: 0; const PFD_TYPE_RGBA = 0;
PFD_TYPE_COLORINDEX :: 1; const PFD_TYPE_COLORINDEX = 1;
PFD_MAIN_PLANE :: 0; const PFD_MAIN_PLANE = 0;
PFD_OVERLAY_PLANE :: 1; const PFD_OVERLAY_PLANE = 1;
PFD_UNDERLAY_PLANE :: -1; const PFD_UNDERLAY_PLANE = -1;
PFD_DOUBLEBUFFER :: 1; const PFD_DOUBLEBUFFER = 1;
PFD_STEREO :: 2; const PFD_STEREO = 2;
PFD_DRAW_TO_WINDOW :: 4; const PFD_DRAW_TO_WINDOW = 4;
PFD_DRAW_TO_BITMAP :: 8; const PFD_DRAW_TO_BITMAP = 8;
PFD_SUPPORT_GDI :: 16; const PFD_SUPPORT_GDI = 16;
PFD_SUPPORT_OPENGL :: 32; const PFD_SUPPORT_OPENGL = 32;
PFD_GENERIC_FORMAT :: 64; const PFD_GENERIC_FORMAT = 64;
PFD_NEED_PALETTE :: 128; const PFD_NEED_PALETTE = 128;
PFD_NEED_SYSTEM_PALETTE :: 0x00000100; const PFD_NEED_SYSTEM_PALETTE = 0x00000100;
PFD_SWAP_EXCHANGE :: 0x00000200; const PFD_SWAP_EXCHANGE = 0x00000200;
PFD_SWAP_COPY :: 0x00000400; const PFD_SWAP_COPY = 0x00000400;
PFD_SWAP_LAYER_BUFFERS :: 0x00000800; const PFD_SWAP_LAYER_BUFFERS = 0x00000800;
PFD_GENERIC_ACCELERATED :: 0x00001000; const PFD_GENERIC_ACCELERATED = 0x00001000;
PFD_DEPTH_DONTCARE :: 0x20000000; const PFD_DEPTH_DONTCARE = 0x20000000;
PFD_DOUBLEBUFFER_DONTCARE :: 0x40000000; const PFD_DOUBLEBUFFER_DONTCARE = 0x40000000;
PFD_STEREO_DONTCARE :: 0x80000000; const PFD_STEREO_DONTCARE = 0x80000000;
type HGLRC HANDLE; type HGLRC HANDLE;
type PROC proc(); type PROC proc();
type wglCreateContextAttribsARBType proc(hdc: HDC, hshareContext: rawptr, attribList: ^i32) -> HGLRC; type wglCreateContextAttribsARBType proc(hdc HDC, hshareContext rawptr, attribList ^i32) -> HGLRC;
type PIXELFORMATDESCRIPTOR struct #ordered { type PIXELFORMATDESCRIPTOR struct #ordered {
@@ -343,29 +343,29 @@ type PIXELFORMATDESCRIPTOR struct #ordered {
damage_mask: u32; damage_mask: u32;
} }
proc GetDC (h: HANDLE) -> HDC #foreign proc GetDC (h HANDLE) -> HDC #foreign
proc SetPixelFormat (hdc: HDC, pixel_format: i32, pfd: ^PIXELFORMATDESCRIPTOR ) -> BOOL #foreign #dll_import proc SetPixelFormat (hdc HDC, pixel_format i32, pfd ^PIXELFORMATDESCRIPTOR ) -> BOOL #foreign #dll_import
proc ChoosePixelFormat(hdc: HDC, pfd: ^PIXELFORMATDESCRIPTOR) -> i32 #foreign #dll_import proc ChoosePixelFormat(hdc HDC, pfd ^PIXELFORMATDESCRIPTOR) -> i32 #foreign #dll_import
proc SwapBuffers (hdc: HDC) -> BOOL #foreign #dll_import proc SwapBuffers (hdc HDC) -> BOOL #foreign #dll_import
proc ReleaseDC (wnd: HWND, hdc: HDC) -> i32 #foreign #dll_import proc ReleaseDC (wnd HWND, hdc HDC) -> i32 #foreign #dll_import
WGL_CONTEXT_MAJOR_VERSION_ARB :: 0x2091; const WGL_CONTEXT_MAJOR_VERSION_ARB = 0x2091;
WGL_CONTEXT_MINOR_VERSION_ARB :: 0x2092; const WGL_CONTEXT_MINOR_VERSION_ARB = 0x2092;
WGL_CONTEXT_PROFILE_MASK_ARB :: 0x9126; const WGL_CONTEXT_PROFILE_MASK_ARB = 0x9126;
WGL_CONTEXT_CORE_PROFILE_BIT_ARB :: 0x0001; const WGL_CONTEXT_CORE_PROFILE_BIT_ARB = 0x0001;
WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB :: 0x0002; const WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB = 0x0002;
proc wglCreateContext (hdc: HDC) -> HGLRC #foreign #dll_import proc wglCreateContext (hdc HDC) -> HGLRC #foreign #dll_import
proc wglMakeCurrent (hdc: HDC, hglrc: HGLRC) -> BOOL #foreign #dll_import proc wglMakeCurrent (hdc HDC, hglrc HGLRC) -> BOOL #foreign #dll_import
proc wglGetProcAddress(c_str: ^u8) -> PROC #foreign #dll_import proc wglGetProcAddress(c_str ^u8) -> PROC #foreign #dll_import
proc wglDeleteContext (hglrc: HGLRC) -> BOOL #foreign #dll_import proc wglDeleteContext (hglrc HGLRC) -> BOOL #foreign #dll_import
proc GetKeyState (v_key: i32) -> i16 #foreign #dll_import proc GetKeyState (v_key i32) -> i16 #foreign #dll_import
proc GetAsyncKeyState(v_key: i32) -> i16 #foreign #dll_import proc GetAsyncKeyState(v_key i32) -> i16 #foreign #dll_import
proc is_key_down(key: Key_Code) -> bool { proc is_key_down(key Key_Code) -> bool {
return GetAsyncKeyState(key as i32) < 0; return GetAsyncKeyState(key as i32) < 0;
} }
+19 -20
View File
@@ -1,13 +1,13 @@
RUNE_ERROR :: '\ufffd'; const RUNE_ERROR = '\ufffd';
RUNE_SELF :: 0x80; const RUNE_SELF = 0x80;
RUNE_BOM :: 0xfeff; const RUNE_BOM = 0xfeff;
RUNE_EOF :: ~(0 as rune); const RUNE_EOF = ~(0 as rune);
MAX_RUNE :: '\U0010ffff'; const MAX_RUNE = '\U0010ffff';
UTF_MAX :: 4; const UTF_MAX = 4;
SURROGATE_MIN :: 0xd800; const SURROGATE_MIN = 0xd800;
SURROGATE_MAX :: 0xdfff; const SURROGATE_MAX = 0xdfff;
type Accept_Range struct { type Accept_Range struct {
@@ -42,11 +42,10 @@ accept_sizes := [256]byte{
0x34, 0x04, 0x04, 0x04, 0x44, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, // 0xf0-0xff 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) { proc encode_rune(r rune) -> ([4]byte, int) {
r := r_;
buf: [4]byte; buf: [4]byte;
i := r as u32; i := r as u32;
mask :: 0x3f as byte; const mask = 0x3f as byte;
if i <= 1<<7-1 { if i <= 1<<7-1 {
buf[0] = r as byte; buf[0] = r as byte;
return buf, 1; return buf, 1;
@@ -77,7 +76,7 @@ proc encode_rune(r_: rune) -> ([4]byte, int) {
return buf, 4; return buf, 4;
} }
proc decode_rune(s: string) -> (rune, int) { proc decode_rune(s string) -> (rune, int) {
n := s.count; n := s.count;
if n < 1 { if n < 1 {
return RUNE_ERROR, 0; return RUNE_ERROR, 0;
@@ -98,10 +97,10 @@ proc decode_rune(s: string) -> (rune, int) {
return RUNE_ERROR, 1; return RUNE_ERROR, 1;
} }
MASK_X :: 0b00111111; const MASK_X = 0b00111111;
MASK_2 :: 0b00011111; const MASK_2 = 0b00011111;
MASK_3 :: 0b00001111; const MASK_3 = 0b00001111;
MASK_4 :: 0b00000111; const MASK_4 = 0b00000111;
if size == 2 { if size == 2 {
return (b0&MASK_2) as rune <<6 | (b1&MASK_X) as rune, 2; return (b0&MASK_2) as rune <<6 | (b1&MASK_X) as rune, 2;
@@ -122,7 +121,7 @@ proc decode_rune(s: string) -> (rune, int) {
} }
proc valid_rune(r: rune) -> bool { proc valid_rune(r rune) -> bool {
if r < 0 { if r < 0 {
return false; return false;
} else if SURROGATE_MIN <= r && r <= SURROGATE_MAX { } else if SURROGATE_MIN <= r && r <= SURROGATE_MAX {
@@ -133,7 +132,7 @@ proc valid_rune(r: rune) -> bool {
return true; return true;
} }
proc valid_string(s: string) -> bool { proc valid_string(s string) -> bool {
n := s.count; n := s.count;
for i := 0; i < n; { for i := 0; i < n; {
si := s[i]; si := s[i];
@@ -166,7 +165,7 @@ proc valid_string(s: string) -> bool {
return true; return true;
} }
proc rune_count(s: string) -> int { proc rune_count(s string) -> int {
count := 0; count := 0;
n := s.count; n := s.count;
for i := 0; i < n; count++ { for i := 0; i < n; count++ {
@@ -203,7 +202,7 @@ proc rune_count(s: string) -> int {
} }
proc rune_size(r: rune) -> int { proc rune_size(r rune) -> int {
match { match {
case r < 0: return -1; case r < 0: return -1;
case r <= 1<<7 - 1: return 1; case r <= 1<<7 - 1: return 1;
+27 -27
View File
@@ -644,18 +644,18 @@ void check_struct_type(Checker *c, Type *struct_type, AstNode *node) {
isize field_count = 0; isize field_count = 0;
isize other_field_count = 0; isize other_field_count = 0;
for_array(decl_index, st->decls) { for_array(field_index, st->fields) {
AstNode *decl = st->decls.e[decl_index]; AstNode *field = st->fields.e[field_index];
switch (decl->kind) { switch (field->kind) {
case_ast_node(vd, VarDecl, decl); case_ast_node(vd, VarDecl, field);
field_count += vd->names.count; field_count += vd->names.count;
case_end; case_end;
case_ast_node(cd, ConstDecl, decl); case_ast_node(cd, ConstDecl, field);
other_field_count += cd->names.count; other_field_count += cd->names.count;
case_end; case_end;
case_ast_node(td, TypeDecl, decl); case_ast_node(td, TypeDecl, field);
other_field_count += 1; other_field_count += 1;
case_end; case_end;
} }
@@ -664,7 +664,7 @@ void check_struct_type(Checker *c, Type *struct_type, AstNode *node) {
Entity **fields = gb_alloc_array(c->allocator, Entity *, field_count); Entity **fields = gb_alloc_array(c->allocator, Entity *, field_count);
Entity **other_fields = gb_alloc_array(c->allocator, Entity *, other_field_count); Entity **other_fields = gb_alloc_array(c->allocator, Entity *, other_field_count);
check_fields(c, node, st->decls, fields, field_count, other_fields, other_field_count, str_lit("struct")); check_fields(c, node, st->fields, fields, field_count, other_fields, other_field_count, str_lit("struct"));
struct_type->Record.struct_is_packed = st->is_packed; struct_type->Record.struct_is_packed = st->is_packed;
struct_type->Record.struct_is_ordered = st->is_ordered; struct_type->Record.struct_is_ordered = st->is_ordered;
@@ -705,18 +705,18 @@ void check_union_type(Checker *c, Type *union_type, AstNode *node) {
isize field_count = 1; isize field_count = 1;
isize other_field_count = 0; isize other_field_count = 0;
for_array(decl_index, ut->decls) { for_array(field_index, ut->fields) {
AstNode *decl = ut->decls.e[decl_index]; AstNode *field = ut->fields.e[field_index];
switch (decl->kind) { switch (field->kind) {
case_ast_node(vd, VarDecl, decl); case_ast_node(vd, VarDecl, field);
field_count += vd->names.count; field_count += vd->names.count;
case_end; case_end;
case_ast_node(cd, ConstDecl, decl); case_ast_node(cd, ConstDecl, field);
other_field_count += cd->names.count; other_field_count += cd->names.count;
case_end; case_end;
case_ast_node(td, TypeDecl, decl); case_ast_node(td, TypeDecl, field);
other_field_count += 1; other_field_count += 1;
case_end; case_end;
} }
@@ -725,7 +725,7 @@ void check_union_type(Checker *c, Type *union_type, AstNode *node) {
Entity **fields = gb_alloc_array(c->allocator, Entity *, field_count); Entity **fields = gb_alloc_array(c->allocator, Entity *, field_count);
Entity **other_fields = gb_alloc_array(c->allocator, Entity *, other_field_count); Entity **other_fields = gb_alloc_array(c->allocator, Entity *, other_field_count);
check_fields(c, node, ut->decls, fields, field_count, other_fields, other_field_count, str_lit("union")); check_fields(c, node, ut->fields, fields, field_count, other_fields, other_field_count, str_lit("union"));
union_type->Record.fields = fields; union_type->Record.fields = fields;
union_type->Record.field_count = field_count; union_type->Record.field_count = field_count;
@@ -740,18 +740,18 @@ void check_raw_union_type(Checker *c, Type *union_type, AstNode *node) {
isize field_count = 0; isize field_count = 0;
isize other_field_count = 0; isize other_field_count = 0;
for_array(decl_index, ut->decls) { for_array(field_index, ut->fields) {
AstNode *decl = ut->decls.e[decl_index]; AstNode *field = ut->fields.e[field_index];
switch (decl->kind) { switch (field->kind) {
case_ast_node(vd, VarDecl, decl); case_ast_node(vd, VarDecl, field);
field_count += vd->names.count; field_count += vd->names.count;
case_end; case_end;
case_ast_node(cd, ConstDecl, decl); case_ast_node(cd, ConstDecl, field);
other_field_count += cd->names.count; other_field_count += cd->names.count;
case_end; case_end;
case_ast_node(td, TypeDecl, decl); case_ast_node(td, TypeDecl, field);
other_field_count += 1; other_field_count += 1;
case_end; case_end;
} }
@@ -760,7 +760,7 @@ void check_raw_union_type(Checker *c, Type *union_type, AstNode *node) {
Entity **fields = gb_alloc_array(c->allocator, Entity *, field_count); Entity **fields = gb_alloc_array(c->allocator, Entity *, field_count);
Entity **other_fields = gb_alloc_array(c->allocator, Entity *, other_field_count); Entity **other_fields = gb_alloc_array(c->allocator, Entity *, other_field_count);
check_fields(c, node, ut->decls, fields, field_count, other_fields, other_field_count, str_lit("raw union")); check_fields(c, node, ut->fields, fields, field_count, other_fields, other_field_count, str_lit("raw union"));
union_type->Record.fields = fields; union_type->Record.fields = fields;
union_type->Record.field_count = field_count; union_type->Record.field_count = field_count;
@@ -4655,11 +4655,11 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
str = gb_string_appendc(str, "struct "); str = gb_string_appendc(str, "struct ");
if (st->is_packed) str = gb_string_appendc(str, "#packed "); if (st->is_packed) str = gb_string_appendc(str, "#packed ");
if (st->is_ordered) str = gb_string_appendc(str, "#ordered "); if (st->is_ordered) str = gb_string_appendc(str, "#ordered ");
for_array(i, st->decls) { for_array(i, st->fields) {
if (i > 0) { if (i > 0) {
str = gb_string_appendc(str, "; "); str = gb_string_appendc(str, "; ");
} }
str = write_expr_to_string(str, st->decls.e[i]); str = write_expr_to_string(str, st->fields.e[i]);
} }
// str = write_params_to_string(str, st->decl_list, ", "); // str = write_params_to_string(str, st->decl_list, ", ");
str = gb_string_appendc(str, "}"); str = gb_string_appendc(str, "}");
@@ -4667,11 +4667,11 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
case_ast_node(st, RawUnionType, node); case_ast_node(st, RawUnionType, node);
str = gb_string_appendc(str, "raw_union {"); str = gb_string_appendc(str, "raw_union {");
for_array(i, st->decls) { for_array(i, st->fields) {
if (i > 0) { if (i > 0) {
str = gb_string_appendc(str, "; "); str = gb_string_appendc(str, "; ");
} }
str = write_expr_to_string(str, st->decls.e[i]); str = write_expr_to_string(str, st->fields.e[i]);
} }
// str = write_params_to_string(str, st->decl_list, ", "); // str = write_params_to_string(str, st->decl_list, ", ");
str = gb_string_appendc(str, "}"); str = gb_string_appendc(str, "}");
@@ -4679,11 +4679,11 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
case_ast_node(st, UnionType, node); case_ast_node(st, UnionType, node);
str = gb_string_appendc(str, "union {"); str = gb_string_appendc(str, "union {");
for_array(i, st->decls) { for_array(i, st->fields) {
if (i > 0) { if (i > 0) {
str = gb_string_appendc(str, "; "); str = gb_string_appendc(str, "; ");
} }
str = write_expr_to_string(str, st->decls.e[i]); str = write_expr_to_string(str, st->fields.e[i]);
} }
// str = write_params_to_string(str, st->decl_list, ", "); // str = write_params_to_string(str, st->decl_list, ", ");
str = gb_string_appendc(str, "}"); str = gb_string_appendc(str, "}");
+141 -112
View File
@@ -302,20 +302,20 @@ AST_NODE_KIND(_TypeBegin, "", i32) \
}) \ }) \
AST_NODE_KIND(StructType, "struct type", struct { \ AST_NODE_KIND(StructType, "struct type", struct { \
Token token; \ Token token; \
AstNodeArray decls; \ AstNodeArray fields; \
isize decl_count; \ isize field_count; \
bool is_packed; \ bool is_packed; \
bool is_ordered; \ bool is_ordered; \
}) \ }) \
AST_NODE_KIND(UnionType, "union type", struct { \ AST_NODE_KIND(UnionType, "union type", struct { \
Token token; \ Token token; \
AstNodeArray decls; \ AstNodeArray fields; \
isize decl_count; \ isize field_count; \
}) \ }) \
AST_NODE_KIND(RawUnionType, "raw union type", struct { \ AST_NODE_KIND(RawUnionType, "raw union type", struct { \
Token token; \ Token token; \
AstNodeArray decls; \ AstNodeArray fields; \
isize decl_count; \ isize field_count; \
}) \ }) \
AST_NODE_KIND(EnumType, "enum type", struct { \ AST_NODE_KIND(EnumType, "enum type", struct { \
Token token; \ Token token; \
@@ -968,30 +968,30 @@ AstNode *make_vector_type(AstFile *f, Token token, AstNode *count, AstNode *elem
return result; return result;
} }
AstNode *make_struct_type(AstFile *f, Token token, AstNodeArray decls, isize decl_count, bool is_packed, bool is_ordered) { AstNode *make_struct_type(AstFile *f, Token token, AstNodeArray fields, isize field_count, bool is_packed, bool is_ordered) {
AstNode *result = make_node(f, AstNode_StructType); AstNode *result = make_node(f, AstNode_StructType);
result->StructType.token = token; result->StructType.token = token;
result->StructType.decls = decls; result->StructType.fields = fields;
result->StructType.decl_count = decl_count; result->StructType.field_count = field_count;
result->StructType.is_packed = is_packed; result->StructType.is_packed = is_packed;
result->StructType.is_ordered = is_ordered; result->StructType.is_ordered = is_ordered;
return result; return result;
} }
AstNode *make_union_type(AstFile *f, Token token, AstNodeArray decls, isize decl_count) { AstNode *make_union_type(AstFile *f, Token token, AstNodeArray fields, isize field_count) {
AstNode *result = make_node(f, AstNode_UnionType); AstNode *result = make_node(f, AstNode_UnionType);
result->UnionType.token = token; result->UnionType.token = token;
result->UnionType.decls = decls; result->UnionType.fields = fields;
result->UnionType.decl_count = decl_count; result->UnionType.field_count = field_count;
return result; return result;
} }
AstNode *make_raw_union_type(AstFile *f, Token token, AstNodeArray decls, isize decl_count) { AstNode *make_raw_union_type(AstFile *f, Token token, AstNodeArray fields, isize field_count) {
AstNode *result = make_node(f, AstNode_RawUnionType); AstNode *result = make_node(f, AstNode_RawUnionType);
result->RawUnionType.token = token; result->RawUnionType.token = token;
result->RawUnionType.decls = decls; result->RawUnionType.fields = fields;
result->RawUnionType.decl_count = decl_count; result->RawUnionType.field_count = field_count;
return result; return result;
} }
@@ -1212,22 +1212,6 @@ void expect_semicolon(AstFile *f, AstNode *s) {
fix_advance_to_next_stmt(f); fix_advance_to_next_stmt(f);
} }
bool parse_at_comma(AstFile *f, String context, TokenKind follow) {
if (f->curr_token.kind == Token_Comma) {
return true;
}
if (f->curr_token.kind != follow) {
if (f->curr_token.kind == Token_Semicolon &&
str_eq(f->curr_token.string, str_lit("\n"))) {
error(f->curr_token, "Missing `,` before new line in %.*s", LIT(context));
}
error(f->curr_token, "Missing `,` in %.*s", LIT(context));
return true;
}
return false;
}
AstNode * parse_expr(AstFile *f, bool lhs); AstNode * parse_expr(AstFile *f, bool lhs);
AstNode * parse_proc_type(AstFile *f); AstNode * parse_proc_type(AstFile *f);
@@ -1276,10 +1260,9 @@ AstNodeArray parse_element_list(AstFile *f) {
array_add(&elems, elem); array_add(&elems, elem);
if (!parse_at_comma(f, str_lit("compound literal"), Token_CloseBrace)) { if (!allow_token(f, Token_Comma)) {
break; break;
} }
next_token(f);
} }
return elems; return elems;
@@ -1617,10 +1600,9 @@ AstNode *parse_call_expr(AstFile *f, AstNode *operand) {
AstNode *arg = parse_expr(f, false); AstNode *arg = parse_expr(f, false);
array_add(&args, arg); array_add(&args, arg);
if (!parse_at_comma(f, str_lit("argument list"), Token_CloseParen)) { if (!allow_token(f, Token_Comma)) {
break; break;
} }
next_token(f);
} }
f->expr_level--; f->expr_level--;
@@ -1862,7 +1844,15 @@ void parse_check_name_list_for_reserves(AstFile *f, AstNodeArray names) {
} }
} }
AstNode *parse_value_decl(AstFile *f);
AstNode *parse_simple_stmt(AstFile *f) { AstNode *parse_simple_stmt(AstFile *f) {
switch (f->curr_token.kind) {
case Token_var:
case Token_const:
return parse_value_decl(f);
}
isize lhs_count = 0, rhs_count = 0; isize lhs_count = 0, rhs_count = 0;
AstNodeArray lhs = parse_lhs_expr_list(f); AstNodeArray lhs = parse_lhs_expr_list(f);
@@ -1926,56 +1916,56 @@ AstNode *parse_simple_stmt(AstFile *f) {
return make_var_decl(f, names, type, values); return make_var_decl(f, names, type, values);
} break; } break;
case Token_ColonColon: { // case Token_ColonColon: {
AstNodeArray names = lhs; // AstNodeArray names = lhs;
parse_check_name_list_for_reserves(f, names); // parse_check_name_list_for_reserves(f, names);
Token colon_colon = expect_token(f, Token_ColonColon); // Token colon_colon = expect_token(f, Token_ColonColon);
// if (f->curr_token.kind == Token_type || // // if (f->curr_token.kind == Token_type ||
// f->curr_token.kind == Token_struct || // // f->curr_token.kind == Token_struct ||
// f->curr_token.kind == Token_enum || // // f->curr_token.kind == Token_enum ||
// f->curr_token.kind == Token_union || // // f->curr_token.kind == Token_union ||
// f->curr_token.kind == Token_raw_union) { // // f->curr_token.kind == Token_raw_union) {
// // if (f->curr_token.kind == Token_type) { // // // if (f->curr_token.kind == Token_type) {
// Token token = f->curr_token; // // Token token = f->curr_token;
// if (token.kind == Token_type) { // // if (token.kind == Token_type) {
// next_token(f); // // next_token(f);
// } // // }
// if (names.count != 1) { // // if (names.count != 1) {
// syntax_error_node(names.e[0], "You can only declare one type at a time"); // // syntax_error_node(names.e[0], "You can only declare one type at a time");
// return make_bad_decl(f, names.e[0]->Ident, token); // // return make_bad_decl(f, names.e[0]->Ident, token);
// } // // }
// return make_type_decl(f, token, names.e[0], parse_type(f)); // // return make_type_decl(f, token, names.e[0], parse_type(f));
// } else if (f->curr_token.kind == Token_proc) { // // } else if (f->curr_token.kind == Token_proc) {
// // NOTE(bill): Procedure declarations // // // NOTE(bill): Procedure declarations
// Token proc_token = f->curr_token; // // Token proc_token = f->curr_token;
// AstNode *name = names.e[0]; // // AstNode *name = names.e[0];
// if (names.count != 1) { // // if (names.count != 1) {
// syntax_error(proc_token, "You can only declare one procedure at a time"); // // syntax_error(proc_token, "You can only declare one procedure at a time");
// return make_bad_decl(f, name->Ident, proc_token); // // return make_bad_decl(f, name->Ident, proc_token);
// } // // }
// return parse_proc_decl(f, proc_token, name); // // return parse_proc_decl(f, proc_token, name);
// } // // }
AstNodeArray values = parse_rhs_expr_list(f); // AstNodeArray values = parse_rhs_expr_list(f);
if (values.count > names.count) { // if (values.count > names.count) {
syntax_error(f->curr_token, "Too many values on the right hand side of the declaration"); // syntax_error(f->curr_token, "Too many values on the right hand side of the declaration");
} else if (values.count < names.count) { // } else if (values.count < names.count) {
syntax_error(f->curr_token, "All constant declarations must be defined"); // syntax_error(f->curr_token, "All constant declarations must be defined");
} else if (values.count == 0) { // } else if (values.count == 0) {
syntax_error(f->curr_token, "Expected an expression for this declaration"); // syntax_error(f->curr_token, "Expected an expression for this declaration");
} // }
if (values.count == 0 && names.count > 0) { // if (values.count == 0 && names.count > 0) {
syntax_error(f->curr_token, "Missing constant value"); // syntax_error(f->curr_token, "Missing constant value");
return make_bad_decl(f, f->curr_token, f->curr_token); // return make_bad_decl(f, f->curr_token, f->curr_token);
} // }
return make_const_decl(f, names, NULL, values); // return make_const_decl(f, names, NULL, values);
} break; // } break;
} }
if (lhs_count > 1) { if (lhs_count > 1) {
@@ -2072,19 +2062,20 @@ AstNode *parse_proc_type(AstFile *f) {
} }
AstNodeArray parse_parameter_list(AstFile *f, bool allow_using) { AstNodeArray parse_parameter_list(AstFile *f, bool allow_using, TokenKind follow) {
AstNodeArray params = make_ast_node_array(f); AstNodeArray params = make_ast_node_array(f);
while (f->curr_token.kind == Token_Ident || while (f->curr_token.kind != follow &&
f->curr_token.kind == Token_using) { f->curr_token.kind != Token_EOF) {
bool is_using = false; bool is_using = false;
if (allow_token(f, Token_using)) { if (allow_token(f, Token_using)) {
is_using = true; is_using = true;
} }
AstNodeArray names = parse_lhs_expr_list(f); AstNodeArray names = parse_identfier_list(f);
if (names.count == 0) { if (names.count == 0) {
syntax_error(f->curr_token, "Empty parameter declaration"); syntax_error(f->curr_token, "Empty parameter declaration");
break;
} }
if (names.count > 1 && is_using) { if (names.count > 1 && is_using) {
@@ -2097,7 +2088,7 @@ AstNodeArray parse_parameter_list(AstFile *f, bool allow_using) {
is_using = false; is_using = false;
} }
expect_token_after(f, Token_Colon, "parameter list"); // expect_token_after(f, Token_Colon, "parameter list");
AstNode *type = NULL; AstNode *type = NULL;
if (f->curr_token.kind == Token_Ellipsis) { if (f->curr_token.kind == Token_Ellipsis) {
@@ -2124,17 +2115,16 @@ AstNodeArray parse_parameter_list(AstFile *f, bool allow_using) {
} }
array_add(&params, make_parameter(f, names, type, is_using)); array_add(&params, make_parameter(f, names, type, is_using));
if (!parse_at_comma(f, str_lit("parameter list"), Token_CloseParen)) { if (!allow_token(f, Token_Comma)) {
break; break;
} }
next_token(f);
} }
return params; return params;
} }
AstNodeArray parse_record_params(AstFile *f, isize *decl_count_, bool using_allowed, String context) { AstNodeArray parse_record_params(AstFile *f, isize *decl_count_, bool allow_using, String context) {
AstNodeArray decls = make_ast_node_array(f); AstNodeArray decls = make_ast_node_array(f);
isize decl_count = 0; isize decl_count = 0;
@@ -2154,13 +2144,13 @@ AstNodeArray parse_record_params(AstFile *f, isize *decl_count_, bool using_allo
case AstNode_UsingStmt: { case AstNode_UsingStmt: {
bool is_using = true; bool is_using = true;
if (!using_allowed) { if (!allow_using) {
syntax_error(f->curr_token, "Cannot apply `using` to members of a %.*s", LIT(context)); syntax_error(f->curr_token, "Cannot apply `using` to members of a %.*s", LIT(context));
is_using = false; is_using = false;
} }
if (decl->UsingStmt.node->kind == AstNode_VarDecl) { if (decl->UsingStmt.node->kind == AstNode_VarDecl) {
AstNode *vd = decl->UsingStmt.node; AstNode *vd = decl->UsingStmt.node;
vd->VarDecl.is_using = is_using && using_allowed; vd->VarDecl.is_using = is_using && allow_using;
if (vd->VarDecl.values.count > 0) { if (vd->VarDecl.values.count > 0) {
syntax_error(f->curr_token, "Default variable assignments within a %.*s will be ignored", LIT(context)); syntax_error(f->curr_token, "Default variable assignments within a %.*s will be ignored", LIT(context));
} }
@@ -2214,10 +2204,6 @@ AstNode *parse_identifier_or_type(AstFile *f) {
return e; return e;
} }
case Token_type:
expect_token(f, Token_type);
return parse_identifier_or_type(f);
case Token_Pointer: { case Token_Pointer: {
Token token = expect_token(f, Token_Pointer); Token token = expect_token(f, Token_Pointer);
AstNode *elem = parse_type(f); AstNode *elem = parse_type(f);
@@ -2358,27 +2344,10 @@ AstNode *parse_identifier_or_type(AstFile *f) {
close = expect_token(f, Token_CloseParen); close = expect_token(f, Token_CloseParen);
return type; return type;
// return make_paren_expr(f, type, open, close); // return make_paren_expr(f, type, open, close);
}
// TODO(bill): Why is this even allowed? Is this a parsing error?
case Token_Colon:
break;
case Token_Eq:
if (f->prev_token.kind == Token_Colon) {
break;
}
// fallthrough
default: {
String prev = str_lit("newline");
if (str_ne(f->prev_token.string, str_lit("\n"))) {
prev = f->prev_token.string;
}
syntax_error(f->curr_token,
"Expected a type or identifier after %.*s, got %.*s", LIT(prev), LIT(f->curr_token.string));
} break; } break;
} }
// No type found
return NULL; return NULL;
} }
@@ -2411,7 +2380,7 @@ void parse_proc_signature(AstFile *f,
AstNodeArray *params, AstNodeArray *params,
AstNodeArray *results) { AstNodeArray *results) {
expect_token(f, Token_OpenParen); expect_token(f, Token_OpenParen);
*params = parse_parameter_list(f, true); *params = parse_parameter_list(f, true, Token_CloseParen);
expect_token_after(f, Token_CloseParen, "parameter list"); expect_token_after(f, Token_CloseParen, "parameter list");
*results = parse_results(f); *results = parse_results(f);
} }
@@ -2777,6 +2746,64 @@ AstNode *parse_type_decl(AstFile *f) {
return decl; return decl;
} }
AstNode *parse_value_decl(AstFile *f) {
Token token = f->curr_token;
switch (token.kind) {
case Token_var:
case Token_const:
next_token(f);
break;
default:
next_token(f);
syntax_error(token, "Expected a variable or constant declaration");
fix_advance_to_next_stmt(f);
return make_bad_decl(f, token, f->curr_token);
}
AstNodeArray names = parse_lhs_expr_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 (values.count > names.count) {
syntax_error(f->curr_token, "Too many values on the right hand side of the declaration");
} else if (token.kind == Token_const) {
if (values.count < names.count) {
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");
}
}
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);
}
// TODO(bill): Fix this so it does not require it
if (values.e == NULL) {
values = make_ast_node_array(f);
}
AstNode *decl = NULL;
switch (token.kind) {
case Token_var:
decl = make_var_decl(f, names, type, values);
break;
case Token_const:
decl = make_const_decl(f, names, type, values);
break;
}
expect_semicolon(f, decl);
return decl;
}
AstNode *parse_stmt(AstFile *f) { AstNode *parse_stmt(AstFile *f) {
AstNode *s = NULL; AstNode *s = NULL;
Token token = f->curr_token; Token token = f->curr_token;
@@ -2816,9 +2843,11 @@ AstNode *parse_stmt(AstFile *f) {
case Token_proc: case Token_proc:
return parse_proc_decl(f); return parse_proc_decl(f);
case Token_type: case Token_type:
return parse_type_decl(f); return parse_type_decl(f);
case Token_var:
case Token_const:
return parse_value_decl(f);
case Token_using: { case Token_using: {
-5
View File
@@ -74,7 +74,6 @@ TOKEN_KIND(Token__ComparisonEnd, "_ComparisonEnd"), \
TOKEN_KIND(Token_OpenBrace, "{"), \ TOKEN_KIND(Token_OpenBrace, "{"), \
TOKEN_KIND(Token_CloseBrace, "}"), \ TOKEN_KIND(Token_CloseBrace, "}"), \
TOKEN_KIND(Token_Colon, ":"), \ TOKEN_KIND(Token_Colon, ":"), \
TOKEN_KIND(Token_ColonColon, "::"), \
TOKEN_KIND(Token_Semicolon, ";"), \ TOKEN_KIND(Token_Semicolon, ";"), \
TOKEN_KIND(Token_Period, "."), \ TOKEN_KIND(Token_Period, "."), \
TOKEN_KIND(Token_Comma, ","), \ TOKEN_KIND(Token_Comma, ","), \
@@ -835,10 +834,6 @@ Token tokenizer_get_token(Tokenizer *t) {
break; break;
case ':': case ':':
token.kind = Token_Colon; token.kind = Token_Colon;
if (t->curr_rune == ':') {
advance_to_next_rune(t);
token.kind = Token_ColonColon;
}
break; break;
case '(': case '(':
token.kind = Token_OpenParen; token.kind = Token_OpenParen;