Update and regression test old demos

This commit is contained in:
Ginger Bill
2017-04-02 22:03:52 +01:00
parent 96e8bb5b6f
commit 382a5ca6a2
12 changed files with 470 additions and 456 deletions
+1 -1
View File
@@ -4,7 +4,7 @@
set exe_name=odin.exe set exe_name=odin.exe
:: Debug = 0, Release = 1 :: Debug = 0, Release = 1
set release_mode=1 set release_mode=0
set compiler_flags= -nologo -Oi -TC -fp:fast -fp:except- -Gm- -MP -FC -GS- -EHsc- -GR- set compiler_flags= -nologo -Oi -TC -fp:fast -fp:except- -Gm- -MP -FC -GS- -EHsc- -GR-
if %release_mode% EQU 0 ( rem Debug if %release_mode% EQU 0 ( rem Debug
+46 -39
View File
@@ -1,4 +1,5 @@
#import "win32.odin" when ODIN_OS == "windows"; #import win32 "sys/windows.odin" when ODIN_OS == "windows";
#import wgl "sys/wgl.odin" when ODIN_OS == "windows";
#import "fmt.odin"; #import "fmt.odin";
#import "math.odin"; #import "math.odin";
#import "os.odin"; #import "os.odin";
@@ -12,11 +13,11 @@ time_now :: proc() -> f64 {
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;
} }
win32_print_last_error :: proc() { win32_print_last_error :: proc() {
err_code := win32.GetLastError() as int; err_code := cast(int)win32.GetLastError();
if err_code != 0 { if err_code != 0 {
fmt.println("GetLastError: %", err_code); fmt.println("GetLastError: %", err_code);
} }
@@ -24,42 +25,42 @@ win32_print_last_error :: proc() {
// Yuk! // Yuk!
to_c_string :: proc(s: string) -> []u8 { to_c_string :: proc(s: string) -> []u8 {
c_str := new_slice(u8, s.count+1); c_str := make([]u8, len(s)+1);
copy(c_str, s as []byte); copy(c_str, cast([]byte)s);
c_str[s.count] = 0; c_str[len(s)] = 0;
return c_str; return c_str;
} }
Window :: struct { Window :: struct {
width, height: int; width, height: int,
wc: win32.WNDCLASSEXA; wc: win32.WndClassExA,
dc: win32.HDC; dc: win32.Hdc,
hwnd: win32.HWND; hwnd: win32.Hwnd,
opengl_context, rc: win32.HGLRC; opengl_context, rc: wgl.Hglrc,
c_title: []u8; c_title: []u8,
} }
make_window :: proc(title: string, msg, height: int, window_proc: win32.WNDPROC) -> (Window, bool) { make_window :: proc(title: string, msg, height: int, window_proc: win32.Wnd_Proc) -> (Window, bool) {
using win32; using win32;
w: Window; w: Window;
w.width, w.height = msg, height; w.width, w.height = msg, height;
class_name := "Win32-Odin-Window\x00"; class_name := "Win32-Odin-Window\x00";
c_class_name := class_name.data; c_class_name := ^class_name[0];
if title[title.count-1] != 0 { if title[len(title)-1] != 0 {
w.c_title = to_c_string(title); w.c_title = to_c_string(title);
} else { } else {
w.c_title = title as []u8; w.c_title = cast([]u8)title;
} }
instance := GetModuleHandleA(nil); instance := GetModuleHandleA(nil);
w.wc = WNDCLASSEXA{ w.wc = WndClassExA{
size = size_of(WNDCLASSEXA) as u32, size = size_of(WndClassExA),
style = CS_VREDRAW | CS_HREDRAW, style = CS_VREDRAW | CS_HREDRAW,
instance = instance as HINSTANCE, instance = cast(Hinstance)instance,
class_name = c_class_name, class_name = c_class_name,
wnd_proc = window_proc, wnd_proc = window_proc,
}; };
@@ -70,10 +71,10 @@ make_window :: proc(title: string, msg, height: int, window_proc: win32.WNDPROC)
} }
w.hwnd = CreateWindowExA(0, w.hwnd = CreateWindowExA(0,
c_class_name, w.c_title.data, c_class_name, ^w.c_title[0],
WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
w.width as i32, w.height as i32, cast(i32)w.width, cast(i32)w.height,
nil, nil, instance, nil); nil, nil, instance, nil);
if w.hwnd == nil { if w.hwnd == nil {
@@ -85,7 +86,7 @@ make_window :: proc(title: string, msg, height: int, window_proc: win32.WNDPROC)
{ {
pfd := PIXELFORMATDESCRIPTOR{ pfd := PIXELFORMATDESCRIPTOR{
size = size_of(PIXELFORMATDESCRIPTOR) as u32, size = size_of(PIXELFORMATDESCRIPTOR),
version = 1, version = 1,
flags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, flags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
pixel_type = PFD_TYPE_RGBA, pixel_type = PFD_TYPE_RGBA,
@@ -97,19 +98,20 @@ make_window :: proc(title: string, msg, height: int, window_proc: win32.WNDPROC)
}; };
SetPixelFormat(w.dc, ChoosePixelFormat(w.dc, ^pfd), nil); SetPixelFormat(w.dc, ChoosePixelFormat(w.dc, ^pfd), nil);
w.opengl_context = wglCreateContext(w.dc); w.opengl_context = wgl.CreateContext(w.dc);
wglMakeCurrent(w.dc, w.opengl_context); wgl.MakeCurrent(w.dc, w.opengl_context);
attribs := [8]i32{ attribs := [8]i32{
WGL_CONTEXT_MAJOR_VERSION_ARB, 2, wgl.CONTEXT_MAJOR_VERSION_ARB, 2,
WGL_CONTEXT_MINOR_VERSION_ARB, 1, wgl.CONTEXT_MINOR_VERSION_ARB, 1,
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, wgl.CONTEXT_PROFILE_MASK_ARB, wgl.CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
0, // NOTE(bill): tells the proc that this is the end of attribs 0, // NOTE(bill): tells the proc that this is the end of attribs
}; };
wglCreateContextAttribsARB := wglGetProcAddress(("wglCreateContextAttribsARB\x00" as string).data) as wglCreateContextAttribsARBType; wgl_str := "wglCreateContextAttribsARB\x00";
w.rc = wglCreateContextAttribsARB(w.dc, 0, ^attribs[0]); wglCreateContextAttribsARB := cast(wgl.Create_Context_Attribs_ARB_Type)wgl.GetProcAddress(^wgl_str[0]);
wglMakeCurrent(w.dc, w.rc); w.rc = wglCreateContextAttribsARB(w.dc, nil, ^attribs[0]);
wgl.MakeCurrent(w.dc, w.rc);
SwapBuffers(w.dc); SwapBuffers(w.dc);
} }
@@ -117,7 +119,7 @@ make_window :: proc(title: string, msg, height: int, window_proc: win32.WNDPROC)
} }
destroy_window :: proc(w: ^Window) { destroy_window :: proc(w: ^Window) {
free(w.c_title.data); free(w.c_title);
} }
display_window :: proc(w: ^Window) { display_window :: proc(w: ^Window) {
@@ -129,7 +131,7 @@ run :: proc() {
using win32; using win32;
using math; using math;
win32_proc :: proc(hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT #no_inline { win32_proc :: proc(hwnd: win32.Hwnd, msg: u32, wparam: win32.Wparam, lparam: win32.Lparam) -> win32.Lresult #no_inline {
if msg == WM_DESTROY || msg == WM_CLOSE || msg == WM_QUIT { if msg == WM_DESTROY || msg == WM_CLOSE || msg == WM_QUIT {
os.exit(0); os.exit(0);
return 0; return 0;
@@ -137,7 +139,7 @@ run :: proc() {
return DefWindowProcA(hwnd, msg, wparam, lparam); return DefWindowProcA(hwnd, msg, wparam, lparam);
} }
window, window_success := make_window("Odin Language Demo", 854, 480, win32_proc); window, window_success := make_window("Odin Language Demo", 854, 480, cast(Wnd_Proc)win32_proc);
if !window_success { if !window_success {
return; return;
} }
@@ -153,10 +155,10 @@ run :: proc() {
for running { for running {
curr_time := time_now(); curr_time := time_now();
dt := (curr_time - prev_time) as f32; dt := cast(f32)(curr_time - prev_time);
prev_time = curr_time; prev_time = curr_time;
msg: MSG; msg: Msg;
for PeekMessageA(^msg, nil, 0, 0, PM_REMOVE) > 0 { for PeekMessageA(^msg, nil, 0, 0, PM_REMOVE) > 0 {
if msg.message == WM_QUIT { if msg.message == WM_QUIT {
running = false; running = false;
@@ -178,7 +180,7 @@ run :: proc() {
if is_key_down(Key_Code.UP) { v[1] += 1; } if is_key_down(Key_Code.UP) { v[1] += 1; }
if is_key_down(Key_Code.DOWN) { v[1] -= 1; } if is_key_down(Key_Code.DOWN) { v[1] -= 1; }
v = vec2_norm0(v); v = norm(v);
pos += v * Vec2{SPEED * dt}; pos += v * Vec2{SPEED * dt};
} }
@@ -188,8 +190,8 @@ run :: proc() {
gl.Clear(gl.COLOR_BUFFER_BIT); gl.Clear(gl.COLOR_BUFFER_BIT);
gl.LoadIdentity(); gl.LoadIdentity();
gl.Ortho(0, window.width as f64, gl.Ortho(0, cast(f64)window.width,
0, window.height as f64, 0, 1); 0, cast(f64)window.height, 0, 1);
draw_rect :: proc(x, y, w, h: f32) { draw_rect :: proc(x, y, w, h: f32) {
gl.Begin(gl.TRIANGLES); gl.Begin(gl.TRIANGLES);
@@ -207,9 +209,14 @@ run :: proc() {
draw_rect(pos.x, pos.y, 50, 50); draw_rect(pos.x, pos.y, 50, 50);
display_window(^window); display_window(^window);
ms_to_sleep := (16 - 1000*dt) as i32; ms_to_sleep := cast(i32)(16 - 1000*dt);
if ms_to_sleep > 0 { if ms_to_sleep > 0 {
win32.Sleep(ms_to_sleep); win32.Sleep(ms_to_sleep);
} }
} }
} }
main :: proc() {
run();
}
+8 -8
View File
@@ -136,7 +136,7 @@ bounds_checking :: proc() {
{ {
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 {
@@ -164,7 +164,7 @@ type_introspection :: proc() {
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 in info { match 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:
@@ -174,7 +174,7 @@ type_introspection :: proc() {
} }
// Unsafe cast // Unsafe cast
integer_info := cast(^Type_Info.Integer)info; integer_info := cast(^Type_Info.Integer)cast(rawptr)info;
} }
{ {
@@ -263,12 +263,12 @@ crazy_introspection :: proc() {
} }
fruit_ti := type_info(Fruit); fruit_ti := type_info(Fruit);
name := (cast(^Type_Info.Named)fruit_ti).name; // Unsafe casts name := (union_cast(^Type_Info.Named)fruit_ti).name; // Unsafe casts
info := cast(^Type_Info.Enum)type_info_base(fruit_ti); // Unsafe casts info, _ := union_cast(^Type_Info.Enum)type_info_base(fruit_ti); // Unsafe casts
fmt.printf("% :: enum % {\n", name, info.base); fmt.printf("%s :: enum %T {\n", name, info.base);
for i := 0; i < info.values.count; i += 1 { for i := 0; i < len(info.values); i++ {
fmt.printf("\t%\t= %,\n", info.names[i], info.values[i]); fmt.printf("\t%s\t= %v,\n", info.names[i], info.values[i]);
} }
fmt.printf("}\n"); fmt.printf("}\n");
File diff suppressed because it is too large Load Diff
+17 -17
View File
@@ -1,14 +1,14 @@
#import "fmt.odin" #import "fmt.odin";
#import "utf8.odin" #import "utf8.odin";
#import "hash.odin" #import "hash.odin";
#import "mem.odin" #import "mem.odin";
main :: proc() { main :: proc() {
{ // New Standard Library stuff { // New Standard Library stuff
s := "Hello" s := "Hello";
fmt.println(s, fmt.println(s,
utf8.valid_string(s), utf8.valid_string(s),
hash.murmur64(s.data, s.count)) hash.murmur64(cast([]byte)s));
// utf8.odin // utf8.odin
// hash.odin // hash.odin
@@ -19,15 +19,15 @@ main :: proc() {
} }
{ {
arena: mem.Arena arena: mem.Arena;
mem.init_arena_from_context(^arena, mem.megabytes(16)) // Uses default allocator mem.init_arena_from_context(^arena, mem.megabytes(16)); // Uses default allocator
defer mem.free_arena(^arena) defer mem.free_arena(^arena);
push_allocator mem.arena_allocator(^arena) { push_allocator mem.arena_allocator(^arena) {
x := new(int) x := new(int);
x^ = 1337 x^ = 1337;
fmt.println(x^) fmt.println(x^);
} }
/* /*
@@ -48,14 +48,14 @@ main :: proc() {
// You can also "push" a context // You can also "push" a context
c := current_context() // Create copy of the allocator c := context; // Create copy of the allocator
c.allocator = mem.arena_allocator(^arena) c.allocator = mem.arena_allocator(^arena);
push_context c { push_context c {
x := new(int) x := new(int);
x^ = 365 x^ = 365;
fmt.println(x^) fmt.println(x^);
} }
} }
+15 -13
View File
@@ -42,12 +42,12 @@ syntax :: proc() {
}; };
Thing2 :: struct {x: f32, y: int, z: ^[]int}; Thing2 :: struct {x: f32, y: int, z: ^[]int};
// Slice interals are now just a `ptr+count` // Slice interals are now just a `ptr+len+cap`
slice: []int; compile_assert(size_of_val(slice) == 2*size_of(int)); slice: []int; compile_assert(size_of_val(slice) == 3*size_of(int));
// Helper type - Help the reader understand what 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;
// All declarations with : are either variable or constant // All declarations with : are either variable or constant
@@ -59,6 +59,7 @@ syntax :: proc() {
c_proc :: proc() { /* code here */ }; c_proc :: proc() { /* code here */ };
/*
x += 1; x += 1;
x -= 1; x -= 1;
// ++ and -- have been removed // ++ and -- have been removed
@@ -67,7 +68,7 @@ syntax :: proc() {
// Question: Should they be added again? // Question: Should they be added again?
// They were removed as they are redundant and statements, not expressions // They were removed as they are redundant and statements, not expressions
// like in C/C++ // like in C/C++
*/
// You can now build files as a `.dll` // You can now build files as a `.dll`
// `odin build_dll demo.odin` // `odin build_dll demo.odin`
@@ -85,7 +86,7 @@ syntax :: proc() {
Prefix_Type :: struct {x: int, y: f32, z: rawptr}; Prefix_Type :: struct {x: int, y: f32, z: rawptr};
thread_local my_tls: Prefix_Type; #thread_local my_tls: Prefix_Type;
prefixes :: proc() { prefixes :: proc() {
using var: Prefix_Type; using var: Prefix_Type;
@@ -98,7 +99,7 @@ prefixes :: proc() {
foo :: proc(using immutable pt: Prefix_Type, immutable int_ptr: ^int) { foo :: proc(using immutable pt: Prefix_Type, immutable int_ptr: ^int) {
// int_ptr = nil; // Not valid // int_ptr = nil; // Not valid
int_ptr^ = 123; // Is valid // int_ptr^ = 123; // Not valid
} }
@@ -154,6 +155,7 @@ foreign_procedures :: proc() {
} }
special_expressions :: proc() { special_expressions :: proc() {
/*
// Block expression // Block expression
x := { x := {
a: f32 = 123; a: f32 = 123;
@@ -168,7 +170,7 @@ special_expressions :: proc() {
// TODO: Type cohesion is not yet finished // TODO: Type cohesion is not yet finished
give 123; give 123;
}; // semicolon is required as it's an expression }; // semicolon is required as it's an expression
*/
// This is allows for inline blocks of code and will be a useful feature to have when // This is allows for inline blocks of code and will be a useful feature to have when
// macros will be implemented into the language // macros will be implemented into the language
@@ -191,17 +193,17 @@ loops :: proc() {
break; break;
} }
for i in 0..<123 { // 123 exclusive for i in 0..123 { // 123 exclusive
} }
for i in 0...122 { // 122 inclusive for i in 0..123-1 { // 122 inclusive
} }
for val, idx in 12..<16 { for val, idx in 12..16 {
fmt.println(val, idx); fmt.println(val, idx);
} }
primes := [...]int{2, 3, 5, 7, 11, 13, 17, 19}; primes := [..]int{2, 3, 5, 7, 11, 13, 17, 19};
for p in primes { for p in primes {
fmt.println(p); fmt.println(p);
@@ -224,7 +226,7 @@ loops :: proc() {
when false { when false {
for i, size := 0; i < name.count; i += size { for i, size := 0; i < name.count; i += size {
r: rune; r: rune;
r, size = utf8.decode_rune(name[i:]); r, size = utf8.decode_rune(name[i..]);
fmt.printf("%r\n", r); fmt.printf("%r\n", r);
} }
} }
+2 -1
View File
@@ -174,7 +174,8 @@ murmur64 :: proc(data: []byte) -> u64 {
len -= 4; len -= 4;
} }
data8 := slice_to_bytes(data32[i..])[..3]; // TODO(bill): Fix this
#no_bounds_check data8 := slice_to_bytes(data32[i..])[..3];
match len { match len {
case 3: case 3:
h2 ~= cast(u32)data8[2] << 16; h2 ~= cast(u32)data8[2] << 16;
+1
View File
@@ -7,6 +7,7 @@ CONTEXT_FLAGS_ARB :: 0x2094;
CONTEXT_PROFILE_MASK_ARB :: 0x9126; CONTEXT_PROFILE_MASK_ARB :: 0x9126;
CONTEXT_FORWARD_COMPATIBLE_BIT_ARB :: 0x0002; CONTEXT_FORWARD_COMPATIBLE_BIT_ARB :: 0x0002;
CONTEXT_CORE_PROFILE_BIT_ARB :: 0x00000001; CONTEXT_CORE_PROFILE_BIT_ARB :: 0x00000001;
CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB :: 0x00000002;
Hglrc :: Handle; Hglrc :: Handle;
Color_Ref :: u32; Color_Ref :: u32;
+3 -5
View File
@@ -249,12 +249,10 @@ void check_assignment(Checker *c, Operand *operand, Type *type, String context_n
operand->mode = Addressing_Invalid; operand->mode = Addressing_Invalid;
return; return;
} }
if (is_type_any(type)) { target_type = default_type(operand->type);
target_type = t_any; if (!is_type_any(type)) {
} else { GB_ASSERT_MSG(is_type_typed(target_type), "%s", type_to_string(type));
target_type = default_type(operand->type);
} }
GB_ASSERT_MSG(is_type_typed(target_type), "%s", type_to_string(type));
add_type_info_type(c, type); add_type_info_type(c, type);
add_type_info_type(c, target_type); add_type_info_type(c, target_type);
} }
+3 -1
View File
@@ -1264,8 +1264,10 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
case Entity_TypeName: { case Entity_TypeName: {
Type *t = base_type(e->type); Type *t = base_type(e->type);
if (is_type_union(t)) { if (is_type_union(t)) {
for (isize i = 0; i < t->Record.variant_count; i++) { TokenPos pos = ast_node_token(expr).pos;
for (isize i = 1; i < t->Record.variant_count; i++) {
Entity *f = t->Record.variants[i]; Entity *f = t->Record.variants[i];
// gb_printf_err("%s\n", type_to_string(f->type));
Entity *found = scope_insert_entity(c->context.scope, f); Entity *found = scope_insert_entity(c->context.scope, f);
if (found != NULL) { if (found != NULL) {
gbString expr_str = expr_to_string(expr); gbString expr_str = expr_to_string(expr);
+11 -1
View File
@@ -4263,8 +4263,10 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
irValue *ptr = ir_emit_conv(proc, ir_slice_elem(proc, s), t_u8_ptr); irValue *ptr = ir_emit_conv(proc, ir_slice_elem(proc, s), t_u8_ptr);
irValue *count = ir_slice_count(proc, s); irValue *count = ir_slice_count(proc, s);
irValue *capacity = ir_slice_capacity(proc, s);
count = ir_emit_arith(proc, Token_Mul, count, ir_const_int(proc->module->allocator, elem_size), t_int); count = ir_emit_arith(proc, Token_Mul, count, ir_const_int(proc->module->allocator, elem_size), t_int);
ir_fill_slice(proc, slice, ptr, count, count); capacity = ir_emit_arith(proc, Token_Mul, capacity, ir_const_int(proc->module->allocator, elem_size), t_int);
ir_fill_slice(proc, slice, ptr, count, capacity);
return ir_emit_load(proc, slice); return ir_emit_load(proc, slice);
} break; } break;
@@ -4602,6 +4604,14 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
ir_emit_store(proc, v, ir_emit_down_cast(proc, ir_build_expr(proc, ce->expr), type)); ir_emit_store(proc, v, ir_emit_down_cast(proc, ir_build_expr(proc, ce->expr), type));
return ir_addr(v); return ir_addr(v);
} }
case Token_union_cast: {
ir_emit_comment(proc, str_lit("Cast - union_cast"));
// NOTE(bill): Needed for dereference of pointer conversion
Type *type = type_of_expr(proc->module->info, expr);
irValue *v = ir_add_local_generated(proc, type);
ir_emit_store(proc, v, ir_emit_union_cast(proc, ir_build_expr(proc, ce->expr), type, ast_node_token(expr).pos));
return ir_addr(v);
}
default: default:
GB_PANIC("Unknown cast expression"); GB_PANIC("Unknown cast expression");
} }
+2 -1
View File
@@ -2272,6 +2272,7 @@ AstNode *parse_value_decl(AstFile *f, AstNodeArray lhs) {
} }
AstNode *parse_simple_stmt(AstFile *f, bool in_stmt_ok) { AstNode *parse_simple_stmt(AstFile *f, bool in_stmt_ok) {
AstNodeArray lhs = parse_lhs_expr_list(f); AstNodeArray lhs = parse_lhs_expr_list(f);
Token token = f->curr_token; Token token = f->curr_token;
@@ -3290,7 +3291,7 @@ AstNode *parse_stmt(AstFile *f) {
return ast_using_stmt(f, token, list); return ast_using_stmt(f, token, list);
} }
AstNode *decl = parse_simple_stmt(f, false); AstNode *decl = parse_value_decl(f, list);
expect_semicolon(f, decl); expect_semicolon(f, decl);
if (decl->kind == AstNode_ValueDecl) { if (decl->kind == AstNode_ValueDecl) {