Disable var and const declarations

This commit is contained in:
Ginger Bill
2017-06-28 23:17:20 +01:00
parent 9ca2246bac
commit 0622509807
27 changed files with 2508 additions and 2537 deletions
+53 -35
View File
@@ -1,4 +1,22 @@
import "fmt.odin"; import (
"atomics.odin";
"bits.odin";
"decimal.odin";
"fmt.odin";
"hash.odin";
"math.odin";
"mem.odin";
"opengl.odin";
"os.odin";
"pool.odin";
"raw.odin";
"strconv.odin";
"strings.odin";
"sync.odin";
"types.odin";
"utf8.odin";
"utf16.odin";
)
proc general_stuff() { proc general_stuff() {
// Complex numbers // Complex numbers
@@ -20,13 +38,13 @@ proc general_stuff() {
} }
type Foo struct { Foo :: struct {
x: int, x: int,
y: f32, y: f32,
z: string, z: string,
} }
var foo = Foo{123, 0.513, "A string"}; foo := Foo{123, 0.513, "A string"};
var x, y, z = expand_to_tuple(foo); x, y, z := expand_to_tuple(foo);
fmt.println(x, y, z); fmt.println(x, y, z);
compile_assert(type_of(x) == int); compile_assert(type_of(x) == int);
compile_assert(type_of(y) == f32); compile_assert(type_of(y) == f32);
@@ -36,7 +54,7 @@ proc general_stuff() {
// By default, all variables are zeroed // By default, all variables are zeroed
// This can be overridden with the "uninitialized value" // This can be overridden with the "uninitialized value"
// This is similar to `nil` but applied to everything // This is similar to `nil` but applied to everything
var undef_int: int = ---; undef_int: int = ---;
// Context system is now implemented using Implicit Parameter Passing (IPP) // Context system is now implemented using Implicit Parameter Passing (IPP)
@@ -66,7 +84,7 @@ proc default_arguments() {
} }
proc named_arguments() { proc named_arguments() {
type Colour enum { Colour :: enum {
Red, Red,
Orange, Orange,
Yellow, Yellow,
@@ -110,7 +128,7 @@ proc named_arguments() {
// Named arguments can also aid with default arguments // Named arguments can also aid with default arguments
proc numerous_things(s: string, a = 1, b = 2, c = 3.14, proc numerous_things(s: string, a = 1, b = 2, c = 3.14,
d = "The Best String!", e = false, f = 10.3/3.1, g = false) { d = "The Best String!", e = false, f = 10.3/3.1, g = false) {
var g_str = g ? "true" : "false"; g_str := g ? "true" : "false";
fmt.printf("How many?! %s: %v\n", s, g_str); fmt.printf("How many?! %s: %v\n", s, g_str);
} }
@@ -150,13 +168,13 @@ proc default_return_values() {
// A more "real" example // A more "real" example
type Error enum { Error :: enum {
None, None,
WhyTheNumberThree, WhyTheNumberThree,
TenIsTooBig, TenIsTooBig,
}; };
type Entity struct { Entity :: struct {
name: string, name: string,
id: u32, id: u32,
} }
@@ -167,7 +185,7 @@ proc default_return_values() {
case input >= 10: return err = Error.TenIsTooBig; case input >= 10: return err = Error.TenIsTooBig;
} }
var e = new(Entity); e := new(Entity);
e.id = u32(input); e.id = u32(input);
return result = e; return result = e;
@@ -183,7 +201,7 @@ proc call_location() {
fmt.println(); fmt.println();
} }
var loc = #location(main); loc := #location(main);
fmt.println("`main` is located at", loc); fmt.println("`main` is located at", loc);
fmt.println("This line is located at", #location()); fmt.println("This line is located at", #location());
@@ -203,18 +221,18 @@ proc explicit_parametric_polymorphic_procedures() {
return ^T(alloc(size_of(T), align_of(T))); return ^T(alloc(size_of(T), align_of(T)));
} }
var int_ptr = alloc_type(int); int_ptr := alloc_type(int);
defer free(int_ptr); defer free(int_ptr);
int_ptr^ = 137; int_ptr^ = 137;
fmt.println(int_ptr, int_ptr^); fmt.println(int_ptr, int_ptr^);
// Named arguments work too! // Named arguments work too!
var another_ptr = alloc_type(T = f32); another_ptr := alloc_type(T = f32);
defer free(another_ptr); defer free(another_ptr);
proc add(T: type, args: ..T) -> T { proc add(T: type, args: ..T) -> T {
var res: T; res: T;
for arg in args { for arg in args {
res += arg; res += arg;
} }
@@ -224,12 +242,12 @@ proc explicit_parametric_polymorphic_procedures() {
fmt.println("add =", add(int, 1, 2, 3, 4, 5, 6)); fmt.println("add =", add(int, 1, 2, 3, 4, 5, 6));
proc swap(T: type, a, b: ^T) { proc swap(T: type, a, b: ^T) {
var tmp = a^; tmp := a^;
a^ = b^; a^ = b^;
b^ = tmp; b^ = tmp;
} }
var a, b: int = 3, 4; a, b: int = 3, 4;
fmt.println("Pre-swap:", a, b); fmt.println("Pre-swap:", a, b);
swap(int, &a, &b); swap(int, &a, &b);
fmt.println("Post-swap:", a, b); fmt.println("Post-swap:", a, b);
@@ -242,9 +260,9 @@ proc explicit_parametric_polymorphic_procedures() {
// A more complicated example using subtyping // A more complicated example using subtyping
// Something like this could be used in a game // Something like this could be used in a game
type Vector2 struct {x, y: f32}; Vector2 :: struct {x, y: f32};
type Entity struct { Entity :: struct {
using position: Vector2, using position: Vector2,
flags: u64, flags: u64,
id: u64, id: u64,
@@ -254,27 +272,27 @@ proc explicit_parametric_polymorphic_procedures() {
derived: any, derived: any,
} }
type Rock struct { Rock :: struct {
using entity: ^Entity, using entity: ^Entity,
heavy: bool, heavy: bool,
} }
type Door struct { Door :: struct {
using entity: ^Entity, using entity: ^Entity,
open: bool, open: bool,
} }
type Monster struct { Monster :: struct {
using entity: ^Entity, using entity: ^Entity,
is_robot: bool, is_robot: bool,
is_zombie: bool, is_zombie: bool,
} }
type EntityManager struct { EntityManager :: struct {
batches: [dynamic]^EntityBatch, batches: [dynamic]^EntityBatch,
next_portable_id: u32, next_portable_id: u32,
} }
const ENTITIES_PER_BATCH = 16; ENTITIES_PER_BATCH :: 16;
type EntityBatch struct { EntityBatch :: struct {
data: [ENTITIES_PER_BATCH]Entity, data: [ENTITIES_PER_BATCH]Entity,
occupied: [ENTITIES_PER_BATCH]bool, occupied: [ENTITIES_PER_BATCH]bool,
batch_index: u32, batch_index: u32,
@@ -285,7 +303,7 @@ proc explicit_parametric_polymorphic_procedures() {
if ok -> continue; if ok -> continue;
batch.occupied[i] = true; batch.occupied[i] = true;
var e = &batch.data[i]; e := &batch.data[i];
e.batch_index = u32(batch.batch_index); e.batch_index = u32(batch.batch_index);
e.slot_index = u32(i); e.slot_index = u32(i);
e.portable_id = manager.next_portable_id; e.portable_id = manager.next_portable_id;
@@ -297,11 +315,11 @@ proc explicit_parametric_polymorphic_procedures() {
proc gen_new_entity(manager: ^EntityManager) -> ^Entity { proc gen_new_entity(manager: ^EntityManager) -> ^Entity {
for b in manager.batches { for b in manager.batches {
var e = use_empty_slot(manager, b); e := use_empty_slot(manager, b);
if e != nil -> return e; if e != nil -> return e;
} }
var new_batch = new(EntityBatch); new_batch := new(EntityBatch);
append(manager.batches, new_batch); append(manager.batches, new_batch);
new_batch.batch_index = u32(len(manager.batches)-1); new_batch.batch_index = u32(len(manager.batches)-1);
@@ -311,7 +329,7 @@ proc explicit_parametric_polymorphic_procedures() {
proc new_entity(manager: ^EntityManager, Type: type, x, y: int) -> ^Type { proc new_entity(manager: ^EntityManager, Type: type, x, y: int) -> ^Type {
var result = new(Type); result := new(Type);
result.entity = gen_new_entity(manager); result.entity = gen_new_entity(manager);
result.derived.data = result; result.derived.data = result;
result.derived.type_info = type_info(Type); result.derived.type_info = type_info(Type);
@@ -322,16 +340,16 @@ proc explicit_parametric_polymorphic_procedures() {
return result; return result;
} }
var manager: EntityManager; manager: EntityManager;
var entities: [dynamic]^Entity; entities: [dynamic]^Entity;
var rock = new_entity(&manager, Rock, 3, 5); rock := new_entity(&manager, Rock, 3, 5);
// Named arguments work too! // Named arguments work too!
var door = new_entity(manager = &manager, Type = Door, x = 3, y = 6); door := new_entity(manager = &manager, Type = Door, x = 3, y = 6);
// And named arguments can be any order // And named arguments can be any order
var monster = new_entity( monster := new_entity(
y = 1, y = 1,
x = 2, x = 2,
manager = &manager, manager = &manager,
@@ -417,8 +435,8 @@ proc main() {
/* /*
proc main() { proc main() {
var program = "+ + * - /"; program := "+ + * - /";
var accumulator = 0; accumulator := 0;
for token in program { for token in program {
match token { match token {
+64 -67
View File
@@ -113,17 +113,16 @@ type (
// NOTE(bill): only the ones that are needed (not all types) // NOTE(bill): only the ones that are needed (not all types)
// This will be set by the compiler // This will be set by the compiler
var (
__type_table: []TypeInfo; __type_table: []TypeInfo;
__argv__: ^^u8; __argv__: ^^u8;
__argc__: i32; __argc__: i32;
)
proc type_info_base(info: ^TypeInfo) -> ^TypeInfo { proc type_info_base(info: ^TypeInfo) -> ^TypeInfo {
if info == nil -> return nil; if info == nil -> return nil;
var base = info; base := info;
match i in base { match i in base {
case TypeInfo.Named: case TypeInfo.Named:
base = i.base; base = i.base;
@@ -135,7 +134,7 @@ proc type_info_base(info: ^TypeInfo) -> ^TypeInfo {
proc type_info_base_without_enum(info: ^TypeInfo) -> ^TypeInfo { proc type_info_base_without_enum(info: ^TypeInfo) -> ^TypeInfo {
if info == nil -> return nil; if info == nil -> return nil;
var base = info; base := info;
match i in base { match i in base {
case TypeInfo.Named: case TypeInfo.Named:
base = i.base; base = i.base;
@@ -197,7 +196,7 @@ proc make_source_code_location(file: string, line, column: i64, procedure: strin
const DEFAULT_ALIGNMENT = align_of([vector 4]f32); DEFAULT_ALIGNMENT :: align_of([vector 4]f32);
proc __init_context_from_ptr(c: ^Context, other: ^Context) #cc_contextless { proc __init_context_from_ptr(c: ^Context, other: ^Context) #cc_contextless {
if c == nil -> return; if c == nil -> return;
@@ -231,7 +230,7 @@ proc __check_context() {
proc alloc(size: int, alignment: int = DEFAULT_ALIGNMENT) -> rawptr #inline { proc alloc(size: int, alignment: int = DEFAULT_ALIGNMENT) -> rawptr #inline {
// __check_context(); // __check_context();
var a = context.allocator; a := context.allocator;
return a.procedure(a.data, AllocatorMode.Alloc, size, alignment, nil, 0, 0); return a.procedure(a.data, AllocatorMode.Alloc, size, alignment, nil, 0, 0);
} }
@@ -252,14 +251,14 @@ proc free_ptr(ptr: rawptr) #inline {
proc free_all() #inline { proc free_all() #inline {
// __check_context(); // __check_context();
var a = context.allocator; a := context.allocator;
a.procedure(a.data, AllocatorMode.FreeAll, 0, 0, nil, 0, 0); a.procedure(a.data, AllocatorMode.FreeAll, 0, 0, nil, 0, 0);
} }
proc resize(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_ALIGNMENT) -> rawptr #inline { proc resize(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_ALIGNMENT) -> rawptr #inline {
// __check_context(); // __check_context();
var a = context.allocator; a := context.allocator;
return a.procedure(a.data, AllocatorMode.Resize, new_size, alignment, ptr, old_size, 0); return a.procedure(a.data, AllocatorMode.Resize, new_size, alignment, ptr, old_size, 0);
} }
@@ -284,7 +283,7 @@ proc default_resize_align(old_memory: rawptr, old_size, new_size, alignment: int
return old_memory; return old_memory;
} }
var new_memory = alloc(new_size, alignment); new_memory := alloc(new_size, alignment);
if new_memory == nil { if new_memory == nil {
return nil; return nil;
} }
@@ -312,7 +311,7 @@ proc default_allocator_proc(allocator_data: rawptr, mode: AllocatorMode,
// NOTE(bill): Does nothing // NOTE(bill): Does nothing
case Resize: case Resize:
var ptr = os.heap_resize(old_memory, size); ptr := os.heap_resize(old_memory, size);
assert(ptr != nil); assert(ptr != nil);
return ptr; return ptr;
} }
@@ -478,11 +477,11 @@ foreign __llvm_core {
proc __sqrt_f64(x: f64) -> f64 #link_name "llvm.sqrt.f64"; proc __sqrt_f64(x: f64) -> f64 #link_name "llvm.sqrt.f64";
} }
proc __abs_complex64(x: complex64) -> f32 #inline #cc_contextless { proc __abs_complex64(x: complex64) -> f32 #inline #cc_contextless {
var r, i = real(x), imag(x); r, i := real(x), imag(x);
return __sqrt_f32(r*r + i*i); return __sqrt_f32(r*r + i*i);
} }
proc __abs_complex128(x: complex128) -> f64 #inline #cc_contextless { proc __abs_complex128(x: complex128) -> f64 #inline #cc_contextless {
var r, i = real(x), imag(x); r, i := real(x), imag(x);
return __sqrt_f64(r*r + i*i); return __sqrt_f64(r*r + i*i);
} }
@@ -490,7 +489,7 @@ proc __abs_complex128(x: complex128) -> f64 #inline #cc_contextless {
proc __dynamic_array_make(array_: rawptr, elem_size, elem_align: int, len, cap: int) { proc __dynamic_array_make(array_: rawptr, elem_size, elem_align: int, len, cap: int) {
var array = ^raw.DynamicArray(array_); array := ^raw.DynamicArray(array_);
// __check_context(); // __check_context();
array.allocator = context.allocator; array.allocator = context.allocator;
assert(array.allocator.procedure != nil); assert(array.allocator.procedure != nil);
@@ -502,7 +501,7 @@ proc __dynamic_array_make(array_: rawptr, elem_size, elem_align: int, len, cap:
} }
proc __dynamic_array_reserve(array_: rawptr, elem_size, elem_align: int, cap: int) -> bool { proc __dynamic_array_reserve(array_: rawptr, elem_size, elem_align: int, cap: int) -> bool {
var array = ^raw.DynamicArray(array_); array := ^raw.DynamicArray(array_);
if cap <= array.cap -> return true; if cap <= array.cap -> return true;
@@ -512,11 +511,11 @@ proc __dynamic_array_reserve(array_: rawptr, elem_size, elem_align: int, cap: in
} }
assert(array.allocator.procedure != nil); assert(array.allocator.procedure != nil);
var old_size = array.cap * elem_size; old_size := array.cap * elem_size;
var new_size = cap * elem_size; new_size := cap * elem_size;
var allocator = array.allocator; allocator := array.allocator;
var new_data = allocator.procedure(allocator.data, AllocatorMode.Resize, new_size, elem_align, array.data, old_size, 0); new_data := allocator.procedure(allocator.data, AllocatorMode.Resize, new_size, elem_align, array.data, old_size, 0);
if new_data == nil -> return false; if new_data == nil -> return false;
array.data = new_data; array.data = new_data;
@@ -525,9 +524,9 @@ proc __dynamic_array_reserve(array_: rawptr, elem_size, elem_align: int, cap: in
} }
proc __dynamic_array_resize(array_: rawptr, elem_size, elem_align: int, len: int) -> bool { proc __dynamic_array_resize(array_: rawptr, elem_size, elem_align: int, len: int) -> bool {
var array = ^raw.DynamicArray(array_); array := ^raw.DynamicArray(array_);
var ok = __dynamic_array_reserve(array_, elem_size, elem_align, len); ok := __dynamic_array_reserve(array_, elem_size, elem_align, len);
if ok -> array.len = len; if ok -> array.len = len;
return ok; return ok;
} }
@@ -535,22 +534,22 @@ proc __dynamic_array_resize(array_: rawptr, elem_size, elem_align: int, len: int
proc __dynamic_array_append(array_: rawptr, elem_size, elem_align: int, proc __dynamic_array_append(array_: rawptr, elem_size, elem_align: int,
items: rawptr, item_count: int) -> int { items: rawptr, item_count: int) -> int {
var array = ^raw.DynamicArray(array_); array := ^raw.DynamicArray(array_);
if item_count <= 0 || items == nil { if item_count <= 0 || items == nil {
return array.len; return array.len;
} }
var ok = true; ok := true;
if array.cap <= array.len+item_count { if array.cap <= array.len+item_count {
var cap = 2 * array.cap + max(8, item_count); cap := 2 * array.cap + max(8, item_count);
ok = __dynamic_array_reserve(array, elem_size, elem_align, cap); ok = __dynamic_array_reserve(array, elem_size, elem_align, cap);
} }
// TODO(bill): Better error handling for failed reservation // TODO(bill): Better error handling for failed reservation
if !ok -> return array.len; if !ok -> return array.len;
var data = ^u8(array.data); data := ^u8(array.data);
assert(data != nil); assert(data != nil);
__mem_copy(data + (elem_size*array.len), items, elem_size * item_count); __mem_copy(data + (elem_size*array.len), items, elem_size * item_count);
array.len += item_count; array.len += item_count;
@@ -558,17 +557,17 @@ proc __dynamic_array_append(array_: rawptr, elem_size, elem_align: int,
} }
proc __dynamic_array_append_nothing(array_: rawptr, elem_size, elem_align: int) -> int { proc __dynamic_array_append_nothing(array_: rawptr, elem_size, elem_align: int) -> int {
var array = ^raw.DynamicArray(array_); array := ^raw.DynamicArray(array_);
var ok = true; ok := true;
if array.cap <= array.len+1 { if array.cap <= array.len+1 {
var cap = 2 * array.cap + max(8, 1); cap := 2 * array.cap + max(8, 1);
ok = __dynamic_array_reserve(array, elem_size, elem_align, cap); ok = __dynamic_array_reserve(array, elem_size, elem_align, cap);
} }
// TODO(bill): Better error handling for failed reservation // TODO(bill): Better error handling for failed reservation
if !ok -> return array.len; if !ok -> return array.len;
var data = ^u8(array.data); data := ^u8(array.data);
assert(data != nil); assert(data != nil);
__mem_zero(data + (elem_size*array.len), elem_size); __mem_zero(data + (elem_size*array.len), elem_size);
array.len++; array.len++;
@@ -577,7 +576,7 @@ proc __dynamic_array_append_nothing(array_: rawptr, elem_size, elem_align: int)
proc __slice_append(slice_: rawptr, elem_size, elem_align: int, proc __slice_append(slice_: rawptr, elem_size, elem_align: int,
items: rawptr, item_count: int) -> int { items: rawptr, item_count: int) -> int {
var slice = ^raw.Slice(slice_); slice := ^raw.Slice(slice_);
if item_count <= 0 || items == nil { if item_count <= 0 || items == nil {
return slice.len; return slice.len;
@@ -585,7 +584,7 @@ proc __slice_append(slice_: rawptr, elem_size, elem_align: int,
item_count = min(slice.cap-slice.len, item_count); item_count = min(slice.cap-slice.len, item_count);
if item_count > 0 { if item_count > 0 {
var data = ^u8(slice.data); data := ^u8(slice.data);
assert(data != nil); assert(data != nil);
__mem_copy(data + (elem_size*slice.len), items, elem_size * item_count); __mem_copy(data + (elem_size*slice.len), items, elem_size * item_count);
slice.len += item_count; slice.len += item_count;
@@ -598,7 +597,7 @@ proc __slice_append(slice_: rawptr, elem_size, elem_align: int,
proc __default_hash(data: []u8) -> u128 { proc __default_hash(data: []u8) -> u128 {
proc fnv128a(data: []u8) -> u128 { proc fnv128a(data: []u8) -> u128 {
var h: u128 = 0x6c62272e07bb014262b821756295c58d; h: u128 = 0x6c62272e07bb014262b821756295c58d;
for b in data { for b in data {
h = (h ~ u128(b)) * 0x1000000000000000000013b; h = (h ~ u128(b)) * 0x1000000000000000000013b;
} }
@@ -610,21 +609,20 @@ proc __default_hash_string(s: string) -> u128 {
return __default_hash([]u8(s)); return __default_hash([]u8(s));
} }
const __INITIAL_MAP_CAP = 16; __INITIAL_MAP_CAP :: 16;
type ( __MapKey :: struct #ordered {
__MapKey struct #ordered {
hash: u128, hash: u128,
str: string, str: string,
} }
__MapFindResult struct #ordered { __MapFindResult :: struct #ordered {
hash_index: int, hash_index: int,
entry_prev: int, entry_prev: int,
entry_index: int, entry_index: int,
} }
__MapEntryHeader struct #ordered { __MapEntryHeader :: struct #ordered {
key: __MapKey, key: __MapKey,
next: int, next: int,
/* /*
@@ -632,7 +630,7 @@ type (
*/ */
} }
__MapHeader struct #ordered { __MapHeader :: struct #ordered {
m: ^raw.DynamicMap, m: ^raw.DynamicMap,
is_key_string: bool, is_key_string: bool,
entry_size: int, entry_size: int,
@@ -640,7 +638,6 @@ type (
value_offset: int, value_offset: int,
value_size: int, value_size: int,
} }
)
proc __dynamic_map_reserve(using header: __MapHeader, cap: int) { proc __dynamic_map_reserve(using header: __MapHeader, cap: int) {
__dynamic_array_reserve(&m.hashes, size_of(int), align_of(int), cap); __dynamic_array_reserve(&m.hashes, size_of(int), align_of(int), cap);
@@ -648,37 +645,37 @@ proc __dynamic_map_reserve(using header: __MapHeader, cap: int) {
} }
proc __dynamic_map_rehash(using header: __MapHeader, new_count: int) { proc __dynamic_map_rehash(using header: __MapHeader, new_count: int) {
var new_header: __MapHeader = header; new_header: __MapHeader = header;
var nm: raw.DynamicMap; nm: raw.DynamicMap;
new_header.m = &nm; new_header.m = &nm;
var header_hashes = ^raw.DynamicArray(&header.m.hashes); header_hashes := ^raw.DynamicArray(&header.m.hashes);
var nm_hashes = ^raw.DynamicArray(&nm.hashes); nm_hashes := ^raw.DynamicArray(&nm.hashes);
__dynamic_array_resize(nm_hashes, size_of(int), align_of(int), new_count); __dynamic_array_resize(nm_hashes, size_of(int), align_of(int), new_count);
__dynamic_array_reserve(&nm.entries, entry_size, entry_align, m.entries.len); __dynamic_array_reserve(&nm.entries, entry_size, entry_align, m.entries.len);
for i in 0..<new_count -> nm.hashes[i] = -1; for i in 0..<new_count -> nm.hashes[i] = -1;
for var i = 0; i < m.entries.len; i++ { for i := 0; i < m.entries.len; i++ {
if len(nm.hashes) == 0 { if len(nm.hashes) == 0 {
__dynamic_map_grow(new_header); __dynamic_map_grow(new_header);
} }
var entry_header = __dynamic_map_get_entry(header, i); entry_header := __dynamic_map_get_entry(header, i);
var data = ^u8(entry_header); data := ^u8(entry_header);
var fr = __dynamic_map_find(new_header, entry_header.key); fr := __dynamic_map_find(new_header, entry_header.key);
var j = __dynamic_map_add_entry(new_header, entry_header.key); j := __dynamic_map_add_entry(new_header, entry_header.key);
if fr.entry_prev < 0 { if fr.entry_prev < 0 {
nm.hashes[fr.hash_index] = j; nm.hashes[fr.hash_index] = j;
} else { } else {
var e = __dynamic_map_get_entry(new_header, fr.entry_prev); e := __dynamic_map_get_entry(new_header, fr.entry_prev);
e.next = j; e.next = j;
} }
var e = __dynamic_map_get_entry(new_header, j); e := __dynamic_map_get_entry(new_header, j);
e.next = fr.entry_index; e.next = fr.entry_index;
var ndata = ^u8(e); ndata := ^u8(e);
__mem_copy(ndata+value_offset, data+value_offset, value_size); __mem_copy(ndata+value_offset, data+value_offset, value_size);
if __dynamic_map_full(new_header) { if __dynamic_map_full(new_header) {
@@ -691,17 +688,17 @@ proc __dynamic_map_rehash(using header: __MapHeader, new_count: int) {
} }
proc __dynamic_map_get(h: __MapHeader, key: __MapKey) -> rawptr { proc __dynamic_map_get(h: __MapHeader, key: __MapKey) -> rawptr {
var index = __dynamic_map_find(h, key).entry_index; index := __dynamic_map_find(h, key).entry_index;
if index >= 0 { if index >= 0 {
var data = ^u8(__dynamic_map_get_entry(h, index)); data := ^u8(__dynamic_map_get_entry(h, index));
var val = data + h.value_offset; val := data + h.value_offset;
return val; return val;
} }
return nil; return nil;
} }
proc __dynamic_map_set(using h: __MapHeader, key: __MapKey, value: rawptr) { proc __dynamic_map_set(using h: __MapHeader, key: __MapKey, value: rawptr) {
var index: int; index: int;
assert(value != nil); assert(value != nil);
@@ -710,22 +707,22 @@ proc __dynamic_map_set(using h: __MapHeader, key: __MapKey, value: rawptr) {
__dynamic_map_grow(h); __dynamic_map_grow(h);
} }
var fr = __dynamic_map_find(h, key); fr := __dynamic_map_find(h, key);
if fr.entry_index >= 0 { if fr.entry_index >= 0 {
index = fr.entry_index; index = fr.entry_index;
} else { } else {
index = __dynamic_map_add_entry(h, key); index = __dynamic_map_add_entry(h, key);
if fr.entry_prev >= 0 { if fr.entry_prev >= 0 {
var entry = __dynamic_map_get_entry(h, fr.entry_prev); entry := __dynamic_map_get_entry(h, fr.entry_prev);
entry.next = index; entry.next = index;
} else { } else {
m.hashes[fr.hash_index] = index; m.hashes[fr.hash_index] = index;
} }
} }
{ {
var e = __dynamic_map_get_entry(h, index); e := __dynamic_map_get_entry(h, index);
e.key = key; e.key = key;
var val = ^u8(e) + value_offset; val := ^u8(e) + value_offset;
__mem_copy(val, value, value_size); __mem_copy(val, value, value_size);
} }
@@ -736,7 +733,7 @@ proc __dynamic_map_set(using h: __MapHeader, key: __MapKey, value: rawptr) {
proc __dynamic_map_grow(using h: __MapHeader) { proc __dynamic_map_grow(using h: __MapHeader) {
var new_count = max(2*m.entries.cap + 8, __INITIAL_MAP_CAP); new_count := max(2*m.entries.cap + 8, __INITIAL_MAP_CAP);
__dynamic_map_rehash(h, new_count); __dynamic_map_rehash(h, new_count);
} }
@@ -754,12 +751,12 @@ proc __dynamic_map_hash_equal(h: __MapHeader, a, b: __MapKey) -> bool {
} }
proc __dynamic_map_find(using h: __MapHeader, key: __MapKey) -> __MapFindResult { proc __dynamic_map_find(using h: __MapHeader, key: __MapKey) -> __MapFindResult {
var fr = __MapFindResult{-1, -1, -1}; fr := __MapFindResult{-1, -1, -1};
if len(m.hashes) > 0 { if len(m.hashes) > 0 {
fr.hash_index = int(key.hash % u128(len(m.hashes))); fr.hash_index = int(key.hash % u128(len(m.hashes)));
fr.entry_index = m.hashes[fr.hash_index]; fr.entry_index = m.hashes[fr.hash_index];
for fr.entry_index >= 0 { for fr.entry_index >= 0 {
var entry = __dynamic_map_get_entry(h, fr.entry_index); entry := __dynamic_map_get_entry(h, fr.entry_index);
if __dynamic_map_hash_equal(h, entry.key, key) { if __dynamic_map_hash_equal(h, entry.key, key) {
return fr; return fr;
} }
@@ -771,10 +768,10 @@ proc __dynamic_map_find(using h: __MapHeader, key: __MapKey) -> __MapFindResult
} }
proc __dynamic_map_add_entry(using h: __MapHeader, key: __MapKey) -> int { proc __dynamic_map_add_entry(using h: __MapHeader, key: __MapKey) -> int {
var prev = m.entries.len; prev := m.entries.len;
var c = __dynamic_array_append_nothing(&m.entries, entry_size, entry_align); c := __dynamic_array_append_nothing(&m.entries, entry_size, entry_align);
if c != prev { if c != prev {
var end = __dynamic_map_get_entry(h, c-1); end := __dynamic_map_get_entry(h, c-1);
end.key = key; end.key = key;
end.next = -1; end.next = -1;
} }
@@ -783,14 +780,14 @@ proc __dynamic_map_add_entry(using h: __MapHeader, key: __MapKey) -> int {
proc __dynamic_map_delete(using h: __MapHeader, key: __MapKey) { proc __dynamic_map_delete(using h: __MapHeader, key: __MapKey) {
var fr = __dynamic_map_find(h, key); fr := __dynamic_map_find(h, key);
if fr.entry_index >= 0 { if fr.entry_index >= 0 {
__dynamic_map_erase(h, fr); __dynamic_map_erase(h, fr);
} }
} }
proc __dynamic_map_get_entry(using h: __MapHeader, index: int) -> ^__MapEntryHeader { proc __dynamic_map_get_entry(using h: __MapHeader, index: int) -> ^__MapEntryHeader {
var data = ^u8(m.entries.data) + index*entry_size; data := ^u8(m.entries.data) + index*entry_size;
return ^__MapEntryHeader(data); return ^__MapEntryHeader(data);
} }
@@ -805,7 +802,7 @@ proc __dynamic_map_erase(using h: __MapHeader, fr: __MapFindResult) {
m.entries.len--; m.entries.len--;
} }
__mem_copy(__dynamic_map_get_entry(h, fr.entry_index), __dynamic_map_get_entry(h, m.entries.len-1), entry_size); __mem_copy(__dynamic_map_get_entry(h, fr.entry_index), __dynamic_map_get_entry(h, m.entries.len-1), entry_size);
var last = __dynamic_map_find(h, __dynamic_map_get_entry(h, fr.entry_index).key); last := __dynamic_map_find(h, __dynamic_map_get_entry(h, fr.entry_index).key);
if last.entry_prev >= 0 { if last.entry_prev >= 0 {
__dynamic_map_get_entry(h, last.entry_prev).next = fr.entry_index; __dynamic_map_get_entry(h, last.entry_prev).next = fr.entry_index;
} else { } else {
+19 -19
View File
@@ -1,8 +1,8 @@
#shared_global_scope; #shared_global_scope;
proc __multi3(a, b: u128) -> u128 #cc_c #link_name "__multi3" { proc __multi3(a, b: u128) -> u128 #cc_c #link_name "__multi3" {
const bits_in_dword_2 = size_of(i64) * 4; bits_in_dword_2 :: size_of(i64) * 4;
const lower_mask = u128(~u64(0) >> bits_in_dword_2); lower_mask :: u128(~u64(0) >> bits_in_dword_2);
when ODIN_ENDIAN == "bit" { when ODIN_ENDIAN == "bit" {
@@ -17,8 +17,8 @@ proc __multi3(a, b: u128) -> u128 #cc_c #link_name "__multi3" {
}; };
} }
var r: TWords; r: TWords;
var t: u64; t: u64;
r.lo = u64(a & lower_mask) * u64(b & lower_mask); r.lo = u64(a & lower_mask) * u64(b & lower_mask);
t = r.lo >> bits_in_dword_2; t = r.lo >> bits_in_dword_2;
@@ -36,7 +36,7 @@ proc __multi3(a, b: u128) -> u128 #cc_c #link_name "__multi3" {
} }
proc __u128_mod(a, b: u128) -> u128 #cc_c #link_name "__umodti3" { proc __u128_mod(a, b: u128) -> u128 #cc_c #link_name "__umodti3" {
var r: u128; r: u128;
__u128_quo_mod(a, b, &r); __u128_quo_mod(a, b, &r);
return r; return r;
} }
@@ -46,7 +46,7 @@ proc __u128_quo(a, b: u128) -> u128 #cc_c #link_name "__udivti3" {
} }
proc __i128_mod(a, b: i128) -> i128 #cc_c #link_name "__modti3" { proc __i128_mod(a, b: i128) -> i128 #cc_c #link_name "__modti3" {
var r: i128; r: i128;
__i128_quo_mod(a, b, &r); __i128_quo_mod(a, b, &r);
return r; return r;
} }
@@ -56,16 +56,16 @@ proc __i128_quo(a, b: i128) -> i128 #cc_c #link_name "__divti3" {
} }
proc __i128_quo_mod(a, b: i128, rem: ^i128) -> (quo: i128) #cc_c #link_name "__divmodti4" { proc __i128_quo_mod(a, b: i128, rem: ^i128) -> (quo: i128) #cc_c #link_name "__divmodti4" {
var s: i128; s: i128;
s = b >> 127; s = b >> 127;
b = (b~s) - s; b = (b~s) - s;
s = a >> 127; s = a >> 127;
b = (a~s) - s; b = (a~s) - s;
var uquo: u128; uquo: u128;
var urem = __u128_quo_mod(transmute(u128, a), transmute(u128, b), &uquo); urem := __u128_quo_mod(transmute(u128, a), transmute(u128, b), &uquo);
var iquo = transmute(i128, uquo); iquo := transmute(i128, uquo);
var irem = transmute(i128, urem); irem := transmute(i128, urem);
iquo = (iquo~s) - s; iquo = (iquo~s) - s;
irem = (irem~s) - s; irem = (irem~s) - s;
@@ -75,14 +75,14 @@ proc __i128_quo_mod(a, b: i128, rem: ^i128) -> (quo: i128) #cc_c #link_name "__d
proc __u128_quo_mod(a, b: u128, rem: ^u128) -> (quo: u128) #cc_c #link_name "__udivmodti4" { proc __u128_quo_mod(a, b: u128, rem: ^u128) -> (quo: u128) #cc_c #link_name "__udivmodti4" {
var alo, ahi = u64(a), u64(a>>64); alo, ahi := u64(a), u64(a>>64);
var blo, bhi = u64(b), u64(b>>64); blo, bhi := u64(b), u64(b>>64);
if b == 0 { if b == 0 {
if rem != nil { rem^ = 0; } if rem != nil { rem^ = 0; }
return u128(alo/blo); return u128(alo/blo);
} }
var r, d, x, q: u128 = a, b, 1, 0; r, d, x, q: u128 = a, b, 1, 0;
for r >= d && (d>>127)&1 == 0 { for r >= d && (d>>127)&1 == 0 {
x <<= 1; x <<= 1;
@@ -106,7 +106,7 @@ proc __u128_quo_mod(a, b: u128, rem: ^u128) -> (quo: u128) #cc_c #link_name "__u
proc __f16_to_f32(f: f16) -> f32 #cc_c #no_inline #link_name "__gnu_h2f_ieee" { proc __f16_to_f32(f: f16) -> f32 #cc_c #no_inline #link_name "__gnu_h2f_ieee" {
when true { when true {
// Source: https://fgiesen.wordpress.com/2012/03/28/half-to-float-done-quic/ // Source: https://fgiesen.wordpress.com/2012/03/28/half-to-float-done-quic/
const FP32 = raw_union {u: u32, f: f32}; FP32 :: raw_union {u: u32, f: f32};
magic, was_infnan: FP32; magic, was_infnan: FP32;
magic.u = (254-15) << 23; magic.u = (254-15) << 23;
@@ -130,16 +130,16 @@ proc __f16_to_f32(f: f16) -> f32 #cc_c #no_inline #link_name "__gnu_h2f_ieee" {
proc __f32_to_f16(f_: f32) -> f16 #cc_c #no_inline #link_name "__gnu_f2h_ieee" { proc __f32_to_f16(f_: f32) -> f16 #cc_c #no_inline #link_name "__gnu_f2h_ieee" {
when false { when false {
// Source: https://gist.github.com/rygorous/2156668 // Source: https://gist.github.com/rygorous/2156668
const FP16 = raw_union {u: u16, f: f16}; FP16 :: raw_union {u: u16, f: f16};
const FP32 = raw_union {u: u32, f: f32}; FP32 :: raw_union {u: u32, f: f32};
f32infty, f16infty, magic: FP32; f32infty, f16infty, magic: FP32;
f32infty.u = 255<<23; f32infty.u = 255<<23;
f16infty.u = 31<<23; f16infty.u = 31<<23;
magic.u = 15<<23; magic.u = 15<<23;
const sign_mask = u32(0x80000000); sign_mask :: u32(0x80000000);
const round_mask = ~u32(0x0fff); round_mask :: ~u32(0x0fff);
f := transmute(FP32, f_); f := transmute(FP32, f_);
+7 -7
View File
@@ -2,7 +2,7 @@
// Inline vs external file? // Inline vs external file?
import win32 "sys/windows.odin" when ODIN_OS == "windows"; import win32 "sys/windows.odin" when ODIN_OS == "windows";
var _ = compile_assert(ODIN_ARCH == "amd64"); // TODO(bill): x86 version _ := compile_assert(ODIN_ARCH == "amd64"); // TODO(bill): x86 version
proc yield_thread() { win32.mm_pause(); } proc yield_thread() { win32.mm_pause(); }
@@ -34,8 +34,8 @@ proc fetch_or(a: ^i32, operand: i32) -> i32 {
return win32.interlocked_or(a, operand); return win32.interlocked_or(a, operand);
} }
proc spin_lock(a: ^i32, time_out: int) -> bool { // NOTE(bill) time_out = -1 as default proc spin_lock(a: ^i32, time_out: int) -> bool { // NOTE(bill) time_out = -1 as default
var old_value = compare_exchange(a, 1, 0); old_value := compare_exchange(a, 1, 0);
var counter = 0; counter := 0;
for old_value != 0 && (time_out < 0 || counter < time_out) { for old_value != 0 && (time_out < 0 || counter < time_out) {
counter++; counter++;
yield_thread(); yield_thread();
@@ -50,7 +50,7 @@ proc spin_unlock(a: ^i32) {
} }
proc try_acquire_lock(a: ^i32) -> bool { proc try_acquire_lock(a: ^i32) -> bool {
yield_thread(); yield_thread();
var old_value = compare_exchange(a, 1, 0); old_value := compare_exchange(a, 1, 0);
mfence(); mfence();
return old_value == 0; return old_value == 0;
} }
@@ -78,8 +78,8 @@ proc fetch_or(a: ^i64, operand: i64) -> i64 {
return win32.interlocked_or64(a, operand); return win32.interlocked_or64(a, operand);
} }
proc spin_lock(a: ^i64, time_out: int) -> bool { // NOTE(bill) time_out = -1 as default proc spin_lock(a: ^i64, time_out: int) -> bool { // NOTE(bill) time_out = -1 as default
var old_value = compare_exchange(a, 1, 0); old_value := compare_exchange(a, 1, 0);
var counter = 0; counter := 0;
for old_value != 0 && (time_out < 0 || counter < time_out) { for old_value != 0 && (time_out < 0 || counter < time_out) {
counter++; counter++;
yield_thread(); yield_thread();
@@ -94,7 +94,7 @@ proc spin_unlock(a: ^i64) {
} }
proc try_acquire_lock(a: ^i64) -> bool { proc try_acquire_lock(a: ^i64) -> bool {
yield_thread(); yield_thread();
var old_value = compare_exchange(a, 1, 0); old_value := compare_exchange(a, 1, 0);
mfence(); mfence();
return old_value == 0; return old_value == 0;
} }
+32 -34
View File
@@ -1,28 +1,26 @@
const ( U8_MIN :: u8(0);
U8_MIN = u8(0); U16_MIN :: u16(0);
U16_MIN = u16(0); U32_MIN :: u32(0);
U32_MIN = u32(0); U64_MIN :: u64(0);
U64_MIN = u64(0); U128_MIN :: u128(0);
U128_MIN = u128(0);
I8_MIN = i8(-0x80); I8_MIN :: i8(-0x80);
I16_MIN = i16(-0x8000); I16_MIN :: i16(-0x8000);
I32_MIN = i32(-0x8000_0000); I32_MIN :: i32(-0x8000_0000);
I64_MIN = i64(-0x8000_0000_0000_0000); I64_MIN :: i64(-0x8000_0000_0000_0000);
I128_MIN = i128(-0x8000_0000_0000_0000_0000_0000_0000_0000); I128_MIN :: i128(-0x8000_0000_0000_0000_0000_0000_0000_0000);
U8_MAX = ~u8(0); U8_MAX :: ~u8(0);
U16_MAX = ~u16(0); U16_MAX :: ~u16(0);
U32_MAX = ~u32(0); U32_MAX :: ~u32(0);
U64_MAX = ~u64(0); U64_MAX :: ~u64(0);
U128_MAX = ~u128(0); U128_MAX :: ~u128(0);
I8_MAX = i8(0x7f); I8_MAX :: i8(0x7f);
I16_MAX = i16(0x7fff); I16_MAX :: i16(0x7fff);
I32_MAX = i32(0x7fff_ffff); I32_MAX :: i32(0x7fff_ffff);
I64_MAX = i64(0x7fff_ffff_ffff_ffff); I64_MAX :: i64(0x7fff_ffff_ffff_ffff);
I128_MAX = i128(0x7fff_ffff_ffff_ffff_ffff_ffff_ffff_ffff); I128_MAX :: i128(0x7fff_ffff_ffff_ffff_ffff_ffff_ffff_ffff);
)
proc count_ones(i: u8) -> u8 { foreign __llvm_core proc __llvm_ctpop(u8) -> u8 #link_name "llvm.ctpop.i8"; return __llvm_ctpop(i); } proc count_ones(i: u8) -> u8 { foreign __llvm_core proc __llvm_ctpop(u8) -> u8 #link_name "llvm.ctpop.i8"; return __llvm_ctpop(i); }
proc count_ones(i: i8) -> i8 { foreign __llvm_core proc __llvm_ctpop(i8) -> i8 #link_name "llvm.ctpop.i8"; return __llvm_ctpop(i); } proc count_ones(i: i8) -> i8 { foreign __llvm_core proc __llvm_ctpop(i8) -> i8 #link_name "llvm.ctpop.i8"; return __llvm_ctpop(i); }
@@ -198,19 +196,19 @@ proc overflowing_add(lhs, rhs: u128) -> (u128, bool) { foreign __llvm_core proc
proc overflowing_add(lhs, rhs: i128) -> (i128, bool) { foreign __llvm_core proc op(i128, i128) -> (i128, bool) #link_name "llvm.sadd.with.overflow.i128"; return op(lhs, rhs); } proc overflowing_add(lhs, rhs: i128) -> (i128, bool) { foreign __llvm_core proc op(i128, i128) -> (i128, bool) #link_name "llvm.sadd.with.overflow.i128"; return op(lhs, rhs); }
proc overflowing_add(lhs, rhs: uint) -> (uint, bool) { proc overflowing_add(lhs, rhs: uint) -> (uint, bool) {
when size_of(uint) == size_of(u32) { when size_of(uint) == size_of(u32) {
var x, ok = overflowing_add(u32(lhs), u32(rhs)); x, ok := overflowing_add(u32(lhs), u32(rhs));
return uint(x), ok; return uint(x), ok;
} else { } else {
var x, ok = overflowing_add(u64(lhs), u64(rhs)); x, ok := overflowing_add(u64(lhs), u64(rhs));
return uint(x), ok; return uint(x), ok;
} }
} }
proc overflowing_add(lhs, rhs: int) -> (int, bool) { proc overflowing_add(lhs, rhs: int) -> (int, bool) {
when size_of(int) == size_of(i32) { when size_of(int) == size_of(i32) {
var x, ok = overflowing_add(i32(lhs), i32(rhs)); x, ok := overflowing_add(i32(lhs), i32(rhs));
return int(x), ok; return int(x), ok;
} else { } else {
var x, ok = overflowing_add(i64(lhs), i64(rhs)); x, ok := overflowing_add(i64(lhs), i64(rhs));
return int(x), ok; return int(x), ok;
} }
} }
@@ -227,19 +225,19 @@ proc overflowing_sub(lhs, rhs: u128) -> (u128, bool) { foreign __llvm_core proc
proc overflowing_sub(lhs, rhs: i128) -> (i128, bool) { foreign __llvm_core proc op(i128, i128) -> (i128, bool) #link_name "llvm.ssub.with.overflow.i128"; return op(lhs, rhs); } proc overflowing_sub(lhs, rhs: i128) -> (i128, bool) { foreign __llvm_core proc op(i128, i128) -> (i128, bool) #link_name "llvm.ssub.with.overflow.i128"; return op(lhs, rhs); }
proc overflowing_sub(lhs, rhs: uint) -> (uint, bool) { proc overflowing_sub(lhs, rhs: uint) -> (uint, bool) {
when size_of(uint) == size_of(u32) { when size_of(uint) == size_of(u32) {
var x, ok = overflowing_sub(u32(lhs), u32(rhs)); x, ok := overflowing_sub(u32(lhs), u32(rhs));
return uint(x), ok; return uint(x), ok;
} else { } else {
var x, ok = overflowing_sub(u64(lhs), u64(rhs)); x, ok := overflowing_sub(u64(lhs), u64(rhs));
return uint(x), ok; return uint(x), ok;
} }
} }
proc overflowing_sub(lhs, rhs: int) -> (int, bool) { proc overflowing_sub(lhs, rhs: int) -> (int, bool) {
when size_of(int) == size_of(i32) { when size_of(int) == size_of(i32) {
var x, ok = overflowing_sub(i32(lhs), i32(rhs)); x, ok := overflowing_sub(i32(lhs), i32(rhs));
return int(x), ok; return int(x), ok;
} else { } else {
var x, ok = overflowing_sub(i64(lhs), i64(rhs)); x, ok := overflowing_sub(i64(lhs), i64(rhs));
return int(x), ok; return int(x), ok;
} }
} }
@@ -256,19 +254,19 @@ proc overflowing_mul(lhs, rhs: u128) -> (u128, bool) { foreign __llvm_core proc
proc overflowing_mul(lhs, rhs: i128) -> (i128, bool) { foreign __llvm_core proc op(i128, i128) -> (i128, bool) #link_name "llvm.smul.with.overflow.i128"; return op(lhs, rhs); } proc overflowing_mul(lhs, rhs: i128) -> (i128, bool) { foreign __llvm_core proc op(i128, i128) -> (i128, bool) #link_name "llvm.smul.with.overflow.i128"; return op(lhs, rhs); }
proc overflowing_mul(lhs, rhs: uint) -> (uint, bool) { proc overflowing_mul(lhs, rhs: uint) -> (uint, bool) {
when size_of(uint) == size_of(u32) { when size_of(uint) == size_of(u32) {
var x, ok = overflowing_mul(u32(lhs), u32(rhs)); x, ok := overflowing_mul(u32(lhs), u32(rhs));
return uint(x), ok; return uint(x), ok;
} else { } else {
var x, ok = overflowing_mul(u64(lhs), u64(rhs)); x, ok := overflowing_mul(u64(lhs), u64(rhs));
return uint(x), ok; return uint(x), ok;
} }
} }
proc overflowing_mul(lhs, rhs: int) -> (int, bool) { proc overflowing_mul(lhs, rhs: int) -> (int, bool) {
when size_of(int) == size_of(i32) { when size_of(int) == size_of(i32) {
var x, ok = overflowing_mul(i32(lhs), i32(rhs)); x, ok := overflowing_mul(i32(lhs), i32(rhs));
return int(x), ok; return int(x), ok;
} else { } else {
var x, ok = overflowing_mul(i64(lhs), i64(rhs)); x, ok := overflowing_mul(i64(lhs), i64(rhs));
return int(x), ok; return int(x), ok;
} }
} }
+28 -30
View File
@@ -16,7 +16,7 @@ proc decimal_to_string(buf: []u8, a: ^Decimal) -> string {
} }
var n = 10 + a.count + abs(a.decimal_point); n := 10 + a.count + abs(a.decimal_point);
// TODO(bill): make this work with a buffer that's not big enough // TODO(bill): make this work with a buffer that's not big enough
assert(len(buf) >= n); assert(len(buf) >= n);
@@ -27,7 +27,7 @@ proc decimal_to_string(buf: []u8, a: ^Decimal) -> string {
return string(buf[0..<1]); return string(buf[0..<1]);
} }
var w = 0; w := 0;
if a.decimal_point <= 0 { if a.decimal_point <= 0 {
buf[w] = '0'; w++; buf[w] = '0'; w++;
buf[w] = '.'; w++; buf[w] = '.'; w++;
@@ -57,10 +57,10 @@ proc trim(a: ^Decimal) {
proc assign(a: ^Decimal, i: u64) { proc assign(a: ^Decimal, i: u64) {
var buf: [32]u8; buf: [32]u8;
var n = 0; n := 0;
for i > 0 { for i > 0 {
var j = i/10; j := i/10;
i -= 10*j; i -= 10*j;
buf[n] = u8('0'+i); buf[n] = u8('0'+i);
n++; n++;
@@ -79,10 +79,10 @@ proc assign(a: ^Decimal, i: u64) {
proc shift_right(a: ^Decimal, k: uint) { proc shift_right(a: ^Decimal, k: uint) {
var r = 0; // read index r := 0; // read index
var w = 0; // write index w := 0; // write index
var n: uint; n: uint;
for ; n>>k == 0; r++ { for ; n>>k == 0; r++ {
if r >= a.count { if r >= a.count {
if n == 0 { if n == 0 {
@@ -96,16 +96,16 @@ proc shift_right(a: ^Decimal, k: uint) {
} }
break; break;
} }
var c = uint(a.digits[r]); c := uint(a.digits[r]);
n = n*10 + c - '0'; n = n*10 + c - '0';
} }
a.decimal_point -= r-1; a.decimal_point -= r-1;
var mask: uint = (1<<k) - 1; mask: uint = (1<<k) - 1;
for ; r < a.count; r++ { for ; r < a.count; r++ {
var c = uint(a.digits[r]); c := uint(a.digits[r]);
var dig = n>>k; dig := n>>k;
n &= mask; n &= mask;
a.digits[w] = u8('0' + dig); a.digits[w] = u8('0' + dig);
w++; w++;
@@ -113,7 +113,7 @@ proc shift_right(a: ^Decimal, k: uint) {
} }
for n > 0 { for n > 0 {
var dig = n>>k; dig := n>>k;
n &= mask; n &= mask;
if w < len(a.digits) { if w < len(a.digits) {
a.digits[w] = u8('0' + dig); a.digits[w] = u8('0' + dig);
@@ -130,16 +130,16 @@ proc shift_right(a: ^Decimal, k: uint) {
} }
proc shift_left(a: ^Decimal, k: uint) { proc shift_left(a: ^Decimal, k: uint) {
var delta = int(k/4); delta := int(k/4);
var r = a.count; // read index r := a.count; // read index
var w = a.count+delta; // write index w := a.count+delta; // write index
var n: uint; n: uint;
for r--; r >= 0; r-- { for r--; r >= 0; r-- {
n += (uint(a.digits[r]) - '0') << k; n += (uint(a.digits[r]) - '0') << k;
var quo = n/10; quo := n/10;
var rem = n - 10*quo; rem := n - 10*quo;
w--; w--;
if w < len(a.digits) { if w < len(a.digits) {
a.digits[w] = u8('0' + rem); a.digits[w] = u8('0' + rem);
@@ -150,8 +150,8 @@ proc shift_left(a: ^Decimal, k: uint) {
} }
for n > 0 { for n > 0 {
var quo = n/10; quo := n/10;
var rem = n - 10*quo; rem := n - 10*quo;
w--; w--;
if 0 <= w && w < len(a.digits) { if 0 <= w && w < len(a.digits) {
a.digits[w] = u8('0' + rem); a.digits[w] = u8('0' + rem);
@@ -168,10 +168,8 @@ proc shift_left(a: ^Decimal, k: uint) {
} }
proc shift(a: ^Decimal, k: int) { proc shift(a: ^Decimal, k: int) {
const ( uint_size :: 8*size_of(uint);
uint_size = 8*size_of(uint); max_shift :: uint_size-4;
max_shift = uint_size-4;
)
match { match {
case a.count == 0: case a.count == 0:
@@ -215,8 +213,8 @@ proc round(a: ^Decimal, nd: int) {
proc round_up(a: ^Decimal, nd: int) { proc round_up(a: ^Decimal, nd: int) {
if nd < 0 || nd >= a.count { return; } if nd < 0 || nd >= a.count { return; }
for var i = nd-1; i >= 0; i-- { for i := nd-1; i >= 0; i-- {
if var c = a.digits[i]; c < '9' { if c := a.digits[i]; c < '9' {
a.digits[i]++; a.digits[i]++;
a.count = i+1; a.count = i+1;
return; return;
@@ -241,9 +239,9 @@ proc rounded_integer(a: ^Decimal) -> u64 {
if a.decimal_point > 20 { if a.decimal_point > 20 {
return 0xffff_ffff_ffff_ffff; return 0xffff_ffff_ffff_ffff;
} }
var i: int; i: int;
var n: u64 = 0; n: u64 = 0;
var m = min(a.decimal_point, a.count); m := min(a.decimal_point, a.count);
for i = 0; i < m; i++ { for i = 0; i < m; i++ {
n = n*10 + u64(a.digits[i]-'0'); n = n*10 + u64(a.digits[i]-'0');
} }
+104 -109
View File
@@ -7,7 +7,7 @@ import (
"raw.odin"; "raw.odin";
) )
const _BUFFER_SIZE = 1<<12; _BUFFER_SIZE :: 1<<12;
type StringBuffer union { type StringBuffer union {
Static {buf: []u8}, Static {buf: []u8},
@@ -89,45 +89,45 @@ proc write_rune(buf: ^StringBuffer, r: rune) {
return; return;
} }
var b, n = utf8.encode_rune(r); b, n := utf8.encode_rune(r);
write_bytes(buf, b[0..<n]); write_bytes(buf, b[0..<n]);
} }
proc write_int(buf: ^StringBuffer, i: i128, base: int) { proc write_int(buf: ^StringBuffer, i: i128, base: int) {
var b: [129]u8; b: [129]u8;
var s = strconv.append_bits(b[0..<0], u128(i), base, true, 128, strconv.digits, 0); s := strconv.append_bits(b[0..<0], u128(i), base, true, 128, strconv.digits, 0);
write_string(buf, s); write_string(buf, s);
} }
proc write_int(buf: ^StringBuffer, i: i64, base: int) { proc write_int(buf: ^StringBuffer, i: i64, base: int) {
var b: [129]u8; b: [129]u8;
var s = strconv.append_bits(b[0..<0], u128(i), base, true, 64, strconv.digits, 0); s := strconv.append_bits(b[0..<0], u128(i), base, true, 64, strconv.digits, 0);
write_string(buf, s); write_string(buf, s);
} }
proc fprint(fd: os.Handle, args: ..any) -> int { proc fprint(fd: os.Handle, args: ..any) -> int {
var data: [_BUFFER_SIZE]u8; data: [_BUFFER_SIZE]u8;
var buf = make_string_buffer_from_slice(data[0..<0]); buf := make_string_buffer_from_slice(data[0..<0]);
sbprint(&buf, ..args); sbprint(&buf, ..args);
var res = string_buffer_data(buf); res := string_buffer_data(buf);
os.write(fd, res); os.write(fd, res);
return len(res); return len(res);
} }
proc fprintln(fd: os.Handle, args: ..any) -> int { proc fprintln(fd: os.Handle, args: ..any) -> int {
var data: [_BUFFER_SIZE]u8; data: [_BUFFER_SIZE]u8;
var buf = make_string_buffer_from_slice(data[0..<0]); buf := make_string_buffer_from_slice(data[0..<0]);
sbprintln(&buf, ..args); sbprintln(&buf, ..args);
var res = string_buffer_data(buf); res := string_buffer_data(buf);
os.write(fd, res); os.write(fd, res);
return len(res); return len(res);
} }
proc fprintf(fd: os.Handle, fmt: string, args: ..any) -> int { proc fprintf(fd: os.Handle, fmt: string, args: ..any) -> int {
var data: [_BUFFER_SIZE]u8; data: [_BUFFER_SIZE]u8;
var buf = make_string_buffer_from_slice(data[0..<0]); buf := make_string_buffer_from_slice(data[0..<0]);
sbprintf(&buf, fmt, ..args); sbprintf(&buf, fmt, ..args);
var res = string_buffer_data(buf); res := string_buffer_data(buf);
os.write(fd, res); os.write(fd, res);
return len(res); return len(res);
} }
@@ -145,17 +145,17 @@ proc printf_err (fmt: string, args: ..any) -> int { return fprintf(os.stderr, f
// aprint* procedures return a string that was allocated with the current context // aprint* procedures return a string that was allocated with the current context
// They must be freed accordingly // They must be freed accordingly
proc aprint(args: ..any) -> string { proc aprint(args: ..any) -> string {
var buf = make_string_dynamic_buffer(); buf := make_string_dynamic_buffer();
sbprint(&buf, ..args); sbprint(&buf, ..args);
return to_string(buf); return to_string(buf);
} }
proc aprintln(args: ..any) -> string { proc aprintln(args: ..any) -> string {
var buf = make_string_dynamic_buffer(); buf := make_string_dynamic_buffer();
sbprintln(&buf, ..args); sbprintln(&buf, ..args);
return to_string(buf); return to_string(buf);
} }
proc aprintf(fmt: string, args: ..any) -> string { proc aprintf(fmt: string, args: ..any) -> string {
var buf = make_string_dynamic_buffer(); buf := make_string_dynamic_buffer();
sbprintf(&buf, fmt, ..args); sbprintf(&buf, fmt, ..args);
return to_string(buf); return to_string(buf);
} }
@@ -164,15 +164,15 @@ proc aprintf(fmt: string, args: ..any) -> string {
// bprint* procedures return a string that was allocated with the current context // bprint* procedures return a string that was allocated with the current context
// They must be freed accordingly // They must be freed accordingly
proc bprint(buf: []u8, args: ..any) -> string { proc bprint(buf: []u8, args: ..any) -> string {
var sb = make_string_buffer_from_slice(buf[0..<0..<len(buf)]); sb := make_string_buffer_from_slice(buf[0..<0..<len(buf)]);
return sbprint(&sb, ..args); return sbprint(&sb, ..args);
} }
proc bprintln(buf: []u8, args: ..any) -> string { proc bprintln(buf: []u8, args: ..any) -> string {
var sb = make_string_buffer_from_slice(buf[0..<0..<len(buf)]); sb := make_string_buffer_from_slice(buf[0..<0..<len(buf)]);
return sbprintln(&sb, ..args); return sbprintln(&sb, ..args);
} }
proc bprintf(buf: []u8, fmt: string, args: ..any) -> string { proc bprintf(buf: []u8, fmt: string, args: ..any) -> string {
var sb = make_string_buffer_from_slice(buf[0..<0..<len(buf)]); sb := make_string_buffer_from_slice(buf[0..<0..<len(buf)]);
return sbprintf(&sb, fmt, ..args); return sbprintf(&sb, fmt, ..args);
} }
@@ -182,8 +182,8 @@ proc bprintf(buf: []u8, fmt: string, args: ..any) -> string {
proc fprint_type(fd: os.Handle, info: ^TypeInfo) { proc fprint_type(fd: os.Handle, info: ^TypeInfo) {
var data: [_BUFFER_SIZE]u8; data: [_BUFFER_SIZE]u8;
var buf = make_string_buffer_from_slice(data[0..<0]); buf := make_string_buffer_from_slice(data[0..<0]);
write_type(&buf, info); write_type(&buf, info);
os.write(fd, string_buffer_data(buf)); os.write(fd, string_buffer_data(buf));
} }
@@ -237,7 +237,7 @@ proc write_type(buf: ^StringBuffer, ti: ^TypeInfo) {
if info.params == nil { if info.params == nil {
write_string(buf, "()"); write_string(buf, "()");
} else { } else {
var t = info.params.(^Tuple); t := info.params.(^Tuple);
write_string(buf, "("); write_string(buf, "(");
for t, i in t.types { for t, i in t.types {
if i > 0 -> write_string(buf, ", "); if i > 0 -> write_string(buf, ", ");
@@ -250,12 +250,12 @@ proc write_type(buf: ^StringBuffer, ti: ^TypeInfo) {
write_type(buf, info.results); write_type(buf, info.results);
} }
case Tuple: case Tuple:
var count = len(info.names); count := len(info.names);
if count != 1 -> write_string(buf, "("); if count != 1 -> write_string(buf, "(");
for name, i in info.names { for name, i in info.names {
if i > 0 -> write_string(buf, ", "); if i > 0 -> write_string(buf, ", ");
var t = info.types[i]; t := info.types[i];
if len(name) > 0 { if len(name) > 0 {
write_string(buf, name); write_string(buf, name);
@@ -267,7 +267,7 @@ proc write_type(buf: ^StringBuffer, ti: ^TypeInfo) {
case Array: case Array:
write_string(buf, "["); write_string(buf, "[");
var fi = FmtInfo{buf = buf}; fi := FmtInfo{buf = buf};
write_int(buf, i64(info.count), 10); write_int(buf, i64(info.count), 10);
write_string(buf, "]"); write_string(buf, "]");
write_type(buf, info.elem); write_type(buf, info.elem);
@@ -309,8 +309,8 @@ proc write_type(buf: ^StringBuffer, ti: ^TypeInfo) {
case Union: case Union:
write_string(buf, "union {"); write_string(buf, "union {");
var cf = info.common_fields; cf := info.common_fields;
var total_count = 0; total_count := 0;
for name, i in cf.names { for name, i in cf.names {
if i > 0 -> write_string(buf, ", "); if i > 0 -> write_string(buf, ", ");
write_string(buf, name); write_string(buf, name);
@@ -324,13 +324,13 @@ proc write_type(buf: ^StringBuffer, ti: ^TypeInfo) {
write_byte(buf, '{'); write_byte(buf, '{');
defer write_byte(buf, '}'); defer write_byte(buf, '}');
var variant_type = type_info_base(info.variant_types[i]); variant_type := type_info_base(info.variant_types[i]);
var variant = variant_type.(^Struct); variant := variant_type.(^Struct);
var vc = len(variant.names)-len(cf.names); vc := len(variant.names)-len(cf.names);
for j in 0..vc { for j in 0..<vc {
if j > 0 -> write_string(buf, ", "); if j > 0 -> write_string(buf, ", ");
var index = j + len(cf.names); index := j + len(cf.names);
write_string(buf, variant.names[index]); write_string(buf, variant.names[index]);
write_string(buf, ": "); write_string(buf, ": ");
write_type(buf, variant.types[index]); write_type(buf, variant.types[index]);
@@ -382,12 +382,12 @@ proc _parse_int(s: string, offset: int) -> (result: int, offset: int, ok: bool)
return '0' <= r && r <= '9'; return '0' <= r && r <= '9';
} }
var result = 0; result := 0;
var ok = true; ok := true;
var i = 0; i := 0;
for i < len(s[offset..]) { for i < len(s[offset..]) {
var c = rune(s[offset+i]); c := rune(s[offset+i]);
if !is_digit(c) -> break; if !is_digit(c) -> break;
i++; i++;
@@ -406,7 +406,7 @@ proc _arg_number(fi: ^FmtInfo, arg_index: int, format: string, offset, arg_count
for i in 1..len(format) { for i in 1..len(format) {
if format[i] == ']' { if format[i] == ']' {
var width, new_index, ok = _parse_int(format, 1); width, new_index, ok := _parse_int(format, 1);
if !ok || new_index != i { if !ok || new_index != i {
return 0, i+1, false; return 0, i+1, false;
} }
@@ -422,7 +422,7 @@ proc _arg_number(fi: ^FmtInfo, arg_index: int, format: string, offset, arg_count
return arg_index, offset, false; return arg_index, offset, false;
} }
fi.reordered = true; fi.reordered = true;
var index, width, ok = parse_arg_number(format[offset..]); index, width, ok := parse_arg_number(format[offset..]);
if ok && 0 <= index && index < arg_count { if ok && 0 <= index && index < arg_count {
return index, offset+width, true; return index, offset+width, true;
} }
@@ -431,11 +431,11 @@ proc _arg_number(fi: ^FmtInfo, arg_index: int, format: string, offset, arg_count
} }
proc int_from_arg(args: []any, arg_index: int) -> (int, int, bool) { proc int_from_arg(args: []any, arg_index: int) -> (int, int, bool) {
var num = 0; num := 0;
var new_arg_index = arg_index; new_arg_index := arg_index;
var ok = true; ok := true;
if arg_index < len(args) { if arg_index < len(args) {
var arg = args[arg_index]; arg := args[arg_index];
arg.type_info = type_info_base(arg.type_info); arg.type_info = type_info_base(arg.type_info);
match i in arg { match i in arg {
case int: num = i; case int: num = i;
@@ -484,30 +484,30 @@ proc fmt_bool(using fi: ^FmtInfo, b: bool, verb: rune) {
proc fmt_write_padding(fi: ^FmtInfo, width: int) { proc fmt_write_padding(fi: ^FmtInfo, width: int) {
if width <= 0 -> return; if width <= 0 -> return;
var pad_byte: u8 = fi.space ? ' ' : '0'; pad_byte: u8 = fi.space ? ' ' : '0';
var data = string_buffer_data(fi.buf^); data := string_buffer_data(fi.buf^);
var count = min(width, cap(data)-len(data)); count := min(width, cap(data)-len(data));
for _ in 0..<count -> write_byte(fi.buf, pad_byte); for _ in 0..<count -> write_byte(fi.buf, pad_byte);
} }
proc _fmt_int(fi: ^FmtInfo, u: u128, base: int, is_signed: bool, bit_size: int, digits: string) { proc _fmt_int(fi: ^FmtInfo, u: u128, base: int, is_signed: bool, bit_size: int, digits: string) {
var _, neg = strconv.is_integer_negative(u128(u), is_signed, bit_size); _, neg := strconv.is_integer_negative(u128(u), is_signed, bit_size);
const BUF_SIZE = 256; BUF_SIZE :: 256;
if fi.width_set || fi.prec_set { if fi.width_set || fi.prec_set {
var width = fi.width + fi.prec + 3; // 3 extra bytes for sign and prefix width := fi.width + fi.prec + 3; // 3 extra bytes for sign and prefix
if width > BUF_SIZE { if width > BUF_SIZE {
// TODO(bill):???? // TODO(bill):????
panic("_fmt_int: buffer overrun. Width and precision too big"); panic("_fmt_int: buffer overrun. Width and precision too big");
} }
} }
var prec = 0; prec := 0;
if fi.prec_set { if fi.prec_set {
prec = fi.prec; prec = fi.prec;
if prec == 0 && u == 0 { if prec == 0 && u == 0 {
var prev_zero = fi.zero; prev_zero := fi.zero;
fi.zero = false; fi.zero = false;
fmt_write_padding(fi, fi.width); fmt_write_padding(fi, fi.width);
fi.zero = prev_zero; fi.zero = prev_zero;
@@ -528,18 +528,18 @@ proc _fmt_int(fi: ^FmtInfo, u: u128, base: int, is_signed: bool, bit_size: int,
panic("_fmt_int: unknown base, whoops"); panic("_fmt_int: unknown base, whoops");
} }
var buf: [256]u8; buf: [256]u8;
var start = 0; start := 0;
var flags: strconv.IntFlag; flags: strconv.IntFlag;
if fi.hash && !fi.zero -> flags |= strconv.IntFlag.Prefix; if fi.hash && !fi.zero -> flags |= strconv.IntFlag.Prefix;
if fi.plus -> flags |= strconv.IntFlag.Plus; if fi.plus -> flags |= strconv.IntFlag.Plus;
if fi.space -> flags |= strconv.IntFlag.Space; if fi.space -> flags |= strconv.IntFlag.Space;
var s = strconv.append_bits(buf[start..<start], u128(u), base, is_signed, bit_size, digits, flags); s := strconv.append_bits(buf[start..<start], u128(u), base, is_signed, bit_size, digits, flags);
if fi.hash && fi.zero { if fi.hash && fi.zero {
var c: u8; c: u8;
match base { match base {
case 2: c = 'b'; case 2: c = 'b';
case 8: c = 'o'; case 8: c = 'o';
@@ -553,16 +553,15 @@ proc _fmt_int(fi: ^FmtInfo, u: u128, base: int, is_signed: bool, bit_size: int,
} }
} }
var prev_zero = fi.zero; prev_zero := fi.zero;
defer fi.zero = prev_zero; defer fi.zero = prev_zero;
fi.zero = false; fi.zero = false;
_pad(fi, s); _pad(fi, s);
} }
var (
__DIGITS_LOWER = "0123456789abcdefx"; __DIGITS_LOWER := "0123456789abcdefx";
__DIGITS_UPPER = "0123456789ABCDEFX"; __DIGITS_UPPER := "0123456789ABCDEFX";
)
proc fmt_rune(fi: ^FmtInfo, r: rune, verb: rune) { proc fmt_rune(fi: ^FmtInfo, r: rune, verb: rune) {
match verb { match verb {
@@ -584,7 +583,7 @@ proc fmt_int(fi: ^FmtInfo, u: u128, is_signed: bool, bit_size: int, verb: rune)
case 'c', 'r': case 'c', 'r':
fmt_rune(fi, rune(u), verb); fmt_rune(fi, rune(u), verb);
case 'U': case 'U':
var r = rune(u); r := rune(u);
if r < 0 || r > utf8.MAX_RUNE { if r < 0 || r > utf8.MAX_RUNE {
fmt_bad_verb(fi, verb); fmt_bad_verb(fi, verb);
} else { } else {
@@ -602,7 +601,7 @@ proc _pad(fi: ^FmtInfo, s: string) {
write_string(fi.buf, s); write_string(fi.buf, s);
return; return;
} }
var width = fi.width - utf8.rune_count(s); width := fi.width - utf8.rune_count(s);
if fi.minus { // right pad if fi.minus { // right pad
write_string(fi.buf, s); write_string(fi.buf, s);
fmt_write_padding(fi, width); fmt_write_padding(fi, width);
@@ -618,10 +617,10 @@ proc fmt_float(fi: ^FmtInfo, v: f64, bit_size: int, verb: rune) {
// case 'f', 'F', 'v': // case 'f', 'F', 'v':
case 'f', 'F', 'v': case 'f', 'F', 'v':
var prec: int = fi.prec_set ? fi.prec : 3; prec: int = fi.prec_set ? fi.prec : 3;
var buf: [386]u8; buf: [386]u8;
var str = strconv.append_float(buf[1..<1], v, 'f', prec, bit_size); str := strconv.append_float(buf[1..<1], v, 'f', prec, bit_size);
str = string(buf[0..len(str)]); str = string(buf[0..len(str)]);
if str[1] == '+' || str[1] == '-' { if str[1] == '+' || str[1] == '-' {
str = str[1..]; str = str[1..];
@@ -660,7 +659,7 @@ proc fmt_string(fi: ^FmtInfo, s: string, verb: rune) {
write_string(fi.buf, s); write_string(fi.buf, s);
case 'x', 'X': case 'x', 'X':
var space = fi.space; space := fi.space;
fi.space = false; fi.space = false;
defer fi.space = space; defer fi.space = space;
@@ -682,7 +681,7 @@ proc fmt_pointer(fi: ^FmtInfo, p: rawptr, verb: rune) {
fmt_bad_verb(fi, verb); fmt_bad_verb(fi, verb);
return; return;
} }
var u = u128(uint(p)); u := u128(uint(p));
if !fi.hash || verb == 'v' { if !fi.hash || verb == 'v' {
write_string(fi.buf, "0x"); write_string(fi.buf, "0x");
} }
@@ -705,13 +704,10 @@ proc fmt_enum(fi: ^FmtInfo, v: any, verb: rune) {
case 'd', 'f': case 'd', 'f':
fmt_arg(fi, any{v.data, type_info_base(e.base)}, verb); fmt_arg(fi, any{v.data, type_info_base(e.base)}, verb);
case 's', 'v': case 's', 'v':
var (
i: i128; i: i128;
f: f64; f: f64;
ok: bool; ok: bool;
a: any; a := any{v.data, type_info_base(e.base)};
)
a = any{v.data, type_info_base(e.base)};
match v in a { match v in a {
case rune: i = i128(v); case rune: i = i128(v);
case i8: i = i128(v); case i8: i = i128(v);
@@ -785,7 +781,7 @@ proc fmt_value(fi: ^FmtInfo, v: any, verb: rune) {
write_string(fi.buf, b.names[i]); write_string(fi.buf, b.names[i]);
write_string(fi.buf, " = "); write_string(fi.buf, " = ");
var data = ^u8(v.data) + b.offsets[i]; data := ^u8(v.data) + b.offsets[i];
fmt_arg(fi, any{rawptr(data), b.types[i]}, 'v'); fmt_arg(fi, any{rawptr(data), b.types[i]}, 'v');
} }
write_byte(fi.buf, '}'); write_byte(fi.buf, '}');
@@ -817,29 +813,29 @@ proc fmt_value(fi: ^FmtInfo, v: any, verb: rune) {
for i in 0..<info.count { for i in 0..<info.count {
if i > 0 -> write_string(fi.buf, ", "); if i > 0 -> write_string(fi.buf, ", ");
var data = ^u8(v.data) + i*info.elem_size; data := ^u8(v.data) + i*info.elem_size;
fmt_arg(fi, any{rawptr(data), info.elem}, verb); fmt_arg(fi, any{rawptr(data), info.elem}, verb);
} }
case DynamicArray: case DynamicArray:
write_byte(fi.buf, '['); write_byte(fi.buf, '[');
defer write_byte(fi.buf, ']'); defer write_byte(fi.buf, ']');
var array = ^raw.DynamicArray(v.data); array := ^raw.DynamicArray(v.data);
for i in 0..<array.len { for i in 0..<array.len {
if i > 0 -> write_string(fi.buf, ", "); if i > 0 -> write_string(fi.buf, ", ");
var data = ^u8(array.data) + i*info.elem_size; data := ^u8(array.data) + i*info.elem_size;
fmt_arg(fi, any{rawptr(data), info.elem}, verb); fmt_arg(fi, any{rawptr(data), info.elem}, verb);
} }
case Slice: case Slice:
write_byte(fi.buf, '['); write_byte(fi.buf, '[');
defer write_byte(fi.buf, ']'); defer write_byte(fi.buf, ']');
var slice = ^[]u8(v.data); slice := ^[]u8(v.data);
for _, i in slice { for _, i in slice {
if i > 0 -> write_string(fi.buf, ", "); if i > 0 -> write_string(fi.buf, ", ");
var data = &slice[0] + i*info.elem_size; data := &slice[0] + i*info.elem_size;
fmt_arg(fi, any{rawptr(data), info.elem}, verb); fmt_arg(fi, any{rawptr(data), info.elem}, verb);
} }
@@ -850,7 +846,7 @@ proc fmt_value(fi: ^FmtInfo, v: any, verb: rune) {
for i in 0..<info.count { for i in 0..<info.count {
if i > 0 -> write_string(fi.buf, ", "); if i > 0 -> write_string(fi.buf, ", ");
var data = ^u8(v.data) + i*info.elem_size; data := ^u8(v.data) + i*info.elem_size;
fmt_value(fi, any{rawptr(data), info.elem}, verb); fmt_value(fi, any{rawptr(data), info.elem}, verb);
} }
@@ -862,29 +858,29 @@ proc fmt_value(fi: ^FmtInfo, v: any, verb: rune) {
write_string(fi.buf, "map["); write_string(fi.buf, "map[");
defer write_byte(fi.buf, ']'); defer write_byte(fi.buf, ']');
var (
entries = &(^raw.DynamicMap(v.data).entries); entries := &(^raw.DynamicMap(v.data).entries);
gs = type_info_base(info.generated_struct).(^Struct); gs := type_info_base(info.generated_struct).(^Struct);
ed = type_info_base(gs.types[1]).(^DynamicArray); ed := type_info_base(gs.types[1]).(^DynamicArray);
entry_type = ed.elem.(^Struct); entry_type := ed.elem.(^Struct);
entry_size = ed.elem_size; entry_size := ed.elem_size;
)
for i in 0..<entries.len { for i in 0..<entries.len {
if i > 0 -> write_string(fi.buf, ", "); if i > 0 -> write_string(fi.buf, ", ");
var data = ^u8(entries.data) + i*entry_size; data := ^u8(entries.data) + i*entry_size;
var header = ^__MapEntryHeader(data); header := ^__MapEntryHeader(data);
if types.is_string(info.key) { if types.is_string(info.key) {
write_string(fi.buf, header.key.str); write_string(fi.buf, header.key.str);
} else { } else {
var fi = FmtInfo{buf = fi.buf}; fi := FmtInfo{buf = fi.buf};
fmt_arg(&fi, any{rawptr(&header.key.hash), info.key}, 'v'); fmt_arg(&fi, any{rawptr(&header.key.hash), info.key}, 'v');
} }
write_string(fi.buf, "="); write_string(fi.buf, "=");
var value = data + entry_type.offsets[2]; value := data + entry_type.offsets[2];
fmt_arg(fi, any{rawptr(value), info.value}, 'v'); fmt_arg(fi, any{rawptr(value), info.value}, 'v');
} }
@@ -899,7 +895,7 @@ proc fmt_value(fi: ^FmtInfo, v: any, verb: rune) {
write_string(fi.buf, info.names[i]); write_string(fi.buf, info.names[i]);
write_string(fi.buf, " = "); write_string(fi.buf, " = ");
var data = ^u8(v.data) + info.offsets[i]; data := ^u8(v.data) + info.offsets[i];
fmt_value(fi, any{rawptr(data), info.types[i]}, 'v'); fmt_value(fi, any{rawptr(data), info.types[i]}, 'v');
} }
@@ -907,13 +903,13 @@ proc fmt_value(fi: ^FmtInfo, v: any, verb: rune) {
write_byte(fi.buf, '{'); write_byte(fi.buf, '{');
defer write_byte(fi.buf, '}'); defer write_byte(fi.buf, '}');
var cf = info.common_fields; cf := info.common_fields;
for _, i in cf.names { for _, i in cf.names {
if i > 0 -> write_string(fi.buf, ", "); if i > 0 -> write_string(fi.buf, ", ");
write_string(fi.buf, cf.names[i]); write_string(fi.buf, cf.names[i]);
write_string(fi.buf, " = "); write_string(fi.buf, " = ");
var data = ^u8(v.data) + cf.offsets[i]; data := ^u8(v.data) + cf.offsets[i];
fmt_value(fi, any{rawptr(data), cf.types[i]}, 'v'); fmt_value(fi, any{rawptr(data), cf.types[i]}, 'v');
} }
@@ -933,7 +929,7 @@ proc fmt_value(fi: ^FmtInfo, v: any, verb: rune) {
proc fmt_complex(fi: ^FmtInfo, c: complex128, bits: int, verb: rune) { proc fmt_complex(fi: ^FmtInfo, c: complex128, bits: int, verb: rune) {
match verb { match verb {
case 'f', 'F', 'v': case 'f', 'F', 'v':
var r, i = real(c), imag(c); r, i := real(c), imag(c);
fmt_float(fi, r, bits/2, verb); fmt_float(fi, r, bits/2, verb);
if !fi.plus && i >= 0 { if !fi.plus && i >= 0 {
write_rune(fi.buf, '+'); write_rune(fi.buf, '+');
@@ -963,7 +959,7 @@ proc fmt_arg(fi: ^FmtInfo, arg: any, verb: rune) {
fi.arg = arg; fi.arg = arg;
if verb == 'T' { if verb == 'T' {
var ti = arg.type_info; ti := arg.type_info;
match a in arg { match a in arg {
case ^TypeInfo: ti = a; case ^TypeInfo: ti = a;
} }
@@ -972,7 +968,7 @@ proc fmt_arg(fi: ^FmtInfo, arg: any, verb: rune) {
} }
var base_arg = arg; base_arg := arg;
base_arg.type_info = type_info_base(base_arg.type_info); base_arg.type_info = type_info_base(base_arg.type_info);
match a in base_arg { match a in base_arg {
case any: fmt_arg(fi, a, verb); case any: fmt_arg(fi, a, verb);
@@ -1011,13 +1007,13 @@ proc fmt_arg(fi: ^FmtInfo, arg: any, verb: rune) {
proc sbprint(buf: ^StringBuffer, args: ..any) -> string { proc sbprint(buf: ^StringBuffer, args: ..any) -> string {
var fi: FmtInfo; fi: FmtInfo;
var prev_string = false; prev_string := false;
fi.buf = buf; fi.buf = buf;
for arg, i in args { for arg, i in args {
var is_string = arg != nil && types.is_string(arg.type_info); is_string := arg != nil && types.is_string(arg.type_info);
if i > 0 && !is_string && !prev_string { if i > 0 && !is_string && !prev_string {
write_byte(buf, ' '); write_byte(buf, ' ');
} }
@@ -1028,7 +1024,7 @@ proc sbprint(buf: ^StringBuffer, args: ..any) -> string {
} }
proc sbprintln(buf: ^StringBuffer, args: ..any) -> string { proc sbprintln(buf: ^StringBuffer, args: ..any) -> string {
var fi: FmtInfo; fi: FmtInfo;
fi.buf = buf; fi.buf = buf;
for arg, i in args { for arg, i in args {
@@ -1041,17 +1037,16 @@ proc sbprintln(buf: ^StringBuffer, args: ..any) -> string {
} }
proc sbprintf(b: ^StringBuffer, fmt: string, args: ..any) -> string { proc sbprintf(b: ^StringBuffer, fmt: string, args: ..any) -> string {
var (
end = len(fmt);
arg_index: int = 0;
was_prev_index = false;
fi: FmtInfo; fi: FmtInfo;
) arg_index: int = 0;
end := len(fmt);
was_prev_index := false;
for var i = 0; i < end; /**/ {
for i := 0; i < end; /**/ {
fi = FmtInfo{buf = b, good_arg_index = true}; fi = FmtInfo{buf = b, good_arg_index = true};
var prev_i = i; prev_i := i;
for i < end && fmt[i] != '%' { for i < end && fmt[i] != '%' {
i++; i++;
} }
@@ -1142,7 +1137,7 @@ proc sbprintf(b: ^StringBuffer, fmt: string, args: ..any) -> string {
break; break;
} }
var verb, w = utf8.decode_rune(fmt[i..]); verb, w := utf8.decode_rune(fmt[i..]);
i += w; i += w;
if verb == '%' { if verb == '%' {
+32 -42
View File
@@ -1,12 +1,12 @@
proc crc32(data: []u8) -> u32 { proc crc32(data: []u8) -> u32 {
var result = ~u32(0); result := ~u32(0);
for b in data { for b in data {
result = result>>8 ~ _crc32_table[(result ~ u32(b)) & 0xff]; result = result>>8 ~ _crc32_table[(result ~ u32(b)) & 0xff];
} }
return ~result; return ~result;
} }
proc crc64(data: []u8) -> u64 { proc crc64(data: []u8) -> u64 {
var result = ~u64(0); result := ~u64(0);
for b in data { for b in data {
result = result>>8 ~ _crc64_table[(result ~ u64(b)) & 0xff]; result = result>>8 ~ _crc64_table[(result ~ u64(b)) & 0xff];
} }
@@ -14,7 +14,7 @@ proc crc64(data: []u8) -> u64 {
} }
proc fnv32(data: []u8) -> u32 { proc fnv32(data: []u8) -> u32 {
var h: u32 = 0x811c9dc5; h: u32 = 0x811c9dc5;
for b in data { for b in data {
h = (h * 0x01000193) ~ u32(b); h = (h * 0x01000193) ~ u32(b);
} }
@@ -22,7 +22,7 @@ proc fnv32(data: []u8) -> u32 {
} }
proc fnv64(data: []u8) -> u64 { proc fnv64(data: []u8) -> u64 {
var h: u64 = 0xcbf29ce484222325; h: u64 = 0xcbf29ce484222325;
for b in data { for b in data {
h = (h * 0x100000001b3) ~ u64(b); h = (h * 0x100000001b3) ~ u64(b);
} }
@@ -30,7 +30,7 @@ proc fnv64(data: []u8) -> u64 {
} }
proc fnv32a(data: []u8) -> u32 { proc fnv32a(data: []u8) -> u32 {
var h: u32 = 0x811c9dc5; h: u32 = 0x811c9dc5;
for b in data { for b in data {
h = (h ~ u32(b)) * 0x01000193; h = (h ~ u32(b)) * 0x01000193;
} }
@@ -38,7 +38,7 @@ proc fnv32a(data: []u8) -> u32 {
} }
proc fnv64a(data: []u8) -> u64 { proc fnv64a(data: []u8) -> u64 {
var h: u64 = 0xcbf29ce484222325; h: u64 = 0xcbf29ce484222325;
for b in data { for b in data {
h = (h ~ u64(b)) * 0x100000001b3; h = (h ~ u64(b)) * 0x100000001b3;
} }
@@ -46,20 +46,16 @@ proc fnv64a(data: []u8) -> u64 {
} }
proc murmur32(data: []u8) -> u32 { proc murmur32(data: []u8) -> u32 {
const ( c1_32: u32 : 0xcc9e2d51;
c1_32: u32 = 0xcc9e2d51; c2_32: u32 : 0x1b873593;
c2_32: u32 = 0x1b873593;
)
var (
h1: u32 = 0; h1: u32 = 0;
nblocks = len(data)/4; nblocks := len(data)/4;
p = &data[0]; p := &data[0];
p1 = p + 4*nblocks; p1 := p + 4*nblocks;
)
for ; p < p1; p += 4 { for ; p < p1; p += 4 {
var k1 = ^u32(p)^; k1 := ^u32(p)^;
k1 *= c1_32; k1 *= c1_32;
k1 = (k1 << 15) | (k1 >> 17); k1 = (k1 << 15) | (k1 >> 17);
@@ -70,8 +66,8 @@ proc murmur32(data: []u8) -> u32 {
h1 = h1*5 + 0xe6546b64; h1 = h1*5 + 0xe6546b64;
} }
var tail = data[nblocks*4 ..]; tail := data[nblocks*4 ..];
var k1: u32; k1: u32;
match len(tail)&3 { match len(tail)&3 {
case 3: case 3:
k1 ~= u32(tail[2]) << 16; k1 ~= u32(tail[2]) << 16;
@@ -99,19 +95,17 @@ proc murmur32(data: []u8) -> u32 {
} }
proc murmur64(data: []u8) -> u64 { proc murmur64(data: []u8) -> u64 {
const SEED = 0x9747b28c; SEED :: 0x9747b28c;
when size_of(int) == 8 { when size_of(int) == 8 {
const ( m :: 0xc6a4a7935bd1e995;
m = 0xc6a4a7935bd1e995; r :: 47;
r = 47;
)
var h: u64 = SEED ~ (u64(len(data)) * m); h: u64 = SEED ~ (u64(len(data)) * m);
var data64 = slice_ptr(^u64(&data[0]), len(data)/size_of(u64)); data64 := slice_ptr(^u64(&data[0]), len(data)/size_of(u64));
for _, i in data64 { for _, i in data64 {
var k = data64[i]; k := data64[i];
k *= m; k *= m;
k ~= k>>r; k ~= k>>r;
@@ -139,21 +133,17 @@ proc murmur64(data: []u8) -> u64 {
return h; return h;
} else { } else {
const ( m :: 0x5bd1e995;
m = 0x5bd1e995; r :: 24;
r = 24;
)
var ( h1 := u32(SEED) ~ u32(len(data));
h1 = u32(SEED) ~ u32(len(data)); h2 := u32(SEED) >> 32;
h2 = u32(SEED) >> 32; data32 := slice_ptr(^u32(&data[0]), len(data)/size_of(u32));
data32 = slice_ptr(^u32(&data[0]), len(data)/size_of(u32)); len := len(data);
len = len(data); i := 0;
i = 0;
)
for len >= 8 { for len >= 8 {
var k1, k2: u32; k1, k2: u32;
k1 = data32[i]; i++; k1 = data32[i]; i++;
k1 *= m; k1 *= m;
k1 ~= k1>>r; k1 ~= k1>>r;
@@ -172,7 +162,7 @@ proc murmur64(data: []u8) -> u64 {
} }
if len >= 4 { if len >= 4 {
var k1: u32; k1: u32;
k1 = data32[i]; i++; k1 = data32[i]; i++;
k1 *= m; k1 *= m;
k1 ~= k1>>r; k1 ~= k1>>r;
@@ -183,7 +173,7 @@ proc murmur64(data: []u8) -> u64 {
} }
// TODO(bill): Fix this // TODO(bill): Fix this
#no_bounds_check var data8 = slice_to_bytes(data32[i..])[0..<3]; #no_bounds_check data8 := slice_to_bytes(data32[i..])[0..<3];
match len { match len {
case 3: case 3:
h2 ~= u32(data8[2]) << 16; h2 ~= u32(data8[2]) << 16;
@@ -210,7 +200,7 @@ proc murmur64(data: []u8) -> u64 {
} }
var _crc32_table = [256]u32{ _crc32_table := [256]u32{
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
@@ -276,7 +266,7 @@ var _crc32_table = [256]u32{
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
}; };
var _crc64_table = [256]u64{ _crc64_table := [256]u64{
0x0000000000000000, 0x42f0e1eba9ea3693, 0x85e1c3d753d46d26, 0xc711223cfa3e5bb5, 0x0000000000000000, 0x42f0e1eba9ea3693, 0x85e1c3d753d46d26, 0xc711223cfa3e5bb5,
0x493366450e42ecdf, 0x0bc387aea7a8da4c, 0xccd2a5925d9681f9, 0x8e224479f47cb76a, 0x493366450e42ecdf, 0x0bc387aea7a8da4c, 0xccd2a5925d9681f9, 0x8e224479f47cb76a,
0x9266cc8a1c85d9be, 0xd0962d61b56fef2d, 0x17870f5d4f51b498, 0x5577eeb6e6bb820b, 0x9266cc8a1c85d9be, 0xd0962d61b56fef2d, 0x17870f5d4f51b498, 0x5577eeb6e6bb820b,
+87 -96
View File
@@ -1,22 +1,21 @@
const ( TAU :: 6.28318530717958647692528676655900576;
TAU = 6.28318530717958647692528676655900576; PI :: 3.14159265358979323846264338327950288;
PI = 3.14159265358979323846264338327950288; ONE_OVER_TAU :: 0.636619772367581343075535053490057448;
ONE_OVER_TAU = 0.636619772367581343075535053490057448; ONE_OVER_PI :: 0.159154943091895335768883763372514362;
ONE_OVER_PI = 0.159154943091895335768883763372514362;
E = 2.71828182845904523536; E :: 2.71828182845904523536;
SQRT_TWO = 1.41421356237309504880168872420969808; SQRT_TWO :: 1.41421356237309504880168872420969808;
SQRT_THREE = 1.73205080756887729352744634150587236; SQRT_THREE :: 1.73205080756887729352744634150587236;
SQRT_FIVE = 2.23606797749978969640917366873127623; SQRT_FIVE :: 2.23606797749978969640917366873127623;
LOG_TWO = 0.693147180559945309417232121458176568; LOG_TWO :: 0.693147180559945309417232121458176568;
LOG_TEN = 2.30258509299404568401799145468436421; LOG_TEN :: 2.30258509299404568401799145468436421;
EPSILON = 1.19209290e-7; EPSILON :: 1.19209290e-7;
τ :: TAU;
π :: PI;
τ = TAU;
π = PI;
)
type ( type (
Vec2 [vector 2]f32; Vec2 [vector 2]f32;
Vec3 [vector 3]f32; Vec3 [vector 3]f32;
@@ -63,16 +62,16 @@ proc sign(x: f64) -> f64 { return x >= 0 ? +1 : -1; }
proc copy_sign(x, y: f32) -> f32 { proc copy_sign(x, y: f32) -> f32 {
var ix = transmute(u32, x); ix := transmute(u32, x);
var iy = transmute(u32, y); iy := transmute(u32, y);
ix &= 0x7fff_ffff; ix &= 0x7fff_ffff;
ix |= iy & 0x8000_0000; ix |= iy & 0x8000_0000;
return transmute(f32, ix); return transmute(f32, ix);
} }
proc copy_sign(x, y: f64) -> f64 { proc copy_sign(x, y: f64) -> f64 {
var ix = transmute(u64, x); ix := transmute(u64, x);
var iy = transmute(u64, y); iy := transmute(u64, y);
ix &= 0x7fff_ffff_ffff_ff; ix &= 0x7fff_ffff_ffff_ff;
ix |= iy & 0x8000_0000_0000_0000; ix |= iy & 0x8000_0000_0000_0000;
return transmute(f64, ix); return transmute(f64, ix);
@@ -91,7 +90,7 @@ proc remainder(x, y: f32) -> f32 { return x - round(x/y) * y; }
proc remainder(x, y: f64) -> f64 { return x - round(x/y) * y; } proc remainder(x, y: f64) -> f64 { return x - round(x/y) * y; }
proc mod(x, y: f32) -> f32 { proc mod(x, y: f32) -> f32 {
var result: f32; result: f32;
y = abs(y); y = abs(y);
result = remainder(abs(x), y); result = remainder(abs(x), y);
if sign(result) < 0 { if sign(result) < 0 {
@@ -100,7 +99,7 @@ proc mod(x, y: f32) -> f32 {
return copy_sign(result, x); return copy_sign(result, x);
} }
proc mod(x, y: f64) -> f64 { proc mod(x, y: f64) -> f64 {
var result: f64; result: f64;
y = abs(y); y = abs(y);
result = remainder(abs(x), y); result = remainder(abs(x), y);
if sign(result) < 0 { if sign(result) < 0 {
@@ -115,13 +114,13 @@ proc to_degrees(radians: f32) -> f32 { return radians * 360 / TAU; }
proc dot(a, b: Vec2) -> f32 { var c = a*b; return c.x + c.y; } proc dot(a, b: Vec2) -> f32 { c := a*b; return c.x + c.y; }
proc dot(a, b: Vec3) -> f32 { var c = a*b; return c.x + c.y + c.z; } proc dot(a, b: Vec3) -> f32 { c := a*b; return c.x + c.y + c.z; }
proc dot(a, b: Vec4) -> f32 { var c = a*b; return c.x + c.y + c.z + c.w; } proc dot(a, b: Vec4) -> f32 { c := a*b; return c.x + c.y + c.z + c.w; }
proc cross(x, y: Vec3) -> Vec3 { proc cross(x, y: Vec3) -> Vec3 {
var a = swizzle(x, 1, 2, 0) * swizzle(y, 2, 0, 1); a := swizzle(x, 1, 2, 0) * swizzle(y, 2, 0, 1);
var 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;
} }
@@ -135,7 +134,7 @@ proc norm(v: Vec3) -> Vec3 { return v / mag(v); }
proc norm(v: Vec4) -> Vec4 { return v / mag(v); } proc norm(v: Vec4) -> Vec4 { return v / mag(v); }
proc norm0(v: Vec2) -> Vec2 { proc norm0(v: Vec2) -> Vec2 {
var m = mag(v); m := mag(v);
if m == 0 { if m == 0 {
return 0; return 0;
} }
@@ -143,7 +142,7 @@ proc norm0(v: Vec2) -> Vec2 {
} }
proc norm0(v: Vec3) -> Vec3 { proc norm0(v: Vec3) -> Vec3 {
var m = mag(v); m := mag(v);
if m == 0 { if m == 0 {
return 0; return 0;
} }
@@ -151,7 +150,7 @@ proc norm0(v: Vec3) -> Vec3 {
} }
proc norm0(v: Vec4) -> Vec4 { proc norm0(v: Vec4) -> Vec4 {
var m = mag(v); m := mag(v);
if m == 0 { if m == 0 {
return 0; return 0;
} }
@@ -179,7 +178,7 @@ proc mat4_transpose(m: Mat4) -> Mat4 {
} }
proc mul(a, b: Mat4) -> Mat4 { proc mul(a, b: Mat4) -> Mat4 {
var c: Mat4; c: Mat4;
for j in 0..<4 { for j in 0..<4 {
for i in 0..<4 { for i in 0..<4 {
c[j][i] = a[0][i]*b[j][0] + c[j][i] = a[0][i]*b[j][0] +
@@ -201,29 +200,28 @@ proc mul(m: Mat4, v: Vec4) -> Vec4 {
} }
proc inverse(m: Mat4) -> Mat4 { proc inverse(m: Mat4) -> Mat4 {
var o: Mat4; o: Mat4;
sf00 := m[2][2] * m[3][3] - m[3][2] * m[2][3];
sf01 := m[2][1] * m[3][3] - m[3][1] * m[2][3];
sf02 := m[2][1] * m[3][2] - m[3][1] * m[2][2];
sf03 := m[2][0] * m[3][3] - m[3][0] * m[2][3];
sf04 := m[2][0] * m[3][2] - m[3][0] * m[2][2];
sf05 := m[2][0] * m[3][1] - m[3][0] * m[2][1];
sf06 := m[1][2] * m[3][3] - m[3][2] * m[1][3];
sf07 := m[1][1] * m[3][3] - m[3][1] * m[1][3];
sf08 := m[1][1] * m[3][2] - m[3][1] * m[1][2];
sf09 := m[1][0] * m[3][3] - m[3][0] * m[1][3];
sf10 := m[1][0] * m[3][2] - m[3][0] * m[1][2];
sf11 := m[1][1] * m[3][3] - m[3][1] * m[1][3];
sf12 := m[1][0] * m[3][1] - m[3][0] * m[1][1];
sf13 := m[1][2] * m[2][3] - m[2][2] * m[1][3];
sf14 := m[1][1] * m[2][3] - m[2][1] * m[1][3];
sf15 := m[1][1] * m[2][2] - m[2][1] * m[1][2];
sf16 := m[1][0] * m[2][3] - m[2][0] * m[1][3];
sf17 := m[1][0] * m[2][2] - m[2][0] * m[1][2];
sf18 := m[1][0] * m[2][1] - m[2][0] * m[1][1];
var (
sf00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
sf01 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
sf02 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
sf03 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
sf04 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
sf05 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
sf06 = m[1][2] * m[3][3] - m[3][2] * m[1][3];
sf07 = m[1][1] * m[3][3] - m[3][1] * m[1][3];
sf08 = m[1][1] * m[3][2] - m[3][1] * m[1][2];
sf09 = m[1][0] * m[3][3] - m[3][0] * m[1][3];
sf10 = m[1][0] * m[3][2] - m[3][0] * m[1][2];
sf11 = m[1][1] * m[3][3] - m[3][1] * m[1][3];
sf12 = m[1][0] * m[3][1] - m[3][0] * m[1][1];
sf13 = m[1][2] * m[2][3] - m[2][2] * m[1][3];
sf14 = m[1][1] * m[2][3] - m[2][1] * m[1][3];
sf15 = m[1][1] * m[2][2] - m[2][1] * m[1][2];
sf16 = m[1][0] * m[2][3] - m[2][0] * m[1][3];
sf17 = m[1][0] * m[2][2] - m[2][0] * m[1][2];
sf18 = m[1][0] * m[2][1] - m[2][0] * m[1][1];
)
o[0][0] = +(m[1][1] * sf00 - m[1][2] * sf01 + m[1][3] * sf02); o[0][0] = +(m[1][1] * sf00 - m[1][2] * sf01 + m[1][3] * sf02);
o[0][1] = -(m[1][0] * sf00 - m[1][2] * sf03 + m[1][3] * sf04); o[0][1] = -(m[1][0] * sf00 - m[1][2] * sf03 + m[1][3] * sf04);
@@ -245,7 +243,7 @@ proc inverse(m: Mat4) -> Mat4 {
o[3][2] = -(m[0][0] * sf14 - m[0][1] * sf16 + m[0][3] * sf18); o[3][2] = -(m[0][0] * sf14 - m[0][1] * sf16 + m[0][3] * sf18);
o[3][3] = +(m[0][0] * sf15 - m[0][1] * sf17 + m[0][2] * sf18); o[3][3] = +(m[0][0] * sf15 - m[0][1] * sf17 + m[0][2] * sf18);
var ood = 1.0 / (m[0][0] * o[0][0] + ood := 1.0 / (m[0][0] * o[0][0] +
m[0][1] * o[0][1] + m[0][1] * o[0][1] +
m[0][2] * o[0][2] + m[0][2] * o[0][2] +
m[0][3] * o[0][3]); m[0][3] * o[0][3]);
@@ -272,7 +270,7 @@ proc inverse(m: Mat4) -> Mat4 {
proc mat4_translate(v: Vec3) -> Mat4 { proc mat4_translate(v: Vec3) -> Mat4 {
var 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;
m[3][2] = v.z; m[3][2] = v.z;
@@ -281,15 +279,13 @@ proc mat4_translate(v: Vec3) -> Mat4 {
} }
proc mat4_rotate(v: Vec3, angle_radians: f32) -> Mat4 { proc mat4_rotate(v: Vec3, angle_radians: f32) -> Mat4 {
var ( c := cos(angle_radians);
c = cos(angle_radians); s := sin(angle_radians);
s = sin(angle_radians);
a = norm(v); a := norm(v);
t = a * (1-c); t := a * (1-c);
rot = mat4_identity(); rot := mat4_identity();
)
rot[0][0] = c + t.x*a.x; rot[0][0] = c + t.x*a.x;
rot[0][1] = 0 + t.x*a.y + s*a.z; rot[0][1] = 0 + t.x*a.y + s*a.z;
@@ -325,11 +321,9 @@ proc scale(m: Mat4, s: f32) -> Mat4 {
proc look_at(eye, centre, up: Vec3) -> Mat4 { proc look_at(eye, centre, up: Vec3) -> Mat4 {
var ( f := norm(centre - eye);
f = norm(centre - eye); s := norm(cross(f, up));
s = norm(cross(f, up)); u := cross(s, f);
u = cross(s, f);
)
return Mat4{ return Mat4{
{+s.x, +u.x, -f.x, 0}, {+s.x, +u.x, -f.x, 0},
@@ -340,10 +334,9 @@ proc look_at(eye, centre, up: Vec3) -> Mat4 {
} }
proc perspective(fovy, aspect, near, far: f32) -> Mat4 { proc perspective(fovy, aspect, near, far: f32) -> Mat4 {
var (
m: Mat4; m: Mat4;
tan_half_fovy = tan(0.5 * fovy); tan_half_fovy := tan(0.5 * fovy);
)
m[0][0] = 1.0 / (aspect*tan_half_fovy); m[0][0] = 1.0 / (aspect*tan_half_fovy);
m[1][1] = 1.0 / (tan_half_fovy); m[1][1] = 1.0 / (tan_half_fovy);
m[2][2] = -(far + near) / (far - near); m[2][2] = -(far + near) / (far - near);
@@ -354,7 +347,7 @@ proc perspective(fovy, aspect, near, far: f32) -> Mat4 {
proc ortho3d(left, right, bottom, top, near, far: f32) -> Mat4 { proc ortho3d(left, right, bottom, top, near, far: f32) -> Mat4 {
var 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);
m[2][2] = -2.0 / (far - near); m[2][2] = -2.0 / (far - near);
@@ -367,30 +360,28 @@ proc ortho3d(left, right, bottom, top, near, far: f32) -> Mat4 {
const ( F32_DIG :: 6;
F32_DIG = 6; F32_EPSILON :: 1.192092896e-07;
F32_EPSILON = 1.192092896e-07; F32_GUARD :: 0;
F32_GUARD = 0; F32_MANT_DIG :: 24;
F32_MANT_DIG = 24; F32_MAX :: 3.402823466e+38;
F32_MAX = 3.402823466e+38; F32_MAX_10_EXP :: 38;
F32_MAX_10_EXP = 38; F32_MAX_EXP :: 128;
F32_MAX_EXP = 128; F32_MIN :: 1.175494351e-38;
F32_MIN = 1.175494351e-38; F32_MIN_10_EXP :: -37;
F32_MIN_10_EXP = -37; F32_MIN_EXP :: -125;
F32_MIN_EXP = -125; F32_NORMALIZE :: 0;
F32_NORMALIZE = 0; F32_RADIX :: 2;
F32_RADIX = 2; F32_ROUNDS :: 1;
F32_ROUNDS = 1;
F64_DIG = 15; // # of decimal digits of precision F64_DIG :: 15; // # of decimal digits of precision
F64_EPSILON = 2.2204460492503131e-016; // smallest such that 1.0+F64_EPSILON != 1.0 F64_EPSILON :: 2.2204460492503131e-016; // smallest such that 1.0+F64_EPSILON != 1.0
F64_MANT_DIG = 53; // # of bits in mantissa F64_MANT_DIG :: 53; // # of bits in mantissa
F64_MAX = 1.7976931348623158e+308; // max value F64_MAX :: 1.7976931348623158e+308; // max value
F64_MAX_10_EXP = 308; // max decimal exponent F64_MAX_10_EXP :: 308; // max decimal exponent
F64_MAX_EXP = 1024; // max binary exponent F64_MAX_EXP :: 1024; // max binary exponent
F64_MIN = 2.2250738585072014e-308; // min positive value F64_MIN :: 2.2250738585072014e-308; // min positive value
F64_MIN_10_EXP = -307; // min decimal exponent F64_MIN_10_EXP :: -307; // min decimal exponent
F64_MIN_EXP = -1021; // min binary exponent F64_MIN_EXP :: -1021; // min binary exponent
F64_RADIX = 2; // exponent radix F64_RADIX :: 2; // exponent radix
F64_ROUNDS = 1; // addition rounding: near F64_ROUNDS :: 1; // addition rounding: near
)
+26 -26
View File
@@ -41,9 +41,9 @@ proc is_power_of_two(x: int) -> bool {
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));
var a = uint(align); a := uint(align);
var p = uint(ptr); p := uint(ptr);
var modulo = p & (a-1); modulo := p & (a-1);
if modulo != 0 { if modulo != 0 {
p += a - modulo; p += a - modulo;
} }
@@ -58,9 +58,9 @@ type AllocationHeader struct {
proc allocation_header_fill(header: ^AllocationHeader, data: rawptr, size: int) { proc allocation_header_fill(header: ^AllocationHeader, data: rawptr, size: int) {
header.size = size; header.size = size;
var ptr = ^int(header+1); ptr := ^int(header+1);
for var i = 0; rawptr(ptr) < data; i++ { for i := 0; rawptr(ptr) < data; i++ {
(ptr+i)^ = -1; (ptr+i)^ = -1;
} }
} }
@@ -68,7 +68,7 @@ proc allocation_header(data: rawptr) -> ^AllocationHeader {
if data == nil { if data == nil {
return nil; return nil;
} }
var p = ^int(data); p := ^int(data);
for (p-1)^ == -1 { for (p-1)^ == -1 {
p = (p-1); p = (p-1);
} }
@@ -130,20 +130,20 @@ proc arena_allocator_proc(allocator_data: rawptr, mode: AllocatorMode,
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 AllocatorMode; using AllocatorMode;
var arena = ^Arena(allocator_data); arena := ^Arena(allocator_data);
match mode { match mode {
case Alloc: case Alloc:
var total_size = size + alignment; total_size := size + alignment;
if arena.offset + total_size > len(arena.memory) { if arena.offset + total_size > len(arena.memory) {
fmt.fprintln(os.stderr, "Arena out of memory"); fmt.fprintln(os.stderr, "Arena out of memory");
return nil; return nil;
} }
#no_bounds_check var end = &arena.memory[arena.offset]; #no_bounds_check end := &arena.memory[arena.offset];
var ptr = align_forward(end, alignment); ptr := align_forward(end, alignment);
arena.offset += total_size; arena.offset += total_size;
return zero(ptr, size); return zero(ptr, size);
@@ -162,7 +162,7 @@ proc arena_allocator_proc(allocator_data: rawptr, mode: AllocatorMode,
} }
proc begin_arena_temp_memory(a: ^Arena) -> ArenaTempMemory { proc begin_arena_temp_memory(a: ^Arena) -> ArenaTempMemory {
var tmp: ArenaTempMemory; tmp: ArenaTempMemory;
tmp.arena = a; tmp.arena = a;
tmp.original_count = len(a.memory); tmp.original_count = len(a.memory);
a.temp_count++; a.temp_count++;
@@ -196,8 +196,8 @@ proc align_of_type_info(type_info: ^TypeInfo) -> int {
return n - (n >> 1); return n - (n >> 1);
} }
const WORD_SIZE = size_of(int); WORD_SIZE :: size_of(int);
const MAX_ALIGN = size_of([vector 64]f64); // TODO(bill): Should these constants be builtin constants? MAX_ALIGN :: size_of([vector 64]f64); // TODO(bill): Should these constants be builtin constants?
using TypeInfo; using TypeInfo;
match info in type_info { match info in type_info {
case Named: case Named:
@@ -223,9 +223,9 @@ proc align_of_type_info(type_info: ^TypeInfo) -> int {
case Slice: case Slice:
return WORD_SIZE; return WORD_SIZE;
case Vector: case Vector:
var size = size_of_type_info(info.elem); size := size_of_type_info(info.elem);
var count = int(max(prev_pow2(i64(info.count)), 1)); count := int(max(prev_pow2(i64(info.count)), 1));
var total = size * count; total := size * count;
return clamp(total, 1, MAX_ALIGN); return clamp(total, 1, MAX_ALIGN);
case Tuple: case Tuple:
return info.align; return info.align;
@@ -245,12 +245,12 @@ proc align_of_type_info(type_info: ^TypeInfo) -> int {
} }
proc align_formula(size, align: int) -> int { proc align_formula(size, align: int) -> int {
var result = size + align-1; result := size + align-1;
return result - result%align; return result - result%align;
} }
proc size_of_type_info(type_info: ^TypeInfo) -> int { proc size_of_type_info(type_info: ^TypeInfo) -> int {
const WORD_SIZE = size_of(int); WORD_SIZE :: size_of(int);
using TypeInfo; using TypeInfo;
match info in type_info { match info in type_info {
case Named: case Named:
@@ -270,26 +270,26 @@ proc size_of_type_info(type_info: ^TypeInfo) -> int {
case Procedure: case Procedure:
return WORD_SIZE; return WORD_SIZE;
case Array: case Array:
var count = info.count; count := info.count;
if count == 0 { if count == 0 {
return 0; return 0;
} }
var size = size_of_type_info(info.elem); size := size_of_type_info(info.elem);
var align = align_of_type_info(info.elem); align := align_of_type_info(info.elem);
var alignment = align_formula(size, align); alignment := align_formula(size, align);
return alignment*(count-1) + size; return alignment*(count-1) + size;
case DynamicArray: case DynamicArray:
return size_of(rawptr) + 2*size_of(int) + size_of(Allocator); return size_of(rawptr) + 2*size_of(int) + size_of(Allocator);
case Slice: case Slice:
return 2*WORD_SIZE; return 2*WORD_SIZE;
case Vector: case Vector:
var count = info.count; count := info.count;
if count == 0 { if count == 0 {
return 0; return 0;
} }
var size = size_of_type_info(info.elem); size := size_of_type_info(info.elem);
var align = align_of_type_info(info.elem); align := align_of_type_info(info.elem);
var alignment = align_formula(size, align); alignment := align_formula(size, align);
return alignment*(count-1) + size; return alignment*(count-1) + size;
case Struct: case Struct:
return info.size; return info.size;
+5 -5
View File
@@ -39,7 +39,7 @@ foreign lib {
proc _string_data(s: string) -> ^u8 #inline { return &s[0]; } proc _string_data(s: string) -> ^u8 #inline { return &s[0]; }
var _libgl = win32.load_library_a(_string_data("opengl32.dll\x00")); _libgl := win32.load_library_a(_string_data("opengl32.dll\x00"));
proc get_proc_address(name: string) -> rawptr { proc get_proc_address(name: string) -> rawptr {
if name[len(name)-1] == 0 { if name[len(name)-1] == 0 {
@@ -47,14 +47,14 @@ proc get_proc_address(name: string) -> rawptr {
} }
// NOTE(bill): null terminated // NOTE(bill): null terminated
assert((&name[0] + len(name))^ == 0); assert((&name[0] + len(name))^ == 0);
var res = wgl.get_proc_address(&name[0]); res := wgl.get_proc_address(&name[0]);
if res == nil { if res == nil {
res = win32.get_proc_address(_libgl, &name[0]); res = win32.get_proc_address(_libgl, &name[0]);
} }
return rawptr(res); return rawptr(res);
} }
var ( // Procedures
GenBuffers: proc(count: i32, buffers: ^u32) #cc_c; GenBuffers: proc(count: i32, buffers: ^u32) #cc_c;
GenVertexArrays: proc(count: i32, buffers: ^u32) #cc_c; GenVertexArrays: proc(count: i32, buffers: ^u32) #cc_c;
GenSamplers: proc(count: i32, buffers: ^u32) #cc_c; GenSamplers: proc(count: i32, buffers: ^u32) #cc_c;
@@ -114,11 +114,11 @@ var (
UniformMatrix4fv: proc(loc: i32, count: u32, transpose: i32, value: ^f32) #cc_c; UniformMatrix4fv: proc(loc: i32, count: u32, transpose: i32, value: ^f32) #cc_c;
GetUniformLocation: proc(program: u32, name: ^u8) -> i32 #cc_c; GetUniformLocation: proc(program: u32, name: ^u8) -> i32 #cc_c;
)
proc init() { proc init() {
proc set_proc_address(p: rawptr, name: string) #inline { proc set_proc_address(p: rawptr, name: string) #inline {
var x = ^rawptr(p); x := ^rawptr(p);
x^ = get_proc_address(name); x^ = get_proc_address(name);
} }
+1365 -1367
View File
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -9,13 +9,13 @@ proc write_string(fd: Handle, str: string) -> (int, Errno) {
} }
proc read_entire_file(name: string) -> ([]u8, bool) { proc read_entire_file(name: string) -> ([]u8, bool) {
var fd, err = open(name, O_RDONLY, 0); fd, err := open(name, O_RDONLY, 0);
if err != 0 { if err != 0 {
return nil, false; return nil, false;
} }
defer close(fd); defer close(fd);
var length: i64; length: i64;
if length, err = file_size(fd); err != 0 { if length, err = file_size(fd); err != 0 {
return nil, false; return nil, false;
} }
@@ -24,12 +24,12 @@ proc read_entire_file(name: string) -> ([]u8, bool) {
return nil, true; return nil, true;
} }
var data = make([]u8, length); data := make([]u8, length);
if data == nil { if data == nil {
return nil, false; return nil, false;
} }
var bytes_read, read_err = read(fd, data); bytes_read, read_err := read(fd, data);
if read_err != 0 { if read_err != 0 {
free(data); free(data);
return nil, false; return nil, false;
@@ -38,12 +38,12 @@ proc read_entire_file(name: string) -> ([]u8, bool) {
} }
proc write_entire_file(name: string, data: []u8) -> bool { proc write_entire_file(name: string, data: []u8) -> bool {
var fd, err = open(name, O_WRONLY, 0); fd, err := open(name, O_WRONLY, 0);
if err != 0 { if err != 0 {
return false; return false;
} }
defer close(fd); defer close(fd);
var bytes_written, write_err = write(fd, data); bytes_written, write_err := write(fd, data);
return write_err != 0; return write_err != 0;
} }
+73 -79
View File
@@ -10,40 +10,37 @@ type (
Errno i32; Errno i32;
) )
const (
O_RDONLY = 0x00000;
O_WRONLY = 0x00001;
O_RDWR = 0x00002;
O_CREAT = 0x00040;
O_EXCL = 0x00080;
O_NOCTTY = 0x00100;
O_TRUNC = 0x00200;
O_NONBLOCK = 0x00800;
O_APPEND = 0x00400;
O_SYNC = 0x01000;
O_ASYNC = 0x02000;
O_CLOEXEC = 0x80000;
)
const ( O_RDONLY :: 0x00000;
SEEK_SET = 0; O_WRONLY :: 0x00001;
SEEK_CUR = 1; O_RDWR :: 0x00002;
SEEK_END = 2; O_CREAT :: 0x00040;
SEEK_DATA = 3; O_EXCL :: 0x00080;
SEEK_HOLE = 4; O_NOCTTY :: 0x00100;
SEEK_MAX = SEEK_HOLE; O_TRUNC :: 0x00200;
) O_NONBLOCK :: 0x00800;
const ( O_APPEND :: 0x00400;
O_SYNC :: 0x01000;
O_ASYNC :: 0x02000;
O_CLOEXEC :: 0x80000;
SEEK_SET :: 0;
SEEK_CUR :: 1;
SEEK_END :: 2;
SEEK_DATA :: 3;
SEEK_HOLE :: 4;
SEEK_MAX :: SEEK_HOLE;
// NOTE(zangent): These are OS specific! // NOTE(zangent): These are OS specific!
// Do not mix these up! // Do not mix these up!
RTLD_LAZY = 0x001; RTLD_LAZY :: 0x001;
RTLD_NOW = 0x002; RTLD_NOW :: 0x002;
RTLD_BINDING_MASK = 0x3; RTLD_BINDING_MASK :: 0x3;
RTLD_GLOBAL = 0x100; RTLD_GLOBAL :: 0x100;
)
// "Argv" arguments converted to Odin strings // "Argv" arguments converted to Odin strings
var args = _alloc_command_line_arguments(); args := _alloc_command_line_arguments();
type _FileTime struct #ordered { type _FileTime struct #ordered {
seconds: i64, seconds: i64,
@@ -80,39 +77,38 @@ type Stat struct #ordered {
}; };
// File type // File type
const ( S_IFMT :: 0170000; // Type of file mask
S_IFMT = 0170000; // Type of file mask S_IFIFO :: 0010000; // Named pipe (fifo)
S_IFIFO = 0010000; // Named pipe (fifo) S_IFCHR :: 0020000; // Character special
S_IFCHR = 0020000; // Character special S_IFDIR :: 0040000; // Directory
S_IFDIR = 0040000; // Directory S_IFBLK :: 0060000; // Block special
S_IFBLK = 0060000; // Block special S_IFREG :: 0100000; // Regular
S_IFREG = 0100000; // Regular S_IFLNK :: 0120000; // Symbolic link
S_IFLNK = 0120000; // Symbolic link S_IFSOCK :: 0140000; // Socket
S_IFSOCK = 0140000; // Socket
// File mode // File mode
// Read, write, execute/search by owner // Read, write, execute/search by owner
S_IRWXU = 0000700; // RWX mask for owner S_IRWXU :: 0000700; // RWX mask for owner
S_IRUSR = 0000400; // R for owner S_IRUSR :: 0000400; // R for owner
S_IWUSR = 0000200; // W for owner S_IWUSR :: 0000200; // W for owner
S_IXUSR = 0000100; // X for owner S_IXUSR :: 0000100; // X for owner
// Read, write, execute/search by group // Read, write, execute/search by group
S_IRWXG = 0000070; // RWX mask for group S_IRWXG :: 0000070; // RWX mask for group
S_IRGRP = 0000040; // R for group S_IRGRP :: 0000040; // R for group
S_IWGRP = 0000020; // W for group S_IWGRP :: 0000020; // W for group
S_IXGRP = 0000010; // X for group S_IXGRP :: 0000010; // X for group
// Read, write, execute/search by others // Read, write, execute/search by others
S_IRWXO = 0000007; // RWX mask for other S_IRWXO :: 0000007; // RWX mask for other
S_IROTH = 0000004; // R for other S_IROTH :: 0000004; // R for other
S_IWOTH = 0000002; // W for other S_IWOTH :: 0000002; // W for other
S_IXOTH = 0000001; // X for other S_IXOTH :: 0000001; // X for other
S_ISUID :: 0004000; // Set user id on execution
S_ISGID :: 0002000; // Set group id on execution
S_ISVTX :: 0001000; // Directory restrcted delete
S_ISUID = 0004000; // Set user id on execution
S_ISGID = 0002000; // Set group id on execution
S_ISVTX = 0001000; // Directory restrcted delete
)
proc S_ISLNK (m: u32) -> bool #inline {return (m & S_IFMT) == S_IFLNK; } proc S_ISLNK (m: u32) -> bool #inline {return (m & S_IFMT) == S_IFLNK; }
proc S_ISREG (m: u32) -> bool #inline {return (m & S_IFMT) == S_IFREG; } proc S_ISREG (m: u32) -> bool #inline {return (m & S_IFMT) == S_IFREG; }
@@ -122,12 +118,10 @@ proc S_ISBLK (m: u32) -> bool #inline {return (m & S_IFMT) == S_IFBLK; }
proc S_ISFIFO(m: u32) -> bool #inline {return (m & S_IFMT) == S_IFIFO; } proc S_ISFIFO(m: u32) -> bool #inline {return (m & S_IFMT) == S_IFIFO; }
proc S_ISSOCK(m: u32) -> bool #inline {return (m & S_IFMT) == S_IFSOCK;} proc S_ISSOCK(m: u32) -> bool #inline {return (m & S_IFMT) == S_IFSOCK;}
const ( F_OK :: 0; // Test for file existance
R_OK = 4; // Test for read permission X_OK :: 1; // Test for execute permission
W_OK = 2; // Test for write permission W_OK :: 2; // Test for write permission
X_OK = 1; // Test for execute permission R_OK :: 4; // Test for read permission
F_OK = 0; // Test for file existance
)
foreign libc { foreign libc {
proc _unix_open (path: ^u8, mode: int) -> Handle #link_name "open"; proc _unix_open (path: ^u8, mode: int) -> Handle #link_name "open";
@@ -156,8 +150,8 @@ foreign dl {
// TODO(zangent): Change this to just `open` when Bill fixes overloading. // TODO(zangent): Change this to just `open` when Bill fixes overloading.
proc open_simple(path: string, mode: int) -> (Handle, Errno) { proc open_simple(path: string, mode: int) -> (Handle, Errno) {
var cstr = strings.new_c_string(path); cstr := strings.new_c_string(path);
var handle = _unix_open(cstr, mode); handle := _unix_open(cstr, mode);
free(cstr); free(cstr);
if(handle == -1) { if(handle == -1) {
return 0, 1; return 0, 1;
@@ -174,49 +168,49 @@ proc close(fd: Handle) {
} }
proc read(fd: Handle, data: []u8) -> (int, Errno) { proc read(fd: Handle, data: []u8) -> (int, Errno) {
var sz = _unix_read(fd, &data[0], len(data)); sz := _unix_read(fd, &data[0], len(data));
return sz, 0; return sz, 0;
} }
proc write(fd: Handle, data: []u8) -> (int, Errno) { proc write(fd: Handle, data: []u8) -> (int, Errno) {
var sz = _unix_write(fd, &data[0], len(data)); sz := _unix_write(fd, &data[0], len(data));
return sz, 0; return sz, 0;
} }
proc seek(fd: Handle, offset: i64, whence: int) -> (i64, Errno) { proc seek(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {
var res = _unix_seek(fd, offset, i32(whence)); res := _unix_seek(fd, offset, i32(whence));
return res, 0; return res, 0;
} }
proc file_size(fd: Handle) -> (i64, Errno) { proc file_size(fd: Handle) -> (i64, Errno) {
var prev, _ = seek(fd, 0, SEEK_CUR); prev, _ := seek(fd, 0, SEEK_CUR);
var size, err = seek(fd, 0, SEEK_END); size, err := seek(fd, 0, SEEK_END);
seek(fd, prev, SEEK_SET); seek(fd, prev, SEEK_SET);
return size, err; return size, err;
} }
// NOTE(bill): Uses startup to initialize it // NOTE(bill): Uses startup to initialize it
var (
stdin: Handle = 0; stdin: Handle = 0;
stdout: Handle = 1; stdout: Handle = 1;
stderr: Handle = 2; stderr: Handle = 2;
)
/* TODO(zangent): Implement these! /* TODO(zangent): Implement these!
proc last_write_time(fd: Handle) -> FileTime {} proc last_write_time(fd: Handle) -> FileTime {}
proc last_write_time_by_name(name: string) -> FileTime {} proc last_write_time_by_name(name: string) -> FileTime {}
*/ */
proc stat(path: string) -> (Stat, int) #inline { proc stat(path: string) -> (Stat, int) #inline {
var s: Stat; s: Stat;
var cstr = strings.new_c_string(path); cstr := strings.new_c_string(path);
defer free(cstr); defer free(cstr);
var ret_int = _unix_stat(cstr, &s); ret_int := _unix_stat(cstr, &s);
return s, int(ret_int); return s, int(ret_int);
} }
proc access(path: string, mask: int) -> bool #inline { proc access(path: string, mask: int) -> bool #inline {
var cstr = strings.new_c_string(path); cstr := strings.new_c_string(path);
defer free(cstr); defer free(cstr);
return _unix_access(cstr, mask) == 0; return _unix_access(cstr, mask) == 0;
} }
@@ -235,8 +229,8 @@ proc heap_free(ptr: rawptr) {
} }
proc getenv(name: string) -> (string, bool) { proc getenv(name: string) -> (string, bool) {
var path_str = strings.new_c_string(name); path_str := strings.new_c_string(name);
var cstr: ^u8 = _unix_getenv(path_str); cstr: ^u8 = _unix_getenv(path_str);
free(path_str); free(path_str);
if(cstr == nil) { if(cstr == nil) {
return "", false; return "", false;
@@ -254,15 +248,15 @@ proc current_thread_id() -> int {
} }
proc dlopen(filename: string, flags: int) -> rawptr #inline { proc dlopen(filename: string, flags: int) -> rawptr #inline {
var cstr = strings.new_c_string(filename); cstr := strings.new_c_string(filename);
var handle = _unix_dlopen(cstr, flags); handle := _unix_dlopen(cstr, flags);
free(cstr); free(cstr);
return handle; return handle;
} }
proc dlsym(handle: rawptr, symbol: string) -> (proc() #cc_c) #inline { proc dlsym(handle: rawptr, symbol: string) -> (proc() #cc_c) #inline {
assert(handle != nil); assert(handle != nil);
var cstr = strings.new_c_string(symbol); cstr := strings.new_c_string(symbol);
var proc_handle = _unix_dlsym(handle, cstr); proc_handle := _unix_dlsym(handle, cstr);
free(cstr); free(cstr);
return proc_handle; return proc_handle;
} }
+94 -95
View File
@@ -5,56 +5,55 @@ type (
FileTime u64; FileTime u64;
) )
const INVALID_HANDLE: Handle = -1; INVALID_HANDLE: Handle : -1;
const (
O_RDONLY = 0x00000; O_RDONLY :: 0x00000;
O_WRONLY = 0x00001; O_WRONLY :: 0x00001;
O_RDWR = 0x00002; O_RDWR :: 0x00002;
O_CREAT = 0x00040; O_CREAT :: 0x00040;
O_EXCL = 0x00080; O_EXCL :: 0x00080;
O_NOCTTY = 0x00100; O_NOCTTY :: 0x00100;
O_TRUNC = 0x00200; O_TRUNC :: 0x00200;
O_NONBLOCK = 0x00800; O_NONBLOCK :: 0x00800;
O_APPEND = 0x00400; O_APPEND :: 0x00400;
O_SYNC = 0x01000; O_SYNC :: 0x01000;
O_ASYNC = 0x02000; O_ASYNC :: 0x02000;
O_CLOEXEC = 0x80000; O_CLOEXEC :: 0x80000;
)
type Errno int; type Errno int;
const (
ERROR_NONE: Errno = 0; ERROR_NONE: Errno : 0;
ERROR_FILE_NOT_FOUND = 2; ERROR_FILE_NOT_FOUND: Errno : 2;
ERROR_PATH_NOT_FOUND = 3; ERROR_PATH_NOT_FOUND: Errno : 3;
ERROR_ACCESS_DENIED = 5; ERROR_ACCESS_DENIED: Errno : 5;
ERROR_NO_MORE_FILES = 18; ERROR_NO_MORE_FILES: Errno : 18;
ERROR_HANDLE_EOF = 38; ERROR_HANDLE_EOF: Errno : 38;
ERROR_NETNAME_DELETED = 64; ERROR_NETNAME_DELETED: Errno : 64;
ERROR_FILE_EXISTS = 80; ERROR_FILE_EXISTS: Errno : 80;
ERROR_BROKEN_PIPE = 109; ERROR_BROKEN_PIPE: Errno : 109;
ERROR_BUFFER_OVERFLOW = 111; ERROR_BUFFER_OVERFLOW: Errno : 111;
ERROR_INSUFFICIENT_BUFFER = 122; ERROR_INSUFFICIENT_BUFFER: Errno : 122;
ERROR_MOD_NOT_FOUND = 126; ERROR_MOD_NOT_FOUND: Errno : 126;
ERROR_PROC_NOT_FOUND = 127; ERROR_PROC_NOT_FOUND: Errno : 127;
ERROR_DIR_NOT_EMPTY = 145; ERROR_DIR_NOT_EMPTY: Errno : 145;
ERROR_ALREADY_EXISTS = 183; ERROR_ALREADY_EXISTS: Errno : 183;
ERROR_ENVVAR_NOT_FOUND = 203; ERROR_ENVVAR_NOT_FOUND: Errno : 203;
ERROR_MORE_DATA = 234; ERROR_MORE_DATA: Errno : 234;
ERROR_OPERATION_ABORTED = 995; ERROR_OPERATION_ABORTED: Errno : 995;
ERROR_IO_PENDING = 997; ERROR_IO_PENDING: Errno : 997;
ERROR_NOT_FOUND = 1168; ERROR_NOT_FOUND: Errno : 1168;
ERROR_PRIVILEGE_NOT_HELD = 1314; ERROR_PRIVILEGE_NOT_HELD: Errno : 1314;
WSAEACCES = 10013; WSAEACCES: Errno : 10013;
WSAECONNRESET = 10054; WSAECONNRESET: Errno : 10054;
// Windows reserves errors >= 1<<29 for application use // Windows reserves errors >= 1<<29 for application use
ERROR_FILE_IS_PIPE = 1<<29 + 0; ERROR_FILE_IS_PIPE: Errno : 1<<29 + 0;
)
// "Argv" arguments converted to Odin strings // "Argv" arguments converted to Odin strings
var args = _alloc_command_line_arguments(); args := _alloc_command_line_arguments();
proc open(path: string, mode: int = O_RDONLY, perm: u32 = 0) -> (Handle, Errno) { proc open(path: string, mode: int = O_RDONLY, perm: u32 = 0) -> (Handle, Errno) {
@@ -62,7 +61,7 @@ proc open(path: string, mode: int = O_RDONLY, perm: u32 = 0) -> (Handle, Errno)
return INVALID_HANDLE, ERROR_FILE_NOT_FOUND; return INVALID_HANDLE, ERROR_FILE_NOT_FOUND;
} }
var access: u32; access: u32;
match mode & (O_RDONLY|O_WRONLY|O_RDWR) { match mode & (O_RDONLY|O_WRONLY|O_RDWR) {
case O_RDONLY: access = win32.FILE_GENERIC_READ; case O_RDONLY: access = win32.FILE_GENERIC_READ;
case O_WRONLY: access = win32.FILE_GENERIC_WRITE; case O_WRONLY: access = win32.FILE_GENERIC_WRITE;
@@ -77,14 +76,14 @@ proc open(path: string, mode: int = O_RDONLY, perm: u32 = 0) -> (Handle, Errno)
access |= win32.FILE_APPEND_DATA; access |= win32.FILE_APPEND_DATA;
} }
var share_mode = u32(win32.FILE_SHARE_READ|win32.FILE_SHARE_WRITE); share_mode := u32(win32.FILE_SHARE_READ|win32.FILE_SHARE_WRITE);
var sa: ^win32.Security_Attributes = nil; sa: ^win32.Security_Attributes = nil;
var sa_inherit = win32.Security_Attributes{length = size_of(win32.Security_Attributes), inherit_handle = 1}; sa_inherit := win32.Security_Attributes{length = size_of(win32.Security_Attributes), inherit_handle = 1};
if mode&O_CLOEXEC == 0 { if mode&O_CLOEXEC == 0 {
sa = &sa_inherit; sa = &sa_inherit;
} }
var create_mode: u32; create_mode: u32;
match { match {
case mode&(O_CREAT|O_EXCL) == (O_CREAT | O_EXCL): case mode&(O_CREAT|O_EXCL) == (O_CREAT | O_EXCL):
create_mode = win32.CREATE_NEW; create_mode = win32.CREATE_NEW;
@@ -98,14 +97,14 @@ proc open(path: string, mode: int = O_RDONLY, perm: u32 = 0) -> (Handle, Errno)
create_mode = win32.OPEN_EXISTING; create_mode = win32.OPEN_EXISTING;
} }
var buf: [300]u8; buf: [300]u8;
copy(buf[..], []u8(path)); copy(buf[..], []u8(path));
var handle = Handle(win32.create_file_a(&buf[0], access, share_mode, sa, create_mode, win32.FILE_ATTRIBUTE_NORMAL, nil)); handle := Handle(win32.create_file_a(&buf[0], access, share_mode, sa, create_mode, win32.FILE_ATTRIBUTE_NORMAL, nil));
if handle != INVALID_HANDLE { if handle != INVALID_HANDLE {
return handle, ERROR_NONE; return handle, ERROR_NONE;
} }
var err = win32.get_last_error(); err := win32.get_last_error();
return INVALID_HANDLE, Errno(err); return INVALID_HANDLE, Errno(err);
} }
@@ -118,22 +117,22 @@ proc write(fd: Handle, data: []u8) -> (int, Errno) {
if len(data) == 0 { if len(data) == 0 {
return 0, ERROR_NONE; return 0, ERROR_NONE;
} }
var single_write_length: i32; single_write_length: i32;
var total_write: i64; total_write: i64;
var length = i64(len(data)); length := i64(len(data));
for total_write < length { for total_write < length {
var remaining = length - total_write; remaining := length - total_write;
var to_read: i32; to_read: i32;
const MAX = 1<<31-1; MAX :: 1<<31-1;
if remaining <= MAX { if remaining <= MAX {
to_read = i32(remaining); to_read = i32(remaining);
} else { } else {
to_read = MAX; to_read = MAX;
} }
var e = win32.write_file(win32.Handle(fd), &data[total_write], to_read, &single_write_length, nil); e := win32.write_file(win32.Handle(fd), &data[total_write], to_read, &single_write_length, nil);
if single_write_length <= 0 || e == win32.FALSE { if single_write_length <= 0 || e == win32.FALSE {
var err = win32.get_last_error(); err := win32.get_last_error();
return int(total_write), Errno(e); return int(total_write), Errno(e);
} }
total_write += i64(single_write_length); total_write += i64(single_write_length);
@@ -146,23 +145,23 @@ proc read(fd: Handle, data: []u8) -> (int, Errno) {
return 0, ERROR_NONE; return 0, ERROR_NONE;
} }
var single_read_length: i32; single_read_length: i32;
var total_read: i64; total_read: i64;
var length = i64(len(data)); length := i64(len(data));
for total_read < length { for total_read < length {
var remaining = length - total_read; remaining := length - total_read;
var to_read: u32; to_read: u32;
const MAX = 1<<32-1; MAX :: 1<<32-1;
if remaining <= MAX { if remaining <= MAX {
to_read = u32(remaining); to_read = u32(remaining);
} else { } else {
to_read = MAX; to_read = MAX;
} }
var e = win32.read_file(win32.Handle(fd), &data[total_read], to_read, &single_read_length, nil); e := win32.read_file(win32.Handle(fd), &data[total_read], to_read, &single_read_length, nil);
if single_read_length <= 0 || e == win32.FALSE { if single_read_length <= 0 || e == win32.FALSE {
var err = win32.get_last_error(); err := win32.get_last_error();
return int(total_read), Errno(e); return int(total_read), Errno(e);
} }
total_read += i64(single_read_length); total_read += i64(single_read_length);
@@ -171,29 +170,29 @@ proc read(fd: Handle, data: []u8) -> (int, Errno) {
} }
proc seek(fd: Handle, offset: i64, whence: int) -> (i64, Errno) { proc seek(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {
var w: u32; w: u32;
match whence { match whence {
case 0: w = win32.FILE_BEGIN; case 0: w = win32.FILE_BEGIN;
case 1: w = win32.FILE_CURRENT; case 1: w = win32.FILE_CURRENT;
case 2: w = win32.FILE_END; case 2: w = win32.FILE_END;
} }
var hi = i32(offset>>32); hi := i32(offset>>32);
var lo = i32(offset); lo := i32(offset);
var ft = win32.get_file_type(win32.Handle(fd)); ft := win32.get_file_type(win32.Handle(fd));
if ft == win32.FILE_TYPE_PIPE { if ft == win32.FILE_TYPE_PIPE {
return 0, ERROR_FILE_IS_PIPE; return 0, ERROR_FILE_IS_PIPE;
} }
var dw_ptr = win32.set_file_pointer(win32.Handle(fd), lo, &hi, w); dw_ptr := win32.set_file_pointer(win32.Handle(fd), lo, &hi, w);
if dw_ptr == win32.INVALID_SET_FILE_POINTER { if dw_ptr == win32.INVALID_SET_FILE_POINTER {
var err = win32.get_last_error(); err := win32.get_last_error();
return 0, Errno(err); return 0, Errno(err);
} }
return i64(hi)<<32 + i64(dw_ptr), ERROR_NONE; return i64(hi)<<32 + i64(dw_ptr), ERROR_NONE;
} }
proc file_size(fd: Handle) -> (i64, Errno) { proc file_size(fd: Handle) -> (i64, Errno) {
var length: i64; length: i64;
var err: Errno; err: Errno;
if win32.get_file_size_ex(win32.Handle(fd), &length) == 0 { if win32.get_file_size_ex(win32.Handle(fd), &length) == 0 {
err = Errno(win32.get_last_error()); err = Errno(win32.get_last_error());
} }
@@ -203,13 +202,13 @@ proc file_size(fd: Handle) -> (i64, Errno) {
// NOTE(bill): Uses startup to initialize it // NOTE(bill): Uses startup to initialize it
var stdin = get_std_handle(win32.STD_INPUT_HANDLE); stdin := get_std_handle(win32.STD_INPUT_HANDLE);
var stdout = get_std_handle(win32.STD_OUTPUT_HANDLE); stdout := get_std_handle(win32.STD_OUTPUT_HANDLE);
var stderr = get_std_handle(win32.STD_ERROR_HANDLE); stderr := get_std_handle(win32.STD_ERROR_HANDLE);
proc get_std_handle(h: int) -> Handle { proc get_std_handle(h: int) -> Handle {
var fd = win32.get_std_handle(i32(h)); fd := win32.get_std_handle(i32(h));
win32.set_handle_information(fd, win32.HANDLE_FLAG_INHERIT, 0); win32.set_handle_information(fd, win32.HANDLE_FLAG_INHERIT, 0);
return Handle(fd); return Handle(fd);
} }
@@ -220,17 +219,17 @@ proc get_std_handle(h: int) -> Handle {
proc last_write_time(fd: Handle) -> FileTime { proc last_write_time(fd: Handle) -> FileTime {
var file_info: win32.ByHandleFileInformation; file_info: win32.ByHandleFileInformation;
win32.get_file_information_by_handle(win32.Handle(fd), &file_info); win32.get_file_information_by_handle(win32.Handle(fd), &file_info);
var lo = FileTime(file_info.last_write_time.lo); lo := FileTime(file_info.last_write_time.lo);
var hi = FileTime(file_info.last_write_time.hi); hi := FileTime(file_info.last_write_time.hi);
return lo | hi << 32; return lo | hi << 32;
} }
proc last_write_time_by_name(name: string) -> FileTime { proc last_write_time_by_name(name: string) -> FileTime {
var last_write_time: win32.Filetime; last_write_time: win32.Filetime;
var data: win32.FileAttributeData; data: win32.FileAttributeData;
var buf: [1024]u8; buf: [1024]u8;
assert(len(buf) > len(name)); assert(len(buf) > len(name));
@@ -240,8 +239,8 @@ proc last_write_time_by_name(name: string) -> FileTime {
last_write_time = data.last_write_time; last_write_time = data.last_write_time;
} }
var l = FileTime(last_write_time.lo); l := FileTime(last_write_time.lo);
var h = FileTime(last_write_time.hi); h := FileTime(last_write_time.hi);
return l | h << 32; return l | h << 32;
} }
@@ -283,15 +282,15 @@ proc current_thread_id() -> int {
proc _alloc_command_line_arguments() -> []string { proc _alloc_command_line_arguments() -> []string {
proc alloc_ucs2_to_utf8(wstr: ^u16) -> string { proc alloc_ucs2_to_utf8(wstr: ^u16) -> string {
var wstr_len = 0; wstr_len := 0;
for (wstr+wstr_len)^ != 0 { for (wstr+wstr_len)^ != 0 {
wstr_len++; wstr_len++;
} }
var len = 2*wstr_len-1; len := 2*wstr_len-1;
var buf = make([]u8, len+1); buf := make([]u8, len+1);
var str = slice_ptr(wstr, wstr_len+1); str := slice_ptr(wstr, wstr_len+1);
var i, j = 0, 0; i, j := 0, 0;
for str[j] != 0 { for str[j] != 0 {
match { match {
case str[j] < 0x80: case str[j] < 0x80:
@@ -311,7 +310,7 @@ proc _alloc_command_line_arguments() -> []string {
if i+4 > len { if i+4 > len {
return ""; return "";
} }
var c = rune((str[j] - 0xd800) << 10) + rune((str[j+1]) - 0xdc00) + 0x10000; c := rune((str[j] - 0xd800) << 10) + rune((str[j+1]) - 0xdc00) + 0x10000;
buf[i] = u8(0xf0 + (c >> 18)); i++; buf[i] = u8(0xf0 + (c >> 18)); i++;
buf[i] = u8(0x80 + ((c >> 12) & 0x3f)); i++; buf[i] = u8(0x80 + ((c >> 12) & 0x3f)); i++;
buf[i] = u8(0x80 + ((c >> 6) & 0x3f)); i++; buf[i] = u8(0x80 + ((c >> 6) & 0x3f)); i++;
@@ -333,9 +332,9 @@ proc _alloc_command_line_arguments() -> []string {
return string(buf[0..<i]); return string(buf[0..<i]);
} }
var arg_count: i32; arg_count: i32;
var arg_list_ptr = win32.command_line_to_argv_w(win32.get_command_line_w(), &arg_count); arg_list_ptr := win32.command_line_to_argv_w(win32.get_command_line_w(), &arg_count);
var arg_list = make([]string, arg_count); arg_list := make([]string, arg_count);
for _, i in arg_list { for _, i in arg_list {
arg_list[i] = alloc_ucs2_to_utf8((arg_list_ptr+i)^); arg_list[i] = alloc_ucs2_to_utf8((arg_list_ptr+i)^);
} }
+77 -82
View File
@@ -13,42 +13,42 @@ type (
AddressSize int; AddressSize int;
) )
const (
O_RDONLY = 0x00000;
O_WRONLY = 0x00001;
O_RDWR = 0x00002;
O_CREAT = 0x00040;
O_EXCL = 0x00080;
O_NOCTTY = 0x00100;
O_TRUNC = 0x00200;
O_NONBLOCK = 0x00800;
O_APPEND = 0x00400;
O_SYNC = 0x01000;
O_ASYNC = 0x02000;
O_CLOEXEC = 0x80000;
)
const (
SEEK_SET = 0;
SEEK_CUR = 1;
SEEK_END = 2;
SEEK_DATA = 3;
SEEK_HOLE = 4;
SEEK_MAX = SEEK_HOLE;
)
const ( O_RDONLY :: 0x00000;
O_WRONLY :: 0x00001;
O_RDWR :: 0x00002;
O_CREAT :: 0x00040;
O_EXCL :: 0x00080;
O_NOCTTY :: 0x00100;
O_TRUNC :: 0x00200;
O_NONBLOCK :: 0x00800;
O_APPEND :: 0x00400;
O_SYNC :: 0x01000;
O_ASYNC :: 0x02000;
O_CLOEXEC :: 0x80000;
SEEK_SET :: 0;
SEEK_CUR :: 1;
SEEK_END :: 2;
SEEK_DATA :: 3;
SEEK_HOLE :: 4;
SEEK_MAX :: SEEK_HOLE;
// NOTE(zangent): These are OS specific! // NOTE(zangent): These are OS specific!
// Do not mix these up! // Do not mix these up!
RTLD_LAZY = 0x1; RTLD_LAZY :: 0x1;
RTLD_NOW = 0x2; RTLD_NOW :: 0x2;
RTLD_LOCAL = 0x4; RTLD_LOCAL :: 0x4;
RTLD_GLOBAL = 0x8; RTLD_GLOBAL :: 0x8;
RTLD_NODELETE = 0x80; RTLD_NODELETE :: 0x80;
RTLD_NOLOAD = 0x10; RTLD_NOLOAD :: 0x10;
RTLD_FIRST = 0x100; RTLD_FIRST :: 0x100;
)
var args: [dynamic]string;
args: [dynamic]string;
type _FileTime struct #ordered { type _FileTime struct #ordered {
seconds: i64, seconds: i64,
@@ -80,39 +80,37 @@ type Stat struct #ordered {
}; };
// File type // File type
const ( S_IFMT :: 0170000; // Type of file mask
S_IFMT = 0170000; // Type of file mask S_IFIFO :: 0010000; // Named pipe (fifo)
S_IFIFO = 0010000; // Named pipe (fifo) S_IFCHR :: 0020000; // Character special
S_IFCHR = 0020000; // Character special S_IFDIR :: 0040000; // Directory
S_IFDIR = 0040000; // Directory S_IFBLK :: 0060000; // Block special
S_IFBLK = 0060000; // Block special S_IFREG :: 0100000; // Regular
S_IFREG = 0100000; // Regular S_IFLNK :: 0120000; // Symbolic link
S_IFLNK = 0120000; // Symbolic link S_IFSOCK :: 0140000; // Socket
S_IFSOCK = 0140000; // Socket
// File mode // File mode
// Read, write, execute/search by owner // Read, write, execute/search by owner
S_IRWXU = 0000700; // RWX mask for owner S_IRWXU :: 0000700; // RWX mask for owner
S_IRUSR = 0000400; // R for owner S_IRUSR :: 0000400; // R for owner
S_IWUSR = 0000200; // W for owner S_IWUSR :: 0000200; // W for owner
S_IXUSR = 0000100; // X for owner S_IXUSR :: 0000100; // X for owner
// Read, write, execute/search by group // Read, write, execute/search by group
S_IRWXG = 0000070; // RWX mask for group S_IRWXG :: 0000070; // RWX mask for group
S_IRGRP = 0000040; // R for group S_IRGRP :: 0000040; // R for group
S_IWGRP = 0000020; // W for group S_IWGRP :: 0000020; // W for group
S_IXGRP = 0000010; // X for group S_IXGRP :: 0000010; // X for group
// Read, write, execute/search by others // Read, write, execute/search by others
S_IRWXO = 0000007; // RWX mask for other S_IRWXO :: 0000007; // RWX mask for other
S_IROTH = 0000004; // R for other S_IROTH :: 0000004; // R for other
S_IWOTH = 0000002; // W for other S_IWOTH :: 0000002; // W for other
S_IXOTH = 0000001; // X for other S_IXOTH :: 0000001; // X for other
S_ISUID = 0004000; // Set user id on execution S_ISUID :: 0004000; // Set user id on execution
S_ISGID = 0002000; // Set group id on execution S_ISGID :: 0002000; // Set group id on execution
S_ISVTX = 0001000; // Directory restrcted delete S_ISVTX :: 0001000; // Directory restrcted delete
)
proc S_ISLNK (m: u32) -> bool #inline {return (m & S_IFMT) == S_IFLNK; } proc S_ISLNK (m: u32) -> bool #inline {return (m & S_IFMT) == S_IFLNK; }
proc S_ISREG (m: u32) -> bool #inline {return (m & S_IFMT) == S_IFREG; } proc S_ISREG (m: u32) -> bool #inline {return (m & S_IFMT) == S_IFREG; }
@@ -122,12 +120,10 @@ proc S_ISBLK (m: u32) -> bool #inline {return (m & S_IFMT) == S_IFBLK; }
proc S_ISFIFO(m: u32) -> bool #inline {return (m & S_IFMT) == S_IFIFO; } proc S_ISFIFO(m: u32) -> bool #inline {return (m & S_IFMT) == S_IFIFO; }
proc S_ISSOCK(m: u32) -> bool #inline {return (m & S_IFMT) == S_IFSOCK;} proc S_ISSOCK(m: u32) -> bool #inline {return (m & S_IFMT) == S_IFSOCK;}
const ( R_OK :: 4; // Test for read permission
R_OK = 4; // Test for read permission W_OK :: 2; // Test for write permission
W_OK = 2; // Test for write permission X_OK :: 1; // Test for execute permission
X_OK = 1; // Test for execute permission F_OK :: 0; // Test for file existance
F_OK = 0; // Test for file existance
)
foreign libc { foreign libc {
proc unix_open (path: ^u8, mode: int) -> Handle #link_name "open"; proc unix_open (path: ^u8, mode: int) -> Handle #link_name "open";
@@ -157,8 +153,8 @@ foreign dl {
// TODO(zangent): Change this to just `open` when Bill fixes overloading. // TODO(zangent): Change this to just `open` when Bill fixes overloading.
proc open_simple(path: string, mode: int) -> (Handle, Errno) { proc open_simple(path: string, mode: int) -> (Handle, Errno) {
var cstr = strings.new_c_string(path); cstr := strings.new_c_string(path);
var handle = unix_open(cstr, mode); handle := unix_open(cstr, mode);
free(cstr); free(cstr);
if(handle == -1) { if(handle == -1) {
return 0, 1; return 0, 1;
@@ -178,7 +174,7 @@ proc close(fd: Handle) {
proc write(fd: Handle, data: []u8) -> (AddressSize, Errno) { proc write(fd: Handle, data: []u8) -> (AddressSize, Errno) {
assert(fd != -1); assert(fd != -1);
var bytes_written = unix_write(fd, &data[0], len(data)); bytes_written := unix_write(fd, &data[0], len(data));
if(bytes_written == -1) { if(bytes_written == -1) {
return 0, 1; return 0, 1;
} }
@@ -188,7 +184,7 @@ proc write(fd: Handle, data: []u8) -> (AddressSize, Errno) {
proc read(fd: Handle, data: []u8) -> (AddressSize, Errno) { proc read(fd: Handle, data: []u8) -> (AddressSize, Errno) {
assert(fd != -1); assert(fd != -1);
var bytes_read = unix_read(fd, &data[0], len(data)); bytes_read := unix_read(fd, &data[0], len(data));
if(bytes_read == -1) { if(bytes_read == -1) {
return 0, 1; return 0, 1;
} }
@@ -198,7 +194,7 @@ proc read(fd: Handle, data: []u8) -> (AddressSize, Errno) {
proc seek(fd: Handle, offset: AddressSize, whence: int) -> (AddressSize, Errno) { proc seek(fd: Handle, offset: AddressSize, whence: int) -> (AddressSize, Errno) {
assert(fd != -1); assert(fd != -1);
var final_offset = unix_lseek(fd, offset, whence); final_offset := unix_lseek(fd, offset, whence);
if(final_offset == -1) { if(final_offset == -1) {
return 0, 1; return 0, 1;
} }
@@ -206,8 +202,8 @@ proc seek(fd: Handle, offset: AddressSize, whence: int) -> (AddressSize, Errno)
} }
proc file_size(fd: Handle) -> (i64, Errno) { proc file_size(fd: Handle) -> (i64, Errno) {
var prev, _ = seek(fd, 0, SEEK_CUR); prev, _ := seek(fd, 0, SEEK_CUR);
var size, err = seek(fd, 0, SEEK_END); size, err := seek(fd, 0, SEEK_END);
seek(fd, prev, SEEK_SET); seek(fd, prev, SEEK_SET);
return size, err; return size, err;
} }
@@ -215,26 +211,25 @@ proc file_size(fd: Handle) -> (i64, Errno) {
// NOTE(bill): Uses startup to initialize it // NOTE(bill): Uses startup to initialize it
var (
stdin: Handle = 0; // get_std_handle(win32.STD_INPUT_HANDLE); stdin: Handle = 0; // get_std_handle(win32.STD_INPUT_HANDLE);
stdout: Handle = 1; // get_std_handle(win32.STD_OUTPUT_HANDLE); stdout: Handle = 1; // get_std_handle(win32.STD_OUTPUT_HANDLE);
stderr: Handle = 2; // get_std_handle(win32.STD_ERROR_HANDLE); stderr: Handle = 2; // get_std_handle(win32.STD_ERROR_HANDLE);
)
/* TODO(zangent): Implement these! /* TODO(zangent): Implement these!
proc last_write_time(fd: Handle) -> FileTime {} proc last_write_time(fd: Handle) -> FileTime {}
proc last_write_time_by_name(name: string) -> FileTime {} proc last_write_time_by_name(name: string) -> FileTime {}
*/ */
proc stat(path: string) -> (Stat, bool) #inline { proc stat(path: string) -> (Stat, bool) #inline {
var s: Stat; s: Stat;
var cstr = strings.new_c_string(path); cstr := strings.new_c_string(path);
defer free(cstr); defer free(cstr);
var ret_int = unix_stat(cstr, &s); ret_int := unix_stat(cstr, &s);
return s, ret_int==0; return s, ret_int==0;
} }
proc access(path: string, mask: int) -> bool #inline { proc access(path: string, mask: int) -> bool #inline {
var cstr = strings.new_c_string(path); cstr := strings.new_c_string(path);
defer free(cstr); defer free(cstr);
return unix_access(cstr, mask) == 0; return unix_access(cstr, mask) == 0;
} }
@@ -251,8 +246,8 @@ proc heap_free(ptr: rawptr) #inline {
} }
proc getenv(name: string) -> (string, bool) { proc getenv(name: string) -> (string, bool) {
var path_str = strings.new_c_string(name); path_str := strings.new_c_string(name);
var cstr: ^u8 = unix_getenv(path_str); cstr: ^u8 = unix_getenv(path_str);
free(path_str); free(path_str);
if(cstr == nil) { if(cstr == nil) {
return "", false; return "", false;
@@ -271,15 +266,15 @@ proc current_thread_id() -> int {
} }
proc dlopen(filename: string, flags: int) -> rawptr #inline { proc dlopen(filename: string, flags: int) -> rawptr #inline {
var cstr = strings.new_c_string(filename); cstr := strings.new_c_string(filename);
var handle = unix_dlopen(cstr, flags); handle := unix_dlopen(cstr, flags);
free(cstr); free(cstr);
return handle; return handle;
} }
proc dlsym(handle: rawptr, symbol: string) -> (proc() #cc_c) #inline { proc dlsym(handle: rawptr, symbol: string) -> (proc() #cc_c) #inline {
assert(handle != nil); assert(handle != nil);
var cstr = strings.new_c_string(symbol); cstr := strings.new_c_string(symbol);
var proc_handle = unix_dlsym(handle, cstr); proc_handle := unix_dlsym(handle, cstr);
free(cstr); free(cstr);
return proc_handle; return proc_handle;
} }
+69 -71
View File
@@ -18,8 +18,8 @@ proc parse_bool(s: string) -> (result: bool, ok: bool) {
} }
proc _digit_value(r: rune) -> int { proc _digit_value(r: rune) -> int {
var ri = int(r); ri := int(r);
var v: int = 16; v: int = 16;
match r { match r {
case '0'..'9': v = ri-'0'; case '0'..'9': v = ri-'0';
case 'a'..'z': v = ri-'a'+10; case 'a'..'z': v = ri-'a'+10;
@@ -29,7 +29,7 @@ proc _digit_value(r: rune) -> int {
} }
proc parse_i128(s: string) -> i128 { proc parse_i128(s: string) -> i128 {
var neg = false; neg := false;
if len(s) > 1 { if len(s) > 1 {
match s[0] { match s[0] {
case '-': case '-':
@@ -41,7 +41,7 @@ proc parse_i128(s: string) -> i128 {
} }
var base: i128 = 10; base: i128 = 10;
if len(s) > 2 && s[0] == '0' { if len(s) > 2 && s[0] == '0' {
match s[1] { match s[1] {
case 'b': base = 2; s = s[2..]; case 'b': base = 2; s = s[2..];
@@ -53,13 +53,13 @@ proc parse_i128(s: string) -> i128 {
} }
var value: i128; value: i128;
for r in s { for r in s {
if r == '_' { if r == '_' {
continue; continue;
} }
var v = i128(_digit_value(r)); v := i128(_digit_value(r));
if v >= base { if v >= base {
break; break;
} }
@@ -71,13 +71,13 @@ proc parse_i128(s: string) -> i128 {
} }
proc parse_u128(s: string) -> u128 { proc parse_u128(s: string) -> u128 {
var neg = false; neg := false;
if len(s) > 1 && s[0] == '+' { if len(s) > 1 && s[0] == '+' {
s = s[1..]; s = s[1..];
} }
var base = u128(10); base := u128(10);
if len(s) > 2 && s[0] == '0' { if len(s) > 2 && s[0] == '0' {
match s[1] { match s[1] {
case 'b': base = 2; s = s[2..]; case 'b': base = 2; s = s[2..];
@@ -89,13 +89,13 @@ proc parse_u128(s: string) -> u128 {
} }
var value: u128; value: u128;
for r in s { for r in s {
if r == '_' { if r == '_' {
continue; continue;
} }
var v = u128(_digit_value(r)); v := u128(_digit_value(r));
if v >= base { if v >= base {
break; break;
} }
@@ -115,21 +115,21 @@ proc parse_uint(s: string, base: int) -> uint {
} }
proc parse_f64(s: string) -> f64 { proc parse_f64(s: string) -> f64 {
var i = 0; i := 0;
var sign: f64 = 1; sign: f64 = 1;
match s[i] { match s[i] {
case '-': i++; sign = -1; case '-': i++; sign = -1;
case '+': i++; case '+': i++;
} }
var value: f64 = 0; value: f64 = 0;
for ; i < len(s); i++ { for ; i < len(s); i++ {
var r = rune(s[i]); r := rune(s[i]);
if r == '_' { if r == '_' {
continue; continue;
} }
var v = _digit_value(r); v := _digit_value(r);
if v >= 10 { if v >= 10 {
break; break;
} }
@@ -138,15 +138,15 @@ proc parse_f64(s: string) -> f64 {
} }
if s[i] == '.' { if s[i] == '.' {
var pow10: f64 = 10; pow10: f64 = 10;
i++; i++;
for ; i < len(s); i++ { for ; i < len(s); i++ {
var r = rune(s[i]); r := rune(s[i]);
if r == '_' { if r == '_' {
continue; continue;
} }
var v = _digit_value(r); v := _digit_value(r);
if v >= 10 { if v >= 10 {
break; break;
} }
@@ -155,8 +155,8 @@ proc parse_f64(s: string) -> f64 {
} }
} }
var frac = false; frac := false;
var scale: f64 = 1; scale: f64 = 1;
if s[i] == 'e' || s[i] == 'E' { if s[i] == 'e' || s[i] == 'E' {
i++; i++;
@@ -166,13 +166,13 @@ proc parse_f64(s: string) -> f64 {
case '+': i++; case '+': i++;
} }
var exp: u32 = 0; exp: u32 = 0;
for ; i < len(s); i++ { for ; i < len(s); i++ {
var r = rune(s[i]); r := rune(s[i]);
if r == '_' { if r == '_' {
continue; continue;
} }
var d = u32(_digit_value(r)); d := u32(_digit_value(r));
if d >= 10 { if d >= 10 {
break; break;
} }
@@ -190,7 +190,7 @@ proc parse_f64(s: string) -> f64 {
proc append_bool(buf: []u8, b: bool) -> string { proc append_bool(buf: []u8, b: bool) -> string {
var s = b ? "true" : "false"; s := b ? "true" : "false";
append(buf, ..[]u8(s)); append(buf, ..[]u8(s));
return string(buf); return string(buf);
} }
@@ -210,28 +210,28 @@ proc append_float(buf: []u8, f: f64, fmt: u8, prec, bit_size: int) -> string {
type DecimalSlice struct { DecimalSlice :: struct {
digits: []u8, digits: []u8,
count: int, count: int,
decimal_point: int, decimal_point: int,
neg: bool, neg: bool,
} }
type Float_Info struct { Float_Info :: struct {
mantbits: uint, mantbits: uint,
expbits: uint, expbits: uint,
bias: int, bias: int,
} }
var (
_f16_info = Float_Info{10, 5, -15}; _f16_info := Float_Info{10, 5, -15};
_f32_info = Float_Info{23, 8, -127}; _f32_info := Float_Info{23, 8, -127};
_f64_info = Float_Info{52, 11, -1023}; _f64_info := Float_Info{52, 11, -1023};
)
proc generic_ftoa(buf: []u8, val: f64, fmt: u8, prec, bit_size: int) -> []u8 { proc generic_ftoa(buf: []u8, val: f64, fmt: u8, prec, bit_size: int) -> []u8 {
var bits: u64; bits: u64;
var flt: ^Float_Info; flt: ^Float_Info;
match bit_size { match bit_size {
case 32: case 32:
bits = u64(transmute(u32, f32(val))); bits = u64(transmute(u32, f32(val)));
@@ -243,13 +243,13 @@ proc generic_ftoa(buf: []u8, val: f64, fmt: u8, prec, bit_size: int) -> []u8 {
panic("strconv: invalid bit_size"); panic("strconv: invalid bit_size");
} }
var neg = bits>>(flt.expbits+flt.mantbits) != 0; neg := bits>>(flt.expbits+flt.mantbits) != 0;
var exp = int(bits>>flt.mantbits) & (1<<flt.expbits - 1); exp := int(bits>>flt.mantbits) & (1<<flt.expbits - 1);
var mant = bits & (u64(1) << flt.mantbits - 1); mant := bits & (u64(1) << flt.mantbits - 1);
match exp { match exp {
case 1<<flt.expbits - 1: case 1<<flt.expbits - 1:
var s: string; s: string;
if mant != 0 { if mant != 0 {
s = "NaN"; s = "NaN";
} else if neg { } else if neg {
@@ -269,12 +269,12 @@ proc generic_ftoa(buf: []u8, val: f64, fmt: u8, prec, bit_size: int) -> []u8 {
exp += flt.bias; exp += flt.bias;
var d_: Decimal; d_: Decimal;
var d = &d_; d := &d_;
assign(d, mant); assign(d, mant);
shift(d, exp - int(flt.mantbits)); shift(d, exp - int(flt.mantbits));
var digs: DecimalSlice; digs: DecimalSlice;
var shortest = prec < 0; shortest := prec < 0;
if shortest { if shortest {
round_shortest(d, mant, exp, flt); round_shortest(d, mant, exp, flt);
digs = DecimalSlice{digits = d.digits[..], count = d.count, decimal_point = d.decimal_point}; digs = DecimalSlice{digits = d.digits[..], count = d.count, decimal_point = d.decimal_point};
@@ -308,7 +308,7 @@ proc format_digits(buf: []u8, shortest: bool, neg: bool, digs: DecimalSlice, pre
// integer, padded with zeros when needed // integer, padded with zeros when needed
if digs.decimal_point > 0 { if digs.decimal_point > 0 {
var m = min(digs.count, digs.decimal_point); m := min(digs.count, digs.decimal_point);
append(buf, ..digs.digits[0..<m]); append(buf, ..digs.digits[0..<m]);
for ; m < digs.decimal_point; m++ { for ; m < digs.decimal_point; m++ {
append(buf, '0'); append(buf, '0');
@@ -322,8 +322,8 @@ proc format_digits(buf: []u8, shortest: bool, neg: bool, digs: DecimalSlice, pre
if prec > 0 { if prec > 0 {
append(buf, '.'); append(buf, '.');
for i in 0..<prec { for i in 0..<prec {
var c: u8 = '0'; c: u8 = '0';
if var j = digs.decimal_point + i; 0 <= j && j < digs.count { if j := digs.decimal_point + i; 0 <= j && j < digs.count {
c = digs.digits[j]; c = digs.digits[j];
} }
append(buf, c); append(buf, c);
@@ -341,9 +341,7 @@ proc format_digits(buf: []u8, shortest: bool, neg: bool, digs: DecimalSlice, pre
return buf; // TODO return buf; // TODO
} }
var c: [2]u8; c := [2]u8{'%', fmt};
c[0] = '%';
c[1] = fmt;
append(buf, ..c[..]); append(buf, ..c[..]);
return buf; return buf;
} }
@@ -360,18 +358,18 @@ proc round_shortest(d: ^Decimal, mant: u64, exp: int, flt: ^Float_Info) {
log(2) >~ 0.332 log(2) >~ 0.332
332*(dp-nd) >= 100*(exp-mantbits) 332*(dp-nd) >= 100*(exp-mantbits)
*/ */
var minexp = flt.bias+1; minexp := flt.bias+1;
if exp > minexp && 332*(d.decimal_point-d.count) >= 100*(exp - int(flt.mantbits)) { if exp > minexp && 332*(d.decimal_point-d.count) >= 100*(exp - int(flt.mantbits)) {
// Number is already its shortest // Number is already its shortest
return; return;
} }
var upper_: Decimal; var upper = &upper_; upper_: Decimal; upper := &upper_;
assign(upper, 2*mant - 1); assign(upper, 2*mant - 1);
shift(upper, exp - int(flt.mantbits) - 1); shift(upper, exp - int(flt.mantbits) - 1);
var mantlo: u64; mantlo: u64;
var explo: int; explo: int;
if mant > 1<<flt.mantbits || exp == minexp { if mant > 1<<flt.mantbits || exp == minexp {
mantlo = mant-1; mantlo = mant-1;
explo = exp; explo = exp;
@@ -379,25 +377,25 @@ proc round_shortest(d: ^Decimal, mant: u64, exp: int, flt: ^Float_Info) {
mantlo = 2*mant - 1; mantlo = 2*mant - 1;
explo = exp-1; explo = exp-1;
} }
var lower_: Decimal; var lower = &lower_; lower_: Decimal; lower := &lower_;
assign(lower, 2*mantlo + 1); assign(lower, 2*mantlo + 1);
shift(lower, explo - int(flt.mantbits) - 1); shift(lower, explo - int(flt.mantbits) - 1);
var inclusive = mant%2 == 0; inclusive := mant%2 == 0;
for i in 0..<d.count { for i in 0..<d.count {
var l: u8 = '0'; // lower digit l: u8 = '0'; // lower digit
if i < lower.count { if i < lower.count {
l = lower.digits[i]; l = lower.digits[i];
} }
var m = d.digits[i]; // middle digit m := d.digits[i]; // middle digit
var u: u8 = '0'; // upper digit u: u8 = '0'; // upper digit
if i < upper.count { if i < upper.count {
u = upper.digits[i]; u = upper.digits[i];
} }
var ok_round_down = l != m || inclusive && i+1 == lower.count; ok_round_down := l != m || inclusive && i+1 == lower.count;
var ok_round_up = m != u && (inclusive || m+1 < u || i+1 < upper.count); ok_round_up := m != u && (inclusive || m+1 < u || i+1 < upper.count);
if (ok_round_down && ok_round_up) { if (ok_round_down && ok_round_up) {
round(d, i+1); round(d, i+1);
@@ -415,36 +413,36 @@ proc round_shortest(d: ^Decimal, mant: u64, exp: int, flt: ^Float_Info) {
} }
const MAX_BASE = 32; MAX_BASE :: 32;
var digits = "0123456789abcdefghijklmnopqrstuvwxyz"; digits := "0123456789abcdefghijklmnopqrstuvwxyz";
proc is_integer_negative(u: u128, is_signed: bool, bit_size: int) -> (unsigned: u128, neg: bool) { proc is_integer_negative(u: u128, is_signed: bool, bit_size: int) -> (unsigned: u128, neg: bool) {
var neg = false; neg := false;
if is_signed { if is_signed {
match bit_size { match bit_size {
case 8: case 8:
var i = i8(u); i := i8(u);
neg = i < 0; neg = i < 0;
if neg { i = -i; } if neg { i = -i; }
u = u128(i); u = u128(i);
case 16: case 16:
var i = i16(u); i := i16(u);
neg = i < 0; neg = i < 0;
if neg { i = -i; } if neg { i = -i; }
u = u128(i); u = u128(i);
case 32: case 32:
var i = i32(u); i := i32(u);
neg = i < 0; neg = i < 0;
if neg { i = -i; } if neg { i = -i; }
u = u128(i); u = u128(i);
case 64: case 64:
var i = i64(u); i := i64(u);
neg = i < 0; neg = i < 0;
if neg { i = -i; } if neg { i = -i; }
u = u128(i); u = u128(i);
case 128: case 128:
var i = i128(u); i := i128(u);
neg = i < 0; neg = i < 0;
if neg { i = -i; } if neg { i = -i; }
u = u128(i); u = u128(i);
@@ -460,11 +458,11 @@ proc append_bits(buf: []u8, u: u128, base: int, is_signed: bool, bit_size: int,
panic("strconv: illegal base passed to append_bits"); panic("strconv: illegal base passed to append_bits");
} }
var neg: bool; neg: bool;
var a: [129]u8; a: [129]u8;
var i = len(a); i := len(a);
u, neg = is_integer_negative(u, is_signed, bit_size); u, neg = is_integer_negative(u, is_signed, bit_size);
var b = u128(base); b := u128(base);
for u >= b { for u >= b {
i--; a[i] = digits[uint(u % b)]; i--; a[i] = digits[uint(u % b)];
u /= b; u /= b;
@@ -472,7 +470,7 @@ proc append_bits(buf: []u8, u: u128, base: int, is_signed: bool, bit_size: int,
i--; a[i] = digits[uint(u % b)]; i--; a[i] = digits[uint(u % b)];
if flags&IntFlag.Prefix != 0 { if flags&IntFlag.Prefix != 0 {
var ok = true; ok := true;
match base { match base {
case 2: i--; a[i] = 'b'; case 2: i--; a[i] = 'b';
case 8: i--; a[i] = 'o'; case 8: i--; a[i] = 'o';
+3 -3
View File
@@ -1,19 +1,19 @@
proc new_string(s: string) -> string { proc new_string(s: string) -> string {
var c = make([]u8, len(s)+1); c := make([]u8, len(s)+1);
copy(c, []u8(s)); copy(c, []u8(s));
c[len(s)] = 0; c[len(s)] = 0;
return string(c[0..<len(s)]); return string(c[0..<len(s)]);
} }
proc new_c_string(s: string) -> ^u8 { proc new_c_string(s: string) -> ^u8 {
var c = make([]u8, len(s)+1); c := make([]u8, len(s)+1);
copy(c, []u8(s)); copy(c, []u8(s));
c[len(s)] = 0; c[len(s)] = 0;
return &c[0]; return &c[0];
} }
proc to_odin_string(c: ^u8) -> string { proc to_odin_string(c: ^u8) -> string {
var len = 0; len := 0;
for (c+len)^ != 0 { for (c+len)^ != 0 {
len++; len++;
} }
+5 -5
View File
@@ -49,7 +49,7 @@ proc mutex_destroy(m: ^Mutex) {
semaphore_destroy(&m._semaphore); semaphore_destroy(&m._semaphore);
} }
proc mutex_lock(m: ^Mutex) { proc mutex_lock(m: ^Mutex) {
var thread_id = current_thread_id(); thread_id := current_thread_id();
if atomics.fetch_add(&m._counter, 1) > 0 { if atomics.fetch_add(&m._counter, 1) > 0 {
if thread_id != atomics.load(&m._owner) { if thread_id != atomics.load(&m._owner) {
semaphore_wait(&m._semaphore); semaphore_wait(&m._semaphore);
@@ -59,11 +59,11 @@ proc mutex_lock(m: ^Mutex) {
m._recursion++; m._recursion++;
} }
proc mutex_try_lock(m: ^Mutex) -> bool { proc mutex_try_lock(m: ^Mutex) -> bool {
var thread_id = current_thread_id(); thread_id := current_thread_id();
if atomics.load(&m._owner) == thread_id { if atomics.load(&m._owner) == thread_id {
atomics.fetch_add(&m._counter, 1); atomics.fetch_add(&m._counter, 1);
} else { } else {
var expected: i32 = 0; expected: i32 = 0;
if atomics.load(&m._counter) != 0 { if atomics.load(&m._counter) != 0 {
return false; return false;
} }
@@ -76,8 +76,8 @@ proc mutex_try_lock(m: ^Mutex) -> bool {
return true; return true;
} }
proc mutex_unlock(m: ^Mutex) { proc mutex_unlock(m: ^Mutex) {
var recursion: i32; recursion: i32;
var thread_id = current_thread_id(); thread_id := current_thread_id();
assert(thread_id == atomics.load(&m._owner)); assert(thread_id == atomics.load(&m._owner));
m._recursion--; m._recursion--;
+5 -5
View File
@@ -47,7 +47,7 @@ proc mutex_destroy(m: ^Mutex) {
semaphore_destroy(&m._semaphore); semaphore_destroy(&m._semaphore);
} }
proc mutex_lock(m: ^Mutex) { proc mutex_lock(m: ^Mutex) {
var thread_id = current_thread_id(); thread_id := current_thread_id();
if atomics.fetch_add(&m._counter, 1) > 0 { if atomics.fetch_add(&m._counter, 1) > 0 {
if thread_id != atomics.load(&m._owner) { if thread_id != atomics.load(&m._owner) {
semaphore_wait(&m._semaphore); semaphore_wait(&m._semaphore);
@@ -57,11 +57,11 @@ proc mutex_lock(m: ^Mutex) {
m._recursion++; m._recursion++;
} }
proc mutex_try_lock(m: ^Mutex) -> bool { proc mutex_try_lock(m: ^Mutex) -> bool {
var thread_id = current_thread_id(); thread_id := current_thread_id();
if atomics.load(&m._owner) == thread_id { if atomics.load(&m._owner) == thread_id {
atomics.fetch_add(&m._counter, 1); atomics.fetch_add(&m._counter, 1);
} else { } else {
var expected: i32 = 0; expected: i32 = 0;
if atomics.load(&m._counter) != 0 { if atomics.load(&m._counter) != 0 {
return false; return false;
} }
@@ -74,8 +74,8 @@ proc mutex_try_lock(m: ^Mutex) -> bool {
return true; return true;
} }
proc mutex_unlock(m: ^Mutex) { proc mutex_unlock(m: ^Mutex) {
var recursion: i32; recursion: i32;
var thread_id = current_thread_id(); thread_id := current_thread_id();
assert(thread_id == atomics.load(&m._owner)); assert(thread_id == atomics.load(&m._owner));
m._recursion--; m._recursion--;
+10 -11
View File
@@ -1,15 +1,14 @@
foreign_system_library "opengl32.lib" when ODIN_OS == "windows"; foreign_system_library "opengl32.lib" when ODIN_OS == "windows";
import . "windows.odin"; import . "windows.odin";
const (
CONTEXT_MAJOR_VERSION_ARB = 0x2091; CONTEXT_MAJOR_VERSION_ARB :: 0x2091;
CONTEXT_MINOR_VERSION_ARB = 0x2092; CONTEXT_MINOR_VERSION_ARB :: 0x2092;
CONTEXT_FLAGS_ARB = 0x2094; CONTEXT_FLAGS_ARB :: 0x2094;
CONTEXT_PROFILE_MASK_ARB = 0x9126; CONTEXT_PROFILE_MASK_ARB :: 0x9126;
CONTEXT_FORWARD_COMPATIBLE_BIT_ARB = 0x0002; CONTEXT_FORWARD_COMPATIBLE_BIT_ARB :: 0x0002;
CONTEXT_CORE_PROFILE_BIT_ARB = 0x00000001; CONTEXT_CORE_PROFILE_BIT_ARB :: 0x00000001;
CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB = 0x00000002; CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB :: 0x00000002;
)
type ( type (
Hglrc Handle; Hglrc Handle;
@@ -62,12 +61,12 @@ type (
GetExtensionsStringARBType proc(Hdc) -> ^u8 #cc_c; GetExtensionsStringARBType proc(Hdc) -> ^u8 #cc_c;
) )
var ( // Procedures
create_context_attribs_arb: CreateContextAttribsARBType; create_context_attribs_arb: CreateContextAttribsARBType;
choose_pixel_format_arb: ChoosePixelFormatARBType; choose_pixel_format_arb: ChoosePixelFormatARBType;
swap_interval_ext: SwapIntervalEXTType; swap_interval_ext: SwapIntervalEXTType;
get_extensions_string_arb: GetExtensionsStringARBType; get_extensions_string_arb: GetExtensionsStringARBType;
)
foreign opengl32 { foreign opengl32 {
+160 -172
View File
@@ -25,16 +25,14 @@ type (
) )
type Bool i32; type Bool i32;
const ( FALSE: Bool : 0;
FALSE: Bool = 0; TRUE: Bool : 1;
TRUE = 1;
)
type Point struct #ordered { Point :: struct #ordered {
x, y: i32, x, y: i32,
} }
type WndClassExA struct #ordered { WndClassExA :: struct #ordered {
size, style: u32, size, style: u32,
wnd_proc: WndProc, wnd_proc: WndProc,
cls_extra, wnd_extra: i32, cls_extra, wnd_extra: i32,
@@ -46,7 +44,7 @@ type WndClassExA struct #ordered {
sm: Hicon, sm: Hicon,
} }
type Msg struct #ordered { Msg :: struct #ordered {
hwnd: Hwnd, hwnd: Hwnd,
message: u32, message: u32,
wparam: Wparam, wparam: Wparam,
@@ -55,24 +53,24 @@ type Msg struct #ordered {
pt: Point, pt: Point,
} }
type Rect struct #ordered { Rect :: struct #ordered {
left: i32, left: i32,
top: i32, top: i32,
right: i32, right: i32,
bottom: i32, bottom: i32,
} }
type Filetime struct #ordered { Filetime :: struct #ordered {
lo, hi: u32, lo, hi: u32,
} }
type Systemtime struct #ordered { Systemtime :: struct #ordered {
year, month: u16, year, month: u16,
day_of_week, day: u16, day_of_week, day: u16,
hour, minute, second, millisecond: u16, hour, minute, second, millisecond: u16,
} }
type ByHandleFileInformation struct #ordered { ByHandleFileInformation :: struct #ordered {
file_attributes: u32, file_attributes: u32,
creation_time, creation_time,
last_access_time, last_access_time,
@@ -85,7 +83,7 @@ type ByHandleFileInformation struct #ordered {
file_index_low: u32, file_index_low: u32,
} }
type FileAttributeData struct #ordered { FileAttributeData :: struct #ordered {
file_attributes: u32, file_attributes: u32,
creation_time, creation_time,
last_access_time, last_access_time,
@@ -94,7 +92,7 @@ type FileAttributeData struct #ordered {
file_size_low: u32, file_size_low: u32,
} }
type FindData struct #ordered { FindData :: struct #ordered {
file_attributes: u32, file_attributes: u32,
creation_time: Filetime, creation_time: Filetime,
last_access_time: Filetime, last_access_time: Filetime,
@@ -107,7 +105,7 @@ type FindData struct #ordered {
alternate_file_name: [14]u8, alternate_file_name: [14]u8,
} }
type Security_Attributes struct #ordered { Security_Attributes :: struct #ordered {
length: u32, length: u32,
security_descriptor: rawptr, security_descriptor: rawptr,
inherit_handle: Bool, inherit_handle: Bool,
@@ -115,7 +113,7 @@ type Security_Attributes struct #ordered {
type PixelFormatDescriptor struct #ordered { PixelFormatDescriptor :: struct #ordered {
size, size,
version, version,
flags: u32, flags: u32,
@@ -151,138 +149,129 @@ type PixelFormatDescriptor struct #ordered {
type Proc proc() #cc_c; type Proc proc() #cc_c;
const ( MAPVK_VK_TO_VSC :: 0;
MAPVK_VK_TO_VSC = 0; MAPVK_VSC_TO_VK :: 1;
MAPVK_VSC_TO_VK = 1; MAPVK_VK_TO_CHAR :: 2;
MAPVK_VK_TO_CHAR = 2; MAPVK_VSC_TO_VK_EX :: 3;
MAPVK_VSC_TO_VK_EX = 3;
)
const INVALID_HANDLE = Handle(~int(0));
INVALID_HANDLE :: Handle(~int(0));
const ( CS_VREDRAW :: 0x0001;
CS_VREDRAW = 0x0001; CS_HREDRAW :: 0x0002;
CS_HREDRAW = 0x0002; CS_OWNDC :: 0x0020;
CS_OWNDC = 0x0020; CW_USEDEFAULT :: -0x80000000;
CW_USEDEFAULT = -0x80000000;
WS_OVERLAPPED = 0; WS_OVERLAPPED :: 0;
WS_MAXIMIZEBOX = 0x00010000; WS_MAXIMIZEBOX :: 0x00010000;
WS_MINIMIZEBOX = 0x00020000; WS_MINIMIZEBOX :: 0x00020000;
WS_THICKFRAME = 0x00040000; WS_THICKFRAME :: 0x00040000;
WS_SYSMENU = 0x00080000; WS_SYSMENU :: 0x00080000;
WS_BORDER = 0x00800000; WS_BORDER :: 0x00800000;
WS_CAPTION = 0x00C00000; WS_CAPTION :: 0x00C00000;
WS_VISIBLE = 0x10000000; WS_VISIBLE :: 0x10000000;
WS_POPUP = 0x80000000; WS_POPUP :: 0x80000000;
WS_OVERLAPPEDWINDOW = WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX; WS_OVERLAPPEDWINDOW :: WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX;
WS_POPUPWINDOW = WS_POPUP | WS_BORDER | WS_SYSMENU; WS_POPUPWINDOW :: WS_POPUP | WS_BORDER | WS_SYSMENU;
WM_DESTROY = 0x0002; WM_DESTROY :: 0x0002;
WM_SIZE = 0x0005; WM_SIZE :: 0x0005;
WM_CLOSE = 0x0010; WM_CLOSE :: 0x0010;
WM_ACTIVATEAPP = 0x001C; WM_ACTIVATEAPP :: 0x001C;
WM_QUIT = 0x0012; WM_QUIT :: 0x0012;
WM_KEYDOWN = 0x0100; WM_KEYDOWN :: 0x0100;
WM_KEYUP = 0x0101; WM_KEYUP :: 0x0101;
WM_SIZING = 0x0214; WM_SIZING :: 0x0214;
WM_SYSKEYDOWN = 0x0104; WM_SYSKEYDOWN :: 0x0104;
WM_SYSKEYUP = 0x0105; WM_SYSKEYUP :: 0x0105;
WM_WINDOWPOSCHANGED = 0x0047; WM_WINDOWPOSCHANGED :: 0x0047;
WM_SETCURSOR = 0x0020; WM_SETCURSOR :: 0x0020;
WM_CHAR = 0x0102; WM_CHAR :: 0x0102;
WM_ACTIVATE = 0x0006; WM_ACTIVATE :: 0x0006;
WM_SETFOCUS = 0x0007; WM_SETFOCUS :: 0x0007;
WM_KILLFOCUS = 0x0008; WM_KILLFOCUS :: 0x0008;
WM_USER = 0x0400; WM_USER :: 0x0400;
WM_MOUSEWHEEL = 0x020A; WM_MOUSEWHEEL :: 0x020A;
WM_MOUSEMOVE = 0x0200; WM_MOUSEMOVE :: 0x0200;
WM_LBUTTONDOWN = 0x0201; WM_LBUTTONDOWN :: 0x0201;
WM_LBUTTONUP = 0x0202; WM_LBUTTONUP :: 0x0202;
WM_LBUTTONDBLCLK = 0x0203; WM_LBUTTONDBLCLK :: 0x0203;
WM_RBUTTONDOWN = 0x0204; WM_RBUTTONDOWN :: 0x0204;
WM_RBUTTONUP = 0x0205; WM_RBUTTONUP :: 0x0205;
WM_RBUTTONDBLCLK = 0x0206; WM_RBUTTONDBLCLK :: 0x0206;
WM_MBUTTONDOWN = 0x0207; WM_MBUTTONDOWN :: 0x0207;
WM_MBUTTONUP = 0x0208; WM_MBUTTONUP :: 0x0208;
WM_MBUTTONDBLCLK = 0x0209; WM_MBUTTONDBLCLK :: 0x0209;
PM_NOREMOVE = 0x0000; PM_NOREMOVE :: 0x0000;
PM_REMOVE = 0x0001; PM_REMOVE :: 0x0001;
PM_NOYIELD = 0x0002; PM_NOYIELD :: 0x0002;
BLACK_BRUSH = 4; BLACK_BRUSH :: 4;
SM_CXSCREEN = 0; SM_CXSCREEN :: 0;
SM_CYSCREEN = 1; SM_CYSCREEN :: 1;
SW_SHOW = 5; SW_SHOW :: 5;
)
const COLOR_BACKGROUND = Hbrush(int(1)); COLOR_BACKGROUND :: Hbrush(int(1));
const INVALID_SET_FILE_POINTER = ~u32(0); INVALID_SET_FILE_POINTER :: ~u32(0);
const HEAP_ZERO_MEMORY = 0x00000008; HEAP_ZERO_MEMORY :: 0x00000008;
const INFINITE = 0xffffffff; INFINITE :: 0xffffffff;
const GWL_STYLE = -16; GWL_STYLE :: -16;
const Hwnd_TOP = Hwnd(uint(0)); Hwnd_TOP :: Hwnd(uint(0));
const BI_RGB = 0; BI_RGB :: 0;
const DIB_RGB_COLORS = 0x00; DIB_RGB_COLORS :: 0x00;
const SRCCOPY: u32 = 0x00cc0020; SRCCOPY: u32 : 0x00cc0020;
const (
MONITOR_DEFAULTTONULL = 0x00000000; MONITOR_DEFAULTTONULL :: 0x00000000;
MONITOR_DEFAULTTOPRIMARY = 0x00000001; MONITOR_DEFAULTTOPRIMARY :: 0x00000001;
MONITOR_DEFAULTTONEAREST = 0x00000002; MONITOR_DEFAULTTONEAREST :: 0x00000002;
)
const ( SWP_FRAMECHANGED :: 0x0020;
SWP_FRAMECHANGED = 0x0020; SWP_NOOWNERZORDER :: 0x0200;
SWP_NOOWNERZORDER = 0x0200; SWP_NOZORDER :: 0x0004;
SWP_NOZORDER = 0x0004; SWP_NOSIZE :: 0x0001;
SWP_NOSIZE = 0x0001; SWP_NOMOVE :: 0x0002;
SWP_NOMOVE = 0x0002;
)
// Windows OpenGL // Windows OpenGL
const (
PFD_TYPE_RGBA = 0;
PFD_TYPE_COLORINDEX = 1;
PFD_MAIN_PLANE = 0;
PFD_OVERLAY_PLANE = 1;
PFD_UNDERLAY_PLANE = -1;
PFD_DOUBLEBUFFER = 1;
PFD_STEREO = 2;
PFD_DRAW_TO_WINDOW = 4;
PFD_DRAW_TO_BITMAP = 8;
PFD_SUPPORT_GDI = 16;
PFD_SUPPORT_OPENGL = 32;
PFD_GENERIC_FORMAT = 64;
PFD_NEED_PALETTE = 128;
PFD_NEED_SYSTEM_PALETTE = 0x00000100;
PFD_SWAP_EXCHANGE = 0x00000200;
PFD_SWAP_COPY = 0x00000400;
PFD_SWAP_LAYER_BUFFERS = 0x00000800;
PFD_GENERIC_ACCELERATED = 0x00001000;
PFD_DEPTH_DONTCARE = 0x20000000;
PFD_DOUBLEBUFFER_DONTCARE = 0x40000000;
PFD_STEREO_DONTCARE = 0x80000000;
)
PFD_TYPE_RGBA :: 0;
PFD_TYPE_COLORINDEX :: 1;
PFD_MAIN_PLANE :: 0;
PFD_OVERLAY_PLANE :: 1;
PFD_UNDERLAY_PLANE :: -1;
PFD_DOUBLEBUFFER :: 1;
PFD_STEREO :: 2;
PFD_DRAW_TO_WINDOW :: 4;
PFD_DRAW_TO_BITMAP :: 8;
PFD_SUPPORT_GDI :: 16;
PFD_SUPPORT_OPENGL :: 32;
PFD_GENERIC_FORMAT :: 64;
PFD_NEED_PALETTE :: 128;
PFD_NEED_SYSTEM_PALETTE :: 0x00000100;
PFD_SWAP_EXCHANGE :: 0x00000200;
PFD_SWAP_COPY :: 0x00000400;
PFD_SWAP_LAYER_BUFFERS :: 0x00000800;
PFD_GENERIC_ACCELERATED :: 0x00001000;
PFD_DEPTH_DONTCARE :: 0x20000000;
PFD_DOUBLEBUFFER_DONTCARE :: 0x40000000;
PFD_STEREO_DONTCARE :: 0x80000000;
type GET_FILEEX_INFO_LEVELS i32; type GET_FILEEX_INFO_LEVELS i32;
const ( GetFileExInfoStandard: GET_FILEEX_INFO_LEVELS : 0;
GetFileExInfoStandard: GET_FILEEX_INFO_LEVELS = 0; GetFileExMaxInfoLevel: GET_FILEEX_INFO_LEVELS : 1;
GetFileExMaxInfoLevel = 1;
)
foreign kernel32 { foreign kernel32 {
proc get_last_error () -> i32 #cc_std #link_name "GetLastError"; proc get_last_error () -> i32 #cc_std #link_name "GetLastError";
@@ -448,7 +437,7 @@ foreign winmm {
proc get_query_performance_frequency() -> i64 { proc get_query_performance_frequency() -> i64 {
var r: i64; r: i64;
query_performance_frequency(&r); query_performance_frequency(&r);
return r; return r;
} }
@@ -463,67 +452,66 @@ proc is_key_down(key: KeyCode) -> bool #inline { return get_async_key_state(i32(
const (
MAX_PATH = 0x00000104;
HANDLE_FLAG_INHERIT = 1; MAX_PATH :: 0x00000104;
HANDLE_FLAG_PROTECT_FROM_CLOSE = 2;
FILE_BEGIN = 0; HANDLE_FLAG_INHERIT :: 1;
FILE_CURRENT = 1; HANDLE_FLAG_PROTECT_FROM_CLOSE :: 2;
FILE_END = 2;
FILE_SHARE_READ = 0x00000001; FILE_BEGIN :: 0;
FILE_SHARE_WRITE = 0x00000002; FILE_CURRENT :: 1;
FILE_SHARE_DELETE = 0x00000004; FILE_END :: 2;
FILE_GENERIC_ALL = 0x10000000;
FILE_GENERIC_EXECUTE = 0x20000000;
FILE_GENERIC_WRITE = 0x40000000;
FILE_GENERIC_READ = 0x80000000;
FILE_APPEND_DATA = 0x0004; FILE_SHARE_READ :: 0x00000001;
FILE_SHARE_WRITE :: 0x00000002;
FILE_SHARE_DELETE :: 0x00000004;
FILE_GENERIC_ALL :: 0x10000000;
FILE_GENERIC_EXECUTE :: 0x20000000;
FILE_GENERIC_WRITE :: 0x40000000;
FILE_GENERIC_READ :: 0x80000000;
STD_INPUT_HANDLE = -10; FILE_APPEND_DATA :: 0x0004;
STD_OUTPUT_HANDLE = -11;
STD_ERROR_HANDLE = -12;
CREATE_NEW = 1; STD_INPUT_HANDLE :: -10;
CREATE_ALWAYS = 2; STD_OUTPUT_HANDLE :: -11;
OPEN_EXISTING = 3; STD_ERROR_HANDLE :: -12;
OPEN_ALWAYS = 4;
TRUNCATE_EXISTING = 5;
INVALID_FILE_ATTRIBUTES = -1; CREATE_NEW :: 1;
CREATE_ALWAYS :: 2;
OPEN_EXISTING :: 3;
OPEN_ALWAYS :: 4;
TRUNCATE_EXISTING :: 5;
FILE_ATTRIBUTE_READONLY = 0x00000001; INVALID_FILE_ATTRIBUTES :: -1;
FILE_ATTRIBUTE_HIDDEN = 0x00000002;
FILE_ATTRIBUTE_SYSTEM = 0x00000004;
FILE_ATTRIBUTE_DIRECTORY = 0x00000010;
FILE_ATTRIBUTE_ARCHIVE = 0x00000020;
FILE_ATTRIBUTE_DEVICE = 0x00000040;
FILE_ATTRIBUTE_NORMAL = 0x00000080;
FILE_ATTRIBUTE_TEMPORARY = 0x00000100;
FILE_ATTRIBUTE_SPARSE_FILE = 0x00000200;
FILE_ATTRIBUTE_REPARSE_Point = 0x00000400;
FILE_ATTRIBUTE_COMPRESSED = 0x00000800;
FILE_ATTRIBUTE_OFFLINE = 0x00001000;
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000;
FILE_ATTRIBUTE_ENCRYPTED = 0x00004000;
FILE_TYPE_DISK = 0x0001; FILE_ATTRIBUTE_READONLY :: 0x00000001;
FILE_TYPE_CHAR = 0x0002; FILE_ATTRIBUTE_HIDDEN :: 0x00000002;
FILE_TYPE_PIPE = 0x0003; FILE_ATTRIBUTE_SYSTEM :: 0x00000004;
) FILE_ATTRIBUTE_DIRECTORY :: 0x00000010;
FILE_ATTRIBUTE_ARCHIVE :: 0x00000020;
FILE_ATTRIBUTE_DEVICE :: 0x00000040;
FILE_ATTRIBUTE_NORMAL :: 0x00000080;
FILE_ATTRIBUTE_TEMPORARY :: 0x00000100;
FILE_ATTRIBUTE_SPARSE_FILE :: 0x00000200;
FILE_ATTRIBUTE_REPARSE_Point :: 0x00000400;
FILE_ATTRIBUTE_COMPRESSED :: 0x00000800;
FILE_ATTRIBUTE_OFFLINE :: 0x00001000;
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED :: 0x00002000;
FILE_ATTRIBUTE_ENCRYPTED :: 0x00004000;
FILE_TYPE_DISK :: 0x0001;
FILE_TYPE_CHAR :: 0x0002;
FILE_TYPE_PIPE :: 0x0003;
type MonitorInfo struct #ordered { MonitorInfo :: struct #ordered {
size: u32, size: u32,
monitor: Rect, monitor: Rect,
work: Rect, work: Rect,
flags: u32, flags: u32,
} }
type WindowPlacement struct #ordered { WindowPlacement :: struct #ordered {
length: u32, length: u32,
flags: u32, flags: u32,
show_cmd: u32, show_cmd: u32,
@@ -532,7 +520,7 @@ type WindowPlacement struct #ordered {
normal_pos: Rect, normal_pos: Rect,
} }
type BitmapInfoHeader struct #ordered { BitmapInfoHeader :: struct #ordered {
size: u32, size: u32,
width, height: i32, width, height: i32,
planes, bit_count: i16, planes, bit_count: i16,
@@ -543,16 +531,16 @@ type BitmapInfoHeader struct #ordered {
clr_used: u32, clr_used: u32,
clr_important: u32, clr_important: u32,
} }
type BitmapInfo struct #ordered { BitmapInfo :: struct #ordered {
using header: BitmapInfoHeader, using header: BitmapInfoHeader,
colors: [1]RgbQuad, colors: [1]RgbQuad,
} }
type RgbQuad struct #ordered { blue, green, red, reserved: u8 } RgbQuad :: struct #ordered { blue, green, red, reserved: u8 }
type KeyCode enum i32 { KeyCode :: enum i32 {
Lbutton = 0x01, Lbutton = 0x01,
Rbutton = 0x02, Rbutton = 0x02,
Cancel = 0x03, Cancel = 0x03,
+18 -18
View File
@@ -8,91 +8,91 @@ proc is_signed(info: ^TypeInfo) -> bool {
} }
proc is_integer(info: ^TypeInfo) -> bool { proc is_integer(info: ^TypeInfo) -> bool {
if info == nil { return false; } if info == nil { return false; }
var _, ok = type_info_base(info).(^TypeInfo.Integer); _, ok := type_info_base(info).(^TypeInfo.Integer);
return ok; return ok;
} }
proc is_float(info: ^TypeInfo) -> bool { proc is_float(info: ^TypeInfo) -> bool {
if info == nil { return false; } if info == nil { return false; }
var _, ok = type_info_base(info).(^TypeInfo.Float); _, ok := type_info_base(info).(^TypeInfo.Float);
return ok; return ok;
} }
proc is_complex(info: ^TypeInfo) -> bool { proc is_complex(info: ^TypeInfo) -> bool {
if info == nil { return false; } if info == nil { return false; }
var _, ok = type_info_base(info).(^TypeInfo.Complex); _, ok := type_info_base(info).(^TypeInfo.Complex);
return ok; return ok;
} }
proc is_any(info: ^TypeInfo) -> bool { proc is_any(info: ^TypeInfo) -> bool {
if info == nil { return false; } if info == nil { return false; }
var _, ok = type_info_base(info).(^TypeInfo.Any); _, ok := type_info_base(info).(^TypeInfo.Any);
return ok; return ok;
} }
proc is_string(info: ^TypeInfo) -> bool { proc is_string(info: ^TypeInfo) -> bool {
if info == nil { return false; } if info == nil { return false; }
var _, ok = type_info_base(info).(^TypeInfo.String); _, ok := type_info_base(info).(^TypeInfo.String);
return ok; return ok;
} }
proc is_boolean(info: ^TypeInfo) -> bool { proc is_boolean(info: ^TypeInfo) -> bool {
if info == nil { return false; } if info == nil { return false; }
var _, ok = type_info_base(info).(^TypeInfo.Boolean); _, ok := type_info_base(info).(^TypeInfo.Boolean);
return ok; return ok;
} }
proc is_pointer(info: ^TypeInfo) -> bool { proc is_pointer(info: ^TypeInfo) -> bool {
if info == nil { return false; } if info == nil { return false; }
var _, ok = type_info_base(info).(^TypeInfo.Pointer); _, ok := type_info_base(info).(^TypeInfo.Pointer);
return ok; return ok;
} }
proc is_procedure(info: ^TypeInfo) -> bool { proc is_procedure(info: ^TypeInfo) -> bool {
if info == nil { return false; } if info == nil { return false; }
var _, ok = type_info_base(info).(^TypeInfo.Procedure); _, ok := type_info_base(info).(^TypeInfo.Procedure);
return ok; return ok;
} }
proc is_array(info: ^TypeInfo) -> bool { proc is_array(info: ^TypeInfo) -> bool {
if info == nil { return false; } if info == nil { return false; }
var _, ok = type_info_base(info).(^TypeInfo.Array); _, ok := type_info_base(info).(^TypeInfo.Array);
return ok; return ok;
} }
proc is_dynamic_array(info: ^TypeInfo) -> bool { proc is_dynamic_array(info: ^TypeInfo) -> bool {
if info == nil { return false; } if info == nil { return false; }
var _, ok = type_info_base(info).(^TypeInfo.DynamicArray); _, ok := type_info_base(info).(^TypeInfo.DynamicArray);
return ok; return ok;
} }
proc is_dynamic_map(info: ^TypeInfo) -> bool { proc is_dynamic_map(info: ^TypeInfo) -> bool {
if info == nil { return false; } if info == nil { return false; }
var _, ok = type_info_base(info).(^TypeInfo.Map); _, ok := type_info_base(info).(^TypeInfo.Map);
return ok; return ok;
} }
proc is_slice(info: ^TypeInfo) -> bool { proc is_slice(info: ^TypeInfo) -> bool {
if info == nil { return false; } if info == nil { return false; }
var _, ok = type_info_base(info).(^TypeInfo.Slice); _, ok := type_info_base(info).(^TypeInfo.Slice);
return ok; return ok;
} }
proc is_vector(info: ^TypeInfo) -> bool { proc is_vector(info: ^TypeInfo) -> bool {
if info == nil { return false; } if info == nil { return false; }
var _, ok = type_info_base(info).(^TypeInfo.Vector); _, ok := type_info_base(info).(^TypeInfo.Vector);
return ok; return ok;
} }
proc is_tuple(info: ^TypeInfo) -> bool { proc is_tuple(info: ^TypeInfo) -> bool {
if info == nil { return false; } if info == nil { return false; }
var _, ok = type_info_base(info).(^TypeInfo.Tuple); _, ok := type_info_base(info).(^TypeInfo.Tuple);
return ok; return ok;
} }
proc is_struct(info: ^TypeInfo) -> bool { proc is_struct(info: ^TypeInfo) -> bool {
if info == nil { return false; } if info == nil { return false; }
var _, ok = type_info_base(info).(^TypeInfo.Struct); _, ok := type_info_base(info).(^TypeInfo.Struct);
return ok; return ok;
} }
proc is_union(info: ^TypeInfo) -> bool { proc is_union(info: ^TypeInfo) -> bool {
if info == nil { return false; } if info == nil { return false; }
var _, ok = type_info_base(info).(^TypeInfo.Union); _, ok := type_info_base(info).(^TypeInfo.Union);
return ok; return ok;
} }
proc is_raw_union(info: ^TypeInfo) -> bool { proc is_raw_union(info: ^TypeInfo) -> bool {
if info == nil { return false; } if info == nil { return false; }
var _, ok = type_info_base(info).(^TypeInfo.RawUnion); _, ok := type_info_base(info).(^TypeInfo.RawUnion);
return ok; return ok;
} }
proc is_enum(info: ^TypeInfo) -> bool { proc is_enum(info: ^TypeInfo) -> bool {
if info == nil { return false; } if info == nil { return false; }
var _, ok = type_info_base(info).(^TypeInfo.Enum); _, ok := type_info_base(info).(^TypeInfo.Enum);
return ok; return ok;
} }
+10 -11
View File
@@ -1,12 +1,11 @@
const ( REPLACEMENT_CHAR :: '\uFFFD';
REPLACEMENT_CHAR = '\uFFFD'; MAX_RUNE :: '\U0010FFFF';
MAX_RUNE = '\U0010FFFF';
_surr1 :: 0xd800;
_surr2 :: 0xdc00;
_surr3 :: 0xe000;
_surr_self :: 0x10000;
_surr1 = 0xd800;
_surr2 = 0xdc00;
_surr3 = 0xe000;
_surr_self = 0x10000;
)
proc is_surrogate(r: rune) -> bool { proc is_surrogate(r: rune) -> bool {
return _surr1 <= r && r < _surr3; return _surr1 <= r && r < _surr3;
@@ -29,14 +28,14 @@ proc encode_surrogate_pair(r: rune) -> (r1, r2: rune) {
} }
proc encode(d: []u16, s: []rune) { proc encode(d: []u16, s: []rune) {
var n = len(s); n := len(s);
for r in s { for r in s {
if r >= _surr_self { if r >= _surr_self {
n++; n++;
} }
} }
var max_n = min(len(d), n); max_n := min(len(d), n);
n = 0; n = 0;
for r in s { for r in s {
@@ -46,7 +45,7 @@ proc encode(d: []u16, s: []rune) {
n++; n++;
case _surr_self..MAX_RUNE: case _surr_self..MAX_RUNE:
var r1, r2 = encode_surrogate_pair(r); r1, r2 := encode_surrogate_pair(r);
d[n] = u16(r1); d[n] = u16(r1);
d[n+1] = u16(r2); d[n+1] = u16(r2);
n += 2; n += 2;
+60 -64
View File
@@ -1,39 +1,36 @@
const ( RUNE_ERROR :: '\ufffd';
RUNE_ERROR = '\ufffd'; RUNE_SELF :: 0x80;
RUNE_SELF = 0x80; RUNE_BOM :: 0xfeff;
RUNE_BOM = 0xfeff; RUNE_EOF :: ~rune(0);
RUNE_EOF = ~rune(0); MAX_RUNE :: '\U0010ffff';
MAX_RUNE = '\U0010ffff'; UTF_MAX :: 4;
UTF_MAX = 4;
SURROGATE_MIN = 0xd800; SURROGATE_MIN :: 0xd800;
SURROGATE_MAX = 0xdfff; SURROGATE_MAX :: 0xdfff;
T1 = 0b0000_0000; T1 :: 0b0000_0000;
TX = 0b1000_0000; TX :: 0b1000_0000;
T2 = 0b1100_0000; T2 :: 0b1100_0000;
T3 = 0b1110_0000; T3 :: 0b1110_0000;
T4 = 0b1111_0000; T4 :: 0b1111_0000;
T5 = 0b1111_1000; T5 :: 0b1111_1000;
MASKX = 0b0011_1111; MASKX :: 0b0011_1111;
MASK2 = 0b0001_1111; MASK2 :: 0b0001_1111;
MASK3 = 0b0000_1111; MASK3 :: 0b0000_1111;
MASK4 = 0b0000_0111; MASK4 :: 0b0000_0111;
RUNE1_MAX = 1<<7 - 1; RUNE1_MAX :: 1<<7 - 1;
RUNE2_MAX = 1<<11 - 1; RUNE2_MAX :: 1<<11 - 1;
RUNE3_MAX = 1<<16 - 1; RUNE3_MAX :: 1<<16 - 1;
// The default lowest and highest continuation byte. // The default lowest and highest continuation byte.
LOCB = 0b1000_0000; LOCB :: 0b1000_0000;
HICB = 0b1011_1111; HICB :: 0b1011_1111;
)
type AcceptRange struct { lo, hi: u8 } AcceptRange :: struct { lo, hi: u8 }
var ( accept_ranges := [5]AcceptRange{
accept_ranges = [5]AcceptRange{
{0x80, 0xbf}, {0x80, 0xbf},
{0xa0, 0xbf}, {0xa0, 0xbf},
{0x80, 0x9f}, {0x80, 0x9f},
@@ -41,7 +38,7 @@ var (
{0x80, 0x8f}, {0x80, 0x8f},
}; };
accept_sizes = [256]u8{ accept_sizes := [256]u8{
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x00-0x0f 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x00-0x0f
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x10-0x1f 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x10-0x1f
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x20-0x2f 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x20-0x2f
@@ -60,12 +57,11 @@ var (
0x13, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x23, 0x03, 0x03, // 0xe0-0xef 0x13, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x23, 0x03, 0x03, // 0xe0-0xef
0x34, 0x04, 0x04, 0x04, 0x44, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, // 0xf0-0xff 0x34, 0x04, 0x04, 0x04, 0x44, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, // 0xf0-0xff
}; };
)
proc encode_rune(r: rune) -> ([4]u8, int) { proc encode_rune(r: rune) -> ([4]u8, int) {
var buf: [4]u8; buf: [4]u8;
var i = u32(r); i := u32(r);
const mask: u8 = 0x3f; mask: u8 : 0x3f;
if i <= 1<<7-1 { if i <= 1<<7-1 {
buf[0] = u8(r); buf[0] = u8(r);
return buf, 1; return buf, 1;
@@ -98,36 +94,36 @@ proc encode_rune(r: rune) -> ([4]u8, int) {
proc decode_rune(s: string) -> (rune, int) #inline { return decode_rune([]u8(s)); } proc decode_rune(s: string) -> (rune, int) #inline { return decode_rune([]u8(s)); }
proc decode_rune(s: []u8) -> (rune, int) { proc decode_rune(s: []u8) -> (rune, int) {
var n = len(s); n := len(s);
if n < 1 { if n < 1 {
return RUNE_ERROR, 0; return RUNE_ERROR, 0;
} }
var s0 = s[0]; s0 := s[0];
var x = accept_sizes[s0]; x := accept_sizes[s0];
if x >= 0xF0 { if x >= 0xF0 {
var mask = rune(x) << 31 >> 31; // NOTE(bill): Create 0x0000 or 0xffff. mask := rune(x) << 31 >> 31; // NOTE(bill): Create 0x0000 or 0xffff.
return rune(s[0])&~mask | RUNE_ERROR&mask, 1; return rune(s[0])&~mask | RUNE_ERROR&mask, 1;
} }
var sz = x & 7; sz := x & 7;
var accept = accept_ranges[x>>4]; accept := accept_ranges[x>>4];
if n < int(sz) { if n < int(sz) {
return RUNE_ERROR, 1; return RUNE_ERROR, 1;
} }
var b1 = s[1]; b1 := s[1];
if b1 < accept.lo || accept.hi < b1 { if b1 < accept.lo || accept.hi < b1 {
return RUNE_ERROR, 1; return RUNE_ERROR, 1;
} }
if sz == 2 { if sz == 2 {
return rune(s0&MASK2)<<6 | rune(b1&MASKX), 2; return rune(s0&MASK2)<<6 | rune(b1&MASKX), 2;
} }
var b2 = s[2]; b2 := s[2];
if b2 < LOCB || HICB < b2 { if b2 < LOCB || HICB < b2 {
return RUNE_ERROR, 1; return RUNE_ERROR, 1;
} }
if sz == 3 { if sz == 3 {
return rune(s0&MASK3)<<12 | rune(b1&MASKX)<<6 | rune(b2&MASKX), 3; return rune(s0&MASK3)<<12 | rune(b1&MASKX)<<6 | rune(b2&MASKX), 3;
} }
var b3 = s[3]; b3 := s[3];
if b3 < LOCB || HICB < b3 { if b3 < LOCB || HICB < b3 {
return RUNE_ERROR, 1; return RUNE_ERROR, 1;
} }
@@ -138,9 +134,9 @@ proc decode_rune(s: []u8) -> (rune, int) {
proc decode_last_rune(s: string) -> (rune, int) #inline { return decode_last_rune([]u8(s)); } proc decode_last_rune(s: string) -> (rune, int) #inline { return decode_last_rune([]u8(s)); }
proc decode_last_rune(s: []u8) -> (rune, int) { proc decode_last_rune(s: []u8) -> (rune, int) {
var r: rune; r: rune;
var size: int; size: int;
var start, end, limit: int; start, end, limit: int;
end = len(s); end = len(s);
if end == 0 { if end == 0 {
@@ -187,31 +183,31 @@ proc valid_rune(r: rune) -> bool {
} }
proc valid_string(s: string) -> bool { proc valid_string(s: string) -> bool {
var n = len(s); n := len(s);
for var i = 0; i < n; { for i := 0; i < n; {
var si = s[i]; si := s[i];
if si < RUNE_SELF { // ascii if si < RUNE_SELF { // ascii
i++; i++;
continue; continue;
} }
var x = accept_sizes[si]; x := accept_sizes[si];
if x == 0xf1 { if x == 0xf1 {
return false; return false;
} }
var size = int(x & 7); size := int(x & 7);
if i+size > n { if i+size > n {
return false; return false;
} }
var ar = accept_ranges[x>>4]; ar := accept_ranges[x>>4];
if var b = s[i+1]; b < ar.lo || ar.hi < b { if b := s[i+1]; b < ar.lo || ar.hi < b {
return false; return false;
} else if size == 2 { } else if size == 2 {
// Okay // Okay
} else if var b = s[i+2]; b < 0x80 || 0xbf < b { } else if b := s[i+2]; b < 0x80 || 0xbf < b {
return false; return false;
} else if size == 3 { } else if size == 3 {
// Okay // Okay
} else if var b = s[i+3]; b < 0x80 || 0xbf < b { } else if b := s[i+3]; b < 0x80 || 0xbf < b {
return false; return false;
} }
i += size; i += size;
@@ -223,36 +219,36 @@ proc rune_start(b: u8) -> bool #inline { return b&0xc0 != 0x80; }
proc rune_count(s: string) -> int #inline { return rune_count([]u8(s)); } proc rune_count(s: string) -> int #inline { return rune_count([]u8(s)); }
proc rune_count(s: []u8) -> int { proc rune_count(s: []u8) -> int {
var count = 0; count := 0;
var n = len(s); n := len(s);
for var i = 0; i < n; { for i := 0; i < n; {
defer count++; defer count++;
var si = s[i]; si := s[i];
if si < RUNE_SELF { // ascii if si < RUNE_SELF { // ascii
i++; i++;
continue; continue;
} }
var x = accept_sizes[si]; x := accept_sizes[si];
if x == 0xf1 { if x == 0xf1 {
i++; i++;
continue; continue;
} }
var size = int(x & 7); size := int(x & 7);
if i+size > n { if i+size > n {
i++; i++;
continue; continue;
} }
var ar = accept_ranges[x>>4]; ar := accept_ranges[x>>4];
if var b = s[i+1]; b < ar.lo || ar.hi < b { if b := s[i+1]; b < ar.lo || ar.hi < b {
size = 1; size = 1;
} else if size == 2 { } else if size == 2 {
// Okay // Okay
} else if var b = s[i+2]; b < 0x80 || 0xbf < b { } else if b := s[i+2]; b < 0x80 || 0xbf < b {
size = 1; size = 1;
} else if size == 3 { } else if size == 3 {
// Okay // Okay
} else if var b = s[i+3]; b < 0x80 || 0xbf < b { } else if b := s[i+3]; b < 0x80 || 0xbf < b {
size = 1; size = 1;
} }
i += size; i += size;
+5
View File
@@ -2219,6 +2219,11 @@ Type *check_type(Checker *c, AstNode *e, Type *named_type) {
} }
} }
if (is_type_gen_proc(type)) {
error(e, "Invalid use of polymorphic procedure type");
type = t_invalid;
}
if (is_type_typed(type)) { if (is_type_typed(type)) {
add_type_and_value(&c->info, e, Addressing_Type, type, empty_exact_value); add_type_and_value(&c->info, e, Addressing_Type, type, empty_exact_value);
} else { } else {
+16 -3
View File
@@ -1871,6 +1871,15 @@ bool is_semicolon_optional_for_node(AstFile *f, AstNode *s) {
case AstNode_ProcDecl: case AstNode_ProcDecl:
return s->ProcDecl.body != NULL; return s->ProcDecl.body != NULL;
case AstNode_ValueDecl:
if (s->ValueDecl.is_mutable) {
return false;
}
if (s->ValueDecl.values.count > 0) {
return is_semicolon_optional_for_node(f, s->ValueDecl.values[s->ValueDecl.values.count-1]);
}
break;
case AstNode_GenDecl: case AstNode_GenDecl:
if (s->GenDecl.close.pos.line != 0) { if (s->GenDecl.close.pos.line != 0) {
return true; return true;
@@ -3149,7 +3158,11 @@ AstNode *parse_value_decl(AstFile *f, Array<AstNode *> names, CommentGroup docs)
} }
if (f->expr_level >= 0) { if (f->expr_level >= 0) {
expect_semicolon(f, NULL); AstNode *end = NULL;
if (!is_mutable && values.count > 0) {
end = values[values.count-1];
}
expect_semicolon(f, end);
} }
return ast_value_decl(f, names, type, values, is_mutable, docs, f->line_comment); return ast_value_decl(f, names, type, values, is_mutable, docs, f->line_comment);
@@ -4317,8 +4330,8 @@ AstNode *parse_stmt(AstFile *f) {
expect_semicolon(f, s); expect_semicolon(f, s);
return s; return s;
case Token_var: // case Token_var:
case Token_const: // case Token_const:
case Token_proc: case Token_proc:
case Token_type: case Token_type:
case Token_import: case Token_import: