aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2017-01-27 23:02:55 +0000
committerGinger Bill <bill@gingerbill.org>2017-01-27 23:02:55 +0000
commit31aacd5bf435224c7d8f9b19359175d3e6d25660 (patch)
treeab9d62de198d9874e1afb7212ab3feb46fde4f01
parent92453369c5558feaaaa116fbc54968b087e1aeab (diff)
Fix parsing for block/if expression within if/for/etc. statementsv0.0.6
-rw-r--r--build.bat2
-rw-r--r--code/demo.odin29
-rw-r--r--code/old_demos/demo001.odin172
-rw-r--r--code/punity.odin324
-rw-r--r--core/fmt.odin32
-rw-r--r--src/check_decl.c9
-rw-r--r--src/check_expr.c5
-rw-r--r--src/main.c2
-rw-r--r--src/parser.c13
-rw-r--r--src/types.c4
10 files changed, 311 insertions, 281 deletions
diff --git a/build.bat b/build.bat
index 86c81eb3f..33a71c2a4 100644
--- a/build.bat
+++ b/build.bat
@@ -46,7 +46,7 @@ cl %compiler_settings% "src\main.c" ^
/link %linker_settings% -OUT:%exe_name% ^
&& odin run code/demo.odin
rem && odin build_dll code/example.odin ^
- rem && odin run code/demo.odin
+ rem odin run code/punity.odin
rem pushd src\asm
rem nasm hellope.asm -fwin64 -o hellope.obj ^
diff --git a/code/demo.odin b/code/demo.odin
index ece779514..a8e7b0726 100644
--- a/code/demo.odin
+++ b/code/demo.odin
@@ -1,12 +1,13 @@
#import "fmt.odin";
#import "utf8.odin";
-#import "atomic.odin";
-#import "hash.odin";
-#import "math.odin";
-#import "mem.odin";
-#import "opengl.odin";
-#import "os.odin";
-#import "sync.odin";
+// #import "atomic.odin";
+// #import "hash.odin";
+// #import "math.odin";
+// #import "mem.odin";
+// #import "opengl.odin";
+// #import "os.odin";
+// #import "sync.odin";
+// #import win32 "sys/windows.odin";
main :: proc() {
syntax();
@@ -15,8 +16,8 @@ main :: proc() {
syntax :: proc() {
// Cyclic type checking
// Uncomment to see the error
- // A :: struct { b: B };
- // B :: struct { a: A };
+ // A :: struct {b: B};
+ // B :: struct {a: A};
x: int;
y := cast(f32)x;
@@ -40,10 +41,10 @@ syntax :: proc() {
};
Thing2 :: struct {x: f32, y: int, z: ^[]int};
- // Slice interals are not just a `ptr+count`
+ // Slice interals are now just a `ptr+count`
slice: []int; compile_assert(size_of_val(slice) == 2*size_of(int));
- // Helper type - Help the reader understand that it is quicker
+ // Helper type - Help the reader understand what it is quicker
My_Int :: type int;
My_Proc :: type proc(int) -> f32;
@@ -62,6 +63,9 @@ syntax :: proc() {
// ++ and -- have been removed
// x++;
// x--;
+ // Question: Should they be added again?
+ // They were removed as they are redundant and statements, not expressions
+ // like in C/C++
// You can now build files as a `.dll`
@@ -167,7 +171,6 @@ special_expressions :: proc() {
}
loops :: proc() {
-
// The C-style for loop
for i := 0; i < 123; i += 1 {
break;
@@ -259,7 +262,7 @@ procedure_overloading :: proc() {
}
- a: i32 = #line;
+ a: i32 = 123;
b: f32;
c: rawptr;
fmt.println(foo(^a));
diff --git a/code/old_demos/demo001.odin b/code/old_demos/demo001.odin
index b5ff5f51d..7e80f0d1b 100644
--- a/code/old_demos/demo001.odin
+++ b/code/old_demos/demo001.odin
@@ -1,9 +1,9 @@
-#import "fmt.odin"
-#import "os.odin"
-#import "mem.odin"
-// #import "http_test.odin" as ht
-// #import "game.odin" as game
-// #import "punity.odin" as pn
+#import "fmt.odin";
+#import "os.odin";
+#import "mem.odin";
+// #import "http_test.odin" as ht;
+// #import "game.odin" as game;
+// #import "punity.odin" as pn;
main :: proc() {
// struct_padding()
@@ -26,58 +26,58 @@ main :: proc() {
struct_padding :: proc() {
{
A :: struct {
- a: u8
- b: u32
- c: u16
+ a: u8,
+ b: u32,
+ c: u16,
}
B :: struct {
- a: [7]u8
- b: [3]u16
- c: u8
- d: u16
+ a: [7]u8,
+ b: [3]u16,
+ c: u8,
+ d: u16,
}
- fmt.println("size_of(A):", size_of(A))
- fmt.println("size_of(B):", size_of(B))
+ fmt.println("size_of(A):", size_of(A));
+ fmt.println("size_of(B):", size_of(B));
// n.b. http://cbloomrants.blogspot.co.uk/2012/07/07-23-12-structs-are-not-what-you-want.html
}
{
A :: struct #ordered {
- a: u8
- b: u32
- c: u16
+ a: u8,
+ b: u32,
+ c: u16,
}
B :: struct #ordered {
- a: [7]u8
- b: [3]u16
- c: u8
- d: u16
+ a: [7]u8,
+ b: [3]u16,
+ c: u8,
+ d: u16,
}
- fmt.println("size_of(A):", size_of(A))
- fmt.println("size_of(B):", size_of(B))
+ fmt.println("size_of(A):", size_of(A));
+ fmt.println("size_of(B):", size_of(B));
// C-style structure layout
}
{
A :: struct #packed {
- a: u8
- b: u32
- c: u16
+ a: u8,
+ b: u32,
+ c: u16,
}
B :: struct #packed {
- a: [7]u8
- b: [3]u16
- c: u8
- d: u16
+ a: [7]u8,
+ b: [3]u16,
+ c: u8,
+ d: u16,
}
- fmt.println("size_of(A):", size_of(A))
- fmt.println("size_of(B):", size_of(B))
+ fmt.println("size_of(A):", size_of(A));
+ fmt.println("size_of(B):", size_of(B));
// Useful for explicit layout
}
@@ -119,7 +119,7 @@ struct_padding :: proc() {
}
bounds_checking :: proc() {
- x: [4]int
+ x: [4]int;
// x[-1] = 0; // Compile Time
// x[4] = 0; // Compile Time
@@ -132,9 +132,9 @@ bounds_checking :: proc() {
// Works for arrays, strings, slices, and related procedures & operations
{
- base: [10]int
- s := base[2:6]
- a, b := -1, 6
+ base: [10]int;
+ s := base[2:6];
+ a, b := -1, 6;
#no_bounds_check {
s[a] = 0;
@@ -154,69 +154,69 @@ bounds_checking :: proc() {
type_introspection :: proc() {
{
- info: ^Type_Info
- x: int
+ info: ^Type_Info;
+ x: int;
- info = type_info(int) // by type
- info = type_info_of_val(x) // by value
+ info = type_info(int); // by type
+ info = type_info_of_val(x); // by value
// See: runtime.odin
- match type i : info {
+ match type i in info {
case Type_Info.Integer:
- fmt.println("integer!")
+ fmt.println("integer!");
case Type_Info.Float:
- fmt.println("float!")
+ fmt.println("float!");
default:
- fmt.println("potato!")
+ fmt.println("potato!");
}
// Unsafe cast
- integer_info := info as ^Type_Info.Integer
+ integer_info := cast(^Type_Info.Integer)info;
}
{
Vector2 :: struct { x, y: f32 }
Vector3 :: struct { x, y, z: f32 }
- v1: Vector2
- v2: Vector3
- v3: Vector3
+ v1: Vector2;
+ v2: Vector3;
+ v3: Vector3;
- t1 := type_info_of_val(v1)
- t2 := type_info_of_val(v2)
- t3 := type_info_of_val(v3)
+ t1 := type_info_of_val(v1);
+ t2 := type_info_of_val(v2);
+ t3 := type_info_of_val(v3);
- fmt.println()
- fmt.print("Type of v1 is:\n\t", t1)
+ fmt.println();
+ fmt.print("Type of v1 is:\n\t", t1);
- fmt.println()
- fmt.print("Type of v2 is:\n\t", t2)
+ fmt.println();
+ fmt.print("Type of v2 is:\n\t", t2);
- fmt.println("\n")
- fmt.println("t1 == t2:", t1 == t2)
- fmt.println("t2 == t3:", t2 == t3)
+ fmt.println("\n");
+ fmt.println("t1 == t2:", t1 == t2);
+ fmt.println("t2 == t3:", t2 == t3);
}
}
any_type :: proc() {
- a: any
+ a: any;
- x: int = 123
- y: f64 = 6.28
- z: string = "Yo-Yo Ma"
+ x: int = 123;
+ y: f64 = 6.28;
+ z: string = "Yo-Yo Ma";
// All types can be implicit cast to `any`
- a = x
- a = y
- a = z
- a = a // This the "identity" type, it doesn't get converted
+ a = x;
+ a = y;
+ a = z;
+ a = a; // This the "identity" type, it doesn't get converted
- a = 123 // Literals are copied onto the stack first
+ a = 123; // Literals are copied onto the stack first
// any has two members
// data - rawptr to the data
// type_info - pointer to the type info
- fmt.println(x, y, z)
+ fmt.println(x, y, z);
// See: fmt.odin
// For variadic any procedures in action
}
@@ -232,15 +232,15 @@ crazy_introspection :: proc() {
TOMATO,
}
- s: string
- s = enum_to_string(Fruit.PEACH)
- fmt.println(s)
+ s: string;
+ // s = enum_to_string(Fruit.PEACH);
+ fmt.println(s);
- f := Fruit.GRAPE
- s = enum_to_string(f)
- fmt.println(s)
+ f := Fruit.GRAPE;
+ // s = enum_to_string(f);
+ fmt.println(s);
- fmt.println(f)
+ fmt.println(f);
// See: runtime.odin
}
@@ -259,15 +259,15 @@ crazy_introspection :: proc() {
TOMATO,
}
- fruit_ti := type_info(Fruit)
- name := (fruit_ti as ^Type_Info.Named).name // Unsafe casts
- info := type_info_base(fruit_ti) as ^Type_Info.Enum // Unsafe casts
+ fruit_ti := type_info(Fruit);
+ name := (cast(^Type_Info.Named)fruit_ti).name; // Unsafe casts
+ info := cast(^Type_Info.Enum)type_info_base(fruit_ti); // Unsafe casts
fmt.printf("% :: enum % {\n", name, info.base);
- for i := 0; i < info.values.count; i++ {
- fmt.printf("\t%\t= %,\n", info.names[i], info.values[i])
+ for i := 0; i < info.values.count; i += 1 {
+ fmt.printf("\t%\t= %,\n", info.names[i], info.values[i]);
}
- fmt.printf("}\n")
+ fmt.printf("}\n");
// NOTE(bill): look at that type-safe printf!
}
@@ -275,10 +275,10 @@ crazy_introspection :: proc() {
{
Vector3 :: struct {x, y, z: f32}
- a := Vector3{x = 1, y = 4, z = 9}
- fmt.println(a)
- b := Vector3{x = 9, y = 3, z = 1}
- fmt.println(b)
+ a := Vector3{x = 1, y = 4, z = 9};
+ fmt.println(a);
+ b := Vector3{x = 9, y = 3, z = 1};
+ fmt.println(b);
// NOTE(bill): See fmt.odin
}
diff --git a/code/punity.odin b/code/punity.odin
index fb93189ec..d5ef3ec19 100644
--- a/code/punity.odin
+++ b/code/punity.odin
@@ -1,34 +1,35 @@
-#import "win32.odin"
-#import "fmt.odin"
-#import "os.odin"
+#import win32 "sys/windows.odin";
+#import "fmt.odin";
+#import "os.odin";
+#import "mem.odin";
-CANVAS_WIDTH :: 128
-CANVAS_HEIGHT :: 128
-CANVAS_SCALE :: 3
-FRAME_TIME :: 1.0/30.0
-WINDOW_TITLE :: "Punity\x00"
+CANVAS_WIDTH :: 128;
+CANVAS_HEIGHT :: 128;
+CANVAS_SCALE :: 3;
+FRAME_TIME :: 1.0/30.0;
+WINDOW_TITLE :: "Punity\x00";
-_ := compile_assert(CANVAS_WIDTH % 16 == 0)
+_ := compile_assert(CANVAS_WIDTH % 16 == 0);
-WINDOW_WIDTH :: CANVAS_WIDTH * CANVAS_SCALE
-WINDOW_HEIGHT :: CANVAS_HEIGHT * CANVAS_SCALE
+WINDOW_WIDTH :: CANVAS_WIDTH * CANVAS_SCALE;
+WINDOW_HEIGHT :: CANVAS_HEIGHT * CANVAS_SCALE;
-STACK_CAPACITY :: 1<<20
-STORAGE_CAPACITY :: 1<<20
+STACK_CAPACITY :: 1<<20;
+STORAGE_CAPACITY :: 1<<20;
-DRAW_LIST_RESERVE :: 128
+DRAW_LIST_RESERVE :: 128;
-MAX_KEYS :: 256
+MAX_KEYS :: 256;
Core :: struct {
- stack: ^Bank
- storage: ^Bank
+ stack: ^Bank,
+ storage: ^Bank,
- running: bool
- key_modifiers: u32
- key_states: [MAX_KEYS]byte
- key_deltas: [MAX_KEYS]byte
+ running: bool,
+ key_modifiers: u32,
+ key_states: [MAX_KEYS]byte,
+ key_deltas: [MAX_KEYS]byte,
perf_frame,
perf_frame_inner,
@@ -36,70 +37,66 @@ Core :: struct {
perf_audio,
perf_blit,
perf_blit_cvt,
- perf_blit_gdi: Perf_Span
+ perf_blit_gdi: Perf_Span,
- frame: i64
+ frame: i64,
- canvas: Canvas
- draw_list: ^Draw_List
+ canvas: Canvas,
+ draw_list: ^Draw_List,
}
Perf_Span :: struct {
- stamp: f64
- delta: f32
+ stamp: f64,
+ delta: f32,
}
Bank :: struct {
- memory: []byte
- cursor: int
+ memory: []byte,
+ cursor: int,
}
Bank_State :: struct {
- state: Bank
- bank: ^Bank
+ state: Bank,
+ bank: ^Bank,
}
Color :: raw_union {
- using channels: struct{ a, b, g, r: byte; }
- rgba: u32
+ using channels: struct{a, b, g, r: byte},
+ rgba: u32,
}
Palette :: struct {
- colors: [256]Color
- colors_count: byte
+ colors: [256]Color,
+ colors_count: byte,
}
Rect :: raw_union {
- using minmax: struct {
- min_x, min_y, max_x, max_y: int
- }
- using pos: struct {
- left, top, right, bottom: int
- }
- e: [4]int
+ using minmax: struct {min_x, min_y, max_x, max_y: int},
+ using pos: struct {left, top, right, bottom: int},
+ e: [4]int,
}
Bitmap :: struct {
- pixels: []byte
- width: int
- height: int
+ pixels: []byte,
+ width: int,
+ height: int,
}
Font :: struct {
- using bitmap: Bitmap
- char_width: int
- char_height: int
+ using bitmap: Bitmap,
+ char_width: int,
+ char_height: int,
}
Canvas :: struct {
- using bitmap: ^Bitmap
- palette: Palette
- translate_x: int
- translate_y: int
- clip: Rect
- font: ^Font
+ using bitmap: ^Bitmap,
+ palette: Palette,
+ translate_x: int,
+ translate_y: int,
+ clip: Rect,
+ font: ^Font,
}
DrawFlag :: enum {
@@ -109,12 +106,9 @@ DrawFlag :: enum {
MASK = 1<<2,
}
-
+Draw_Item :: struct {}
Draw_List :: struct {
- Item :: struct {
-
- }
- items: []Item
+ items: []Draw_Item,
}
Key :: enum {
@@ -268,112 +262,112 @@ Key :: enum {
BACKSLASH = 92, /* \ */
RIGHT_BRACKET = 93, /* ] */
GRAVE_ACCENT = 96, /* ` */
-}
+};
key_down :: proc(k: Key) -> bool {
- return _core.key_states[k] != 0
+ return _core.key_states[k] != 0;
}
key_pressed :: proc(k: Key) -> bool {
- return (_core.key_deltas[k] != 0) && key_down(k)
+ return (_core.key_deltas[k] != 0) && key_down(k);
}
-win32_perf_count_freq := win32.GetQueryPerformanceFrequency()
+win32_perf_count_freq := win32.GetQueryPerformanceFrequency();
time_now :: proc() -> f64 {
- assert(win32_perf_count_freq != 0)
+ assert(win32_perf_count_freq != 0);
- counter: i64
- win32.QueryPerformanceCounter(^counter)
- result := counter as f64 / win32_perf_count_freq as f64
- return result
+ counter: i64;
+ win32.QueryPerformanceCounter(^counter);
+ result := cast(f64)counter / cast(f64)win32_perf_count_freq;
+ return result;
}
-_core: Core
+_core: Core;
run :: proc(user_init, user_step: proc(c: ^Core)) {
- using win32
+ using win32;
- _core.running = true
+ _core.running = true;
- win32_proc :: proc(hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT #no_inline #stdcall {
+ win32_proc :: proc(hwnd: win32.HWND, msg: u32, wparam: win32.WPARAM, lparam: win32.LPARAM) -> win32.LRESULT #no_inline #cc_c {
win32_app_key_mods :: proc() -> u32 {
- mods: u32 = 0
+ mods: u32 = 0;
if is_key_down(Key_Code.SHIFT) {
- mods |= Key.MOD_SHIFT as u32
+ mods |= cast(u32)Key.MOD_SHIFT;
}
if is_key_down(Key_Code.CONTROL) {
- mods |= Key.MOD_CONTROL as u32
+ mods |= cast(u32)Key.MOD_CONTROL;
}
if is_key_down(Key_Code.MENU) {
- mods |= Key.MOD_ALT as u32
+ mods |= cast(u32)Key.MOD_ALT;
}
if is_key_down(Key_Code.LWIN) || is_key_down(Key_Code.RWIN) {
- mods |= Key.MOD_SUPER as u32
+ mods |= cast(u32)Key.MOD_SUPER;
}
- return mods
+ return mods;
}
match msg {
case WM_KEYDOWN:
- _core.key_modifiers = win32_app_key_mods()
+ _core.key_modifiers = win32_app_key_mods();
if wparam < MAX_KEYS {
- _core.key_states[wparam] = 1
- _core.key_deltas[wparam] = 1
+ _core.key_states[wparam] = 1;
+ _core.key_deltas[wparam] = 1;
}
- return 0
+ return 0;
case WM_KEYUP:
- _core.key_modifiers = win32_app_key_mods()
+ _core.key_modifiers = win32_app_key_mods();
if wparam < MAX_KEYS {
- _core.key_states[wparam] = 0
- _core.key_deltas[wparam] = 1
+ _core.key_states[wparam] = 0;
+ _core.key_deltas[wparam] = 1;
}
- return 0
+ return 0;
case WM_CLOSE:
- PostQuitMessage(0)
- _core.running = false
- return 0
+ PostQuitMessage(0);
+ _core.running = false;
+ return 0;
}
- return DefWindowProcA(hwnd, msg, wparam, lparam)
+ return DefWindowProcA(hwnd, msg, wparam, lparam);
}
window_class := WNDCLASSEXA{
- class_name = ("Punity\x00" as string).data, // C-style string
- size = size_of(WNDCLASSEXA) as u32,
+ class_name = (cast(string)"Punity\x00").data, // C-style string
+ size = size_of(WNDCLASSEXA),
style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC,
- instance = GetModuleHandleA(nil) as HINSTANCE,
+ instance = cast(HINSTANCE)GetModuleHandleA(nil),
wnd_proc = win32_proc,
// wnd_proc = DefWindowProcA,
- background = GetStockObject(BLACK_BRUSH) as HBRUSH,
- }
+ background = cast(HBRUSH)GetStockObject(BLACK_BRUSH),
+ };
if RegisterClassExA(^window_class) == 0 {
- fmt.fprintln(os.stderr, "RegisterClassExA failed")
- return
+ fmt.fprintln(os.stderr, "RegisterClassExA failed");
+ return;
}
- screen_width := GetSystemMetrics(SM_CXSCREEN)
- screen_height := GetSystemMetrics(SM_CYSCREEN)
+ screen_width := GetSystemMetrics(SM_CXSCREEN);
+ screen_height := GetSystemMetrics(SM_CYSCREEN);
- rc: RECT
- rc.left = (screen_width - WINDOW_WIDTH) / 2
- rc.top = (screen_height - WINDOW_HEIGHT) / 2
- rc.right = rc.left + WINDOW_WIDTH
- rc.bottom = rc.top + WINDOW_HEIGHT
+ rc: RECT;
+ rc.left = (screen_width - WINDOW_WIDTH) / 2;
+ rc.top = (screen_height - WINDOW_HEIGHT) / 2;
+ rc.right = rc.left + WINDOW_WIDTH;
+ rc.bottom = rc.top + WINDOW_HEIGHT;
- style: u32 = WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX
- assert(AdjustWindowRect(^rc, style, 0) != 0)
+ style: u32 = WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
+ assert(AdjustWindowRect(^rc, style, 0) != 0);
- wt := WINDOW_TITLE
+ wt := WINDOW_TITLE;
win32_window := CreateWindowExA(0,
window_class.class_name,
@@ -382,101 +376,115 @@ run :: proc(user_init, user_step: proc(c: ^Core)) {
rc.left, rc.top,
rc.right-rc.left, rc.bottom-rc.top,
nil, nil, window_class.instance,
- nil)
+ nil);
if win32_window == nil {
- fmt.fprintln(os.stderr, "CreateWindowExA failed")
- return
+ fmt.fprintln(os.stderr, "CreateWindowExA failed");
+ return;
}
- window_bmi: BITMAPINFO
- window_bmi.size = size_of(BITMAPINFO.HEADER) as u32
- window_bmi.width = CANVAS_WIDTH
- window_bmi.height = CANVAS_HEIGHT
- window_bmi.planes = 1
- window_bmi.bit_count = 32
- window_bmi.compression = BI_RGB
+ window_bmi: BITMAPINFO;
+ window_bmi.size = size_of(BITMAPINFOHEADER);
+ window_bmi.width = CANVAS_WIDTH;
+ window_bmi.height = CANVAS_HEIGHT;
+ window_bmi.planes = 1;
+ window_bmi.bit_count = 32;
+ window_bmi.compression = BI_RGB;
- user_init(^_core)
+ user_init(^_core);
+ ShowWindow(win32_window, SW_SHOW);
- ShowWindow(win32_window, SW_SHOW)
+ window_buffer := new_slice(u32, CANVAS_WIDTH * CANVAS_HEIGHT);
+ assert(window_buffer.data != nil);
+ defer free(window_buffer.data);
- window_buffer := new_slice(u32, CANVAS_WIDTH * CANVAS_HEIGHT)
- assert(window_buffer.data != nil)
- defer free(window_buffer.data)
- for i := 0; i < window_buffer.count; i++ {
- window_buffer[i] = 0xff00ff
+ for i := 0; i < window_buffer.count; i += 1 {
+ window_buffer[i] = 0xff00ff;
}
- prev_time, curr_time,dt: f64
- prev_time = time_now()
- curr_time = time_now()
- total_time : f64 = 0
- offset_x := 0
- offset_y := 0
+ dt: f64;
+ prev_time := time_now();
+ curr_time := time_now();
+ total_time : f64 = 0;
+ offset_x := 0;
+ offset_y := 0;
- message: MSG
+ message: MSG;
for _core.running {
- curr_time = time_now()
- dt = curr_time - prev_time
- prev_time = curr_time
- total_time += dt
+ curr_time = time_now();
+ dt = curr_time - prev_time;
+ prev_time = curr_time;
+ total_time += dt;
- offset_x += 1
- offset_y += 2
+ offset_x += 1;
+ offset_y += 2;
{
- data: [128]byte
- buf := data[:0]
- fmt.bprintf(^buf, "Punity: % ms\x00", dt*1000)
- win32.SetWindowTextA(win32_window, buf.data)
+ data: [128]byte;
+ buf: fmt.Buffer;
+ buf.data = data[:];
+ fmt.bprintf(^buf, "Punity: %.4f ms\x00", dt*1000);
+ win32.SetWindowTextA(win32_window, ^buf[0]);
}
- for y := 0; y < CANVAS_HEIGHT; y++ {
- for x := 0; x < CANVAS_WIDTH; x++ {
- g := (x % 32) * 8
- b := (y % 32) * 8
- window_buffer[x + y*CANVAS_WIDTH] = (g << 8 | b) as u32
+ for y := 0; y < CANVAS_HEIGHT; y += 1 {
+ for x := 0; x < CANVAS_WIDTH; x += 1 {
+ g := (x % 32) * 8;
+ b := (y % 32) * 8;
+ window_buffer[x + y*CANVAS_WIDTH] = cast(u32)(g << 8 | b);
}
}
- _core.key_deltas = nil
+ mem.zero(^_core.key_deltas[0], size_of_val(_core.key_deltas));
for PeekMessageA(^message, nil, 0, 0, PM_REMOVE) != 0 {
if message.message == WM_QUIT {
- _core.running = false
+ _core.running = false;
}
- TranslateMessage(^message)
- DispatchMessageA(^message)
+ TranslateMessage(^message);
+ DispatchMessageA(^message);
}
- user_step(^_core)
+ user_step(^_core);
- dc := GetDC(win32_window)
+ dc := GetDC(win32_window);
StretchDIBits(dc,
0, 0, CANVAS_WIDTH * CANVAS_SCALE, CANVAS_HEIGHT * CANVAS_SCALE,
0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
window_buffer.data,
^window_bmi,
DIB_RGB_COLORS,
- SRCCOPY)
- ReleaseDC(win32_window, dc)
+ SRCCOPY);
+ ReleaseDC(win32_window, dc);
{
- delta := time_now() - prev_time
- ms := ((FRAME_TIME - delta) * 1000) as i32
+ delta := time_now() - prev_time;
+ ms := cast(i32)((FRAME_TIME - delta) * 1000);
if ms > 0 {
- win32.Sleep(ms)
+ win32.Sleep(ms);
}
}
- _core.frame++
+ _core.frame += 1;
+ }
+}
+
+
+main :: proc() {
+ user_init :: proc(c: ^Core) {
+
}
+
+ user_step :: proc(c: ^Core) {
+
+ }
+
+ run(user_init, user_step);
}
diff --git a/core/fmt.odin b/core/fmt.odin
index bd11d05e0..fe822b4c8 100644
--- a/core/fmt.odin
+++ b/core/fmt.odin
@@ -421,9 +421,7 @@ fmt_write_padding :: proc(fi: ^Fmt_Info, width: int) {
fmt_integer :: proc(fi: ^Fmt_Info, u: u64, base: int, signed: bool, digits: string) {
negative := signed && cast(i64)u < 0;
- if negative {
- u = -u;
- }
+ u = abs(u);
buf: [256]byte;
if fi.width_set || fi.prec_set {
width := fi.width + fi.prec + 3;
@@ -504,14 +502,16 @@ fmt_integer :: proc(fi: ^Fmt_Info, u: u64, base: int, signed: bool, digits: stri
buffer_write(fi.buf, buf[i:]);
} else {
width := fi.width - utf8.rune_count(cast(string)buf[i:]);
- if fi.minus {
- // Right pad
- buffer_write(fi.buf, buf[i:]);
- fmt_write_padding(fi, width);
- } else {
- // Left pad
- fmt_write_padding(fi, width);
- buffer_write(fi.buf, buf[i:]);
+ if width > 0 {
+ if fi.minus {
+ // Right pad
+ buffer_write(fi.buf, buf[i:]);
+ fmt_write_padding(fi, width);
+ } else {
+ // Left pad
+ fmt_write_padding(fi, width);
+ buffer_write(fi.buf, buf[i:]);
+ }
}
}
@@ -574,8 +574,16 @@ fmt_float :: proc(fi: ^Fmt_Info, v: f64, bit_size: int, verb: rune) {
signed := v < 0;
v = abs(v);
+ if signed {
+ buffer_write_byte(fi.buf, '-');
+ }
+
val := cast(u64)v;
- fmt_integer(fi, val, 10, signed, __DIGITS_LOWER);
+ fi.minus = false;
+ fi.width = 0;
+ fi.prec = 0;
+ // TODO(bill): Write integer to buffer than use this crap
+ fmt_integer(fi, val, 10, false, __DIGITS_LOWER);
if fi.hash || prec > 0 {
arg := v - cast(f64)val;
diff --git a/src/check_decl.c b/src/check_decl.c
index 9fb786286..51655d445 100644
--- a/src/check_decl.c
+++ b/src/check_decl.c
@@ -302,10 +302,11 @@ void check_proc_lit(Checker *c, Entity *e, DeclInfo *d) {
error_node(pd->body, "A procedure tagged as `#foreign` cannot have a body");
}
- if (proc_type->Proc.calling_convention != ProcCC_Odin) {
- error_node(d->proc_lit, "An internal procedure may only have the Odin calling convention");
- proc_type->Proc.calling_convention = ProcCC_Odin;
- }
+ // TODO(bill): Is this the best option? What about passing to external shit?!
+ // if (proc_type->Proc.calling_convention != ProcCC_Odin) {
+ // error_node(d->proc_lit, "An internal procedure may only have the Odin calling convention");
+ // proc_type->Proc.calling_convention = ProcCC_Odin;
+ // }
d->scope = c->context.scope;
diff --git a/src/check_expr.c b/src/check_expr.c
index f6037beee..18c75ac9d 100644
--- a/src/check_expr.c
+++ b/src/check_expr.c
@@ -203,6 +203,11 @@ i64 check_distance_between_types(Checker *c, Operand *operand, Type *type) {
}
}
+ // if (is_type_proc(dst)) {
+ // if (are_types_identical(src, dst)) {
+ // return 1;
+ // }
+ // }
if (is_type_any(dst)) {
// NOTE(bill): Anything can cast to `Any`
diff --git a/src/main.c b/src/main.c
index 6e9afda3d..b35f399eb 100644
--- a/src/main.c
+++ b/src/main.c
@@ -240,7 +240,7 @@ int main(int argc, char **argv) {
char lib_str_buf[1024] = {0};
for_array(i, ir_gen.module.foreign_library_paths) {
String lib = ir_gen.module.foreign_library_paths.e[i];
- gb_printf_err("Linking lib: %.*s\n", LIT(lib));
+ // gb_printf_err("Linking lib: %.*s\n", LIT(lib));
isize len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf),
" \"%.*s\"", LIT(lib));
lib_str = gb_string_appendc(lib_str, lib_str_buf);
diff --git a/src/parser.c b/src/parser.c
index 0a9b39ea9..eac6fbd68 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -1827,11 +1827,15 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
}
case Token_if:
- if (lhs) goto error;
- return parse_if_expr(f);
+ if (!lhs && f->expr_level >= 0) {
+ return parse_if_expr(f);
+ }
+ break;
case Token_OpenBrace:
- if (lhs) goto error;
- return parse_block_expr(f);
+ if (!lhs && f->expr_level >= 0) {
+ return parse_block_expr(f);
+ }
+ break;
default: {
AstNode *type = parse_identifier_or_type(f);
@@ -1846,7 +1850,6 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
}
}
-error:
Token begin = f->curr_token;
syntax_error(begin, "Expected an operand");
fix_advance_to_next_stmt(f);
diff --git a/src/types.c b/src/types.c
index c49ad4a42..7bb849fff 100644
--- a/src/types.c
+++ b/src/types.c
@@ -1194,7 +1194,9 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
} else if (!is_type_union(type)) {
for (isize i = 0; i < type->Record.field_count; i++) {
Entity *f = type->Record.fields[i];
- GB_ASSERT(f->kind == Entity_Variable && f->flags & EntityFlag_Field);
+ if (f->kind != Entity_Variable || (f->flags & EntityFlag_Field) == 0) {
+ continue;
+ }
String str = f->token.string;
if (str_eq(field_name, str)) {
selection_add_index(&sel, i); // HACK(bill): Leaky memory