Fix parsing for block/if expression within if/for/etc. statements

This commit is contained in:
Ginger Bill
2017-01-27 23:02:55 +00:00
parent 92453369c5
commit 31aacd5bf4
10 changed files with 313 additions and 283 deletions
+1 -1
View File
@@ -46,7 +46,7 @@ cl %compiler_settings% "src\main.c" ^
/link %linker_settings% -OUT:%exe_name% ^ /link %linker_settings% -OUT:%exe_name% ^
&& odin run code/demo.odin && odin run code/demo.odin
rem && odin build_dll code/example.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 pushd src\asm
rem nasm hellope.asm -fwin64 -o hellope.obj ^ rem nasm hellope.asm -fwin64 -o hellope.obj ^
+16 -13
View File
@@ -1,12 +1,13 @@
#import "fmt.odin"; #import "fmt.odin";
#import "utf8.odin"; #import "utf8.odin";
#import "atomic.odin"; // #import "atomic.odin";
#import "hash.odin"; // #import "hash.odin";
#import "math.odin"; // #import "math.odin";
#import "mem.odin"; // #import "mem.odin";
#import "opengl.odin"; // #import "opengl.odin";
#import "os.odin"; // #import "os.odin";
#import "sync.odin"; // #import "sync.odin";
// #import win32 "sys/windows.odin";
main :: proc() { main :: proc() {
syntax(); syntax();
@@ -15,8 +16,8 @@ main :: proc() {
syntax :: proc() { syntax :: proc() {
// Cyclic type checking // Cyclic type checking
// Uncomment to see the error // Uncomment to see the error
// A :: struct { b: B }; // A :: struct {b: B};
// B :: struct { a: A }; // B :: struct {a: A};
x: int; x: int;
y := cast(f32)x; y := cast(f32)x;
@@ -40,10 +41,10 @@ syntax :: proc() {
}; };
Thing2 :: struct {x: f32, y: int, z: ^[]int}; 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)); 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_Int :: type int;
My_Proc :: type proc(int) -> f32; My_Proc :: type proc(int) -> f32;
@@ -62,6 +63,9 @@ syntax :: proc() {
// ++ and -- have been removed // ++ and -- have been removed
// x++; // x++;
// 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` // You can now build files as a `.dll`
@@ -167,7 +171,6 @@ special_expressions :: proc() {
} }
loops :: proc() { loops :: proc() {
// The C-style for loop // The C-style for loop
for i := 0; i < 123; i += 1 { for i := 0; i < 123; i += 1 {
break; break;
@@ -259,7 +262,7 @@ procedure_overloading :: proc() {
} }
a: i32 = #line; a: i32 = 123;
b: f32; b: f32;
c: rawptr; c: rawptr;
fmt.println(foo(^a)); fmt.println(foo(^a));
+86 -86
View File
@@ -1,9 +1,9 @@
#import "fmt.odin" #import "fmt.odin";
#import "os.odin" #import "os.odin";
#import "mem.odin" #import "mem.odin";
// #import "http_test.odin" as ht // #import "http_test.odin" as ht;
// #import "game.odin" as game // #import "game.odin" as game;
// #import "punity.odin" as pn // #import "punity.odin" as pn;
main :: proc() { main :: proc() {
// struct_padding() // struct_padding()
@@ -26,58 +26,58 @@ main :: proc() {
struct_padding :: proc() { struct_padding :: proc() {
{ {
A :: struct { A :: struct {
a: u8 a: u8,
b: u32 b: u32,
c: u16 c: u16,
} }
B :: struct { B :: struct {
a: [7]u8 a: [7]u8,
b: [3]u16 b: [3]u16,
c: u8 c: u8,
d: u16 d: u16,
} }
fmt.println("size_of(A):", size_of(A)) fmt.println("size_of(A):", size_of(A));
fmt.println("size_of(B):", size_of(B)) 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 // n.b. http://cbloomrants.blogspot.co.uk/2012/07/07-23-12-structs-are-not-what-you-want.html
} }
{ {
A :: struct #ordered { A :: struct #ordered {
a: u8 a: u8,
b: u32 b: u32,
c: u16 c: u16,
} }
B :: struct #ordered { B :: struct #ordered {
a: [7]u8 a: [7]u8,
b: [3]u16 b: [3]u16,
c: u8 c: u8,
d: u16 d: u16,
} }
fmt.println("size_of(A):", size_of(A)) fmt.println("size_of(A):", size_of(A));
fmt.println("size_of(B):", size_of(B)) fmt.println("size_of(B):", size_of(B));
// C-style structure layout // C-style structure layout
} }
{ {
A :: struct #packed { A :: struct #packed {
a: u8 a: u8,
b: u32 b: u32,
c: u16 c: u16,
} }
B :: struct #packed { B :: struct #packed {
a: [7]u8 a: [7]u8,
b: [3]u16 b: [3]u16,
c: u8 c: u8,
d: u16 d: u16,
} }
fmt.println("size_of(A):", size_of(A)) fmt.println("size_of(A):", size_of(A));
fmt.println("size_of(B):", size_of(B)) fmt.println("size_of(B):", size_of(B));
// Useful for explicit layout // Useful for explicit layout
} }
@@ -119,7 +119,7 @@ struct_padding :: proc() {
} }
bounds_checking :: proc() { bounds_checking :: proc() {
x: [4]int x: [4]int;
// x[-1] = 0; // Compile Time // x[-1] = 0; // Compile Time
// x[4] = 0; // Compile Time // x[4] = 0; // Compile Time
@@ -132,9 +132,9 @@ bounds_checking :: proc() {
// Works for arrays, strings, slices, and related procedures & operations // Works for arrays, strings, slices, and related procedures & operations
{ {
base: [10]int base: [10]int;
s := base[2:6] s := base[2:6];
a, b := -1, 6 a, b := -1, 6;
#no_bounds_check { #no_bounds_check {
s[a] = 0; s[a] = 0;
@@ -154,69 +154,69 @@ bounds_checking :: proc() {
type_introspection :: proc() { type_introspection :: proc() {
{ {
info: ^Type_Info info: ^Type_Info;
x: int x: int;
info = type_info(int) // by type info = type_info(int); // by type
info = type_info_of_val(x) // by value info = type_info_of_val(x); // by value
// See: runtime.odin // See: runtime.odin
match type i : info { match type i in info {
case Type_Info.Integer: case Type_Info.Integer:
fmt.println("integer!") fmt.println("integer!");
case Type_Info.Float: case Type_Info.Float:
fmt.println("float!") fmt.println("float!");
default: default:
fmt.println("potato!") fmt.println("potato!");
} }
// Unsafe cast // Unsafe cast
integer_info := info as ^Type_Info.Integer integer_info := cast(^Type_Info.Integer)info;
} }
{ {
Vector2 :: struct { x, y: f32 } Vector2 :: struct { x, y: f32 }
Vector3 :: struct { x, y, z: f32 } Vector3 :: struct { x, y, z: f32 }
v1: Vector2 v1: Vector2;
v2: Vector3 v2: Vector3;
v3: Vector3 v3: Vector3;
t1 := type_info_of_val(v1) t1 := type_info_of_val(v1);
t2 := type_info_of_val(v2) t2 := type_info_of_val(v2);
t3 := type_info_of_val(v3) t3 := type_info_of_val(v3);
fmt.println() fmt.println();
fmt.print("Type of v1 is:\n\t", t1) fmt.print("Type of v1 is:\n\t", t1);
fmt.println() fmt.println();
fmt.print("Type of v2 is:\n\t", t2) fmt.print("Type of v2 is:\n\t", t2);
fmt.println("\n") fmt.println("\n");
fmt.println("t1 == t2:", t1 == t2) fmt.println("t1 == t2:", t1 == t2);
fmt.println("t2 == t3:", t2 == t3) fmt.println("t2 == t3:", t2 == t3);
} }
} }
any_type :: proc() { any_type :: proc() {
a: any a: any;
x: int = 123 x: int = 123;
y: f64 = 6.28 y: f64 = 6.28;
z: string = "Yo-Yo Ma" z: string = "Yo-Yo Ma";
// All types can be implicit cast to `any` // All types can be implicit cast to `any`
a = x a = x;
a = y a = y;
a = z a = z;
a = a // This the "identity" type, it doesn't get converted 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 // any has two members
// data - rawptr to the data // data - rawptr to the data
// type_info - pointer to the type info // type_info - pointer to the type info
fmt.println(x, y, z) fmt.println(x, y, z);
// See: fmt.odin // See: fmt.odin
// For variadic any procedures in action // For variadic any procedures in action
} }
@@ -232,15 +232,15 @@ crazy_introspection :: proc() {
TOMATO, TOMATO,
} }
s: string s: string;
s = enum_to_string(Fruit.PEACH) // s = enum_to_string(Fruit.PEACH);
fmt.println(s) fmt.println(s);
f := Fruit.GRAPE f := Fruit.GRAPE;
s = enum_to_string(f) // s = enum_to_string(f);
fmt.println(s) fmt.println(s);
fmt.println(f) fmt.println(f);
// See: runtime.odin // See: runtime.odin
} }
@@ -259,15 +259,15 @@ crazy_introspection :: proc() {
TOMATO, TOMATO,
} }
fruit_ti := type_info(Fruit) fruit_ti := type_info(Fruit);
name := (fruit_ti as ^Type_Info.Named).name // Unsafe casts name := (cast(^Type_Info.Named)fruit_ti).name; // Unsafe casts
info := type_info_base(fruit_ti) as ^Type_Info.Enum // Unsafe casts info := cast(^Type_Info.Enum)type_info_base(fruit_ti); // Unsafe casts
fmt.printf("% :: enum % {\n", name, info.base); fmt.printf("% :: enum % {\n", name, info.base);
for i := 0; i < info.values.count; i++ { for i := 0; i < info.values.count; i += 1 {
fmt.printf("\t%\t= %,\n", info.names[i], info.values[i]) 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! // NOTE(bill): look at that type-safe printf!
} }
@@ -275,10 +275,10 @@ crazy_introspection :: proc() {
{ {
Vector3 :: struct {x, y, z: f32} Vector3 :: struct {x, y, z: f32}
a := Vector3{x = 1, y = 4, z = 9} a := Vector3{x = 1, y = 4, z = 9};
fmt.println(a) fmt.println(a);
b := Vector3{x = 9, y = 3, z = 1} b := Vector3{x = 9, y = 3, z = 1};
fmt.println(b) fmt.println(b);
// NOTE(bill): See fmt.odin // NOTE(bill): See fmt.odin
} }
+168 -160
View File
@@ -1,34 +1,35 @@
#import "win32.odin" #import win32 "sys/windows.odin";
#import "fmt.odin" #import "fmt.odin";
#import "os.odin" #import "os.odin";
#import "mem.odin";
CANVAS_WIDTH :: 128 CANVAS_WIDTH :: 128;
CANVAS_HEIGHT :: 128 CANVAS_HEIGHT :: 128;
CANVAS_SCALE :: 3 CANVAS_SCALE :: 3;
FRAME_TIME :: 1.0/30.0 FRAME_TIME :: 1.0/30.0;
WINDOW_TITLE :: "Punity\x00" WINDOW_TITLE :: "Punity\x00";
_ := compile_assert(CANVAS_WIDTH % 16 == 0) _ := compile_assert(CANVAS_WIDTH % 16 == 0);
WINDOW_WIDTH :: CANVAS_WIDTH * CANVAS_SCALE WINDOW_WIDTH :: CANVAS_WIDTH * CANVAS_SCALE;
WINDOW_HEIGHT :: CANVAS_HEIGHT * CANVAS_SCALE WINDOW_HEIGHT :: CANVAS_HEIGHT * CANVAS_SCALE;
STACK_CAPACITY :: 1<<20 STACK_CAPACITY :: 1<<20;
STORAGE_CAPACITY :: 1<<20 STORAGE_CAPACITY :: 1<<20;
DRAW_LIST_RESERVE :: 128 DRAW_LIST_RESERVE :: 128;
MAX_KEYS :: 256 MAX_KEYS :: 256;
Core :: struct { Core :: struct {
stack: ^Bank stack: ^Bank,
storage: ^Bank storage: ^Bank,
running: bool running: bool,
key_modifiers: u32 key_modifiers: u32,
key_states: [MAX_KEYS]byte key_states: [MAX_KEYS]byte,
key_deltas: [MAX_KEYS]byte key_deltas: [MAX_KEYS]byte,
perf_frame, perf_frame,
perf_frame_inner, perf_frame_inner,
@@ -36,70 +37,66 @@ Core :: struct {
perf_audio, perf_audio,
perf_blit, perf_blit,
perf_blit_cvt, perf_blit_cvt,
perf_blit_gdi: Perf_Span perf_blit_gdi: Perf_Span,
frame: i64 frame: i64,
canvas: Canvas canvas: Canvas,
draw_list: ^Draw_List draw_list: ^Draw_List,
} }
Perf_Span :: struct { Perf_Span :: struct {
stamp: f64 stamp: f64,
delta: f32 delta: f32,
} }
Bank :: struct { Bank :: struct {
memory: []byte memory: []byte,
cursor: int cursor: int,
} }
Bank_State :: struct { Bank_State :: struct {
state: Bank state: Bank,
bank: ^Bank bank: ^Bank,
} }
Color :: raw_union { Color :: raw_union {
using channels: struct{ a, b, g, r: byte; } using channels: struct{a, b, g, r: byte},
rgba: u32 rgba: u32,
} }
Palette :: struct { Palette :: struct {
colors: [256]Color colors: [256]Color,
colors_count: byte colors_count: byte,
} }
Rect :: raw_union { Rect :: raw_union {
using minmax: struct { using minmax: struct {min_x, min_y, max_x, max_y: int},
min_x, min_y, max_x, max_y: int using pos: struct {left, top, right, bottom: int},
} e: [4]int,
using pos: struct {
left, top, right, bottom: int
}
e: [4]int
} }
Bitmap :: struct { Bitmap :: struct {
pixels: []byte pixels: []byte,
width: int width: int,
height: int height: int,
} }
Font :: struct { Font :: struct {
using bitmap: Bitmap using bitmap: Bitmap,
char_width: int char_width: int,
char_height: int char_height: int,
} }
Canvas :: struct { Canvas :: struct {
using bitmap: ^Bitmap using bitmap: ^Bitmap,
palette: Palette palette: Palette,
translate_x: int translate_x: int,
translate_y: int translate_y: int,
clip: Rect clip: Rect,
font: ^Font font: ^Font,
} }
DrawFlag :: enum { DrawFlag :: enum {
@@ -109,12 +106,9 @@ DrawFlag :: enum {
MASK = 1<<2, MASK = 1<<2,
} }
Draw_Item :: struct {}
Draw_List :: struct { Draw_List :: struct {
Item :: struct { items: []Draw_Item,
}
items: []Item
} }
Key :: enum { Key :: enum {
@@ -268,112 +262,112 @@ Key :: enum {
BACKSLASH = 92, /* \ */ BACKSLASH = 92, /* \ */
RIGHT_BRACKET = 93, /* ] */ RIGHT_BRACKET = 93, /* ] */
GRAVE_ACCENT = 96, /* ` */ GRAVE_ACCENT = 96, /* ` */
} };
key_down :: proc(k: Key) -> bool { key_down :: proc(k: Key) -> bool {
return _core.key_states[k] != 0 return _core.key_states[k] != 0;
} }
key_pressed :: proc(k: Key) -> bool { 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 { time_now :: proc() -> f64 {
assert(win32_perf_count_freq != 0) assert(win32_perf_count_freq != 0);
counter: i64 counter: i64;
win32.QueryPerformanceCounter(^counter) win32.QueryPerformanceCounter(^counter);
result := counter as f64 / win32_perf_count_freq as f64 result := cast(f64)counter / cast(f64)win32_perf_count_freq;
return result return result;
} }
_core: Core _core: Core;
run :: proc(user_init, user_step: proc(c: ^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 { win32_app_key_mods :: proc() -> u32 {
mods: u32 = 0 mods: u32 = 0;
if is_key_down(Key_Code.SHIFT) { 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) { 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) { 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) { 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 { match msg {
case WM_KEYDOWN: case WM_KEYDOWN:
_core.key_modifiers = win32_app_key_mods() _core.key_modifiers = win32_app_key_mods();
if wparam < MAX_KEYS { if wparam < MAX_KEYS {
_core.key_states[wparam] = 1 _core.key_states[wparam] = 1;
_core.key_deltas[wparam] = 1 _core.key_deltas[wparam] = 1;
} }
return 0 return 0;
case WM_KEYUP: case WM_KEYUP:
_core.key_modifiers = win32_app_key_mods() _core.key_modifiers = win32_app_key_mods();
if wparam < MAX_KEYS { if wparam < MAX_KEYS {
_core.key_states[wparam] = 0 _core.key_states[wparam] = 0;
_core.key_deltas[wparam] = 1 _core.key_deltas[wparam] = 1;
} }
return 0 return 0;
case WM_CLOSE: case WM_CLOSE:
PostQuitMessage(0) PostQuitMessage(0);
_core.running = false _core.running = false;
return 0 return 0;
} }
return DefWindowProcA(hwnd, msg, wparam, lparam) return DefWindowProcA(hwnd, msg, wparam, lparam);
} }
window_class := WNDCLASSEXA{ window_class := WNDCLASSEXA{
class_name = ("Punity\x00" as string).data, // C-style string class_name = (cast(string)"Punity\x00").data, // C-style string
size = size_of(WNDCLASSEXA) as u32, size = size_of(WNDCLASSEXA),
style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC, style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC,
instance = GetModuleHandleA(nil) as HINSTANCE, instance = cast(HINSTANCE)GetModuleHandleA(nil),
wnd_proc = win32_proc, wnd_proc = win32_proc,
// wnd_proc = DefWindowProcA, // wnd_proc = DefWindowProcA,
background = GetStockObject(BLACK_BRUSH) as HBRUSH, background = cast(HBRUSH)GetStockObject(BLACK_BRUSH),
} };
if RegisterClassExA(^window_class) == 0 { if RegisterClassExA(^window_class) == 0 {
fmt.fprintln(os.stderr, "RegisterClassExA failed") fmt.fprintln(os.stderr, "RegisterClassExA failed");
return return;
} }
screen_width := GetSystemMetrics(SM_CXSCREEN) screen_width := GetSystemMetrics(SM_CXSCREEN);
screen_height := GetSystemMetrics(SM_CYSCREEN) screen_height := GetSystemMetrics(SM_CYSCREEN);
rc: RECT rc: RECT;
rc.left = (screen_width - WINDOW_WIDTH) / 2 rc.left = (screen_width - WINDOW_WIDTH) / 2;
rc.top = (screen_height - WINDOW_HEIGHT) / 2 rc.top = (screen_height - WINDOW_HEIGHT) / 2;
rc.right = rc.left + WINDOW_WIDTH rc.right = rc.left + WINDOW_WIDTH;
rc.bottom = rc.top + WINDOW_HEIGHT rc.bottom = rc.top + WINDOW_HEIGHT;
style: u32 = WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX style: u32 = WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
assert(AdjustWindowRect(^rc, style, 0) != 0) assert(AdjustWindowRect(^rc, style, 0) != 0);
wt := WINDOW_TITLE wt := WINDOW_TITLE;
win32_window := CreateWindowExA(0, win32_window := CreateWindowExA(0,
window_class.class_name, window_class.class_name,
@@ -382,101 +376,115 @@ run :: proc(user_init, user_step: proc(c: ^Core)) {
rc.left, rc.top, rc.left, rc.top,
rc.right-rc.left, rc.bottom-rc.top, rc.right-rc.left, rc.bottom-rc.top,
nil, nil, window_class.instance, nil, nil, window_class.instance,
nil) nil);
if win32_window == nil { if win32_window == nil {
fmt.fprintln(os.stderr, "CreateWindowExA failed") fmt.fprintln(os.stderr, "CreateWindowExA failed");
return return;
} }
window_bmi: BITMAPINFO window_bmi: BITMAPINFO;
window_bmi.size = size_of(BITMAPINFO.HEADER) as u32 window_bmi.size = size_of(BITMAPINFOHEADER);
window_bmi.width = CANVAS_WIDTH window_bmi.width = CANVAS_WIDTH;
window_bmi.height = CANVAS_HEIGHT window_bmi.height = CANVAS_HEIGHT;
window_bmi.planes = 1 window_bmi.planes = 1;
window_bmi.bit_count = 32 window_bmi.bit_count = 32;
window_bmi.compression = BI_RGB window_bmi.compression = BI_RGB;
user_init(^_core) user_init(^_core);
ShowWindow(win32_window, SW_SHOW);
window_buffer := new_slice(u32, CANVAS_WIDTH * CANVAS_HEIGHT);
assert(window_buffer.data != nil);
defer free(window_buffer.data);
ShowWindow(win32_window, SW_SHOW) for i := 0; i < window_buffer.count; i += 1 {
window_buffer[i] = 0xff00ff;
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
} }
prev_time, curr_time,dt: f64 dt: f64;
prev_time = time_now() prev_time := time_now();
curr_time = time_now() curr_time := time_now();
total_time : f64 = 0 total_time : f64 = 0;
offset_x := 0 offset_x := 0;
offset_y := 0 offset_y := 0;
message: MSG message: MSG;
for _core.running { for _core.running {
curr_time = time_now() curr_time = time_now();
dt = curr_time - prev_time dt = curr_time - prev_time;
prev_time = curr_time prev_time = curr_time;
total_time += dt total_time += dt;
offset_x += 1 offset_x += 1;
offset_y += 2 offset_y += 2;
{ {
data: [128]byte data: [128]byte;
buf := data[:0] buf: fmt.Buffer;
fmt.bprintf(^buf, "Punity: % ms\x00", dt*1000) buf.data = data[:];
win32.SetWindowTextA(win32_window, buf.data) fmt.bprintf(^buf, "Punity: %.4f ms\x00", dt*1000);
win32.SetWindowTextA(win32_window, ^buf[0]);
} }
for y := 0; y < CANVAS_HEIGHT; y++ { for y := 0; y < CANVAS_HEIGHT; y += 1 {
for x := 0; x < CANVAS_WIDTH; x++ { for x := 0; x < CANVAS_WIDTH; x += 1 {
g := (x % 32) * 8 g := (x % 32) * 8;
b := (y % 32) * 8 b := (y % 32) * 8;
window_buffer[x + y*CANVAS_WIDTH] = (g << 8 | b) as u32 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 { for PeekMessageA(^message, nil, 0, 0, PM_REMOVE) != 0 {
if message.message == WM_QUIT { if message.message == WM_QUIT {
_core.running = false _core.running = false;
} }
TranslateMessage(^message) TranslateMessage(^message);
DispatchMessageA(^message) DispatchMessageA(^message);
} }
user_step(^_core) user_step(^_core);
dc := GetDC(win32_window) dc := GetDC(win32_window);
StretchDIBits(dc, StretchDIBits(dc,
0, 0, CANVAS_WIDTH * CANVAS_SCALE, CANVAS_HEIGHT * CANVAS_SCALE, 0, 0, CANVAS_WIDTH * CANVAS_SCALE, CANVAS_HEIGHT * CANVAS_SCALE,
0, 0, CANVAS_WIDTH, CANVAS_HEIGHT, 0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
window_buffer.data, window_buffer.data,
^window_bmi, ^window_bmi,
DIB_RGB_COLORS, DIB_RGB_COLORS,
SRCCOPY) SRCCOPY);
ReleaseDC(win32_window, dc) ReleaseDC(win32_window, dc);
{ {
delta := time_now() - prev_time delta := time_now() - prev_time;
ms := ((FRAME_TIME - delta) * 1000) as i32 ms := cast(i32)((FRAME_TIME - delta) * 1000);
if ms > 0 { 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);
}
+20 -12
View File
@@ -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) { fmt_integer :: proc(fi: ^Fmt_Info, u: u64, base: int, signed: bool, digits: string) {
negative := signed && cast(i64)u < 0; negative := signed && cast(i64)u < 0;
if negative { u = abs(u);
u = -u;
}
buf: [256]byte; buf: [256]byte;
if fi.width_set || fi.prec_set { if fi.width_set || fi.prec_set {
width := fi.width + fi.prec + 3; 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:]); buffer_write(fi.buf, buf[i:]);
} else { } else {
width := fi.width - utf8.rune_count(cast(string)buf[i:]); width := fi.width - utf8.rune_count(cast(string)buf[i:]);
if fi.minus { if width > 0 {
// Right pad if fi.minus {
buffer_write(fi.buf, buf[i:]); // Right pad
fmt_write_padding(fi, width); buffer_write(fi.buf, buf[i:]);
} else { fmt_write_padding(fi, width);
// Left pad } else {
fmt_write_padding(fi, width); // Left pad
buffer_write(fi.buf, buf[i:]); 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; signed := v < 0;
v = abs(v); v = abs(v);
if signed {
buffer_write_byte(fi.buf, '-');
}
val := cast(u64)v; 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 { if fi.hash || prec > 0 {
arg := v - cast(f64)val; arg := v - cast(f64)val;
+5 -4
View File
@@ -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"); error_node(pd->body, "A procedure tagged as `#foreign` cannot have a body");
} }
if (proc_type->Proc.calling_convention != ProcCC_Odin) { // TODO(bill): Is this the best option? What about passing to external shit?!
error_node(d->proc_lit, "An internal procedure may only have the Odin calling convention"); // if (proc_type->Proc.calling_convention != ProcCC_Odin) {
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; d->scope = c->context.scope;
+5
View File
@@ -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)) { if (is_type_any(dst)) {
// NOTE(bill): Anything can cast to `Any` // NOTE(bill): Anything can cast to `Any`
+1 -1
View File
@@ -240,7 +240,7 @@ int main(int argc, char **argv) {
char lib_str_buf[1024] = {0}; char lib_str_buf[1024] = {0};
for_array(i, ir_gen.module.foreign_library_paths) { for_array(i, ir_gen.module.foreign_library_paths) {
String lib = ir_gen.module.foreign_library_paths.e[i]; 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), isize len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf),
" \"%.*s\"", LIT(lib)); " \"%.*s\"", LIT(lib));
lib_str = gb_string_appendc(lib_str, lib_str_buf); lib_str = gb_string_appendc(lib_str, lib_str_buf);
+8 -5
View File
@@ -1827,11 +1827,15 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
} }
case Token_if: case Token_if:
if (lhs) goto error; if (!lhs && f->expr_level >= 0) {
return parse_if_expr(f); return parse_if_expr(f);
}
break;
case Token_OpenBrace: case Token_OpenBrace:
if (lhs) goto error; if (!lhs && f->expr_level >= 0) {
return parse_block_expr(f); return parse_block_expr(f);
}
break;
default: { default: {
AstNode *type = parse_identifier_or_type(f); AstNode *type = parse_identifier_or_type(f);
@@ -1846,7 +1850,6 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
} }
} }
error:
Token begin = f->curr_token; Token begin = f->curr_token;
syntax_error(begin, "Expected an operand"); syntax_error(begin, "Expected an operand");
fix_advance_to_next_stmt(f); fix_advance_to_next_stmt(f);
+3 -1
View File
@@ -1194,7 +1194,9 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
} else if (!is_type_union(type)) { } else if (!is_type_union(type)) {
for (isize i = 0; i < type->Record.field_count; i++) { for (isize i = 0; i < type->Record.field_count; i++) {
Entity *f = type->Record.fields[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; String str = f->token.string;
if (str_eq(field_name, str)) { if (str_eq(field_name, str)) {
selection_add_index(&sel, i); // HACK(bill): Leaky memory selection_add_index(&sel, i); // HACK(bill): Leaky memory