mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-07 16:18:52 +00:00
Disable var and const declarations
This commit is contained in:
+53
-35
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
+6
-6
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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--;
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||||
|
|||||||
@@ -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
@@ -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:
|
||||||
|
|||||||
Reference in New Issue
Block a user