diff --git a/code/demo.odin b/code/demo.odin index 9a16c56c2..b1d7dd426 100644 --- a/code/demo.odin +++ b/code/demo.odin @@ -1,13 +1,13 @@ -import "atomic.odin"; -import "fmt.odin"; -import "hash.odin"; -import "math.odin"; -import "mem.odin"; -import "opengl.odin"; -import "os.odin"; -import "sync.odin"; -import "utf8.odin"; -import win32 "sys/windows.odin"; +#import "atomic.odin"; +#import "fmt.odin"; +#import "hash.odin"; +#import "math.odin"; +#import "mem.odin"; +#import "opengl.odin"; +#import "os.odin"; +#import "sync.odin"; +#import "utf8.odin"; +#import win32 "sys/windows.odin"; Thing :: enum f64 { _, // Ignore first value @@ -15,11 +15,8 @@ Thing :: enum f64 { B, C, D, -}; +} main :: proc() { fmt.println(Thing.A, Thing.B, Thing.C, Thing.D); - - x := 123; - fmt.println(x); } diff --git a/core/_preload.odin b/core/_preload.odin index 78de6d2e0..28494f53d 100644 --- a/core/_preload.odin +++ b/core/_preload.odin @@ -1,8 +1,8 @@ #shared_global_scope; -import "os.odin"; -import "fmt.odin"; -import "mem.odin"; +#import "os.odin"; +#import "fmt.odin"; +#import "mem.odin"; // IMPORTANT NOTE(bill): `type_info` & `type_info_val` cannot be used within a // #shared_global_scope due to the internals of the compiler. @@ -13,71 +13,71 @@ import "mem.odin"; // IMPORTANT NOTE(bill): Do not change the order of any of this data // The compiler relies upon this _exact_ order Type_Info_Member :: struct #ordered { - name string; // can be empty if tuple - type_info ^Type_Info; - offset int; // offsets are not used in tuples + name: string; // can be empty if tuple + type_info: ^Type_Info; + offset: int; // offsets are not used in tuples } Type_Info_Record :: struct #ordered { - fields []Type_Info_Member; - size int; // in bytes - align int; // in bytes - packed bool; - ordered bool; + fields: []Type_Info_Member; + size: int; // in bytes + align: int; // in bytes + packed: bool; + ordered: bool; } Type_Info :: union { - Named struct #ordered { - name string; - base ^Type_Info; // This will _not_ be a Type_Info.Named + Named: struct #ordered { + name: string; + base: ^Type_Info; // This will _not_ be a Type_Info.Named }; - Integer struct #ordered { - size int; // in bytes - signed bool; + Integer: struct #ordered { + size: int; // in bytes + signed: bool; }; - Float struct #ordered { - size int; // in bytes + Float: struct #ordered { + size: int; // in bytes }; - Any struct #ordered {}; - String struct #ordered {}; - Boolean struct #ordered {}; - Pointer struct #ordered { - elem ^Type_Info; // nil -> rawptr + Any: struct #ordered {}; + String: struct #ordered {}; + Boolean: struct #ordered {}; + Pointer: struct #ordered { + elem: ^Type_Info; // nil -> rawptr }; - Maybe struct #ordered { - elem ^Type_Info; + Maybe: struct #ordered { + elem: ^Type_Info; }; - Procedure struct #ordered { - params ^Type_Info; // Type_Info.Tuple - results ^Type_Info; // Type_Info.Tuple - variadic bool; + Procedure: struct #ordered { + params: ^Type_Info; // Type_Info.Tuple + results: ^Type_Info; // Type_Info.Tuple + variadic: bool; }; - Array struct #ordered { - elem ^Type_Info; - elem_size int; - count int; + Array: struct #ordered { + elem: ^Type_Info; + elem_size: int; + count: int; }; - Slice struct #ordered { - elem ^Type_Info; - elem_size int; + Slice: struct #ordered { + elem: ^Type_Info; + elem_size: int; }; - Vector struct #ordered { - elem ^Type_Info; - elem_size int; - count int; - align int; + Vector: struct #ordered { + elem: ^Type_Info; + elem_size: int; + count: int; + align: int; }; - Tuple Type_Info_Record; - Struct Type_Info_Record; - Union Type_Info_Record; - Raw_Union Type_Info_Record; - Enum struct #ordered { - base ^Type_Info; - names []string; + Tuple: Type_Info_Record; + Struct: Type_Info_Record; + Union: Type_Info_Record; + Raw_Union: Type_Info_Record; + Enum: struct #ordered { + base: ^Type_Info; + names: []string; // TODO(bill): store values some how. Maybe using a raw_union }; } -type_info_base :: proc(info ^Type_Info) -> ^Type_Info { +type_info_base :: proc(info: ^Type_Info) -> ^Type_Info { if info == nil { return nil; } @@ -91,22 +91,22 @@ type_info_base :: proc(info ^Type_Info) -> ^Type_Info { -assume :: proc(cond bool) #foreign "llvm.assume" +assume :: proc(cond: bool) #foreign "llvm.assume" __debug_trap :: proc() #foreign "llvm.debugtrap" __trap :: proc() #foreign "llvm.trap" read_cycle_counter :: proc() -> u64 #foreign "llvm.readcyclecounter" -bit_reverse16 :: proc(b u16) -> u16 #foreign "llvm.bitreverse.i16" -bit_reverse32 :: proc(b u32) -> u32 #foreign "llvm.bitreverse.i32" -bit_reverse64 :: proc(b u64) -> u64 #foreign "llvm.bitreverse.i64" +bit_reverse16 :: proc(b: u16) -> u16 #foreign "llvm.bitreverse.i16" +bit_reverse32 :: proc(b: u32) -> u32 #foreign "llvm.bitreverse.i32" +bit_reverse64 :: proc(b: u64) -> u64 #foreign "llvm.bitreverse.i64" -byte_swap16 :: proc(b u16) -> u16 #foreign "llvm.bswap.i16" -byte_swap32 :: proc(b u32) -> u32 #foreign "llvm.bswap.i32" -byte_swap64 :: proc(b u64) -> u64 #foreign "llvm.bswap.i64" +byte_swap16 :: proc(b: u16) -> u16 #foreign "llvm.bswap.i16" +byte_swap32 :: proc(b: u32) -> u32 #foreign "llvm.bswap.i32" +byte_swap64 :: proc(b: u64) -> u64 #foreign "llvm.bswap.i64" -fmuladd32 :: proc(a, b, c f32) -> f32 #foreign "llvm.fmuladd.f32" -fmuladd64 :: proc(a, b, c f64) -> f64 #foreign "llvm.fmuladd.f64" +fmuladd32 :: proc(a, b, c: f32) -> f32 #foreign "llvm.fmuladd.f32" +fmuladd64 :: proc(a, b, c: f64) -> f64 #foreign "llvm.fmuladd.f64" @@ -119,21 +119,21 @@ Allocator_Mode :: enum u8 { FREE_ALL, RESIZE, } -Allocator_Proc :: type proc(allocator_data rawptr, mode Allocator_Mode, - size, alignment int, - old_memory rawptr, old_size int, flags u64) -> rawptr; +Allocator_Proc :: type proc(allocator_data: rawptr, mode: Allocator_Mode, + size, alignment: int, + old_memory: rawptr, old_size: int, flags: u64) -> rawptr; Allocator :: struct #ordered { - procedure Allocator_Proc; - data rawptr; + procedure: Allocator_Proc; + data: rawptr; } Context :: struct #ordered { - thread_id int; + thread_id: int; - allocator Allocator; + allocator: Allocator; - user_data rawptr; - user_index int; + user_data: rawptr; + user_index: int; } #thread_local __context: Context; @@ -142,7 +142,7 @@ Context :: struct #ordered { DEFAULT_ALIGNMENT :: align_of([vector 4]f32); -__check_context:: proc() { +__check_context :: proc() { c := ^__context; if c.allocator.procedure == nil { @@ -153,30 +153,30 @@ __check_context:: proc() { } } -alloc:: proc(size int) -> rawptr #inline { return alloc_align(size, DEFAULT_ALIGNMENT); } +alloc :: proc(size: int) -> rawptr #inline { return alloc_align(size, DEFAULT_ALIGNMENT); } -alloc_align:: proc(size, alignment int) -> rawptr #inline { +alloc_align :: proc(size, alignment: int) -> rawptr #inline { __check_context(); a := context.allocator; return a.procedure(a.data, Allocator_Mode.ALLOC, size, alignment, nil, 0, 0); } -free:: proc(ptr rawptr) #inline { +free :: proc(ptr: rawptr) #inline { __check_context(); a := context.allocator; if ptr != nil { a.procedure(a.data, Allocator_Mode.FREE, 0, 0, ptr, 0, 0); } } -free_all:: proc() #inline { +free_all :: proc() #inline { __check_context(); a := context.allocator; a.procedure(a.data, Allocator_Mode.FREE_ALL, 0, 0, nil, 0, 0); } -resize:: proc (ptr rawptr, old_size, new_size int) -> rawptr #inline { return resize_align(ptr, old_size, new_size, DEFAULT_ALIGNMENT); } -resize_align:: proc(ptr rawptr, old_size, new_size, alignment int) -> rawptr #inline { +resize :: proc(ptr: rawptr, old_size, new_size: int) -> rawptr #inline { return resize_align(ptr, old_size, new_size, DEFAULT_ALIGNMENT); } +resize_align :: proc(ptr: rawptr, old_size, new_size, alignment: int) -> rawptr #inline { __check_context(); a := context.allocator; return a.procedure(a.data, Allocator_Mode.RESIZE, new_size, alignment, ptr, old_size, 0); @@ -184,7 +184,7 @@ resize_align:: proc(ptr rawptr, old_size, new_size, alignment int) -> rawptr #in -default_resize_align:: proc(old_memory rawptr, old_size, new_size, alignment int) -> rawptr { +default_resize_align :: proc(old_memory: rawptr, old_size, new_size, alignment: int) -> rawptr { if old_memory == nil { return alloc_align(new_size, alignment); } @@ -209,9 +209,9 @@ default_resize_align:: proc(old_memory rawptr, old_size, new_size, alignment int } -default_allocator_proc:: proc(allocator_data rawptr, mode Allocator_Mode, - size, alignment int, - old_memory rawptr, old_size int, flags u64) -> rawptr { +default_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, + size, alignment: int, + old_memory: rawptr, old_size: int, flags: u64) -> rawptr { using Allocator_Mode; when false { @@ -259,7 +259,7 @@ default_allocator_proc:: proc(allocator_data rawptr, mode Allocator_Mode, return nil; } -default_allocator:: proc() -> Allocator { +default_allocator :: proc() -> Allocator { return Allocator{ procedure = default_allocator_proc, data = nil, @@ -276,7 +276,7 @@ default_allocator:: proc() -> Allocator { -__string_eq:: proc(a, b string) -> bool { +__string_eq :: proc(a, b: string) -> bool { if a.count != b.count { return false; } @@ -286,24 +286,24 @@ __string_eq:: proc(a, b string) -> bool { return mem.compare(a.data, b.data, a.count) == 0; } -__string_cmp:: proc(a, b string) -> int { +__string_cmp :: proc(a, b: string) -> int { return mem.compare(a.data, b.data, min(a.count, b.count)); } -__string_ne:: proc(a, b string) -> bool #inline { return !__string_eq(a, b); } -__string_lt:: proc(a, b string) -> bool #inline { return __string_cmp(a, b) < 0; } -__string_gt:: proc(a, b string) -> bool #inline { return __string_cmp(a, b) > 0; } -__string_le:: proc(a, b string) -> bool #inline { return __string_cmp(a, b) <= 0; } -__string_ge:: proc(a, b string) -> bool #inline { return __string_cmp(a, b) >= 0; } +__string_ne :: proc(a, b: string) -> bool #inline { return !__string_eq(a, b); } +__string_lt :: proc(a, b: string) -> bool #inline { return __string_cmp(a, b) < 0; } +__string_gt :: proc(a, b: string) -> bool #inline { return __string_cmp(a, b) > 0; } +__string_le :: proc(a, b: string) -> bool #inline { return __string_cmp(a, b) <= 0; } +__string_ge :: proc(a, b: string) -> bool #inline { return __string_cmp(a, b) >= 0; } -__assert:: proc(file string, line, column int, msg string) #inline { +__assert :: proc(file: string, line, column: int, msg: string) #inline { fmt.fprintf(os.stderr, "%(%:%) Runtime assertion: %\n", file, line, column, msg); __debug_trap(); } -__bounds_check_error:: proc(file string, line, column int, index, count int) { +__bounds_check_error :: proc(file: string, line, column: int, index, count: int) { if 0 <= index && index < count { return; } @@ -312,7 +312,7 @@ __bounds_check_error:: proc(file string, line, column int, index, count int) { __debug_trap(); } -__slice_expr_error:: proc(file string, line, column int, low, high, max int) { +__slice_expr_error :: proc(file: string, line, column: int, low, high, max: int) { if 0 <= low && low <= high && high <= max { return; } @@ -320,7 +320,7 @@ __slice_expr_error:: proc(file string, line, column int, low, high, max int) { file, line, column, low, high, max); __debug_trap(); } -__substring_expr_error:: proc(file string, line, column int, low, high int) { +__substring_expr_error :: proc(file: string, line, column: int, low, high: int) { if 0 <= low && low <= high { return; } diff --git a/core/atomic.odin b/core/atomic.odin index 5fa50a649..d41685d6b 100644 --- a/core/atomic.odin +++ b/core/atomic.odin @@ -1,7 +1,7 @@ // TODO(bill): Use assembly instead here to implement atomics // Inline vs external file? -import win32 "sys/windows.odin" when ODIN_OS == "windows"; +#import win32 "sys/windows.odin" when ODIN_OS == "windows"; _ := compile_assert(ODIN_ARCH == "amd64"); // TODO(bill): x86 version @@ -11,30 +11,30 @@ sfence :: proc() { win32.WriteBarrier(); } lfence :: proc() { win32.ReadBarrier(); } -load32 :: proc(a ^i32) -> i32 { +load32 :: proc(a: ^i32) -> i32 { return a^; } -store32 :: proc(a ^i32, value i32) { +store32 :: proc(a: ^i32, value: i32) { a^ = value; } -compare_exchange32 :: proc(a ^i32, expected, desired i32) -> i32 { +compare_exchange32 :: proc(a: ^i32, expected, desired: i32) -> i32 { return win32.InterlockedCompareExchange(a, desired, expected); } -exchanged32 :: proc(a ^i32, desired i32) -> i32 { +exchanged32 :: proc(a: ^i32, desired: i32) -> i32 { return win32.InterlockedExchange(a, desired); } -fetch_add32 :: proc(a ^i32, operand i32) -> i32 { +fetch_add32 :: proc(a: ^i32, operand: i32) -> i32 { return win32.InterlockedExchangeAdd(a, operand); } -fetch_and32 :: proc(a ^i32, operand i32) -> i32 { +fetch_and32 :: proc(a: ^i32, operand: i32) -> i32 { return win32.InterlockedAnd(a, operand); } -fetch_or32 :: proc(a ^i32, operand i32) -> i32 { +fetch_or32 :: proc(a: ^i32, operand: i32) -> i32 { return win32.InterlockedOr(a, operand); } -spin_lock32 :: proc(a ^i32, time_out int) -> bool { // NOTE(bill) time_out = -1 as default +spin_lock32 :: proc(a: ^i32, time_out: int) -> bool { // NOTE(bill) time_out = -1 as default old_value := compare_exchange32(a, 1, 0); counter := 0; for old_value != 0 && (time_out < 0 || counter < time_out) { @@ -45,11 +45,11 @@ spin_lock32 :: proc(a ^i32, time_out int) -> bool { // NOTE(bill) time_out = -1 } return old_value == 0; } -spin_unlock32 :: proc(a ^i32) { +spin_unlock32 :: proc(a: ^i32) { store32(a, 0); mfence(); } -try_acquire_lock32 :: proc(a ^i32) -> bool { +try_acquire_lock32 :: proc(a: ^i32) -> bool { yield_thread(); old_value := compare_exchange32(a, 1, 0); mfence(); @@ -57,28 +57,28 @@ try_acquire_lock32 :: proc(a ^i32) -> bool { } -load64 :: proc(a ^i64) -> i64 { +load64 :: proc(a: ^i64) -> i64 { return a^; } -store64 :: proc(a ^i64, value i64) { +store64 :: proc(a: ^i64, value: i64) { a^ = value; } -compare_exchange64 :: proc(a ^i64, expected, desired i64) -> i64 { +compare_exchange64 :: proc(a: ^i64, expected, desired: i64) -> i64 { return win32.InterlockedCompareExchange64(a, desired, expected); } -exchanged64 :: proc(a ^i64, desired i64) -> i64 { +exchanged64 :: proc(a: ^i64, desired: i64) -> i64 { return win32.InterlockedExchange64(a, desired); } -fetch_add64 :: proc(a ^i64, operand i64) -> i64 { +fetch_add64 :: proc(a: ^i64, operand: i64) -> i64 { return win32.InterlockedExchangeAdd64(a, operand); } -fetch_and64 :: proc(a ^i64, operand i64) -> i64 { +fetch_and64 :: proc(a: ^i64, operand: i64) -> i64 { return win32.InterlockedAnd64(a, operand); } -fetch_or64 :: proc(a ^i64, operand i64) -> i64 { +fetch_or64 :: proc(a: ^i64, operand: i64) -> i64 { return win32.InterlockedOr64(a, operand); } -spin_lock64 :: proc(a ^i64, time_out int) -> bool { // NOTE(bill) time_out = -1 as default +spin_lock64 :: proc(a: ^i64, time_out: int) -> bool { // NOTE(bill) time_out = -1 as default old_value := compare_exchange64(a, 1, 0); counter := 0; for old_value != 0 && (time_out < 0 || counter < time_out) { @@ -89,11 +89,11 @@ spin_lock64 :: proc(a ^i64, time_out int) -> bool { // NOTE(bill) time_out = -1 } return old_value == 0; } -spin_unlock64 :: proc(a ^i64) { +spin_unlock64 :: proc(a: ^i64) { store64(a, 0); mfence(); } -try_acquire_lock64 :: proc(a ^i64) -> bool { +try_acquire_lock64 :: proc(a: ^i64) -> bool { yield_thread(); old_value := compare_exchange64(a, 1, 0); mfence(); diff --git a/core/fmt.odin b/core/fmt.odin index 11afcf889..4fbb8b126 100644 --- a/core/fmt.odin +++ b/core/fmt.odin @@ -1,12 +1,10 @@ -import { - "os.odin"; - "mem.odin"; - "utf8.odin"; -} +#import "os.odin"; +#import "mem.odin"; +#import "utf8.odin"; PRINT_BUF_SIZE :: 1<<12; -fprint :: proc(fd os.Handle, args ..any) -> int { +fprint :: proc(fd: os.Handle, args: ..any) -> int { data: [PRINT_BUF_SIZE]byte; buf := data[:0]; bprint(^buf, ..args); @@ -14,14 +12,14 @@ fprint :: proc(fd os.Handle, args ..any) -> int { return buf.count; } -fprintln :: proc(fd os.Handle, args ..any) -> int { +fprintln :: proc(fd: os.Handle, args: ..any) -> int { data: [PRINT_BUF_SIZE]byte; buf := data[:0]; bprintln(^buf, ..args); os.write(fd, buf); return buf.count; } -fprintf :: proc(fd os.Handle, fmt string, args ..any) -> int { +fprintf :: proc(fd: os.Handle, fmt: string, args: ..any) -> int { data: [PRINT_BUF_SIZE]byte; buf := data[:0]; bprintf(^buf, fmt, ..args); @@ -30,19 +28,19 @@ fprintf :: proc(fd os.Handle, fmt string, args ..any) -> int { } -print :: proc(args ..any) -> int { +print :: proc(args: ..any) -> int { return fprint(os.stdout, ..args); } -println :: proc(args ..any) -> int { +println :: proc(args: ..any) -> int { return fprintln(os.stdout, ..args); } -printf :: proc(fmt string, args ..any) -> int { +printf :: proc(fmt: string, args: ..any) -> int { return fprintf(os.stdout, fmt, ..args); } -fprint_type :: proc(fd os.Handle, info ^Type_Info) { +fprint_type :: proc(fd: os.Handle, info: ^Type_Info) { data: [PRINT_BUF_SIZE]byte; buf := data[:0]; bprint_type(^buf, info); @@ -51,7 +49,7 @@ fprint_type :: proc(fd os.Handle, info ^Type_Info) { -print_byte_buffer :: proc(buf ^[]byte, b []byte) { +print_byte_buffer :: proc(buf: ^[]byte, b: []byte) { if buf.count < buf.capacity { n := min(buf.capacity-buf.count, b.count); if n > 0 { @@ -61,29 +59,29 @@ print_byte_buffer :: proc(buf ^[]byte, b []byte) { } } -bprint_string :: proc(buf ^[]byte, s string) { +bprint_string :: proc(buf: ^[]byte, s: string) { print_byte_buffer(buf, s as []byte); } -byte_reverse :: proc(b []byte) { +byte_reverse :: proc(b: []byte) { n := b.count; for i := 0; i < n/2; i++ { b[i], b[n-1-i] = b[n-1-i], b[i]; } } -bprint_rune :: proc(buf ^[]byte, r rune) { +bprint_rune :: proc(buf: ^[]byte, r: rune) { b, n := utf8.encode_rune(r); bprint_string(buf, b[:n] as string); } -bprint_space :: proc(buf ^[]byte) { bprint_rune(buf, ' '); } -bprint_nl :: proc (buf ^[]byte) { bprint_rune(buf, '\n'); } +bprint_space :: proc(buf: ^[]byte) { bprint_rune(buf, ' '); } +bprint_nl :: proc (buf: ^[]byte) { bprint_rune(buf, '\n'); } __NUM_TO_CHAR_TABLE := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz@$"; -bprint_bool :: proc(buffer ^[]byte, b bool) { +bprint_bool :: proc(buffer: ^[]byte, b: bool) { if b { bprint_string(buffer, "true"); } else { @@ -91,15 +89,15 @@ bprint_bool :: proc(buffer ^[]byte, b bool) { } } -bprint_pointer :: proc(buffer ^[]byte, p rawptr) #inline { +bprint_pointer :: proc(buffer: ^[]byte, p: rawptr) #inline { bprint_string(buffer, "0x"); bprint_u64(buffer, p as uint as u64); } -bprint_f16 :: proc (buffer ^[]byte, f f32) #inline { print__f64(buffer, f as f64, 4); } -bprint_f32 :: proc (buffer ^[]byte, f f32) #inline { print__f64(buffer, f as f64, 7); } -bprint_f64 :: proc (buffer ^[]byte, f f64) #inline { print__f64(buffer, f as f64, 16); } -bprint_u64 :: proc(buffer ^[]byte, value u64) { +// bprint_f16 :: proc (buffer: ^[]byte, f: f32) #inline { print__f64(buffer, f as f64, 4); } +bprint_f32 :: proc (buffer: ^[]byte, f: f32) #inline { print__f64(buffer, f as f64, 7); } +bprint_f64 :: proc (buffer: ^[]byte, f: f64) #inline { print__f64(buffer, f as f64, 16); } +bprint_u64 :: proc(buffer: ^[]byte, value: u64) { i := value; buf :[20]byte; len := 0; @@ -115,7 +113,7 @@ bprint_u64 :: proc(buffer ^[]byte, value u64) { byte_reverse(buf[:len]); bprint_string(buffer, buf[:len] as string); } -bprint_i64 :: proc(buffer ^[]byte, value i64) { +bprint_i64 :: proc(buffer: ^[]byte, value: i64) { // TODO(bill): Cleanup printing i := value; if i < 0 { @@ -126,14 +124,14 @@ bprint_i64 :: proc(buffer ^[]byte, value i64) { } /* -bprint_u128 :: proc(buffer ^[]byte, value u128) { +bprint_u128 :: proc(buffer: ^[]byte, value u128) { a := value transmute [2]u64; if a[1] != 0 { bprint_u64(buffer, a[1]); } bprint_u64(buffer, a[0]); } -bprint_i128 :: proc(buffer ^[]byte, value i128) { +bprint_i128 :: proc(buffer: ^[]byte, value i128) { i := value; if i < 0 { i = -i; @@ -144,7 +142,7 @@ bprint_i128 :: proc(buffer ^[]byte, value i128) { */ -print__f64 :: proc(buffer ^[]byte, value f64, decimal_places int) { +print__f64 :: proc(buffer: ^[]byte, value: f64, decimal_places: int) { f := value; if f == 0 { bprint_rune(buffer, '0'); @@ -170,7 +168,7 @@ print__f64 :: proc(buffer ^[]byte, value f64, decimal_places int) { } } -bprint_type :: proc(buf ^[]byte, ti ^Type_Info) { +bprint_type :: proc(buf: ^[]byte, ti: ^Type_Info) { if ti == nil { return; } @@ -302,14 +300,14 @@ bprint_type :: proc(buf ^[]byte, ti ^Type_Info) { } -make_any :: proc(type_info ^Type_Info, data rawptr) -> any { +make_any :: proc(type_info: ^Type_Info, data: rawptr) -> any { a :any; a.type_info = type_info; a.data = data; return a; } -bprint_any :: proc(buf ^[]byte, arg any) { +bprint_any :: proc(buf: ^[]byte, arg: any) { if arg.type_info == nil { bprint_string(buf, ""); return; @@ -423,7 +421,7 @@ bprint_any :: proc(buf ^[]byte, arg any) { } case Vector: - is_bool :: proc(type_info ^Type_Info) -> bool { + is_bool :: proc(type_info: ^Type_Info) -> bool { match type info : type_info { case Named: return is_bool(info.base); @@ -481,12 +479,12 @@ bprint_any :: proc(buf ^[]byte, arg any) { } -bprintf :: proc(buf ^[]byte, fmt string, args ..any) -> int { - is_digit :: proc(r rune) -> bool #inline { +bprintf :: proc(buf: ^[]byte, fmt: string, args: ..any) -> int { + is_digit :: proc(r: rune) -> bool #inline { return '0' <= r && r <= '9'; } - parse_int :: proc(s string, offset int) -> (int, int) { + parse_int :: proc(s: string, offset: int) -> (int, int) { result := 0; for ; offset < s.count; offset++ { @@ -546,8 +544,8 @@ bprintf :: proc(buf ^[]byte, fmt string, args ..any) -> int { } -bprint :: proc(buf ^[]byte, args ..any) -> int { - is_type_string :: proc(info ^Type_Info) -> bool { +bprint :: proc(buf: ^[]byte, args: ..any) -> int { + is_type_string :: proc(info: ^Type_Info) -> bool { using Type_Info; if info == nil { return false; @@ -574,7 +572,7 @@ bprint :: proc(buf ^[]byte, args ..any) -> int { return buf.count; } -bprintln :: proc(buf ^[]byte, args ..any) -> int { +bprintln :: proc(buf: ^[]byte, args: ..any) -> int { for i := 0; i < args.count; i++ { if i > 0 { append(buf, ' '); diff --git a/core/hash.odin b/core/hash.odin index dd579b89d..372a7cd4a 100644 --- a/core/hash.odin +++ b/core/hash.odin @@ -1,4 +1,4 @@ -crc32 :: proc(data rawptr, len int) -> u32 { +crc32 :: proc(data: rawptr, len: int) -> u32 { result := ~(0 as u32); s := slice_ptr(data as ^u8, len); for i := 0; i < len; i++ { @@ -7,7 +7,7 @@ crc32 :: proc(data rawptr, len int) -> u32 { } return ~result; } -crc64 :: proc(data rawptr, len int) -> u64 { +crc64 :: proc(data: rawptr, len: int) -> u64 { result := ~(0 as u64); s := slice_ptr(data as ^u8, len); for i := 0; i < len; i++ { @@ -17,7 +17,7 @@ crc64 :: proc(data rawptr, len int) -> u64 { return ~result; } -fnv32 :: proc(data rawptr, len int) -> u32 { +fnv32 :: proc(data: rawptr, len: int) -> u32 { s := slice_ptr(data as ^u8, len); h :u32 = 0x811c9dc5; @@ -27,7 +27,7 @@ fnv32 :: proc(data rawptr, len int) -> u32 { return h; } -fnv64 :: proc(data rawptr, len int) -> u64 { +fnv64 :: proc(data: rawptr, len: int) -> u64 { s := slice_ptr(data as ^u8, len); h :u64 = 0xcbf29ce484222325; @@ -37,7 +37,7 @@ fnv64 :: proc(data rawptr, len int) -> u64 { return h; } -fnv32a :: proc(data rawptr, len int) -> u32 { +fnv32a :: proc(data: rawptr, len: int) -> u32 { s := slice_ptr(data as ^u8, len); h :u32 = 0x811c9dc5; @@ -47,7 +47,7 @@ fnv32a :: proc(data rawptr, len int) -> u32 { return h; } -fnv64a :: proc(data rawptr, len int) -> u64 { +fnv64a :: proc(data: rawptr, len: int) -> u64 { s := slice_ptr(data as ^u8, len); h :u64 = 0xcbf29ce484222325; @@ -58,7 +58,7 @@ fnv64a :: proc(data rawptr, len int) -> u64 { } -murmur64 :: proc(data_ rawptr, len int) -> u64 { +murmur64 :: proc(data_: rawptr, len: int) -> u64 { SEED :: 0x9747b28c; when size_of(int) == 8 { diff --git a/core/math.odin b/core/math.odin index 2ff9340e9..27afb45a5 100644 --- a/core/math.odin +++ b/core/math.odin @@ -24,57 +24,57 @@ Mat2 :: [2]Vec2; Mat3 :: [3]Vec3; Mat4 :: [4]Vec4; -sqrt32 :: proc(x f32) -> f32 #foreign "llvm.sqrt.f32" -sqrt64 :: proc(x f64) -> f64 #foreign "llvm.sqrt.f64" +sqrt32 :: proc(x: f32) -> f32 #foreign "llvm.sqrt.f32" +sqrt64 :: proc(x: f64) -> f64 #foreign "llvm.sqrt.f64" -sin32 :: proc(x f32) -> f32 #foreign "llvm.sin.f32" -sin64 :: proc(x f64) -> f64 #foreign "llvm.sin.f64" +sin32 :: proc(x: f32) -> f32 #foreign "llvm.sin.f32" +sin64 :: proc(x: f64) -> f64 #foreign "llvm.sin.f64" -cos32 :: proc(x f32) -> f32 #foreign "llvm.cos.f32" -cos64 :: proc(x f64) -> f64 #foreign "llvm.cos.f64" +cos32 :: proc(x: f32) -> f32 #foreign "llvm.cos.f32" +cos64 :: proc(x: f64) -> f64 #foreign "llvm.cos.f64" -tan32 :: proc(x f32) -> f32 #inline { return sin32(x)/cos32(x); } -tan64 :: proc(x f64) -> f64 #inline { return sin64(x)/cos64(x); } +tan32 :: proc(x: f32) -> f32 #inline { return sin32(x)/cos32(x); } +tan64 :: proc(x: f64) -> f64 #inline { return sin64(x)/cos64(x); } -lerp32 :: proc(a, b, t f32) -> f32 { return a*(1-t) + b*t; } -lerp64 :: proc(a, b, t f64) -> f64 { return a*(1-t) + b*t; } +lerp32 :: proc(a, b, t: f32) -> f32 { return a*(1-t) + b*t; } +lerp64 :: proc(a, b, t: f64) -> f64 { return a*(1-t) + b*t; } -sign32 :: proc(x f32) -> f32 { if x >= 0 { return +1; } return -1; } -sign64 :: proc(x f64) -> f64 { if x >= 0 { return +1; } return -1; } +sign32 :: proc(x: f32) -> f32 { if x >= 0 { return +1; } return -1; } +sign64 :: proc(x: f64) -> f64 { if x >= 0 { return +1; } return -1; } -copy_sign32 :: proc(x, y f32) -> f32 { +copy_sign32 :: proc(x, y: f32) -> f32 { ix := x transmute u32; iy := y transmute u32; ix &= 0x7fffffff; ix |= iy & 0x80000000; return ix transmute f32; } -round32 :: proc(x f32) -> f32 { +round32 :: proc(x: f32) -> f32 { if x >= 0 { return floor32(x + 0.5); } return ceil32(x - 0.5); } -floor32 :: proc(x f32) -> f32 { +floor32 :: proc(x: f32) -> f32 { if x >= 0 { return x as int as f32; } return (x-0.5) as int as f32; } -ceil32 :: proc(x f32) -> f32 { +ceil32 :: proc(x: f32) -> f32 { if x < 0 { return x as int as f32; } return ((x as int)+1) as f32; } -remainder32 :: proc(x, y f32) -> f32 { +remainder32 :: proc(x, y: f32) -> f32 { return x - round32(x/y) * y; } -fmod32 :: proc(x, y f32) -> f32 { +fmod32 :: proc(x, y: f32) -> f32 { y = abs(y); result := remainder32(abs(x), y); if sign32(result) < 0 { @@ -84,32 +84,32 @@ fmod32 :: proc(x, y f32) -> f32 { } -to_radians :: proc(degrees f32) -> f32 { return degrees * TAU / 360; } -to_degrees :: proc(radians f32) -> f32 { return radians * 360 / TAU; } +to_radians :: proc(degrees: f32) -> f32 { return degrees * TAU / 360; } +to_degrees :: proc(radians: f32) -> f32 { return radians * 360 / TAU; } -dot2 :: proc(a, b Vec2) -> f32 { c := a*b; return c.x + c.y; } -dot3 :: proc(a, b Vec3) -> f32 { c := a*b; return c.x + c.y + c.z; } -dot4 :: proc(a, b Vec4) -> f32 { c := a*b; return c.x + c.y + c.z + c.w; } +dot2 :: proc(a, b: Vec2) -> f32 { c := a*b; return c.x + c.y; } +dot3 :: proc(a, b: Vec3) -> f32 { c := a*b; return c.x + c.y + c.z; } +dot4 :: proc(a, b: Vec4) -> f32 { c := a*b; return c.x + c.y + c.z + c.w; } -cross3 :: proc(x, y Vec3) -> Vec3 { +cross3 :: proc(x, y: Vec3) -> Vec3 { a := swizzle(x, 1, 2, 0) * swizzle(y, 2, 0, 1); b := swizzle(x, 2, 0, 1) * swizzle(y, 1, 2, 0); return a - b; } -vec2_mag :: proc(v Vec2) -> f32 { return sqrt32(dot2(v, v)); } -vec3_mag :: proc(v Vec3) -> f32 { return sqrt32(dot3(v, v)); } -vec4_mag :: proc(v Vec4) -> f32 { return sqrt32(dot4(v, v)); } +vec2_mag :: proc(v: Vec2) -> f32 { return sqrt32(dot2(v, v)); } +vec3_mag :: proc(v: Vec3) -> f32 { return sqrt32(dot3(v, v)); } +vec4_mag :: proc(v: Vec4) -> f32 { return sqrt32(dot4(v, v)); } -vec2_norm :: proc(v Vec2) -> Vec2 { return v / Vec2{vec2_mag(v)}; } -vec3_norm :: proc(v Vec3) -> Vec3 { return v / Vec3{vec3_mag(v)}; } -vec4_norm :: proc(v Vec4) -> Vec4 { return v / Vec4{vec4_mag(v)}; } +vec2_norm :: proc(v: Vec2) -> Vec2 { return v / Vec2{vec2_mag(v)}; } +vec3_norm :: proc(v: Vec3) -> Vec3 { return v / Vec3{vec3_mag(v)}; } +vec4_norm :: proc(v: Vec4) -> Vec4 { return v / Vec4{vec4_mag(v)}; } -vec2_norm0 :: proc(v Vec2) -> Vec2 { +vec2_norm0 :: proc(v: Vec2) -> Vec2 { m := vec2_mag(v); if m == 0 { return Vec2{0}; @@ -117,7 +117,7 @@ vec2_norm0 :: proc(v Vec2) -> Vec2 { return v / Vec2{m}; } -vec3_norm0 :: proc(v Vec3) -> Vec3 { +vec3_norm0 :: proc(v: Vec3) -> Vec3 { m := vec3_mag(v); if m == 0 { return Vec3{0}; @@ -125,7 +125,7 @@ vec3_norm0 :: proc(v Vec3) -> Vec3 { return v / Vec3{m}; } -vec4_norm0 :: proc(v Vec4) -> Vec4 { +vec4_norm0 :: proc(v: Vec4) -> Vec4 { m := vec4_mag(v); if m == 0 { return Vec4{0}; @@ -144,7 +144,7 @@ mat4_identity :: proc() -> Mat4 { }; } -mat4_transpose :: proc(m Mat4) -> Mat4 { +mat4_transpose :: proc(m: Mat4) -> Mat4 { for j := 0; j < 4; j++ { for i := 0; i < 4; i++ { m[i][j], m[j][i] = m[j][i], m[i][j]; @@ -153,7 +153,7 @@ mat4_transpose :: proc(m Mat4) -> Mat4 { return m; } -mat4_mul :: proc(a, b Mat4) -> Mat4 { +mat4_mul :: proc(a, b: Mat4) -> Mat4 { c: Mat4; for j := 0; j < 4; j++ { for i := 0; i < 4; i++ { @@ -166,7 +166,7 @@ mat4_mul :: proc(a, b Mat4) -> Mat4 { return c; } -mat4_mul_vec4 :: proc(m Mat4, v Vec4) -> Vec4 { +mat4_mul_vec4 :: proc(m: Mat4, v: Vec4) -> Vec4 { return Vec4{ m[0][0]*v.x + m[1][0]*v.y + m[2][0]*v.z + m[3][0]*v.w, m[0][1]*v.x + m[1][1]*v.y + m[2][1]*v.z + m[3][1]*v.w, @@ -175,7 +175,7 @@ mat4_mul_vec4 :: proc(m Mat4, v Vec4) -> Vec4 { }; } -mat4_inverse :: proc(m Mat4) -> Mat4 { +mat4_inverse :: proc(m: Mat4) -> Mat4 { o: Mat4; sf00 := m[2][2] * m[3][3] - m[3][2] * m[2][3]; @@ -244,7 +244,7 @@ mat4_inverse :: proc(m Mat4) -> Mat4 { } -mat4_translate :: proc(v Vec3) -> Mat4 { +mat4_translate :: proc(v: Vec3) -> Mat4 { m := mat4_identity(); m[3][0] = v.x; m[3][1] = v.y; @@ -253,7 +253,7 @@ mat4_translate :: proc(v Vec3) -> Mat4 { return m; } -mat4_rotate :: proc(v Vec3, angle_radians f32) -> Mat4 { +mat4_rotate :: proc(v: Vec3, angle_radians: f32) -> Mat4 { c := cos32(angle_radians); s := sin32(angle_radians); @@ -280,14 +280,14 @@ mat4_rotate :: proc(v Vec3, angle_radians f32) -> Mat4 { return rot; } -mat4_scale :: proc(m Mat4, v Vec3) -> Mat4 { +mat4_scale :: proc(m: Mat4, v: Vec3) -> Mat4 { m[0][0] *= v.x; m[1][1] *= v.y; m[2][2] *= v.z; return m; } -mat4_scalef :: proc(m Mat4, s f32) -> Mat4 { +mat4_scalef :: proc(m: Mat4, s: f32) -> Mat4 { m[0][0] *= s; m[1][1] *= s; m[2][2] *= s; @@ -295,7 +295,7 @@ mat4_scalef :: proc(m Mat4, s f32) -> Mat4 { } -mat4_look_at :: proc(eye, centre, up Vec3) -> Mat4 { +mat4_look_at :: proc(eye, centre, up: Vec3) -> Mat4 { f := vec3_norm(centre - eye); s := vec3_norm(cross3(f, up)); u := cross3(s, f); @@ -309,7 +309,7 @@ mat4_look_at :: proc(eye, centre, up Vec3) -> Mat4 { return m; } -mat4_perspective :: proc(fovy, aspect, near, far f32) -> Mat4 { +mat4_perspective :: proc(fovy, aspect, near, far: f32) -> Mat4 { m: Mat4; tan_half_fovy := tan32(0.5 * fovy); m[0][0] = 1.0 / (aspect*tan_half_fovy); @@ -321,7 +321,7 @@ mat4_perspective :: proc(fovy, aspect, near, far f32) -> Mat4 { } -mat4_ortho3d :: proc(left, right, bottom, top, near, far f32) -> Mat4 { +mat4_ortho3d :: proc(left, right, bottom, top, near, far: f32) -> Mat4 { m := mat4_identity(); m[0][0] = +2.0 / (right - left); m[1][1] = +2.0 / (top - bottom); diff --git a/core/mem.odin b/core/mem.odin index d481fe014..c6e84bc9a 100644 --- a/core/mem.odin +++ b/core/mem.odin @@ -1,33 +1,31 @@ -import { - "fmt.odin"; - "os.odin"; -} +#import "fmt.odin"; +#import "os.odin"; -set :: proc(data rawptr, value i32, len int) -> rawptr #link_name "__mem_set" { - llvm_memset_64bit :: proc(dst rawptr, val byte, len int, align i32, is_volatile bool) #foreign "llvm.memset.p0i8.i64" +set :: proc(data: rawptr, value: i32, len: int) -> rawptr #link_name "__mem_set" { + llvm_memset_64bit :: proc(dst: rawptr, val: byte, len: int, align: i32, is_volatile: bool) #foreign "llvm.memset.p0i8.i64" llvm_memset_64bit(data, value as byte, len, 1, false); return data; } -zero :: proc(data rawptr, len int) -> rawptr #link_name "__mem_zero" { +zero :: proc(data: rawptr, len: int) -> rawptr #link_name "__mem_zero" { return set(data, 0, len); } -copy :: proc(dst, src rawptr, len int) -> rawptr #link_name "__mem_copy" { +copy :: proc(dst, src: rawptr, len: int) -> rawptr #link_name "__mem_copy" { // NOTE(bill): This _must_ implemented like C's memmove - llvm_memmove_64bit :: proc(dst, src rawptr, len int, align i32, is_volatile bool) #foreign "llvm.memmove.p0i8.p0i8.i64" + llvm_memmove_64bit :: proc(dst, src: rawptr, len: int, align: i32, is_volatile: bool) #foreign "llvm.memmove.p0i8.p0i8.i64" llvm_memmove_64bit(dst, src, len, 1, false); return dst; } -copy_non_overlapping :: proc(dst, src rawptr, len int) -> rawptr #link_name "__mem_copy_non_overlapping" { +copy_non_overlapping :: proc(dst, src: rawptr, len: int) -> rawptr #link_name "__mem_copy_non_overlapping" { // NOTE(bill): This _must_ implemented like C's memcpy - llvm_memcpy_64bit :: proc(dst, src rawptr, len int, align i32, is_volatile bool) #foreign "llvm.memcpy.p0i8.p0i8.i64" + llvm_memcpy_64bit :: proc(dst, src: rawptr, len: int, align: i32, is_volatile: bool) #foreign "llvm.memcpy.p0i8.p0i8.i64" llvm_memcpy_64bit(dst, src, len, 1, false); return dst; } -compare :: proc(dst, src rawptr, n int) -> int #link_name "__mem_compare" { +compare :: proc(dst, src: rawptr, n: int) -> int #link_name "__mem_compare" { // Translation of http://mgronhol.github.io/fast-strcmp/ a := slice_ptr(dst as ^byte, n); b := slice_ptr(src as ^byte, n); @@ -64,19 +62,19 @@ compare :: proc(dst, src rawptr, n int) -> int #link_name "__mem_compare" { -kilobytes :: proc(x int) -> int #inline { return (x) * 1024; } -megabytes :: proc(x int) -> int #inline { return kilobytes(x) * 1024; } -gigabytes :: proc(x int) -> int #inline { return gigabytes(x) * 1024; } -terabytes :: proc(x int) -> int #inline { return terabytes(x) * 1024; } +kilobytes :: proc(x: int) -> int #inline { return (x) * 1024; } +megabytes :: proc(x: int) -> int #inline { return kilobytes(x) * 1024; } +gigabytes :: proc(x: int) -> int #inline { return gigabytes(x) * 1024; } +terabytes :: proc(x: int) -> int #inline { return terabytes(x) * 1024; } -is_power_of_two :: proc(x int) -> bool { +is_power_of_two :: proc(x: int) -> bool { if x <= 0 { return false; } return (x & (x-1)) == 0; } -align_forward :: proc(ptr rawptr, align int) -> rawptr { +align_forward :: proc(ptr: rawptr, align: int) -> rawptr { assert(is_power_of_two(align)); a := align as uint; @@ -91,10 +89,10 @@ align_forward :: proc(ptr rawptr, align int) -> rawptr { Allocation_Header :: struct { - size int; + size: int; } -allocation_header_fill :: proc(header ^Allocation_Header, data rawptr, size int) { +allocation_header_fill :: proc(header: ^Allocation_Header, data: rawptr, size: int) { header.size = size; ptr := (header+1) as ^int; @@ -102,7 +100,7 @@ allocation_header_fill :: proc(header ^Allocation_Header, data rawptr, size int) (ptr+i)^ = -1; } } -allocation_header :: proc(data rawptr) -> ^Allocation_Header { +allocation_header :: proc(data: rawptr) -> ^Allocation_Header { p := data as ^int; for (p-1)^ == -1 { p = (p-1); @@ -116,33 +114,33 @@ allocation_header :: proc(data rawptr) -> ^Allocation_Header { // Custom allocators Arena :: struct { - backing Allocator; - memory []byte; - temp_count int; + backing: Allocator; + memory: []byte; + temp_count: int; } Arena_Temp_Memory :: struct { - arena ^Arena; - original_count int; + arena: ^Arena; + original_count: int; } -init_arena_from_memory :: proc(using a ^Arena, data []byte) { +init_arena_from_memory :: proc(using a: ^Arena, data: []byte) { backing = Allocator{}; memory = data[:0]; temp_count = 0; } -init_arena_from_context :: proc(using a ^Arena, size int) { +init_arena_from_context :: proc(using a: ^Arena, size: int) { backing = context.allocator; memory = new_slice(byte, 0, size); temp_count = 0; } -free_arena :: proc(using a ^Arena) { +free_arena :: proc(using a: ^Arena) { if backing.procedure != nil { push_allocator backing { free(memory.data); @@ -151,16 +149,16 @@ free_arena :: proc(using a ^Arena) { } } -arena_allocator :: proc(arena ^Arena) -> Allocator { +arena_allocator :: proc(arena: ^Arena) -> Allocator { return Allocator{ procedure = arena_allocator_proc, data = arena, }; } -arena_allocator_proc :: proc(allocator_data rawptr, mode Allocator_Mode, - size, alignment int, - old_memory rawptr, old_size int, flags u64) -> rawptr { +arena_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, + size, alignment: int, + old_memory: rawptr, old_size: int, flags: u64) -> rawptr { using Allocator_Mode; arena := allocator_data as ^Arena; @@ -193,7 +191,7 @@ arena_allocator_proc :: proc(allocator_data rawptr, mode Allocator_Mode, return nil; } -begin_arena_temp_memory :: proc(a ^Arena) -> Arena_Temp_Memory { +begin_arena_temp_memory :: proc(a: ^Arena) -> Arena_Temp_Memory { tmp: Arena_Temp_Memory; tmp.arena = a; tmp.original_count = a.memory.count; @@ -201,7 +199,7 @@ begin_arena_temp_memory :: proc(a ^Arena) -> Arena_Temp_Memory { return tmp; } -end_arena_temp_memory :: proc(using tmp Arena_Temp_Memory) { +end_arena_temp_memory :: proc(using tmp: Arena_Temp_Memory) { assert(arena.memory.count >= original_count); assert(arena.temp_count > 0); arena.memory.count = original_count; @@ -214,8 +212,8 @@ end_arena_temp_memory :: proc(using tmp Arena_Temp_Memory) { -align_of_type_info :: proc(type_info ^Type_Info) -> int { - prev_pow2 :: proc(n i64) -> i64 { +align_of_type_info :: proc(type_info: ^Type_Info) -> int { + prev_pow2 :: proc(n: i64) -> i64 { if n <= 0 { return 0; } @@ -269,12 +267,12 @@ align_of_type_info :: proc(type_info ^Type_Info) -> int { return 0; } -align_formula :: proc(size, align int) -> int { +align_formula :: proc(size, align: int) -> int { result := size + align-1; return result - result%align; } -size_of_type_info :: proc(type_info ^Type_Info) -> int { +size_of_type_info :: proc(type_info: ^Type_Info) -> int { WORD_SIZE :: size_of(int); using Type_Info; match type info : type_info { @@ -308,7 +306,7 @@ size_of_type_info :: proc(type_info ^Type_Info) -> int { case Slice: return 3*WORD_SIZE; case Vector: - is_bool :: proc(type_info ^Type_Info) -> bool { + is_bool :: proc(type_info: ^Type_Info) -> bool { match type info : type_info { case Named: return is_bool(info.base); diff --git a/core/opengl.odin b/core/opengl.odin index 91b23f8e7..f7bf2ac00 100644 --- a/core/opengl.odin +++ b/core/opengl.odin @@ -1,38 +1,38 @@ #foreign_system_library "opengl32" when ODIN_OS == "windows"; -import win32 "sys/windows.odin" when ODIN_OS == "windows"; -include "opengl_constants.odin"; +#import win32 "sys/windows.odin" when ODIN_OS == "windows"; +#include "opengl_constants.odin"; -Clear :: proc(mask u32) #foreign "glClear" -ClearColor :: proc(r, g, b, a f32) #foreign "glClearColor" -Begin :: proc(mode i32) #foreign "glBegin" -End :: proc() #foreign "glEnd" -Finish :: proc() #foreign "glFinish" -BlendFunc :: proc(sfactor, dfactor i32) #foreign "glBlendFunc" -Enable :: proc(cap i32) #foreign "glEnable" -Disable :: proc(cap i32) #foreign "glDisable" -GenTextures :: proc(count i32, result ^u32) #foreign "glGenTextures" -DeleteTextures:: proc(count i32, result ^u32) #foreign "glDeleteTextures" -TexParameteri :: proc(target, pname, param i32) #foreign "glTexParameteri" -TexParameterf :: proc(target i32, pname i32, param f32) #foreign "glTexParameterf" -BindTexture :: proc(target i32, texture u32) #foreign "glBindTexture" -LoadIdentity :: proc() #foreign "glLoadIdentity" -Viewport :: proc(x, y, width, height i32) #foreign "glViewport" -Ortho :: proc(left, right, bottom, top, near, far f64) #foreign "glOrtho" -Color3f :: proc(r, g, b f32) #foreign "glColor3f" -Vertex3f :: proc(x, y, z f32) #foreign "glVertex3f" +Clear :: proc(mask: u32) #foreign "glClear" +ClearColor :: proc(r, g, b, a: f32) #foreign "glClearColor" +Begin :: proc(mode: i32) #foreign "glBegin" +End :: proc() #foreign "glEnd" +Finish :: proc() #foreign "glFinish" +BlendFunc :: proc(sfactor, dfactor: i32) #foreign "glBlendFunc" +Enable :: proc(cap: i32) #foreign "glEnable" +Disable :: proc(cap: i32) #foreign "glDisable" +GenTextures :: proc(count: i32, result: ^u32) #foreign "glGenTextures" +DeleteTextures:: proc(count: i32, result: ^u32) #foreign "glDeleteTextures" +TexParameteri :: proc(target, pname, param: i32) #foreign "glTexParameteri" +TexParameterf :: proc(target: i32, pname: i32, param: f32) #foreign "glTexParameterf" +BindTexture :: proc(target: i32, texture: u32) #foreign "glBindTexture" +LoadIdentity :: proc() #foreign "glLoadIdentity" +Viewport :: proc(x, y, width, height: i32) #foreign "glViewport" +Ortho :: proc(left, right, bottom, top, near, far: f64) #foreign "glOrtho" +Color3f :: proc(r, g, b: f32) #foreign "glColor3f" +Vertex3f :: proc(x, y, z: f32) #foreign "glVertex3f" TexImage2D :: proc(target, level, internal_format, width, height, border, - format, _type i32, pixels rawptr) #foreign "glTexImage2D" + format, _type: i32, pixels: rawptr) #foreign "glTexImage2D" GetError :: proc() -> i32 #foreign "glGetError" -GetString :: proc(name i32) -> ^byte #foreign "glGetString" -GetIntegerv :: proc(name i32, v ^i32) #foreign "glGetIntegerv" +GetString :: proc(name: i32) -> ^byte #foreign "glGetString" +GetIntegerv :: proc(name: i32, v: ^i32) #foreign "glGetIntegerv" _libgl := win32.LoadLibraryA(("opengl32.dll\x00" as string).data); -GetProcAddress :: proc(name string) -> proc() #cc_c { +GetProcAddress :: proc(name: string) -> proc() #cc_c { assert(name[name.count-1] == 0); res := win32.wglGetProcAddress(name.data); if res == nil { @@ -41,66 +41,66 @@ GetProcAddress :: proc(name string) -> proc() #cc_c { return res; } -GenBuffers: proc(count i32, buffers ^u32) #cc_c; -GenVertexArrays: proc(count i32, buffers ^u32) #cc_c; -GenSamplers: proc(count i32, buffers ^u32) #cc_c; -BindBuffer: proc(target i32, buffer u32) #cc_c; -BindVertexArray: proc(buffer u32) #cc_c; -BindSampler: proc(position i32, sampler u32) #cc_c; -BufferData: proc(target i32, size int, data rawptr, usage i32) #cc_c; -BufferSubData: proc(target i32, offset, size int, data rawptr) #cc_c; +GenBuffers: proc(count: i32, buffers: ^u32) #cc_c; +GenVertexArrays: proc(count: i32, buffers: ^u32) #cc_c; +GenSamplers: proc(count: i32, buffers: ^u32) #cc_c; +BindBuffer: proc(target: i32, buffer: u32) #cc_c; +BindVertexArray: proc(buffer: u32) #cc_c; +BindSampler: proc(position: i32, sampler: u32) #cc_c; +BufferData: proc(target: i32, size: int, data: rawptr, usage: i32) #cc_c; +BufferSubData: proc(target: i32, offset, size: int, data: rawptr) #cc_c; -DrawArrays: proc(mode, first i32, count u32) #cc_c; -DrawElements: proc(mode i32, count u32, type_ i32, indices rawptr) #cc_c; +DrawArrays: proc(mode, first: i32, count: u32) #cc_c; +DrawElements: proc(mode: i32, count: u32, type_: i32, indices: rawptr) #cc_c; -MapBuffer: proc(target, access i32) -> rawptr #cc_c; -UnmapBuffer: proc(target i32) #cc_c; +MapBuffer: proc(target, access: i32) -> rawptr #cc_c; +UnmapBuffer: proc(target: i32) #cc_c; -VertexAttribPointer: proc(index u32, size, type_ i32, normalized i32, stride u32, pointer rawptr) #cc_c; -EnableVertexAttribArray: proc(index u32) #cc_c; +VertexAttribPointer: proc(index: u32, size, type_: i32, normalized: i32, stride: u32, pointer: rawptr) #cc_c; +EnableVertexAttribArray: proc(index: u32) #cc_c; -CreateShader: proc(shader_type i32) -> u32 #cc_c; -ShaderSource: proc(shader u32, count u32, str ^^byte, length ^i32) #cc_c; -CompileShader: proc(shader u32) #cc_c; +CreateShader: proc(shader_type: i32) -> u32 #cc_c; +ShaderSource: proc(shader: u32, count: u32, str: ^^byte, length: ^i32) #cc_c; +CompileShader: proc(shader: u32) #cc_c; CreateProgram: proc() -> u32 #cc_c; -AttachShader: proc(program, shader u32) #cc_c; -DetachShader: proc(program, shader u32) #cc_c; -DeleteShader: proc(shader u32) #cc_c; -LinkProgram: proc(program u32) #cc_c; -UseProgram: proc(program u32) #cc_c; -DeleteProgram: proc(program u32) #cc_c; +AttachShader: proc(program, shader: u32) #cc_c; +DetachShader: proc(program, shader: u32) #cc_c; +DeleteShader: proc(shader: u32) #cc_c; +LinkProgram: proc(program: u32) #cc_c; +UseProgram: proc(program: u32) #cc_c; +DeleteProgram: proc(program: u32) #cc_c; -GetShaderiv: proc(shader u32, pname i32, params ^i32) #cc_c; -GetProgramiv: proc(program u32, pname i32, params ^i32) #cc_c; -GetShaderInfoLog: proc(shader u32, max_length u32, length ^u32, info_long ^byte) #cc_c; -GetProgramInfoLog: proc(program u32, max_length u32, length ^u32, info_long ^byte) #cc_c; +GetShaderiv: proc(shader: u32, pname: i32, params: ^i32) #cc_c; +GetProgramiv: proc(program: u32, pname: i32, params: ^i32) #cc_c; +GetShaderInfoLog: proc(shader: u32, max_length: u32, length: ^u32, info_long: ^byte) #cc_c; +GetProgramInfoLog: proc(program: u32, max_length: u32, length: ^u32, info_long: ^byte) #cc_c; -ActiveTexture: proc(texture i32) #cc_c; -GenerateMipmap: proc(target i32) #cc_c; +ActiveTexture: proc(texture: i32) #cc_c; +GenerateMipmap: proc(target: i32) #cc_c; -SamplerParameteri: proc(sampler u32, pname i32, param i32) #cc_c; -SamplerParameterf: proc(sampler u32, pname i32, param f32) #cc_c; -SamplerParameteriv: proc(sampler u32, pname i32, params ^i32) #cc_c; -SamplerParameterfv: proc(sampler u32, pname i32, params ^f32) #cc_c; -SamplerParameterIiv: proc(sampler u32, pname i32, params ^i32) #cc_c; -SamplerParameterIuiv: proc(sampler u32, pname i32, params ^u32) #cc_c; +SamplerParameteri: proc(sampler: u32, pname: i32, param: i32) #cc_c; +SamplerParameterf: proc(sampler: u32, pname: i32, param: f32) #cc_c; +SamplerParameteriv: proc(sampler: u32, pname: i32, params: ^i32) #cc_c; +SamplerParameterfv: proc(sampler: u32, pname: i32, params: ^f32) #cc_c; +SamplerParameterIiv: proc(sampler: u32, pname: i32, params: ^i32) #cc_c; +SamplerParameterIuiv: proc(sampler: u32, pname: i32, params: ^u32) #cc_c; -Uniform1i: proc(loc i32, v0 i32) #cc_c; -Uniform2i: proc(loc i32, v0, v1 i32) #cc_c; -Uniform3i: proc(loc i32, v0, v1, v2 i32) #cc_c; -Uniform4i: proc(loc i32, v0, v1, v2, v3 i32) #cc_c; -Uniform1f: proc(loc i32, v0 f32) #cc_c; -Uniform2f: proc(loc i32, v0, v1 f32) #cc_c; -Uniform3f: proc(loc i32, v0, v1, v2 f32) #cc_c; -Uniform4f: proc(loc i32, v0, v1, v2, v3 f32) #cc_c; -UniformMatrix4fv: proc(loc i32, count u32, transpose i32, value ^f32) #cc_c; +Uniform1i: proc(loc: i32, v0: i32) #cc_c; +Uniform2i: proc(loc: i32, v0, v1: i32) #cc_c; +Uniform3i: proc(loc: i32, v0, v1, v2: i32) #cc_c; +Uniform4i: proc(loc: i32, v0, v1, v2, v3: i32) #cc_c; +Uniform1f: proc(loc: i32, v0: f32) #cc_c; +Uniform2f: proc(loc: i32, v0, v1: f32) #cc_c; +Uniform3f: proc(loc: i32, v0, v1, v2: f32) #cc_c; +Uniform4f: proc(loc: i32, v0, v1, v2, v3: f32) #cc_c; +UniformMatrix4fv: proc(loc: i32, count: u32, transpose: i32, value: ^f32) #cc_c; -GetUniformLocation: proc(program u32, name ^byte) -> i32 #cc_c; +GetUniformLocation: proc(program: u32, name: ^byte) -> i32 #cc_c; init :: proc() { - set_proc_address :: proc(p rawptr, name string) #inline { (p as ^(proc() #cc_c))^ = GetProcAddress(name); } + set_proc_address :: proc(p: rawptr, name: string) #inline { (p as ^(proc() #cc_c))^ = GetProcAddress(name); } set_proc_address(^GenBuffers, "glGenBuffers\x00"); set_proc_address(^GenVertexArrays, "glGenVertexArrays\x00"); diff --git a/core/os.odin b/core/os.odin index 42e7909a9..22e2d533c 100644 --- a/core/os.odin +++ b/core/os.odin @@ -1,2 +1,2 @@ -include "os_windows.odin" when ODIN_OS == "windows" +#include "os_windows.odin" when ODIN_OS == "windows" diff --git a/core/os_windows.odin b/core/os_windows.odin index 8921588f1..1ed897a0c 100644 --- a/core/os_windows.odin +++ b/core/os_windows.odin @@ -1,7 +1,5 @@ -import { - win32 "sys/windows.odin"; - "fmt.odin"; -} +#import win32 "sys/windows.odin"; +#import "fmt.odin"; Handle :: uint; @@ -24,37 +22,37 @@ O_SYNC :: 0x01000; O_ASYNC :: 0x02000; O_CLOEXEC :: 0x80000; -ERROR_NONE : Error : 0; -ERROR_FILE_NOT_FOUND : Error : 2; -ERROR_PATH_NOT_FOUND : Error : 3; -ERROR_ACCESS_DENIED : Error : 5; -ERROR_NO_MORE_FILES : Error : 18; -ERROR_HANDLE_EOF : Error : 38; -ERROR_NETNAME_DELETED : Error : 64; -ERROR_FILE_EXISTS : Error : 80; -ERROR_BROKEN_PIPE : Error : 109; -ERROR_BUFFER_OVERFLOW : Error : 111; -ERROR_INSUFFICIENT_BUFFER : Error : 122; -ERROR_MOD_NOT_FOUND : Error : 126; -ERROR_PROC_NOT_FOUND : Error : 127; -ERROR_DIR_NOT_EMPTY : Error : 145; -ERROR_ALREADY_EXISTS : Error : 183; -ERROR_ENVVAR_NOT_FOUND : Error : 203; -ERROR_MORE_DATA : Error : 234; -ERROR_OPERATION_ABORTED : Error : 995; -ERROR_IO_PENDING : Error : 997; -ERROR_NOT_FOUND : Error : 1168; -ERROR_PRIVILEGE_NOT_HELD : Error : 1314; -WSAEACCES : Error : 10013; -WSAECONNRESET : Error : 10054; +ERROR_NONE: Error : 0; +ERROR_FILE_NOT_FOUND: Error : 2; +ERROR_PATH_NOT_FOUND: Error : 3; +ERROR_ACCESS_DENIED: Error : 5; +ERROR_NO_MORE_FILES: Error : 18; +ERROR_HANDLE_EOF: Error : 38; +ERROR_NETNAME_DELETED: Error : 64; +ERROR_FILE_EXISTS: Error : 80; +ERROR_BROKEN_PIPE: Error : 109; +ERROR_BUFFER_OVERFLOW: Error : 111; +ERROR_INSUFFICIENT_BUFFER: Error : 122; +ERROR_MOD_NOT_FOUND: Error : 126; +ERROR_PROC_NOT_FOUND: Error : 127; +ERROR_DIR_NOT_EMPTY: Error : 145; +ERROR_ALREADY_EXISTS: Error : 183; +ERROR_ENVVAR_NOT_FOUND: Error : 203; +ERROR_MORE_DATA: Error : 234; +ERROR_OPERATION_ABORTED: Error : 995; +ERROR_IO_PENDING: Error : 997; +ERROR_NOT_FOUND: Error : 1168; +ERROR_PRIVILEGE_NOT_HELD: Error : 1314; +WSAEACCES: Error : 10013; +WSAECONNRESET: Error : 10054; // Windows reserves errors >= 1<<29 for application use -ERROR_FILE_IS_PIPE : Error : 1<<29 + 0; +ERROR_FILE_IS_PIPE: Error : 1<<29 + 0; -open :: proc(path string, mode int, perm u32) -> (Handle, Error) { +open :: proc(path: string, mode: int, perm: u32) -> (Handle, Error) { using win32; if path.count == 0 { return INVALID_HANDLE, ERROR_FILE_NOT_FOUND; @@ -107,11 +105,11 @@ open :: proc(path string, mode int, perm u32) -> (Handle, Error) { return INVALID_HANDLE, err as Error; } -close :: proc(fd Handle) { +close :: proc(fd: Handle) { win32.CloseHandle(fd as win32.HANDLE); } -write :: proc(fd Handle, data []byte) -> (int, Error) { +write :: proc(fd: Handle, data: []byte) -> (int, Error) { bytes_written: i32; e := win32.WriteFile(fd as win32.HANDLE, data.data, data.count as i32, ^bytes_written, nil); if e != 0 { @@ -120,7 +118,7 @@ write :: proc(fd Handle, data []byte) -> (int, Error) { return bytes_written as int, ERROR_NONE; } -read :: proc(fd Handle, data []byte) -> (int, Error) { +read :: proc(fd: Handle, data: []byte) -> (int, Error) { bytes_read: i32; e := win32.ReadFile(fd as win32.HANDLE, data.data, data.count as u32, ^bytes_read, nil); if e != win32.FALSE { @@ -130,7 +128,7 @@ read :: proc(fd Handle, data []byte) -> (int, Error) { return bytes_read as int, ERROR_NONE; } -seek :: proc(fd Handle, offset i64, whence int) -> (i64, Error) { +seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) { using win32; w: u32; match whence { @@ -159,7 +157,7 @@ stdout := get_std_handle(win32.STD_OUTPUT_HANDLE); stderr := get_std_handle(win32.STD_ERROR_HANDLE); -get_std_handle :: proc(h int) -> Handle { +get_std_handle :: proc(h: int) -> Handle { fd := win32.GetStdHandle(h as i32); win32.SetHandleInformation(fd, win32.HANDLE_FLAG_INHERIT, 0); return fd as Handle; @@ -170,7 +168,7 @@ get_std_handle :: proc(h int) -> Handle { -last_write_time :: proc(fd Handle) -> File_Time { +last_write_time :: proc(fd: Handle) -> File_Time { file_info: win32.BY_HANDLE_FILE_INFORMATION; win32.GetFileInformationByHandle(fd as win32.HANDLE, ^file_info); lo := file_info.last_write_time.lo as File_Time; @@ -178,7 +176,7 @@ last_write_time :: proc(fd Handle) -> File_Time { return lo | hi << 32; } -last_write_time_by_name :: proc(name string) -> File_Time { +last_write_time_by_name :: proc(name: string) -> File_Time { last_write_time: win32.FILETIME; data: win32.FILE_ATTRIBUTE_DATA; buf: [1024]byte; @@ -200,7 +198,7 @@ last_write_time_by_name :: proc(name string) -> File_Time { -read_entire_file :: proc(name string) -> ([]byte, bool) { +read_entire_file :: proc(name: string) -> ([]byte, bool) { buf: [300]byte; copy(buf[:], name as []byte); @@ -248,18 +246,18 @@ read_entire_file :: proc(name string) -> ([]byte, bool) { -heap_alloc :: proc(size int) -> rawptr { +heap_alloc :: proc(size: int) -> rawptr { return win32.HeapAlloc(win32.GetProcessHeap(), win32.HEAP_ZERO_MEMORY, size); } -heap_resize :: proc(ptr rawptr, new_size int) -> rawptr { +heap_resize :: proc(ptr: rawptr, new_size: int) -> rawptr { return win32.HeapReAlloc(win32.GetProcessHeap(), win32.HEAP_ZERO_MEMORY, ptr, new_size); } -heap_free :: proc(ptr rawptr) { +heap_free :: proc(ptr: rawptr) { win32.HeapFree(win32.GetProcessHeap(), 0, ptr); } -exit :: proc(code int) { +exit :: proc(code: int) { win32.ExitProcess(code as u32); } diff --git a/core/sync.odin b/core/sync.odin index 28f7cbaf1..72e83ae2d 100644 --- a/core/sync.odin +++ b/core/sync.odin @@ -1,52 +1,50 @@ -import { - win32 "sys/windows.odin" when ODIN_OS == "windows"; - "atomic.odin"; -} +#import win32 "sys/windows.odin" when ODIN_OS == "windows"; +#import "atomic.odin"; Semaphore :: struct { - handle win32.HANDLE; + handle: win32.HANDLE; } Mutex :: struct { - semaphore Semaphore; - counter i32; - owner i32; - recursion i32; + semaphore: Semaphore; + counter: i32; + owner: i32; + recursion: i32; } current_thread_id :: proc() -> i32 { return win32.GetCurrentThreadId() as i32; } -semaphore_init :: proc(s ^Semaphore) { +semaphore_init :: proc(s: ^Semaphore) { s.handle = win32.CreateSemaphoreA(nil, 0, 1<<31-1, nil); } -semaphore_destroy :: proc(s ^Semaphore) { +semaphore_destroy :: proc(s: ^Semaphore) { win32.CloseHandle(s.handle); } -semaphore_post :: proc(s ^Semaphore, count int) { +semaphore_post :: proc(s: ^Semaphore, count: int) { win32.ReleaseSemaphore(s.handle, count as i32, nil); } -semaphore_release :: proc(s ^Semaphore) #inline { semaphore_post(s, 1); } +semaphore_release :: proc(s: ^Semaphore) #inline { semaphore_post(s, 1); } -semaphore_wait :: proc(s ^Semaphore) { +semaphore_wait :: proc(s: ^Semaphore) { win32.WaitForSingleObject(s.handle, win32.INFINITE); } -mutex_init :: proc(m ^Mutex) { +mutex_init :: proc(m: ^Mutex) { atomic.store32(^m.counter, 0); atomic.store32(^m.owner, current_thread_id()); semaphore_init(^m.semaphore); m.recursion = 0; } -mutex_destroy :: proc(m ^Mutex) { +mutex_destroy :: proc(m: ^Mutex) { semaphore_destroy(^m.semaphore); } -mutex_lock :: proc(m ^Mutex) { +mutex_lock :: proc(m: ^Mutex) { thread_id := current_thread_id(); if atomic.fetch_add32(^m.counter, 1) > 0 { if thread_id != atomic.load32(^m.owner) { @@ -56,7 +54,7 @@ mutex_lock :: proc(m ^Mutex) { atomic.store32(^m.owner, thread_id); m.recursion++; } -mutex_try_lock :: proc(m ^Mutex) -> bool { +mutex_try_lock :: proc(m: ^Mutex) -> bool { thread_id := current_thread_id(); if atomic.load32(^m.owner) == thread_id { atomic.fetch_add32(^m.counter, 1); @@ -73,7 +71,7 @@ mutex_try_lock :: proc(m ^Mutex) -> bool { m.recursion++; return true; } -mutex_unlock :: proc(m ^Mutex) { +mutex_unlock :: proc(m: ^Mutex) { recursion: i32; thread_id := current_thread_id(); assert(thread_id == atomic.load32(^m.owner)); diff --git a/core/sys/windows.odin b/core/sys/windows.odin index 40839b4cd..09b3eb68e 100644 --- a/core/sys/windows.odin +++ b/core/sys/windows.odin @@ -16,7 +16,7 @@ LPARAM :: int; LRESULT :: int; ATOM :: i16; BOOL :: i32; -WNDPROC :: type proc(hwnd HWND, msg u32, wparam WPARAM, lparam LPARAM) -> LRESULT; +WNDPROC :: type proc(hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT; INVALID_HANDLE_VALUE :: (-1 as int) as HANDLE; @@ -56,61 +56,61 @@ SW_SHOW :: 5; POINT :: struct #ordered { - x, y i32; + x, y: i32; } WNDCLASSEXA :: struct #ordered { - size, style u32; - wnd_proc WNDPROC; - cls_extra, wnd_extra i32; - instance HINSTANCE; - icon HICON; - cursor HCURSOR; - background HBRUSH; - menu_name, class_name ^u8; - sm HICON; + size, style: u32; + wnd_proc: WNDPROC; + cls_extra, wnd_extra: i32; + instance: HINSTANCE; + icon: HICON; + cursor: HCURSOR; + background: HBRUSH; + menu_name, class_name: ^u8; + sm: HICON; } MSG :: struct #ordered { - hwnd HWND; - message u32; - wparam WPARAM; - lparam LPARAM; - time u32; - pt POINT; + hwnd: HWND; + message: u32; + wparam: WPARAM; + lparam: LPARAM; + time: u32; + pt: POINT; } RECT :: struct #ordered { - left i32; - top i32; - right i32; - bottom i32; + left: i32; + top: i32; + right: i32; + bottom: i32; } FILETIME :: struct #ordered { - lo, hi u32; + lo, hi: u32; } BY_HANDLE_FILE_INFORMATION :: struct #ordered { - file_attributes u32; + file_attributes: u32; creation_time, last_access_time, - last_write_time FILETIME; + last_write_time: FILETIME; volume_serial_number, file_size_high, file_size_low, number_of_links, file_index_high, - file_index_low u32; + file_index_low: u32; } FILE_ATTRIBUTE_DATA :: struct #ordered { - file_attributes u32; + file_attributes: u32; creation_time, last_access_time, - last_write_time FILETIME; + last_write_time: FILETIME; file_size_high, - file_size_low u32; + file_size_low: u32; } GET_FILEEX_INFO_LEVELS :: i32; @@ -118,42 +118,42 @@ GET_FILEEX_INFO_LEVELS :: i32; GetFileExInfoStandard: GET_FILEEX_INFO_LEVELS : 0; GetFileExMaxInfoLevel: GET_FILEEX_INFO_LEVELS : 1; -GetLastError :: proc() -> i32 #foreign #dll_import -ExitProcess :: proc(exit_code u32) #foreign #dll_import -GetDesktopWindow :: proc() -> HWND #foreign #dll_import -GetCursorPos :: proc(p ^POINT) -> i32 #foreign #dll_import -ScreenToClient :: proc(h HWND, p ^POINT) -> i32 #foreign #dll_import -GetModuleHandleA :: proc(module_name ^u8) -> HINSTANCE #foreign #dll_import -GetStockObject :: proc(fn_object i32) -> HGDIOBJ #foreign #dll_import -PostQuitMessage :: proc(exit_code i32) #foreign #dll_import -SetWindowTextA :: proc(hwnd HWND, c_string ^u8) -> BOOL #foreign #dll_import +GetLastError :: proc() -> i32 #foreign #dll_import +ExitProcess :: proc(exit_code: u32) #foreign #dll_import +GetDesktopWindow :: proc() -> HWND #foreign #dll_import +GetCursorPos :: proc(p: ^POINT) -> i32 #foreign #dll_import +ScreenToClient :: proc(h: HWND, p: ^POINT) -> i32 #foreign #dll_import +GetModuleHandleA :: proc(module_name: ^u8) -> HINSTANCE #foreign #dll_import +GetStockObject :: proc(fn_object: i32) -> HGDIOBJ #foreign #dll_import +PostQuitMessage :: proc(exit_code: i32) #foreign #dll_import +SetWindowTextA :: proc(hwnd: HWND, c_string: ^u8) -> BOOL #foreign #dll_import -QueryPerformanceFrequency :: proc(result ^i64) -> i32 #foreign #dll_import -QueryPerformanceCounter :: proc(result ^i64) -> i32 #foreign #dll_import +QueryPerformanceFrequency :: proc(result: ^i64) -> i32 #foreign #dll_import +QueryPerformanceCounter :: proc(result: ^i64) -> i32 #foreign #dll_import -Sleep :: proc(ms i32) -> i32 #foreign #dll_import +Sleep :: proc(ms: i32) -> i32 #foreign #dll_import -OutputDebugStringA :: proc(c_str ^u8) #foreign #dll_import +OutputDebugStringA :: proc(c_str: ^u8) #foreign #dll_import -RegisterClassExA :: proc(wc ^WNDCLASSEXA) -> ATOM #foreign #dll_import -CreateWindowExA :: proc(ex_style u32, - class_name, title ^u8, - style u32, - x, y, w, h i32, - parent HWND, menu HMENU, instance HINSTANCE, - param rawptr) -> HWND #foreign #dll_import +RegisterClassExA :: proc(wc: ^WNDCLASSEXA) -> ATOM #foreign #dll_import +CreateWindowExA :: proc(ex_style: u32, + class_name, title: ^u8, + style: u32, + x, y, w, h: i32, + parent: HWND, menu: HMENU, instance: HINSTANCE, + param: rawptr) -> HWND #foreign #dll_import -ShowWindow :: proc(hwnd HWND, cmd_show i32) -> BOOL #foreign #dll_import -TranslateMessage :: proc(msg ^MSG) -> BOOL #foreign #dll_import -DispatchMessageA :: proc(msg ^MSG) -> LRESULT #foreign #dll_import -UpdateWindow :: proc(hwnd HWND) -> BOOL #foreign #dll_import -PeekMessageA :: proc(msg ^MSG, hwnd HWND, - msg_filter_min, msg_filter_max, remove_msg u32) -> BOOL #foreign #dll_import +ShowWindow :: proc(hwnd: HWND, cmd_show: i32) -> BOOL #foreign #dll_import +TranslateMessage :: proc(msg: ^MSG) -> BOOL #foreign #dll_import +DispatchMessageA :: proc(msg: ^MSG) -> LRESULT #foreign #dll_import +UpdateWindow :: proc(hwnd: HWND) -> BOOL #foreign #dll_import +PeekMessageA :: proc(msg: ^MSG, hwnd: HWND, + msg_filter_min, msg_filter_max, remove_msg: u32) -> BOOL #foreign #dll_import -DefWindowProcA :: proc(hwnd HWND, msg u32, wparam WPARAM, lparam LPARAM) -> LRESULT #foreign #dll_import +DefWindowProcA :: proc(hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT #foreign #dll_import -AdjustWindowRect :: proc(rect ^RECT, style u32, menu BOOL) -> BOOL #foreign #dll_import +AdjustWindowRect :: proc(rect: ^RECT, style: u32, menu: BOOL) -> BOOL #foreign #dll_import GetActiveWindow :: proc() -> HWND #foreign #dll_import @@ -164,27 +164,27 @@ GetQueryPerformanceFrequency :: proc() -> i64 { } GetCommandLineA :: proc() -> ^u8 #foreign #dll_import -GetSystemMetrics :: proc(index i32) -> i32 #foreign #dll_import +GetSystemMetrics :: proc(index: i32) -> i32 #foreign #dll_import GetCurrentThreadId :: proc() -> u32 #foreign #dll_import // File Stuff -CloseHandle :: proc(h HANDLE) -> i32 #foreign #dll_import -GetStdHandle :: proc(h i32) -> HANDLE #foreign #dll_import -CreateFileA :: proc(filename ^u8, desired_access, share_mode u32, - security rawptr, - creation, flags_and_attribs u32, template_file HANDLE) -> HANDLE #foreign #dll_import -ReadFile :: proc(h HANDLE, buf rawptr, to_read u32, bytes_read ^i32, overlapped rawptr) -> BOOL #foreign #dll_import -WriteFile :: proc(h HANDLE, buf rawptr, len i32, written_result ^i32, overlapped rawptr) -> i32 #foreign #dll_import +CloseHandle :: proc(h: HANDLE) -> i32 #foreign #dll_import +GetStdHandle :: proc(h: i32) -> HANDLE #foreign #dll_import +CreateFileA :: proc(filename: ^u8, desired_access, share_mode: u32, + security: rawptr, + creation, flags_and_attribs: u32, template_file: HANDLE) -> HANDLE #foreign #dll_import +ReadFile :: proc(h: HANDLE, buf: rawptr, to_read: u32, bytes_read: ^i32, overlapped: rawptr) -> BOOL #foreign #dll_import +WriteFile :: proc(h: HANDLE, buf: rawptr, len: i32, written_result: ^i32, overlapped: rawptr) -> i32 #foreign #dll_import -GetFileSizeEx :: proc(file_handle HANDLE, file_size ^i64) -> BOOL #foreign #dll_import -GetFileAttributesExA :: proc(filename ^u8, info_level_id GET_FILEEX_INFO_LEVELS, file_info rawptr) -> BOOL #foreign #dll_import -GetFileInformationByHandle :: proc(file_handle HANDLE, file_info ^BY_HANDLE_FILE_INFORMATION) -> BOOL #foreign #dll_import +GetFileSizeEx :: proc(file_handle: HANDLE, file_size: ^i64) -> BOOL #foreign #dll_import +GetFileAttributesExA :: proc(filename: ^u8, info_level_id: GET_FILEEX_INFO_LEVELS, file_info: rawptr) -> BOOL #foreign #dll_import +GetFileInformationByHandle :: proc(file_handle: HANDLE, file_info: ^BY_HANDLE_FILE_INFORMATION) -> BOOL #foreign #dll_import -GetFileType :: proc(file_handle HANDLE) -> u32 #foreign #dll_import -SetFilePointer :: proc(file_handle HANDLE, distance_to_move i32, distance_to_move_high ^i32, move_method u32) -> u32 #foreign #dll_import +GetFileType :: proc(file_handle: HANDLE) -> u32 #foreign #dll_import +SetFilePointer :: proc(file_handle: HANDLE, distance_to_move: i32, distance_to_move_high: ^i32, move_method: u32) -> u32 #foreign #dll_import -SetHandleInformation :: proc(obj HANDLE, mask, flags u32) -> BOOL #foreign #dll_import +SetHandleInformation :: proc(obj: HANDLE, mask, flags: u32) -> BOOL #foreign #dll_import HANDLE_FLAG_INHERIT :: 1; HANDLE_FLAG_PROTECT_FROM_CLOSE :: 2; @@ -238,9 +238,9 @@ INVALID_SET_FILE_POINTER :: ~(0 as u32); -HeapAlloc :: proc (h HANDLE, flags u32, bytes int) -> rawptr #foreign #dll_import -HeapReAlloc :: proc (h HANDLE, flags u32, memory rawptr, bytes int) -> rawptr #foreign #dll_import -HeapFree :: proc (h HANDLE, flags u32, memory rawptr) -> BOOL #foreign #dll_import +HeapAlloc :: proc (h: HANDLE, flags: u32, bytes: int) -> rawptr #foreign #dll_import +HeapReAlloc :: proc (h: HANDLE, flags: u32, memory: rawptr, bytes: int) -> rawptr #foreign #dll_import +HeapFree :: proc (h: HANDLE, flags: u32, memory: rawptr) -> BOOL #foreign #dll_import GetProcessHeap :: proc () -> HANDLE #foreign #dll_import @@ -249,29 +249,29 @@ HEAP_ZERO_MEMORY :: 0x00000008; // Synchronization SECURITY_ATTRIBUTES :: struct #ordered { - length u32; - security_descriptor rawptr; - inherit_handle BOOL; + length: u32; + security_descriptor: rawptr; + inherit_handle: BOOL; } INFINITE :: 0xffffffff; -CreateSemaphoreA :: proc(attributes ^SECURITY_ATTRIBUTES, initial_count, maximum_count i32, name ^byte) -> HANDLE #foreign #dll_import -ReleaseSemaphore :: proc(semaphore HANDLE, release_count i32, previous_count ^i32) -> BOOL #foreign #dll_import -WaitForSingleObject :: proc(handle HANDLE, milliseconds u32) -> u32 #foreign #dll_import +CreateSemaphoreA :: proc(attributes: ^SECURITY_ATTRIBUTES, initial_count, maximum_count: i32, name: ^byte) -> HANDLE #foreign #dll_import +ReleaseSemaphore :: proc(semaphore: HANDLE, release_count: i32, previous_count: ^i32) -> BOOL #foreign #dll_import +WaitForSingleObject :: proc(handle: HANDLE, milliseconds: u32) -> u32 #foreign #dll_import -InterlockedCompareExchange :: proc(dst ^i32, exchange, comparand i32) -> i32 #foreign -InterlockedExchange :: proc(dst ^i32, desired i32) -> i32 #foreign -InterlockedExchangeAdd :: proc(dst ^i32, desired i32) -> i32 #foreign -InterlockedAnd :: proc(dst ^i32, desired i32) -> i32 #foreign -InterlockedOr :: proc(dst ^i32, desired i32) -> i32 #foreign +InterlockedCompareExchange :: proc(dst: ^i32, exchange, comparand: i32) -> i32 #foreign +InterlockedExchange :: proc(dst: ^i32, desired: i32) -> i32 #foreign +InterlockedExchangeAdd :: proc(dst: ^i32, desired: i32) -> i32 #foreign +InterlockedAnd :: proc(dst: ^i32, desired: i32) -> i32 #foreign +InterlockedOr :: proc(dst: ^i32, desired: i32) -> i32 #foreign -InterlockedCompareExchange64 :: proc(dst ^i64, exchange, comparand i64) -> i64 #foreign -InterlockedExchange64 :: proc(dst ^i64, desired i64) -> i64 #foreign -InterlockedExchangeAdd64 :: proc(dst ^i64, desired i64) -> i64 #foreign -InterlockedAnd64 :: proc(dst ^i64, desired i64) -> i64 #foreign -InterlockedOr64 :: proc(dst ^i64, desired i64) -> i64 #foreign +InterlockedCompareExchange64 :: proc(dst: ^i64, exchange, comparand: i64) -> i64 #foreign +InterlockedExchange64 :: proc(dst: ^i64, desired: i64) -> i64 #foreign +InterlockedExchangeAdd64 :: proc(dst: ^i64, desired: i64) -> i64 #foreign +InterlockedAnd64 :: proc(dst: ^i64, desired: i64) -> i64 #foreign +InterlockedOr64 :: proc(dst: ^i64, desired: i64) -> i64 #foreign _mm_pause :: proc() #foreign ReadWriteBarrier :: proc() #foreign @@ -281,24 +281,24 @@ ReadBarrier :: proc() #foreign // GDI BITMAPINFOHEADER :: struct #ordered { - size u32; - width, height i32; - planes, bit_count i16; - compression u32; - size_image u32; - x_pels_per_meter i32; - y_pels_per_meter i32; - clr_used u32; - clr_important u32; + size: u32; + width, height: i32; + planes, bit_count: i16; + compression: u32; + size_image: u32; + x_pels_per_meter: i32; + y_pels_per_meter: i32; + clr_used: u32; + clr_important: u32; } BITMAPINFO :: struct #ordered { - using header BITMAPINFOHEADER; - colors [1]RGBQUAD; + using header: BITMAPINFOHEADER; + colors: [1]RGBQUAD; } RGBQUAD :: struct #ordered { - blue, green, red, reserved byte; + blue, green, red, reserved: byte; } BI_RGB :: 0; @@ -306,20 +306,20 @@ DIB_RGB_COLORS :: 0x00; SRCCOPY: u32 : 0x00cc0020; -StretchDIBits :: proc (hdc HDC, - x_dst, y_dst, width_dst, height_dst i32, - x_src, y_src, width_src, header_src i32, - bits rawptr, bits_info ^BITMAPINFO, - usage u32, - rop u32) -> i32 #foreign #dll_import +StretchDIBits :: proc (hdc: HDC, + x_dst, y_dst, width_dst, height_dst: i32, + x_src, y_src, width_src, header_src: i32, + bits: rawptr, bits_info: ^BITMAPINFO, + usage: u32, + rop: u32) -> i32 #foreign #dll_import -LoadLibraryA :: proc (c_str ^u8) -> HMODULE #foreign -FreeLibrary :: proc (h HMODULE) #foreign -GetProcAddress :: proc (h HMODULE, c_str ^u8) -> PROC #foreign +LoadLibraryA :: proc (c_str: ^u8) -> HMODULE #foreign +FreeLibrary :: proc (h: HMODULE) #foreign +GetProcAddress :: proc (h: HMODULE, c_str: ^u8) -> PROC #foreign -GetClientRect :: proc(hwnd HWND, rect ^RECT) -> BOOL #foreign +GetClientRect :: proc(hwnd: HWND, rect: ^RECT) -> BOOL #foreign @@ -348,13 +348,13 @@ PFD_STEREO_DONTCARE :: 0x80000000; HGLRC :: HANDLE; PROC :: type proc() #cc_c; -wglCreateContextAttribsARBType :: proc(hdc HDC, hshareContext rawptr, attribList ^i32) -> HGLRC; +wglCreateContextAttribsARBType :: proc(hdc: HDC, hshareContext: rawptr, attribList: ^i32) -> HGLRC; PIXELFORMATDESCRIPTOR :: struct #ordered { size, version, - flags u32; + flags: u32; pixel_type, color_bits, @@ -375,18 +375,18 @@ PIXELFORMATDESCRIPTOR :: struct #ordered { stencil_bits, aux_buffers, layer_type, - reserved byte; + reserved: byte; layer_mask, visible_mask, - damage_mask u32; + damage_mask: u32; } -GetDC :: proc(h HANDLE) -> HDC #foreign -SetPixelFormat :: proc(hdc HDC, pixel_format i32, pfd ^PIXELFORMATDESCRIPTOR ) -> BOOL #foreign #dll_import -ChoosePixelFormat :: proc(hdc HDC, pfd ^PIXELFORMATDESCRIPTOR) -> i32 #foreign #dll_import -SwapBuffers :: proc(hdc HDC) -> BOOL #foreign #dll_import -ReleaseDC :: proc(wnd HWND, hdc HDC) -> i32 #foreign #dll_import +GetDC :: proc(h: HANDLE) -> HDC #foreign +SetPixelFormat :: proc(hdc: HDC, pixel_format: i32, pfd: ^PIXELFORMATDESCRIPTOR ) -> BOOL #foreign #dll_import +ChoosePixelFormat :: proc(hdc: HDC, pfd: ^PIXELFORMATDESCRIPTOR) -> i32 #foreign #dll_import +SwapBuffers :: proc(hdc: HDC) -> BOOL #foreign #dll_import +ReleaseDC :: proc(wnd: HWND, hdc: HDC) -> i32 #foreign #dll_import WGL_CONTEXT_MAJOR_VERSION_ARB :: 0x2091; WGL_CONTEXT_MINOR_VERSION_ARB :: 0x2092; @@ -394,17 +394,17 @@ WGL_CONTEXT_PROFILE_MASK_ARB :: 0x9126; WGL_CONTEXT_CORE_PROFILE_BIT_ARB :: 0x0001; WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB :: 0x0002; -wglCreateContext :: proc(hdc HDC) -> HGLRC #foreign #dll_import -wglMakeCurrent :: proc(hdc HDC, hglrc HGLRC) -> BOOL #foreign #dll_import -wglGetProcAddress :: proc(c_str ^u8) -> PROC #foreign #dll_import -wglDeleteContext :: proc(hglrc HGLRC) -> BOOL #foreign #dll_import +wglCreateContext :: proc(hdc: HDC) -> HGLRC #foreign #dll_import +wglMakeCurrent :: proc(hdc: HDC, hglrc: HGLRC) -> BOOL #foreign #dll_import +wglGetProcAddress :: proc(c_str: ^u8) -> PROC #foreign #dll_import +wglDeleteContext :: proc(hglrc: HGLRC) -> BOOL #foreign #dll_import -GetKeyState :: proc(v_key i32) -> i16 #foreign #dll_import -GetAsyncKeyState :: proc(v_key i32) -> i16 #foreign #dll_import +GetKeyState :: proc(v_key: i32) -> i16 #foreign #dll_import +GetAsyncKeyState :: proc(v_key: i32) -> i16 #foreign #dll_import -is_key_down :: proc(key Key_Code) -> bool #inline { return GetAsyncKeyState(key as i32) < 0; } +is_key_down :: proc(key: Key_Code) -> bool #inline { return GetAsyncKeyState(key as i32) < 0; } Key_Code :: enum i32 { LBUTTON = 0x01, diff --git a/core/utf8.odin b/core/utf8.odin index f3de5f3d0..45ff89ee3 100644 --- a/core/utf8.odin +++ b/core/utf8.odin @@ -9,7 +9,7 @@ SURROGATE_MIN :: 0xd800; SURROGATE_MAX :: 0xdfff; Accept_Range :: struct { - lo, hi u8; + lo, hi: u8; } accept_ranges := [5]Accept_Range{ @@ -40,7 +40,7 @@ accept_sizes := [256]byte{ 0x34, 0x04, 0x04, 0x04, 0x44, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, // 0xf0-0xff }; -encode_rune :: proc(r rune) -> ([4]byte, int) { +encode_rune :: proc(r: rune) -> ([4]byte, int) { buf: [4]byte; i := r as u32; mask: byte : 0x3f; @@ -74,7 +74,7 @@ encode_rune :: proc(r rune) -> ([4]byte, int) { return buf, 4; } -decode_rune :: proc(s string) -> (rune, int) { +decode_rune :: proc(s: string) -> (rune, int) { n := s.count; if n < 1 { return RUNE_ERROR, 0; @@ -119,7 +119,7 @@ decode_rune :: proc(s string) -> (rune, int) { } -valid_rune :: proc(r rune) -> bool { +valid_rune :: proc(r: rune) -> bool { if r < 0 { return false; } else if SURROGATE_MIN <= r && r <= SURROGATE_MAX { @@ -130,7 +130,7 @@ valid_rune :: proc(r rune) -> bool { return true; } -valid_string :: proc(s string) -> bool { +valid_string :: proc(s: string) -> bool { n := s.count; for i := 0; i < n; { si := s[i]; @@ -163,7 +163,7 @@ valid_string :: proc(s string) -> bool { return true; } -rune_count :: proc(s string) -> int { +rune_count :: proc(s: string) -> int { count := 0; n := s.count; for i := 0; i < n; count++ { @@ -200,7 +200,7 @@ rune_count :: proc(s string) -> int { } -rune_size :: proc(r rune) -> int { +rune_size :: proc(r: rune) -> int { match { case r < 0: return -1; case r <= 1<<7 - 1: return 1; diff --git a/src/checker/checker.c b/src/checker/checker.c index ace13dcab..a43a7853b 100644 --- a/src/checker/checker.c +++ b/src/checker/checker.c @@ -1235,31 +1235,14 @@ void check_global_collect_entities_from_file(Checker *c, Scope *parent_scope, As } case_end; - case_ast_node(gd, GenericDecl, decl); + case_ast_node(id, ImportDecl, decl); if (!parent_scope->is_file) { - // NOTE(bill): Within a procedure, variables must be in order + // NOTE(bill): _Should_ be caught by the parser + // TODO(bill): Better error handling if it isn't continue; } - - for_array(iota, gd->specs) { - AstNode *spec = gd->specs.e[iota]; - switch (spec->kind) { - case AstNode_BadDecl: - break; - case_ast_node(is, ImportSpec, spec); - if (!parent_scope->is_file) { - // NOTE(bill): _Should_ be caught by the parser - // TODO(bill): Better error handling if it isn't - continue; - } - DelayedDecl di = {parent_scope, spec}; - array_add(&c->delayed_imports, di); - case_end; - default: - error(ast_node_token(spec), "Invalid specification in declaration: `%.*s`", LIT(ast_node_strings[spec->kind])); - break; - } - } + DelayedDecl di = {parent_scope, decl}; + array_add(&c->delayed_imports, di); case_end; case_ast_node(fl, ForeignLibrary, decl); if (!parent_scope->is_file) { @@ -1283,8 +1266,8 @@ void check_global_collect_entities_from_file(Checker *c, Scope *parent_scope, As void check_import_entities(Checker *c, MapScope *file_scopes) { for_array(i, c->delayed_imports) { Scope *parent_scope = c->delayed_imports.e[i].parent; - AstNode *spec = c->delayed_imports.e[i].decl; - ast_node(id, ImportSpec, spec); + AstNode *decl = c->delayed_imports.e[i].decl; + ast_node(id, ImportDecl, decl); Token token = id->relpath; HashKey key = hash_string(id->fullpath); @@ -1342,7 +1325,7 @@ void check_import_entities(Checker *c, MapScope *file_scopes) { } // NOTE(bill): Do not add other imported entities add_entity(c, parent_scope, NULL, e); - if (id->keyword == Token_import) { // `#import`ed entities don't get exported + if (id->is_import) { // `#import`ed entities don't get exported HashKey key = hash_string(e->token.string); map_entity_set(&parent_scope->implicit, key, e); } diff --git a/src/checker/decl.c b/src/checker/decl.c index ec236ef2f..4fffc81b4 100644 --- a/src/checker/decl.c +++ b/src/checker/decl.c @@ -283,7 +283,7 @@ void check_const_decl(Checker *c, Entity *e, AstNode *type_expr, AstNode *init, check_init_constant(c, e, &operand); c->context.iota = (ExactValue){0}; - if (e->type == t_invalid) { + if (operand.mode == Addressing_Invalid) { error(e->token, "Illegal cyclic declaration"); } } diff --git a/src/parser.c b/src/parser.c index 8546e692a..086bf9bd7 100644 --- a/src/parser.c +++ b/src/parser.c @@ -250,21 +250,6 @@ AST_NODE_KIND(_ComplexStmtBegin, "", i32) \ }) \ AST_NODE_KIND(_ComplexStmtEnd, "", i32) \ AST_NODE_KIND(_StmtEnd, "", i32) \ -AST_NODE_KIND(_SpecBegin, "", i32) \ - AST_NODE_KIND(TypeSpec, "type specification", struct { \ - AstNode *name; \ - AstNode *type; \ - AstNode *note; \ - }) \ - AST_NODE_KIND(ImportSpec, "import specification", struct { \ - TokenKind keyword; \ - Token relpath; \ - String fullpath; \ - Token import_name; \ - AstNode *cond; \ - AstNode *note; \ - }) \ -AST_NODE_KIND(_SpecEnd, "", i32) \ AST_NODE_KIND(_DeclBegin, "", i32) \ AST_NODE_KIND(BadDecl, "bad declaration", struct { Token begin, end; }) \ AST_NODE_KIND(GenericDecl, "declaration", struct { \ @@ -281,6 +266,15 @@ AST_NODE_KIND(_DeclBegin, "", i32) \ AstNodeArray values; \ u64 tags; \ }) \ + AST_NODE_KIND(ImportDecl, "import declaration", struct { \ + Token token; \ + bool is_import; \ + Token relpath; \ + String fullpath; \ + Token import_name; \ + AstNode *cond; \ + AstNode *note; \ + }) \ AST_NODE_KIND(ForeignLibrary, "foreign library", struct { \ Token token, filepath; \ String base_dir; \ @@ -496,14 +490,11 @@ Token ast_node_token(AstNode *node) { return node->GenericDecl.token; case AstNode_ValueDecl: return ast_node_token(node->ValueDecl.names.e[0]); - + case AstNode_ImportDecl: + return node->ImportDecl.token; case AstNode_ForeignLibrary: return node->ForeignLibrary.token; - case AstNode_TypeSpec: - return ast_node_token(node->TypeSpec.name); - case AstNode_ImportSpec: - return node->ImportSpec.relpath; case AstNode_Field: { if (node->Field.names.count > 0) { @@ -1081,20 +1072,14 @@ AstNode *make_value_decl(AstFile *f, bool is_var, AstNodeArray names, AstNode *t return result; } -AstNode *make_type_spec(AstFile *f, AstNode *name, AstNode *type) { - AstNode *result = make_node(f, AstNode_TypeSpec); - result->TypeSpec.name = name; - result->TypeSpec.type = type; - return result; -} - -AstNode *make_import_spec(AstFile *f, TokenKind keyword, Token relpath, Token import_name, AstNode *cond) { - AstNode *result = make_node(f, AstNode_ImportSpec); - result->ImportSpec.keyword = keyword; - result->ImportSpec.relpath = relpath; - result->ImportSpec.import_name = import_name; - result->ImportSpec.cond = cond; +AstNode *make_import_decl(AstFile *f, Token token, bool is_import, Token relpath, Token import_name, AstNode *cond) { + AstNode *result = make_node(f, AstNode_ImportDecl); + result->ImportDecl.token = token; + result->ImportDecl.is_import = is_import; + result->ImportDecl.relpath = relpath; + result->ImportDecl.import_name = import_name; + result->ImportDecl.cond = cond; return result; } @@ -1206,13 +1191,6 @@ void fix_advance_to_next_stmt(AstFile *f) { case Token_Semicolon: return; - // case Token_var: - // case Token_const: - case Token_type: - case Token_proc: - case Token_import: - case Token_include: - case Token_if: case Token_when: case Token_return: @@ -1294,12 +1272,6 @@ bool is_semicolon_optional_for_node(AstFile *f, AstNode *s) { } } break; - - case AstNode_TypeSpec: - if (f->prev_token.kind == Token_CloseBrace) { - return true; - } - break; } return false; @@ -1787,8 +1759,8 @@ AstNode *parse_operand(AstFile *f, bool lhs) { if ((tags & ProcTag_foreign) != 0) { return make_proc_lit(f, type, NULL, tags, foreign_name, link_name); } - if ((tags & ProcTag_link_name) != 0) { - syntax_error(token, "A procedure typed cannot be tagged with `#link_name`"); + if (tags != 0) { + syntax_error(token, "A procedure type cannot have tags"); } return type; @@ -1802,8 +1774,8 @@ AstNode *parse_operand(AstFile *f, bool lhs) { if (type != NULL) { // TODO(bill): Is this correct??? // NOTE(bill): Sanity check as identifiers should be handled already - // TokenPos pos = ast_node_token(type).pos; - // GB_ASSERT_MSG(type->kind != AstNode_Ident, "Type Cannot be identifier %.*s(%td:%td)", LIT(pos.file), pos.line, pos.column); + TokenPos pos = ast_node_token(type).pos; + GB_ASSERT_MSG(type->kind != AstNode_Ident, "Type cannot be identifier %.*s(%td:%td)", LIT(pos.file), pos.line, pos.column); return type; } break; @@ -2138,153 +2110,6 @@ AstNode *parse_type(AstFile *f) { return type; } - -#define PARSE_SPEC_PROC(name) AstNode *(name)(AstFile *f, TokenKind keyword, isize index) -typedef PARSE_SPEC_PROC(*ParserSpecProc); - - -AstNode *parse_generic_decl(AstFile *f, TokenKind keyword, ParserSpecProc spec_proc) { - Token token = expect_token(f, keyword); - Token open = {0}, close = {0}; - AstNodeArray specs = {0}; - if (f->curr_token.kind == Token_OpenBrace) { - open = expect_token(f, Token_OpenBrace); - array_init(&specs, heap_allocator()); - - - for (isize index = 0; - f->curr_token.kind != Token_CloseBrace && - f->curr_token.kind != Token_EOF; - index++) { - AstNode *spec = spec_proc(f, keyword, index); - array_add(&specs, spec); - expect_semicolon(f, spec); - } - - close = expect_token(f, Token_CloseBrace); - } else { - array_init_reserve(&specs, heap_allocator(), 1); - array_add(&specs, spec_proc(f, keyword, 0)); - } - - return make_generic_decl(f, token, open, close, specs, 0, false); -} - -// PARSE_SPEC_PROC(parse_value_spec) { -// AstNodeArray names = parse_identfier_list(f); -// parse_check_name_list_for_reserves(f, names); -// AstNode *type = parse_type_attempt(f); -// AstNodeArray values = {0}; - -// if (allow_token(f, Token_Eq)) { -// values = parse_rhs_expr_list(f); -// } - -// if (values.count > names.count) { -// syntax_error(f->curr_token, "Too many values on the right hand side of the declaration"); -// } - -// switch (keyword) { -// case Token_var: -// if (type == NULL && values.count == 0 && names.count > 0) { -// syntax_error(f->curr_token, "Missing type or initialization"); -// return make_bad_decl(f, f->curr_token, f->curr_token); -// } -// break; -// case Token_const: -// if (values.count == 0 && (index == 0 || type != NULL)) { -// syntax_error(f->curr_token, "Missing constant value"); -// return make_bad_decl(f, f->curr_token, f->curr_token); -// } -// break; -// } - -// // TODO(bill): Fix this so it does not require it -// if (values.e == NULL) { -// values = make_ast_node_array(f); -// } - -// return make_value_spec(f, keyword, names, type, values); -// } -PARSE_SPEC_PROC(parse_type_spec) { - AstNode *name = parse_identifier(f); - AstNode *type = parse_type(f); - return make_type_spec(f, name, type); -} -PARSE_SPEC_PROC(parse_import_spec) { - AstNode *cond = NULL; - Token import_name = {0}; - - switch (f->curr_token.kind) { - case Token_Period: - import_name = f->curr_token; - import_name.kind = Token_Ident; - next_token(f); - break; - case Token_Ident: - import_name = f->curr_token; - next_token(f); - break; - default: - import_name.pos = f->curr_token.pos; - break; - } - - if (str_eq(import_name.string, str_lit("_"))) { - syntax_error(import_name, "Illegal import name: `_`"); - } - - Token file_path = expect_token_after(f, Token_String, "import"); - if (allow_token(f, Token_when)) { - cond = parse_expr(f, false); - } - - AstNode *spec = NULL; - if (f->curr_proc != NULL) { - syntax_error(import_name, "You cannot use `import` within a procedure. This must be done at the file scope"); - spec = make_bad_decl(f, import_name, file_path); - } else { - spec = make_import_spec(f, Token_import, file_path, import_name, cond); - } - return spec; -} -PARSE_SPEC_PROC(parse_include_spec) { - AstNode *cond = NULL; - Token file_path = expect_token_after(f, Token_String, "include"); - Token import_name = file_path; - import_name.string = str_lit("."); - - if (allow_token(f, Token_when)) { - cond = parse_expr(f, false); - } - - AstNode *spec = NULL; - if (f->curr_proc != NULL) { - syntax_error(import_name, "You cannot use `include` within a procedure. This must be done at the file scope"); - spec = make_bad_decl(f, import_name, file_path); - } else { - spec = make_import_spec(f, Token_include, file_path, import_name, cond); - } - return spec; -} - -AstNode *parse_decl(AstFile *f) { - switch (f->curr_token.kind) { - case Token_import: - return parse_generic_decl(f, f->curr_token.kind, parse_import_spec); - case Token_include: - return parse_generic_decl(f, f->curr_token.kind, parse_include_spec); - - default: { - Token token = f->curr_token; - syntax_error(token, "Expected a declaration"); - fix_advance_to_next_stmt(f); - return make_bad_decl(f, token, f->curr_token); - } - } -} - - AstNode *parse_simple_stmt(AstFile *f) { Token start_token = f->curr_token; AstNodeArray lhs = parse_lhs_expr_list(f); @@ -2458,7 +2283,7 @@ AstNodeArray parse_field_list(AstFile *f, isize *name_count_, bool allow_using, name_count += names.count; - // expect_token_after(f, Token_Colon, "parameter list"); + expect_token_after(f, Token_Colon, "parameter list"); AstNode *type = NULL; if (ellipsis_ok && f->curr_token.kind == Token_Ellipsis) { @@ -3101,16 +2926,6 @@ AstNode *parse_stmt(AstFile *f) { expect_semicolon(f, s); return s; - // case Token_var: - // case Token_const: - case Token_proc: - case Token_type: - case Token_import: - case Token_include: - s = parse_decl(f); - expect_semicolon(f, s); - return s; - case Token_if: return parse_if_stmt(f); case Token_when: return parse_when_stmt(f); case Token_for: return parse_for_stmt(f); @@ -3183,7 +2998,63 @@ AstNode *parse_stmt(AstFile *f) { Token hash_token = expect_token(f, Token_Hash); Token name = expect_token(f, Token_Ident); String tag = name.string; - if (str_eq(tag, str_lit("shared_global_scope"))) { + if (str_eq(tag, str_lit("import"))) { + AstNode *cond = NULL; + Token import_name = {0}; + + switch (f->curr_token.kind) { + case Token_Period: + import_name = f->curr_token; + import_name.kind = Token_Ident; + next_token(f); + break; + case Token_Ident: + import_name = f->curr_token; + next_token(f); + break; + default: + import_name.pos = f->curr_token.pos; + break; + } + + if (str_eq(import_name.string, str_lit("_"))) { + syntax_error(import_name, "Illegal #import name: `_`"); + } + + Token file_path = expect_token_after(f, Token_String, "#import"); + if (allow_token(f, Token_when)) { + cond = parse_expr(f, false); + } + + AstNode *decl = NULL; + if (f->curr_proc != NULL) { + syntax_error(import_name, "You cannot use `#import` within a procedure. This must be done at the file scope"); + decl = make_bad_decl(f, import_name, file_path); + } else { + decl = make_import_decl(f, hash_token, true, file_path, import_name, cond); + } + expect_semicolon(f, decl); + return decl; + } else if (str_eq(tag, str_lit("include"))) { + AstNode *cond = NULL; + Token file_path = expect_token_after(f, Token_String, "#include"); + Token import_name = file_path; + import_name.string = str_lit("."); + + if (allow_token(f, Token_when)) { + cond = parse_expr(f, false); + } + + AstNode *decl = NULL; + if (f->curr_proc != NULL) { + syntax_error(import_name, "You cannot use `#include` within a procedure. This must be done at the file scope"); + decl = make_bad_decl(f, import_name, file_path); + } else { + decl = make_import_decl(f, hash_token, false, file_path, import_name, cond); + } + expect_semicolon(f, decl); + return decl; + } else if (str_eq(tag, str_lit("shared_global_scope"))) { if (f->curr_proc == NULL) { f->is_global_scope = true; s = make_empty_stmt(f, f->curr_token); @@ -3461,41 +3332,34 @@ void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, AstNodeArray node->kind != AstNode_EmptyStmt) { // NOTE(bill): Sanity check syntax_error_node(node, "Only declarations are allowed at file scope %.*s", LIT(ast_node_strings[node->kind])); - } else if (node->kind == AstNode_GenericDecl) { - AstNodeGenericDecl *gd = &node->GenericDecl; - for_array(spec_index, gd->specs) { - AstNode *spec = gd->specs.e[spec_index]; - switch (spec->kind) { - case_ast_node(is, ImportSpec, spec); - String file_str = is->relpath.string; + } else if (node->kind == AstNode_ImportDecl) { + ast_node(id, ImportDecl, node); + String file_str = id->relpath.string; - if (!is_import_path_valid(file_str)) { - if (is->keyword == Token_include) { - syntax_error_node(node, "Invalid #include path: `%.*s`", LIT(file_str)); - } else { - syntax_error_node(node, "Invalid #import path: `%.*s`", LIT(file_str)); - } - // NOTE(bill): It's a naughty name - gd->specs.e[spec_index] = make_bad_decl(f, is->relpath, is->relpath); - continue; - } + if (!is_import_path_valid(file_str)) { + if (id->is_import) { + syntax_error_node(node, "Invalid import path: `%.*s`", LIT(file_str)); + } else { + syntax_error_node(node, "Invalid include path: `%.*s`", LIT(file_str)); + } + // NOTE(bill): It's a naughty name + decls.e[i] = make_bad_decl(f, id->relpath, id->relpath); + continue; + } - gbAllocator allocator = heap_allocator(); // TODO(bill): Change this allocator + gbAllocator allocator = heap_allocator(); // TODO(bill): Change this allocator - String rel_path = get_fullpath_relative(allocator, base_dir, file_str); - String import_file = rel_path; - if (!gb_file_exists(cast(char *)rel_path.text)) { // NOTE(bill): This should be null terminated - String abs_path = get_fullpath_core(allocator, file_str); - if (gb_file_exists(cast(char *)abs_path.text)) { - import_file = abs_path; - } - } - - is->fullpath = import_file; - try_add_import_path(p, import_file, file_str, ast_node_token(node).pos); - case_end; + String rel_path = get_fullpath_relative(allocator, base_dir, file_str); + String import_file = rel_path; + if (!gb_file_exists(cast(char *)rel_path.text)) { // NOTE(bill): This should be null terminated + String abs_path = get_fullpath_core(allocator, file_str); + if (gb_file_exists(cast(char *)abs_path.text)) { + import_file = abs_path; } } + + id->fullpath = import_file; + try_add_import_path(p, import_file, file_str, ast_node_token(node).pos); } else if (node->kind == AstNode_ForeignLibrary) { AstNodeForeignLibrary *fl = &node->ForeignLibrary; String file_str = fl->filepath.string; diff --git a/src/tokenizer.c b/src/tokenizer.c index 7138dc6ae..2625dbf42 100644 --- a/src/tokenizer.c +++ b/src/tokenizer.c @@ -86,8 +86,8 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \ TOKEN_KIND(Token_proc, "proc"), \ /* TOKEN_KIND(Token_var, "var"), */\ /* TOKEN_KIND(Token_const, "const"), */\ - TOKEN_KIND(Token_import, "import"), \ - TOKEN_KIND(Token_include, "include"), \ + /* TOKEN_KIND(Token_import, "import"), */\ + /* TOKEN_KIND(Token_include, "include"), */\ TOKEN_KIND(Token_macro, "macro"), \ TOKEN_KIND(Token_match, "match"), \ TOKEN_KIND(Token_break, "break"), \ @@ -824,7 +824,6 @@ Token tokenizer_get_token(Tokenizer *t) { break; case ';': token.kind = Token_Semicolon; - token.string = str_lit(";"); break; case ',': token.kind = Token_Comma;