diff --git a/examples/basic.odin b/examples/basic.odin index 265d5cc83..548f93fff 100644 --- a/examples/basic.odin +++ b/examples/basic.odin @@ -1,7 +1,5 @@ #load "runtime.odin" -TWO_HEARTS :: '💕'; - print_string :: proc(s: string) { for i := 0; i < len(s); i++ { putchar(s[i] as i32); @@ -15,10 +13,10 @@ byte_reverse :: proc(b: []byte) { } } -encode_rune :: proc(r : rune) -> ([4]byte, int) { - buf : [4]byte; +encode_rune :: proc(r: rune) -> ([4]byte, int) { + buf: [4]byte; i := r as u32; - mask : byte : 0x3f; + mask: byte : 0x3f; if i <= 1<<7-1 { buf[0] = r as byte; return buf, 1; @@ -49,16 +47,16 @@ encode_rune :: proc(r : rune) -> ([4]byte, int) { return buf, 4; } -print_rune :: proc(r : rune) { +print_rune :: proc(r: rune) { buf, n := encode_rune(r); str := buf[:n] as string; print_string(str); } -print_int :: proc(i : int) { +print_int :: proc(i: int) { print_int_base(i, 10); } -print_int_base :: proc(i, base : int) { +print_int_base :: proc(i, base: int) { NUM_TO_CHAR_TABLE :: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz@$"; buf: [65]byte; @@ -87,19 +85,14 @@ print_int_base :: proc(i, base : int) { print_string(buf[:len] as string); } -print_uint :: proc(i : uint) { - print_uint_base(i, 10); +print_uint :: proc(i: uint) { + print__uint(i, 10, 0, ' '); } -print_uint_base :: proc(i, base : uint) { +print__uint :: proc(i, base: uint, min_width: int, pad_char: byte) { NUM_TO_CHAR_TABLE :: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz@$"; buf: [65]byte; len := 0; - negative := false; - if i < 0 { - negative = true; - i = -i; - } if i == 0 { buf[len] = '0'; len++; @@ -109,9 +102,8 @@ print_uint_base :: proc(i, base : uint) { len++; i /= base; } - - if negative { - buf[len] = '-'; + for len < min_width { + buf[len] = pad_char; len++; } @@ -119,9 +111,55 @@ print_uint_base :: proc(i, base : uint) { print_string(buf[:len] as string); } - print_bool :: proc(b : bool) { if b { print_string("true"); } else { print_string("false"); } } +print_pointer :: proc(p: rawptr) #inline { print__uint(p as uint, 16, 0, ' '); } + +print_f32 :: proc(f: f32) #inline { print__f64(f as f64, 7); } +print_f64 :: proc(f: f64) #inline { print__f64(f, 10); } + +print__f64 :: proc(f: f64, decimal_places: int) { + if f == 0 { + print_rune('0'); + return; + } + if f < 0 { + print_rune('-'); + f = -f; + } + + print_u64 :: proc(i: u64) { + NUM_TO_CHAR_TABLE :: "0123456789"; + + buf: [22]byte; + len := 0; + if i == 0 { + buf[len] = '0'; + len++; + } + for i > 0 { + buf[len] = NUM_TO_CHAR_TABLE[i % 10]; + len++; + i /= 10; + } + byte_reverse(buf[:len]); + print_string(buf[:len] as string); + } + + i := f as u64; + print_u64(i); + f -= i as f64; + + print_rune('.'); + + mult := 10.0; + for decimal_places := 6; decimal_places >= 0; decimal_places-- { + i = (f * mult) as u64; + print_u64(i as u64); + f -= i as f64 / mult; + mult *= 10; + } +} diff --git a/examples/main.ll b/examples/main.ll index 09fcd5f4c..ad83d4b5d 100644 --- a/examples/main.ll +++ b/examples/main.ll @@ -14,8 +14,8 @@ %LPARAM = type i64 %LRESULT = type i64 %ATOM = type i16 -%POINT = type {i32, i32} %BOOL = type i32 +%POINT = type {i32, i32} %WNDPROC = type %LRESULT (%HWND, i32, %WPARAM, %LPARAM)* %WNDCLASSEXA = type {i32, i32, %LRESULT (%HWND, i32, %WPARAM, %LPARAM)*, i32, i32, %.rawptr, %.rawptr, %.rawptr, %.rawptr, i8*, i8*, %.rawptr} %MSG = type {%.rawptr, i32, i64, i64, i32, %POINT} @@ -23,7 +23,6 @@ %PROC = type void ()* %wglCreateContextAttribsARBType = type %HGLRC (%HDC, %.rawptr, i32*)* %PIXELFORMATDESCRIPTOR = type {i32, i32, i32, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i32, i32, i32} -%Bitmap = type {i32, i32, i32, {i8*, i64, i64}} %Vec2 = type <2 x float> %Vec3 = type <3 x float> %Vec4 = type <4 x float> @@ -127,7 +126,275 @@ entry.-.0: ret i8* %19 } -define %LRESULT @win32_proc(%HWND %hwnd, i32 %msg, %WPARAM %wparam, %LPARAM %lparam) noinline { +define {%Window, i1} @make_window(%.string %title, i64 %msg, i64 %height, %WNDPROC %window_proc) { +entry.-.0: + %0 = alloca %.string, align 8 ; title + store %.string zeroinitializer, %.string* %0 + store %.string %title, %.string* %0 + %1 = alloca i64, align 8 ; msg + store i64 zeroinitializer, i64* %1 + store i64 %msg, i64* %1 + %2 = alloca i64, align 8 ; height + store i64 zeroinitializer, i64* %2 + store i64 %height, i64* %2 + %3 = alloca %WNDPROC, align 8 ; window_proc + store %WNDPROC zeroinitializer, %WNDPROC* %3 + store %WNDPROC %window_proc, %WNDPROC* %3 + %4 = alloca %Window, align 8 ; w + store %Window zeroinitializer, %Window* %4 + %5 = getelementptr inbounds %Window, %Window* %4, i64 0, i32 0 + %6 = getelementptr inbounds %Window, %Window* %4, i64 0, i32 1 + %7 = load i64, i64* %1, align 8 + %8 = load i64, i64* %2, align 8 + store i64 %7, i64* %5 + store i64 %8, i64* %6 + %9 = alloca %.string, align 8 ; class_name + store %.string zeroinitializer, %.string* %9 + %10 = getelementptr inbounds [18 x i8], [18 x i8]* @.str2, i64 0, i64 0 + %11 = alloca %.string, align 8 + store %.string zeroinitializer, %.string* %11 + %12 = getelementptr inbounds %.string, %.string* %11, i64 0, i32 0 + %13 = getelementptr inbounds %.string, %.string* %11, i64 0, i32 1 + store i8* %10, i8** %12 + store i64 18, i64* %13 + %14 = load %.string, %.string* %11, align 8 + store %.string %14, %.string* %9 + %15 = alloca i8*, align 8 ; c_class_name + store i8* zeroinitializer, i8** %15 + %16 = getelementptr inbounds %.string, %.string* %9, i64 0, i32 0 + %17 = load i8*, i8** %16, align 8 + %18 = getelementptr i8, i8* %17, i64 0 + %19 = getelementptr inbounds i8, i8* %18 + store i8* %19, i8** %15 + %20 = getelementptr inbounds %Window, %Window* %4, i64 0, i32 7 + %21 = load %.string, %.string* %0, align 8 + %22 = call i8* @to_c_string(%.string %21) + store i8* %22, i8** %20 + %23 = alloca %HINSTANCE, align 8 ; instance + store %HINSTANCE zeroinitializer, %HINSTANCE* %23 + %24 = call %HINSTANCE @GetModuleHandleA(i8* null) + store %HINSTANCE %24, %HINSTANCE* %23 + %25 = getelementptr inbounds %Window, %Window* %4, i64 0, i32 2 + %26 = alloca %WNDCLASSEXA, align 8 + store %WNDCLASSEXA zeroinitializer, %WNDCLASSEXA* %26 + %27 = getelementptr inbounds %WNDCLASSEXA, %WNDCLASSEXA* %26, i64 0, i32 0 + store i32 80, i32* %27 + %28 = getelementptr inbounds %WNDCLASSEXA, %WNDCLASSEXA* %26, i64 0, i32 1 + store i32 3, i32* %28 + %29 = load %HINSTANCE, %HINSTANCE* %23, align 8 + %30 = getelementptr inbounds %WNDCLASSEXA, %WNDCLASSEXA* %26, i64 0, i32 5 + store %HINSTANCE %29, %HINSTANCE* %30 + %31 = load i8*, i8** %15, align 8 + %32 = getelementptr inbounds %WNDCLASSEXA, %WNDCLASSEXA* %26, i64 0, i32 10 + store i8* %31, i8** %32 + %33 = load %WNDPROC, %WNDPROC* %3, align 8 + %34 = getelementptr inbounds %WNDCLASSEXA, %WNDCLASSEXA* %26, i64 0, i32 2 + store %WNDPROC %33, %WNDPROC* %34 + %35 = load %WNDCLASSEXA, %WNDCLASSEXA* %26, align 8 + store %WNDCLASSEXA %35, %WNDCLASSEXA* %25 + %36 = getelementptr inbounds %Window, %Window* %4, i64 0, i32 2 + %37 = getelementptr inbounds %WNDCLASSEXA, %WNDCLASSEXA* %36 + %38 = call %ATOM @RegisterClassExA(%WNDCLASSEXA* %37) + %39 = icmp eq i16 %38, 0 + br i1 %39, label %if.then.-.1, label %if.done.-.2 + +if.then.-.1: + %40 = alloca {%Window, i1}, align 8 + store {%Window, i1} zeroinitializer, {%Window, i1}* %40 + %41 = load %Window, %Window* %4, align 8 + %42 = getelementptr inbounds {%Window, i1}, {%Window, i1}* %40, i64 0, i32 0 + store %Window %41, %Window* %42 + %43 = getelementptr inbounds {%Window, i1}, {%Window, i1}* %40, i64 0, i32 1 + store i1 false, i1* %43 + %44 = load {%Window, i1}, {%Window, i1}* %40, align 8 + ret {%Window, i1} %44 + +if.done.-.2: + %45 = getelementptr inbounds %Window, %Window* %4, i64 0, i32 4 + %46 = load i8*, i8** %15, align 8 + %47 = getelementptr inbounds %Window, %Window* %4, i64 0, i32 7 + %48 = load i8*, i8** %47, align 8 + %49 = getelementptr inbounds %Window, %Window* %4, i64 0, i32 0 + %50 = load i64, i64* %49, align 8 + %51 = trunc i64 %50 to i32 + %52 = getelementptr inbounds %Window, %Window* %4, i64 0, i32 1 + %53 = load i64, i64* %52, align 8 + %54 = trunc i64 %53 to i32 + %55 = load %HINSTANCE, %HINSTANCE* %23, align 8 + %56 = call %HWND @CreateWindowExA(i32 0, i8* %46, i8* %48, i32 281673728, i32 2147483648, i32 2147483648, i32 %51, i32 %54, %HWND null, %HMENU null, %HINSTANCE %55, %.rawptr null) + store %HWND %56, %HWND* %45 + %57 = getelementptr inbounds %Window, %Window* %4, i64 0, i32 4 + %58 = load %HWND, %HWND* %57, align 8 + %59 = icmp eq %.rawptr %58, null + br i1 %59, label %if.then.-.3, label %if.done.-.4 + +if.then.-.3: + call void @win32_print_last_error() + %60 = alloca {%Window, i1}, align 8 + store {%Window, i1} zeroinitializer, {%Window, i1}* %60 + %61 = load %Window, %Window* %4, align 8 + %62 = getelementptr inbounds {%Window, i1}, {%Window, i1}* %60, i64 0, i32 0 + store %Window %61, %Window* %62 + %63 = getelementptr inbounds {%Window, i1}, {%Window, i1}* %60, i64 0, i32 1 + store i1 false, i1* %63 + %64 = load {%Window, i1}, {%Window, i1}* %60, align 8 + ret {%Window, i1} %64 + +if.done.-.4: + %65 = getelementptr inbounds %Window, %Window* %4, i64 0, i32 3 + %66 = getelementptr inbounds %Window, %Window* %4, i64 0, i32 4 + %67 = load %HWND, %HWND* %66, align 8 + %68 = call %HDC @GetDC(%HANDLE %67) + store %HDC %68, %HDC* %65 + %69 = alloca %PIXELFORMATDESCRIPTOR, align 4 ; pfd + store %PIXELFORMATDESCRIPTOR zeroinitializer, %PIXELFORMATDESCRIPTOR* %69 + %70 = alloca %PIXELFORMATDESCRIPTOR, align 4 + store %PIXELFORMATDESCRIPTOR zeroinitializer, %PIXELFORMATDESCRIPTOR* %70 + %71 = getelementptr inbounds %PIXELFORMATDESCRIPTOR, %PIXELFORMATDESCRIPTOR* %70, i64 0, i32 0 + store i32 44, i32* %71 + %72 = getelementptr inbounds %PIXELFORMATDESCRIPTOR, %PIXELFORMATDESCRIPTOR* %70, i64 0, i32 1 + store i32 1, i32* %72 + %73 = getelementptr inbounds %PIXELFORMATDESCRIPTOR, %PIXELFORMATDESCRIPTOR* %70, i64 0, i32 2 + store i32 37, i32* %73 + %74 = getelementptr inbounds %PIXELFORMATDESCRIPTOR, %PIXELFORMATDESCRIPTOR* %70, i64 0, i32 3 + store i8 0, i8* %74 + %75 = getelementptr inbounds %PIXELFORMATDESCRIPTOR, %PIXELFORMATDESCRIPTOR* %70, i64 0, i32 4 + store i8 32, i8* %75 + %76 = getelementptr inbounds %PIXELFORMATDESCRIPTOR, %PIXELFORMATDESCRIPTOR* %70, i64 0, i32 11 + store i8 8, i8* %76 + %77 = getelementptr inbounds %PIXELFORMATDESCRIPTOR, %PIXELFORMATDESCRIPTOR* %70, i64 0, i32 18 + store i8 24, i8* %77 + %78 = getelementptr inbounds %PIXELFORMATDESCRIPTOR, %PIXELFORMATDESCRIPTOR* %70, i64 0, i32 19 + store i8 8, i8* %78 + %79 = getelementptr inbounds %PIXELFORMATDESCRIPTOR, %PIXELFORMATDESCRIPTOR* %70, i64 0, i32 21 + store i8 0, i8* %79 + %80 = load %PIXELFORMATDESCRIPTOR, %PIXELFORMATDESCRIPTOR* %70, align 4 + store %PIXELFORMATDESCRIPTOR %80, %PIXELFORMATDESCRIPTOR* %69 + %81 = getelementptr inbounds %Window, %Window* %4, i64 0, i32 3 + %82 = load %HDC, %HDC* %81, align 8 + %83 = getelementptr inbounds %Window, %Window* %4, i64 0, i32 3 + %84 = load %HDC, %HDC* %83, align 8 + %85 = getelementptr inbounds %PIXELFORMATDESCRIPTOR, %PIXELFORMATDESCRIPTOR* %69 + %86 = call i32 @ChoosePixelFormat(%HDC %84, %PIXELFORMATDESCRIPTOR* %85) + %87 = call %BOOL @SetPixelFormat(%HDC %82, i32 %86, %PIXELFORMATDESCRIPTOR* null) + %88 = getelementptr inbounds %Window, %Window* %4, i64 0, i32 5 + %89 = getelementptr inbounds %Window, %Window* %4, i64 0, i32 3 + %90 = load %HDC, %HDC* %89, align 8 + %91 = call %HGLRC @wglCreateContext(%HDC %90) + store %.rawptr %91, %.rawptr* %88 + %92 = getelementptr inbounds %Window, %Window* %4, i64 0, i32 3 + %93 = load %HDC, %HDC* %92, align 8 + %94 = getelementptr inbounds %Window, %Window* %4, i64 0, i32 5 + %95 = load %.rawptr, %.rawptr* %94, align 8 + %96 = call %BOOL @wglMakeCurrent(%HDC %93, %HGLRC %95) + %97 = alloca [8 x i32], align 4 ; attribs + store [8 x i32] zeroinitializer, [8 x i32]* %97 + %98 = alloca [8 x i32], align 4 + store [8 x i32] zeroinitializer, [8 x i32]* %98 + %99 = getelementptr inbounds [8 x i32], [8 x i32]* %98, i64 0, i32 0 + store i32 8337, i32* %99 + %100 = getelementptr inbounds [8 x i32], [8 x i32]* %98, i64 0, i32 1 + store i32 2, i32* %100 + %101 = getelementptr inbounds [8 x i32], [8 x i32]* %98, i64 0, i32 2 + store i32 8338, i32* %101 + %102 = getelementptr inbounds [8 x i32], [8 x i32]* %98, i64 0, i32 3 + store i32 1, i32* %102 + %103 = getelementptr inbounds [8 x i32], [8 x i32]* %98, i64 0, i32 4 + store i32 37158, i32* %103 + %104 = getelementptr inbounds [8 x i32], [8 x i32]* %98, i64 0, i32 5 + store i32 2, i32* %104 + %105 = getelementptr inbounds [8 x i32], [8 x i32]* %98, i64 0, i32 6 + store i32 0, i32* %105 + %106 = load [8 x i32], [8 x i32]* %98, align 4 + store [8 x i32] %106, [8 x i32]* %97 + %107 = alloca %.string, align 8 ; wgl_string + store %.string zeroinitializer, %.string* %107 + %108 = getelementptr inbounds [27 x i8], [27 x i8]* @.str3, i64 0, i64 0 + %109 = alloca %.string, align 8 + store %.string zeroinitializer, %.string* %109 + %110 = getelementptr inbounds %.string, %.string* %109, i64 0, i32 0 + %111 = getelementptr inbounds %.string, %.string* %109, i64 0, i32 1 + store i8* %108, i8** %110 + store i64 27, i64* %111 + %112 = load %.string, %.string* %109, align 8 + store %.string %112, %.string* %107 + %113 = alloca i8*, align 8 ; c_wgl_string + store i8* zeroinitializer, i8** %113 + %114 = getelementptr inbounds %.string, %.string* %107, i64 0, i32 0 + %115 = load i8*, i8** %114, align 8 + %116 = getelementptr i8, i8* %115, i64 0 + %117 = getelementptr inbounds i8, i8* %116 + store i8* %117, i8** %113 + %118 = alloca %wglCreateContextAttribsARBType, align 8 ; wglCreateContextAttribsARB + store %wglCreateContextAttribsARBType zeroinitializer, %wglCreateContextAttribsARBType* %118 + %119 = load i8*, i8** %113, align 8 + %120 = call %PROC @wglGetProcAddress(i8* %119) + %121 = bitcast void ()* %120 to %HGLRC (%HDC, %.rawptr, i32*)* + %122 = bitcast %HGLRC (%HDC, %.rawptr, i32*)* %121 to %HGLRC (%HDC, %.rawptr, i32*)* + store %wglCreateContextAttribsARBType %122, %wglCreateContextAttribsARBType* %118 + %123 = getelementptr inbounds %Window, %Window* %4, i64 0, i32 6 + %124 = load %wglCreateContextAttribsARBType, %wglCreateContextAttribsARBType* %118, align 8 + %125 = getelementptr inbounds %Window, %Window* %4, i64 0, i32 3 + %126 = load %HDC, %HDC* %125, align 8 + %127 = getelementptr inbounds [8 x i32], [8 x i32]* %97, i64 0, i64 0 + %128 = getelementptr i32, i32* %127, i64 0 + %129 = getelementptr inbounds i32, i32* %128 + %130 = call %HGLRC %124(%HDC %126, %.rawptr null, i32* %129) + store %HGLRC %130, %HGLRC* %123 + %131 = getelementptr inbounds %Window, %Window* %4, i64 0, i32 3 + %132 = load %HDC, %HDC* %131, align 8 + %133 = getelementptr inbounds %Window, %Window* %4, i64 0, i32 6 + %134 = load %HGLRC, %HGLRC* %133, align 8 + %135 = call %BOOL @wglMakeCurrent(%HDC %132, %HGLRC %134) + %136 = getelementptr inbounds %Window, %Window* %4, i64 0, i32 3 + %137 = load %HDC, %HDC* %136, align 8 + %138 = call %BOOL @SwapBuffers(%HDC %137) + %139 = alloca {%Window, i1}, align 8 + store {%Window, i1} zeroinitializer, {%Window, i1}* %139 + %140 = load %Window, %Window* %4, align 8 + %141 = getelementptr inbounds {%Window, i1}, {%Window, i1}* %139, i64 0, i32 0 + store %Window %140, %Window* %141 + %142 = getelementptr inbounds {%Window, i1}, {%Window, i1}* %139, i64 0, i32 1 + store i1 true, i1* %142 + %143 = load {%Window, i1}, {%Window, i1}* %139, align 8 + ret {%Window, i1} %143 +} + +define void @destroy_window(%Window* %w) { +entry.-.0: + %0 = alloca %Window*, align 8 ; w + store %Window* zeroinitializer, %Window** %0 + store %Window* %w, %Window** %0 + %1 = load %Window*, %Window** %0, align 8 + %2 = getelementptr %Window, %Window* %1, i64 0 + %3 = getelementptr inbounds %Window, %Window* %2, i64 0, i32 7 + %4 = load i8*, i8** %3, align 8 + call void @free(%.rawptr %4) + ret void +} + +define void @display_window(%Window* %w) { +entry.-.0: + %0 = alloca %Window*, align 8 ; w + store %Window* zeroinitializer, %Window** %0 + store %Window* %w, %Window** %0 + %1 = load %Window*, %Window** %0, align 8 + %2 = getelementptr %Window, %Window* %1, i64 0 + %3 = getelementptr inbounds %Window, %Window* %2, i64 0, i32 3 + %4 = load %HDC, %HDC* %3, align 8 + %5 = call %BOOL @SwapBuffers(%HDC %4) + ret void +} + +define void @main() { +entry.-.0: + call void @__$startup_runtime() + call void @print_f64(double 0x402abd70a3d70a3e) + call void @print_rune(i32 10) + ret void +} + +define %LRESULT @main$win32_proc-0(%HWND %hwnd, i32 %msg, %WPARAM %wparam, %LPARAM %lparam) noinline { entry.-.0: %0 = alloca %HWND, align 8 ; hwnd store %HWND zeroinitializer, %HWND* %0 @@ -168,455 +435,6 @@ if.done.-.4: ret i64 %14 } -define {%Window, i1} @make_window(%.string %title, i64 %msg, i64 %height) { -entry.-.0: - %0 = alloca %.string, align 8 ; title - store %.string zeroinitializer, %.string* %0 - store %.string %title, %.string* %0 - %1 = alloca i64, align 8 ; msg - store i64 zeroinitializer, i64* %1 - store i64 %msg, i64* %1 - %2 = alloca i64, align 8 ; height - store i64 zeroinitializer, i64* %2 - store i64 %height, i64* %2 - %3 = alloca %Window, align 8 ; w - store %Window zeroinitializer, %Window* %3 - %4 = getelementptr inbounds %Window, %Window* %3, i64 0, i32 0 - %5 = getelementptr inbounds %Window, %Window* %3, i64 0, i32 1 - %6 = load i64, i64* %1, align 8 - %7 = load i64, i64* %2, align 8 - store i64 %6, i64* %4 - store i64 %7, i64* %5 - %8 = alloca %.string, align 8 ; class_name - store %.string zeroinitializer, %.string* %8 - %9 = getelementptr inbounds [18 x i8], [18 x i8]* @.str2, i64 0, i64 0 - %10 = alloca %.string, align 8 - store %.string zeroinitializer, %.string* %10 - %11 = getelementptr inbounds %.string, %.string* %10, i64 0, i32 0 - %12 = getelementptr inbounds %.string, %.string* %10, i64 0, i32 1 - store i8* %9, i8** %11 - store i64 18, i64* %12 - %13 = load %.string, %.string* %10, align 8 - store %.string %13, %.string* %8 - %14 = alloca i8*, align 8 ; c_class_name - store i8* zeroinitializer, i8** %14 - %15 = getelementptr inbounds %.string, %.string* %8, i64 0, i32 0 - %16 = load i8*, i8** %15, align 8 - %17 = getelementptr i8, i8* %16, i64 0 - %18 = getelementptr inbounds i8, i8* %17 - store i8* %18, i8** %14 - %19 = getelementptr inbounds %Window, %Window* %3, i64 0, i32 7 - %20 = load %.string, %.string* %0, align 8 - %21 = call i8* @to_c_string(%.string %20) - store i8* %21, i8** %19 - %22 = alloca %HINSTANCE, align 8 ; instance - store %HINSTANCE zeroinitializer, %HINSTANCE* %22 - %23 = call %HINSTANCE @GetModuleHandleA(i8* null) - store %HINSTANCE %23, %HINSTANCE* %22 - %24 = getelementptr inbounds %Window, %Window* %3, i64 0, i32 2 - %25 = alloca %WNDCLASSEXA, align 8 - store %WNDCLASSEXA zeroinitializer, %WNDCLASSEXA* %25 - %26 = getelementptr inbounds %WNDCLASSEXA, %WNDCLASSEXA* %25, i64 0, i32 0 - store i32 80, i32* %26 - %27 = getelementptr inbounds %WNDCLASSEXA, %WNDCLASSEXA* %25, i64 0, i32 1 - store i32 3, i32* %27 - %28 = load %HINSTANCE, %HINSTANCE* %22, align 8 - %29 = getelementptr inbounds %WNDCLASSEXA, %WNDCLASSEXA* %25, i64 0, i32 5 - store %HINSTANCE %28, %HINSTANCE* %29 - %30 = load i8*, i8** %14, align 8 - %31 = getelementptr inbounds %WNDCLASSEXA, %WNDCLASSEXA* %25, i64 0, i32 10 - store i8* %30, i8** %31 - %32 = bitcast %LRESULT (%HWND, i32, %WPARAM, %LPARAM)* @win32_proc to %LRESULT (%HWND, i32, %WPARAM, %LPARAM)* - %33 = getelementptr inbounds %WNDCLASSEXA, %WNDCLASSEXA* %25, i64 0, i32 2 - store %WNDPROC %32, %WNDPROC* %33 - %34 = load %WNDCLASSEXA, %WNDCLASSEXA* %25, align 8 - store %WNDCLASSEXA %34, %WNDCLASSEXA* %24 - %35 = getelementptr inbounds %Window, %Window* %3, i64 0, i32 2 - %36 = getelementptr inbounds %WNDCLASSEXA, %WNDCLASSEXA* %35 - %37 = call %ATOM @RegisterClassExA(%WNDCLASSEXA* %36) - %38 = icmp eq i16 %37, 0 - br i1 %38, label %if.then.-.1, label %if.done.-.2 - -if.then.-.1: - %39 = alloca {%Window, i1}, align 8 - store {%Window, i1} zeroinitializer, {%Window, i1}* %39 - %40 = load %Window, %Window* %3, align 8 - %41 = getelementptr inbounds {%Window, i1}, {%Window, i1}* %39, i64 0, i32 0 - store %Window %40, %Window* %41 - %42 = getelementptr inbounds {%Window, i1}, {%Window, i1}* %39, i64 0, i32 1 - store i1 false, i1* %42 - %43 = load {%Window, i1}, {%Window, i1}* %39, align 8 - ret {%Window, i1} %43 - -if.done.-.2: - %44 = getelementptr inbounds %Window, %Window* %3, i64 0, i32 4 - %45 = load i8*, i8** %14, align 8 - %46 = getelementptr inbounds %Window, %Window* %3, i64 0, i32 7 - %47 = load i8*, i8** %46, align 8 - %48 = getelementptr inbounds %Window, %Window* %3, i64 0, i32 0 - %49 = load i64, i64* %48, align 8 - %50 = trunc i64 %49 to i32 - %51 = getelementptr inbounds %Window, %Window* %3, i64 0, i32 1 - %52 = load i64, i64* %51, align 8 - %53 = trunc i64 %52 to i32 - %54 = load %HINSTANCE, %HINSTANCE* %22, align 8 - %55 = call %HWND @CreateWindowExA(i32 0, i8* %45, i8* %47, i32 281673728, i32 2147483648, i32 2147483648, i32 %50, i32 %53, %HWND null, %HMENU null, %HINSTANCE %54, %.rawptr null) - store %HWND %55, %HWND* %44 - %56 = getelementptr inbounds %Window, %Window* %3, i64 0, i32 4 - %57 = load %HWND, %HWND* %56, align 8 - %58 = icmp eq %.rawptr %57, null - br i1 %58, label %if.then.-.3, label %if.done.-.4 - -if.then.-.3: - call void @win32_print_last_error() - %59 = alloca {%Window, i1}, align 8 - store {%Window, i1} zeroinitializer, {%Window, i1}* %59 - %60 = load %Window, %Window* %3, align 8 - %61 = getelementptr inbounds {%Window, i1}, {%Window, i1}* %59, i64 0, i32 0 - store %Window %60, %Window* %61 - %62 = getelementptr inbounds {%Window, i1}, {%Window, i1}* %59, i64 0, i32 1 - store i1 false, i1* %62 - %63 = load {%Window, i1}, {%Window, i1}* %59, align 8 - ret {%Window, i1} %63 - -if.done.-.4: - %64 = getelementptr inbounds %Window, %Window* %3, i64 0, i32 3 - %65 = getelementptr inbounds %Window, %Window* %3, i64 0, i32 4 - %66 = load %HWND, %HWND* %65, align 8 - %67 = call %HDC @GetDC(%HANDLE %66) - store %HDC %67, %HDC* %64 - %68 = alloca %PIXELFORMATDESCRIPTOR, align 4 ; pfd - store %PIXELFORMATDESCRIPTOR zeroinitializer, %PIXELFORMATDESCRIPTOR* %68 - %69 = alloca %PIXELFORMATDESCRIPTOR, align 4 - store %PIXELFORMATDESCRIPTOR zeroinitializer, %PIXELFORMATDESCRIPTOR* %69 - %70 = getelementptr inbounds %PIXELFORMATDESCRIPTOR, %PIXELFORMATDESCRIPTOR* %69, i64 0, i32 0 - store i32 44, i32* %70 - %71 = getelementptr inbounds %PIXELFORMATDESCRIPTOR, %PIXELFORMATDESCRIPTOR* %69, i64 0, i32 1 - store i32 1, i32* %71 - %72 = getelementptr inbounds %PIXELFORMATDESCRIPTOR, %PIXELFORMATDESCRIPTOR* %69, i64 0, i32 2 - store i32 37, i32* %72 - %73 = getelementptr inbounds %PIXELFORMATDESCRIPTOR, %PIXELFORMATDESCRIPTOR* %69, i64 0, i32 3 - store i8 0, i8* %73 - %74 = getelementptr inbounds %PIXELFORMATDESCRIPTOR, %PIXELFORMATDESCRIPTOR* %69, i64 0, i32 4 - store i8 32, i8* %74 - %75 = getelementptr inbounds %PIXELFORMATDESCRIPTOR, %PIXELFORMATDESCRIPTOR* %69, i64 0, i32 11 - store i8 8, i8* %75 - %76 = getelementptr inbounds %PIXELFORMATDESCRIPTOR, %PIXELFORMATDESCRIPTOR* %69, i64 0, i32 18 - store i8 24, i8* %76 - %77 = getelementptr inbounds %PIXELFORMATDESCRIPTOR, %PIXELFORMATDESCRIPTOR* %69, i64 0, i32 19 - store i8 8, i8* %77 - %78 = getelementptr inbounds %PIXELFORMATDESCRIPTOR, %PIXELFORMATDESCRIPTOR* %69, i64 0, i32 21 - store i8 0, i8* %78 - %79 = load %PIXELFORMATDESCRIPTOR, %PIXELFORMATDESCRIPTOR* %69, align 4 - store %PIXELFORMATDESCRIPTOR %79, %PIXELFORMATDESCRIPTOR* %68 - %80 = getelementptr inbounds %Window, %Window* %3, i64 0, i32 3 - %81 = load %HDC, %HDC* %80, align 8 - %82 = getelementptr inbounds %Window, %Window* %3, i64 0, i32 3 - %83 = load %HDC, %HDC* %82, align 8 - %84 = getelementptr inbounds %PIXELFORMATDESCRIPTOR, %PIXELFORMATDESCRIPTOR* %68 - %85 = call i32 @ChoosePixelFormat(%HDC %83, %PIXELFORMATDESCRIPTOR* %84) - %86 = call %BOOL @SetPixelFormat(%HDC %81, i32 %85, %PIXELFORMATDESCRIPTOR* null) - %87 = getelementptr inbounds %Window, %Window* %3, i64 0, i32 5 - %88 = getelementptr inbounds %Window, %Window* %3, i64 0, i32 3 - %89 = load %HDC, %HDC* %88, align 8 - %90 = call %HGLRC @wglCreateContext(%HDC %89) - store %HGLRC %90, %HGLRC* %87 - %91 = getelementptr inbounds %Window, %Window* %3, i64 0, i32 3 - %92 = load %HDC, %HDC* %91, align 8 - %93 = getelementptr inbounds %Window, %Window* %3, i64 0, i32 5 - %94 = load %HGLRC, %HGLRC* %93, align 8 - %95 = call %BOOL @wglMakeCurrent(%HDC %92, %HGLRC %94) - %96 = alloca [8 x i32], align 4 ; attribs - store [8 x i32] zeroinitializer, [8 x i32]* %96 - %97 = alloca [8 x i32], align 4 - store [8 x i32] zeroinitializer, [8 x i32]* %97 - %98 = getelementptr inbounds [8 x i32], [8 x i32]* %97, i64 0, i32 0 - store i32 8337, i32* %98 - %99 = getelementptr inbounds [8 x i32], [8 x i32]* %97, i64 0, i32 1 - store i32 2, i32* %99 - %100 = getelementptr inbounds [8 x i32], [8 x i32]* %97, i64 0, i32 2 - store i32 8338, i32* %100 - %101 = getelementptr inbounds [8 x i32], [8 x i32]* %97, i64 0, i32 3 - store i32 1, i32* %101 - %102 = getelementptr inbounds [8 x i32], [8 x i32]* %97, i64 0, i32 4 - store i32 37158, i32* %102 - %103 = getelementptr inbounds [8 x i32], [8 x i32]* %97, i64 0, i32 5 - store i32 2, i32* %103 - %104 = getelementptr inbounds [8 x i32], [8 x i32]* %97, i64 0, i32 6 - store i32 0, i32* %104 - %105 = load [8 x i32], [8 x i32]* %97, align 4 - store [8 x i32] %105, [8 x i32]* %96 - %106 = alloca %.string, align 8 ; wgl_string - store %.string zeroinitializer, %.string* %106 - %107 = getelementptr inbounds [27 x i8], [27 x i8]* @.str3, i64 0, i64 0 - %108 = alloca %.string, align 8 - store %.string zeroinitializer, %.string* %108 - %109 = getelementptr inbounds %.string, %.string* %108, i64 0, i32 0 - %110 = getelementptr inbounds %.string, %.string* %108, i64 0, i32 1 - store i8* %107, i8** %109 - store i64 27, i64* %110 - %111 = load %.string, %.string* %108, align 8 - store %.string %111, %.string* %106 - %112 = alloca i8*, align 8 ; c_wgl_string - store i8* zeroinitializer, i8** %112 - %113 = getelementptr inbounds %.string, %.string* %106, i64 0, i32 0 - %114 = load i8*, i8** %113, align 8 - %115 = getelementptr i8, i8* %114, i64 0 - %116 = getelementptr inbounds i8, i8* %115 - store i8* %116, i8** %112 - %117 = alloca %wglCreateContextAttribsARBType, align 8 ; wglCreateContextAttribsARB - store %wglCreateContextAttribsARBType zeroinitializer, %wglCreateContextAttribsARBType* %117 - %118 = load i8*, i8** %112, align 8 - %119 = call %PROC @wglGetProcAddress(i8* %118) - %120 = bitcast void ()* %119 to %HGLRC (%HDC, %.rawptr, i32*)* - %121 = bitcast %HGLRC (%HDC, %.rawptr, i32*)* %120 to %HGLRC (%HDC, %.rawptr, i32*)* - store %wglCreateContextAttribsARBType %121, %wglCreateContextAttribsARBType* %117 - %122 = getelementptr inbounds %Window, %Window* %3, i64 0, i32 6 - %123 = load %wglCreateContextAttribsARBType, %wglCreateContextAttribsARBType* %117, align 8 - %124 = getelementptr inbounds %Window, %Window* %3, i64 0, i32 3 - %125 = load %HDC, %HDC* %124, align 8 - %126 = getelementptr inbounds [8 x i32], [8 x i32]* %96, i64 0, i64 0 - %127 = getelementptr i32, i32* %126, i64 0 - %128 = getelementptr inbounds i32, i32* %127 - %129 = call %HGLRC %123(%HDC %125, %.rawptr null, i32* %128) - store %HGLRC %129, %HGLRC* %122 - %130 = getelementptr inbounds %Window, %Window* %3, i64 0, i32 3 - %131 = load %HDC, %HDC* %130, align 8 - %132 = getelementptr inbounds %Window, %Window* %3, i64 0, i32 6 - %133 = load %HGLRC, %HGLRC* %132, align 8 - %134 = call %BOOL @wglMakeCurrent(%HDC %131, %HGLRC %133) - %135 = getelementptr inbounds %Window, %Window* %3, i64 0, i32 3 - %136 = load %HDC, %HDC* %135, align 8 - %137 = call %BOOL @SwapBuffers(%HDC %136) - %138 = alloca {%Window, i1}, align 8 - store {%Window, i1} zeroinitializer, {%Window, i1}* %138 - %139 = load %Window, %Window* %3, align 8 - %140 = getelementptr inbounds {%Window, i1}, {%Window, i1}* %138, i64 0, i32 0 - store %Window %139, %Window* %140 - %141 = getelementptr inbounds {%Window, i1}, {%Window, i1}* %138, i64 0, i32 1 - store i1 true, i1* %141 - %142 = load {%Window, i1}, {%Window, i1}* %138, align 8 - ret {%Window, i1} %142 -} - -define void @destroy_window(%Window* %w) { -entry.-.0: - %0 = alloca %Window*, align 8 ; w - store %Window* zeroinitializer, %Window** %0 - store %Window* %w, %Window** %0 - %1 = load %Window*, %Window** %0, align 8 - %2 = getelementptr %Window, %Window* %1, i64 0 - %3 = getelementptr inbounds %Window, %Window* %2, i64 0, i32 7 - %4 = load i8*, i8** %3, align 8 - call void @free(%.rawptr %4) - ret void -} - -define i1 @update_window(%Window* %w) { -entry.-.0: - %0 = alloca %Window*, align 8 ; w - store %Window* zeroinitializer, %Window** %0 - store %Window* %w, %Window** %0 - %1 = alloca %MSG, align 8 ; msg - store %MSG zeroinitializer, %MSG* %1 - br label %for.body.-.1 - -for.body.-.1: - %2 = alloca i1, align 1 ; ok - store i1 zeroinitializer, i1* %2 - %3 = getelementptr inbounds %MSG, %MSG* %1 - %4 = call %BOOL @PeekMessageA(%MSG* %3, %HWND null, i32 0, i32 0, i32 1) - %5 = icmp ne i32 %4, 0 - store i1 %5, i1* %2 - %6 = load i1, i1* %2, align 1 - br i1 %6, label %if.done.-.3, label %if.then.-.2 - -if.then.-.2: - br label %for.done.-.6 - -if.done.-.3: - %7 = getelementptr inbounds %MSG, %MSG* %1, i64 0, i32 1 - %8 = load i32, i32* %7, align 4 - %9 = icmp eq i32 %8, 18 - br i1 %9, label %if.then.-.4, label %if.done.-.5 - -if.then.-.4: - ret i1 true - -if.done.-.5: - %10 = getelementptr inbounds %MSG, %MSG* %1 - %11 = call %BOOL @TranslateMessage(%MSG* %10) - %12 = getelementptr inbounds %MSG, %MSG* %1 - %13 = call %LRESULT @DispatchMessageA(%MSG* %12) - br label %for.body.-.1 - -for.done.-.6: - ret i1 false -} - -define void @display_window(%Window* %w) { -entry.-.0: - %0 = alloca %Window*, align 8 ; w - store %Window* zeroinitializer, %Window** %0 - store %Window* %w, %Window** %0 - %1 = load %Window*, %Window** %0, align 8 - %2 = getelementptr %Window, %Window* %1, i64 0 - %3 = getelementptr inbounds %Window, %Window* %2, i64 0, i32 3 - %4 = load %HDC, %HDC* %3, align 8 - %5 = call %BOOL @SwapBuffers(%HDC %4) - ret void -} - -define void @main() { -entry.-.0: - call void @__$startup_runtime() - %0 = alloca %Window, align 8 ; window - store %Window zeroinitializer, %Window* %0 - %1 = alloca i1, align 1 ; window_success - store i1 zeroinitializer, i1* %1 - %2 = getelementptr inbounds [18 x i8], [18 x i8]* @.str4, i64 0, i64 0 - %3 = alloca %.string, align 8 - store %.string zeroinitializer, %.string* %3 - %4 = getelementptr inbounds %.string, %.string* %3, i64 0, i32 0 - %5 = getelementptr inbounds %.string, %.string* %3, i64 0, i32 1 - store i8* %2, i8** %4 - store i64 18, i64* %5 - %6 = load %.string, %.string* %3, align 8 - %7 = call {%Window, i1} @make_window(%.string %6, i64 854, i64 480) - %8 = extractvalue {%Window, i1} %7, 0 - %9 = extractvalue {%Window, i1} %7, 1 - store %Window %8, %Window* %0 - store i1 %9, i1* %1 - %10 = load i1, i1* %1, align 1 - br i1 %10, label %if.done.-.2, label %if.then.-.1 - -if.then.-.1: - ret void - -if.done.-.2: - %11 = alloca double, align 8 ; prev_time - store double zeroinitializer, double* %11 - %12 = call double @time_now() - store double %12, double* %11 - %13 = alloca i1, align 1 ; running - store i1 zeroinitializer, i1* %13 - store i1 true, i1* %13 - br label %for.loop.-.4 - -for.body.-.3: - %14 = alloca double, align 8 ; curr_time - store double zeroinitializer, double* %14 - %15 = call double @time_now() - store double %15, double* %14 - %16 = alloca float, align 4 ; dt - store float zeroinitializer, float* %16 - %17 = load double, double* %11, align 8 - %18 = load double, double* %14, align 8 - %19 = fsub double %18, %17 - %20 = fptrunc double %19 to float - store float %20, float* %16 - %21 = load double, double* %14, align 8 - store double %21, double* %11 - %22 = getelementptr inbounds %Window, %Window* %0 - %23 = call i1 @update_window(%Window* %22) - br i1 %23, label %if.then.-.5, label %if.done.-.6 - -for.loop.-.4: - %24 = load i1, i1* %13, align 1 - br i1 %24, label %for.body.-.3, label %for.done.-.7 - -if.then.-.5: - store i1 false, i1* %13 - br label %if.done.-.6 - -if.done.-.6: - call void @glClearColor(float 0x3fe0000000000000, float 0x3fe6666660000000, float 0x3ff0000000000000, float 0x3ff0000000000000) - call void @glClear(i32 16384) - call void @glLoadIdentity() - %25 = getelementptr inbounds %Window, %Window* %0, i64 0, i32 0 - %26 = load i64, i64* %25, align 8 - %27 = sitofp i64 %26 to double - %28 = getelementptr inbounds %Window, %Window* %0, i64 0, i32 1 - %29 = load i64, i64* %28, align 8 - %30 = sitofp i64 %29 to double - call void @glOrtho(double 0x0000000000000000, double %27, double 0x0000000000000000, double %30, double 0x0000000000000000, double 0x3ff0000000000000) - %31 = alloca float, align 4 ; x - store float zeroinitializer, float* %31 - %32 = alloca float, align 4 ; y - store float zeroinitializer, float* %32 - store float 0x4059000000000000, float* %31 - store float 0x4059000000000000, float* %32 - %33 = load float, float* %31, align 4 - %34 = load float, float* %32, align 4 - call void @main$draw_rect-0(float %33, float %34, float 0x4049000000000000, float 0x4049000000000000) - %35 = getelementptr inbounds %Window, %Window* %0 - call void @display_window(%Window* %35) - br label %for.loop.-.4 - -for.done.-.7: - br label %defer.-.8 - -defer.-.8: - %36 = getelementptr inbounds %Window, %Window* %0 - call void @destroy_window(%Window* %36) - ret void -} - -define void @main$draw_rect-0(float %x, float %y, float %w, float %h) { -entry.-.0: - %0 = alloca float, align 4 ; x - store float zeroinitializer, float* %0 - store float %x, float* %0 - %1 = alloca float, align 4 ; y - store float zeroinitializer, float* %1 - store float %y, float* %1 - %2 = alloca float, align 4 ; w - store float zeroinitializer, float* %2 - store float %w, float* %2 - %3 = alloca float, align 4 ; h - store float zeroinitializer, float* %3 - store float %h, float* %3 - call void @glBegin(i32 4) - call void @glColor3f(float 0x3ff0000000000000, float 0x0000000000000000, float 0x0000000000000000) - %4 = load float, float* %0, align 4 - %5 = load float, float* %1, align 4 - call void @glVertex3f(float %4, float %5, float 0x0000000000000000) - call void @glColor3f(float 0x0000000000000000, float 0x3ff0000000000000, float 0x0000000000000000) - %6 = load float, float* %2, align 4 - %7 = load float, float* %0, align 4 - %8 = fadd float %7, %6 - %9 = load float, float* %1, align 4 - call void @glVertex3f(float %8, float %9, float 0x0000000000000000) - call void @glColor3f(float 0x0000000000000000, float 0x0000000000000000, float 0x3ff0000000000000) - %10 = load float, float* %2, align 4 - %11 = load float, float* %0, align 4 - %12 = fadd float %11, %10 - %13 = load float, float* %3, align 4 - %14 = load float, float* %1, align 4 - %15 = fadd float %14, %13 - call void @glVertex3f(float %12, float %15, float 0x0000000000000000) - call void @glColor3f(float 0x0000000000000000, float 0x0000000000000000, float 0x3ff0000000000000) - %16 = load float, float* %2, align 4 - %17 = load float, float* %0, align 4 - %18 = fadd float %17, %16 - %19 = load float, float* %3, align 4 - %20 = load float, float* %1, align 4 - %21 = fadd float %20, %19 - call void @glVertex3f(float %18, float %21, float 0x0000000000000000) - call void @glColor3f(float 0x3ff0000000000000, float 0x3ff0000000000000, float 0x0000000000000000) - %22 = load float, float* %0, align 4 - %23 = load float, float* %3, align 4 - %24 = load float, float* %1, align 4 - %25 = fadd float %24, %23 - call void @glVertex3f(float %22, float %25, float 0x0000000000000000) - call void @glColor3f(float 0x3ff0000000000000, float 0x0000000000000000, float 0x0000000000000000) - %26 = load float, float* %0, align 4 - %27 = load float, float* %1, align 4 - call void @glVertex3f(float %26, float %27, float 0x0000000000000000) - call void @glEnd() - ret void -} - define void @print_string(%.string %s) { entry.-.0: %0 = alloca %.string, align 8 ; s @@ -991,7 +809,7 @@ for.body.-.5: %16 = getelementptr inbounds [65 x i8], [65 x i8]* %2, i64 0, i64 0 %17 = load i64, i64* %3, align 8 %18 = getelementptr i8, i8* %16, i64 %17 - %19 = getelementptr inbounds [64 x i8], [64 x i8]* @.str5, i64 0, i64 0 + %19 = getelementptr inbounds [64 x i8], [64 x i8]* @.str4, i64 0, i64 0 %20 = load i64, i64* %1, align 8 %21 = load i64, i64* %0, align 8 %22 = srem i64 %21, %20 @@ -1080,11 +898,11 @@ entry.-.0: store i64 zeroinitializer, i64* %0 store i64 %i, i64* %0 %1 = load i64, i64* %0, align 8 - call void @print_uint_base(i64 %1, i64 10) + call void @print__uint(i64 %1, i64 10, i64 0, i8 32) ret void } -define void @print_uint_base(i64 %i, i64 %base) { +define void @print__uint(i64 %i, i64 %base, i64 %min_width, i8 %pad_char) { entry.-.0: %0 = alloca i64, align 8 ; i store i64 zeroinitializer, i64* %0 @@ -1092,87 +910,84 @@ entry.-.0: %1 = alloca i64, align 8 ; base store i64 zeroinitializer, i64* %1 store i64 %base, i64* %1 - %2 = alloca [65 x i8], align 1 ; buf - store [65 x i8] zeroinitializer, [65 x i8]* %2 - %3 = alloca i64, align 8 ; len - store i64 zeroinitializer, i64* %3 - store i64 0, i64* %3 - %4 = alloca i1, align 1 ; negative - store i1 zeroinitializer, i1* %4 - store i1 false, i1* %4 - %5 = load i64, i64* %0, align 8 - %6 = icmp ult i64 %5, 0 - br i1 %6, label %if.then.-.1, label %if.done.-.2 + %2 = alloca i64, align 8 ; min_width + store i64 zeroinitializer, i64* %2 + store i64 %min_width, i64* %2 + %3 = alloca i8, align 1 ; pad_char + store i8 zeroinitializer, i8* %3 + store i8 %pad_char, i8* %3 + %4 = alloca [65 x i8], align 1 ; buf + store [65 x i8] zeroinitializer, [65 x i8]* %4 + %5 = alloca i64, align 8 ; len + store i64 zeroinitializer, i64* %5 + store i64 0, i64* %5 + %6 = load i64, i64* %0, align 8 + %7 = icmp eq i64 %6, 0 + br i1 %7, label %if.then.-.1, label %if.done.-.2 if.then.-.1: - store i1 true, i1* %4 - %7 = load i64, i64* %0, align 8 - %8 = sub i64 0, %7 - store i64 %8, i64* %0 + %8 = getelementptr inbounds [65 x i8], [65 x i8]* %4, i64 0, i64 0 + %9 = load i64, i64* %5, align 8 + %10 = getelementptr i8, i8* %8, i64 %9 + store i8 48, i8* %10 + %11 = load i64, i64* %5, align 8 + %12 = add i64 %11, 1 + store i64 %12, i64* %5 br label %if.done.-.2 if.done.-.2: - %9 = load i64, i64* %0, align 8 - %10 = icmp eq i64 %9, 0 - br i1 %10, label %if.then.-.3, label %if.done.-.4 + br label %for.loop.-.4 -if.then.-.3: - %11 = getelementptr inbounds [65 x i8], [65 x i8]* %2, i64 0, i64 0 - %12 = load i64, i64* %3, align 8 - %13 = getelementptr i8, i8* %11, i64 %12 - store i8 48, i8* %13 - %14 = load i64, i64* %3, align 8 - %15 = add i64 %14, 1 - store i64 %15, i64* %3 - br label %if.done.-.4 +for.body.-.3: + %13 = getelementptr inbounds [65 x i8], [65 x i8]* %4, i64 0, i64 0 + %14 = load i64, i64* %5, align 8 + %15 = getelementptr i8, i8* %13, i64 %14 + %16 = getelementptr inbounds [64 x i8], [64 x i8]* @.str5, i64 0, i64 0 + %17 = load i64, i64* %1, align 8 + %18 = load i64, i64* %0, align 8 + %19 = urem i64 %18, %17 + %20 = getelementptr i8, i8* %16, i64 %19 + %21 = load i8, i8* %20, align 1 + store i8 %21, i8* %15 + %22 = load i64, i64* %5, align 8 + %23 = add i64 %22, 1 + store i64 %23, i64* %5 + %24 = load i64, i64* %1, align 8 + %25 = load i64, i64* %0, align 8 + %26 = udiv i64 %25, %24 + store i64 %26, i64* %0 + br label %for.loop.-.4 -if.done.-.4: - br label %for.loop.-.6 +for.loop.-.4: + %27 = load i64, i64* %0, align 8 + %28 = icmp ugt i64 %27, 0 + br i1 %28, label %for.body.-.3, label %for.done.-.5 -for.body.-.5: - %16 = getelementptr inbounds [65 x i8], [65 x i8]* %2, i64 0, i64 0 - %17 = load i64, i64* %3, align 8 - %18 = getelementptr i8, i8* %16, i64 %17 - %19 = getelementptr inbounds [64 x i8], [64 x i8]* @.str6, i64 0, i64 0 - %20 = load i64, i64* %1, align 8 - %21 = load i64, i64* %0, align 8 - %22 = urem i64 %21, %20 - %23 = getelementptr i8, i8* %19, i64 %22 - %24 = load i8, i8* %23, align 1 - store i8 %24, i8* %18 - %25 = load i64, i64* %3, align 8 - %26 = add i64 %25, 1 - store i64 %26, i64* %3 - %27 = load i64, i64* %1, align 8 - %28 = load i64, i64* %0, align 8 - %29 = udiv i64 %28, %27 - store i64 %29, i64* %0 - br label %for.loop.-.6 +for.done.-.5: + br label %for.loop.-.7 -for.loop.-.6: - %30 = load i64, i64* %0, align 8 - %31 = icmp ugt i64 %30, 0 - br i1 %31, label %for.body.-.5, label %for.done.-.7 +for.body.-.6: + %29 = getelementptr inbounds [65 x i8], [65 x i8]* %4, i64 0, i64 0 + %30 = load i64, i64* %5, align 8 + %31 = getelementptr i8, i8* %29, i64 %30 + %32 = load i8, i8* %3, align 1 + store i8 %32, i8* %31 + %33 = load i64, i64* %5, align 8 + %34 = add i64 %33, 1 + store i64 %34, i64* %5 + br label %for.loop.-.7 -for.done.-.7: - %32 = load i1, i1* %4, align 1 - br i1 %32, label %if.then.-.8, label %if.done.-.9 +for.loop.-.7: + %35 = load i64, i64* %5, align 8 + %36 = load i64, i64* %2, align 8 + %37 = icmp slt i64 %35, %36 + br i1 %37, label %for.body.-.6, label %for.done.-.8 -if.then.-.8: - %33 = getelementptr inbounds [65 x i8], [65 x i8]* %2, i64 0, i64 0 - %34 = load i64, i64* %3, align 8 - %35 = getelementptr i8, i8* %33, i64 %34 - store i8 45, i8* %35 - %36 = load i64, i64* %3, align 8 - %37 = add i64 %36, 1 - store i64 %37, i64* %3 - br label %if.done.-.9 - -if.done.-.9: - %38 = load i64, i64* %3, align 8 +for.done.-.8: + %38 = load i64, i64* %5, align 8 %39 = sub i64 %38, 0 %40 = sub i64 65, 0 - %41 = getelementptr inbounds [65 x i8], [65 x i8]* %2, i64 0, i64 0 + %41 = getelementptr inbounds [65 x i8], [65 x i8]* %4, i64 0, i64 0 %42 = getelementptr i8, i8* %41, i64 0 %43 = alloca {i8*, i64, i64}, align 8 store {i8*, i64, i64} zeroinitializer, {i8*, i64, i64}* %43 @@ -1184,10 +999,10 @@ if.done.-.9: store i64 %40, i64* %46 %47 = load {i8*, i64, i64}, {i8*, i64, i64}* %43, align 8 call void @byte_reverse({i8*, i64, i64} %47) - %48 = load i64, i64* %3, align 8 + %48 = load i64, i64* %5, align 8 %49 = sub i64 %48, 0 %50 = sub i64 65, 0 - %51 = getelementptr inbounds [65 x i8], [65 x i8]* %2, i64 0, i64 0 + %51 = getelementptr inbounds [65 x i8], [65 x i8]* %4, i64 0, i64 0 %52 = getelementptr i8, i8* %51, i64 0 %53 = alloca {i8*, i64, i64}, align 8 store {i8*, i64, i64} zeroinitializer, {i8*, i64, i64}* %53 @@ -1216,6 +1031,38 @@ if.done.-.9: ret void } +define void @print_pointer(%.rawptr %p) alwaysinline { +entry.-.0: + %0 = alloca %.rawptr, align 8 ; p + store %.rawptr zeroinitializer, %.rawptr* %0 + store %.rawptr %p, %.rawptr* %0 + %1 = load %.rawptr, %.rawptr* %0, align 8 + %2 = ptrtoint %.rawptr %1 to i64 + call void @print__uint(i64 %2, i64 16, i64 0, i8 32) + ret void +} + +define void @print_f32(float %f) alwaysinline { +entry.-.0: + %0 = alloca float, align 4 ; f + store float zeroinitializer, float* %0 + store float %f, float* %0 + %1 = load float, float* %0, align 4 + %2 = fpext float %1 to double + call void @print__f64(double %2, i64 7) + ret void +} + +define void @print_f64(double %f) alwaysinline { +entry.-.0: + %0 = alloca double, align 8 ; f + store double zeroinitializer, double* %0 + store double %f, double* %0 + %1 = load double, double* %0, align 8 + call void @print__f64(double %1, i64 10) + ret void +} + define void @print_bool(i1 %b) { entry.-.0: %0 = alloca i1, align 1 ; b @@ -1225,7 +1072,7 @@ entry.-.0: br i1 %1, label %if.then.-.1, label %if.else.-.2 if.then.-.1: - %2 = getelementptr inbounds [4 x i8], [4 x i8]* @.str7, i64 0, i64 0 + %2 = getelementptr inbounds [4 x i8], [4 x i8]* @.str6, i64 0, i64 0 %3 = alloca %.string, align 8 store %.string zeroinitializer, %.string* %3 %4 = getelementptr inbounds %.string, %.string* %3, i64 0, i32 0 @@ -1237,7 +1084,7 @@ if.then.-.1: br label %if.done.-.3 if.else.-.2: - %7 = getelementptr inbounds [5 x i8], [5 x i8]* @.str8, i64 0, i64 0 + %7 = getelementptr inbounds [5 x i8], [5 x i8]* @.str7, i64 0, i64 0 %8 = alloca %.string, align 8 store %.string zeroinitializer, %.string* %8 %9 = getelementptr inbounds %.string, %.string* %8, i64 0, i32 0 @@ -1251,6 +1098,192 @@ if.else.-.2: if.done.-.3: ret void } + +define void @print__f64(double %f, i64 %decimal_places) { +entry.-.0: + %0 = alloca double, align 8 ; f + store double zeroinitializer, double* %0 + store double %f, double* %0 + %1 = alloca i64, align 8 ; decimal_places + store i64 zeroinitializer, i64* %1 + store i64 %decimal_places, i64* %1 + %2 = load double, double* %0, align 8 + %3 = fcmp oeq double %2, 0x0000000000000000 + br i1 %3, label %if.then.-.1, label %if.done.-.2 + +if.then.-.1: + call void @print_rune(i32 48) + ret void + +if.done.-.2: + %4 = load double, double* %0, align 8 + %5 = fcmp olt double %4, 0x0000000000000000 + br i1 %5, label %if.then.-.3, label %if.done.-.4 + +if.then.-.3: + call void @print_rune(i32 45) + %6 = load double, double* %0, align 8 + %7 = fsub double 0x0000000000000000, %6 + store double %7, double* %0 + br label %if.done.-.4 + +if.done.-.4: + %8 = alloca i64, align 8 ; i + store i64 zeroinitializer, i64* %8 + %9 = load double, double* %0, align 8 + %10 = fptoui double %9 to i64 + store i64 %10, i64* %8 + %11 = load i64, i64* %8, align 8 + call void @print__f64$print_u64-0(i64 %11) + %12 = load i64, i64* %8, align 8 + %13 = uitofp i64 %12 to double + %14 = load double, double* %0, align 8 + %15 = fsub double %14, %13 + store double %15, double* %0 + call void @print_rune(i32 46) + %16 = alloca double, align 8 ; mult + store double zeroinitializer, double* %16 + store double 0x4024000000000000, double* %16 + br label %for.init.-.5 + +for.init.-.5: + %17 = alloca i64, align 8 ; decimal_places + store i64 zeroinitializer, i64* %17 + store i64 6, i64* %17 + br label %for.loop.-.7 + +for.body.-.6: + %18 = load double, double* %16, align 8 + %19 = load double, double* %0, align 8 + %20 = fmul double %19, %18 + %21 = fptoui double %20 to i64 + store i64 %21, i64* %8 + %22 = load i64, i64* %8, align 8 + call void @print__f64$print_u64-0(i64 %22) + %23 = load double, double* %16, align 8 + %24 = load i64, i64* %8, align 8 + %25 = uitofp i64 %24 to double + %26 = fdiv double %25, %23 + %27 = load double, double* %0, align 8 + %28 = fsub double %27, %26 + store double %28, double* %0 + %29 = load double, double* %16, align 8 + %30 = fmul double %29, 0x4024000000000000 + store double %30, double* %16 + br label %for.post.-.8 + +for.loop.-.7: + %31 = load i64, i64* %17, align 8 + %32 = icmp sge i64 %31, 0 + br i1 %32, label %for.body.-.6, label %for.done.-.9 + +for.post.-.8: + %33 = load i64, i64* %17, align 8 + %34 = sub i64 %33, 1 + store i64 %34, i64* %17 + br label %for.loop.-.7 + +for.done.-.9: + ret void +} + +define void @print__f64$print_u64-0(i64 %i) { +entry.-.0: + %0 = alloca i64, align 8 ; i + store i64 zeroinitializer, i64* %0 + store i64 %i, i64* %0 + %1 = alloca [22 x i8], align 1 ; buf + store [22 x i8] zeroinitializer, [22 x i8]* %1 + %2 = alloca i64, align 8 ; len + store i64 zeroinitializer, i64* %2 + store i64 0, i64* %2 + %3 = load i64, i64* %0, align 8 + %4 = icmp eq i64 %3, 0 + br i1 %4, label %if.then.-.1, label %if.done.-.2 + +if.then.-.1: + %5 = getelementptr inbounds [22 x i8], [22 x i8]* %1, i64 0, i64 0 + %6 = load i64, i64* %2, align 8 + %7 = getelementptr i8, i8* %5, i64 %6 + store i8 48, i8* %7 + %8 = load i64, i64* %2, align 8 + %9 = add i64 %8, 1 + store i64 %9, i64* %2 + br label %if.done.-.2 + +if.done.-.2: + br label %for.loop.-.4 + +for.body.-.3: + %10 = getelementptr inbounds [22 x i8], [22 x i8]* %1, i64 0, i64 0 + %11 = load i64, i64* %2, align 8 + %12 = getelementptr i8, i8* %10, i64 %11 + %13 = getelementptr inbounds [10 x i8], [10 x i8]* @.str8, i64 0, i64 0 + %14 = load i64, i64* %0, align 8 + %15 = urem i64 %14, 10 + %16 = getelementptr i8, i8* %13, i64 %15 + %17 = load i8, i8* %16, align 1 + store i8 %17, i8* %12 + %18 = load i64, i64* %2, align 8 + %19 = add i64 %18, 1 + store i64 %19, i64* %2 + %20 = load i64, i64* %0, align 8 + %21 = udiv i64 %20, 10 + store i64 %21, i64* %0 + br label %for.loop.-.4 + +for.loop.-.4: + %22 = load i64, i64* %0, align 8 + %23 = icmp ugt i64 %22, 0 + br i1 %23, label %for.body.-.3, label %for.done.-.5 + +for.done.-.5: + %24 = load i64, i64* %2, align 8 + %25 = sub i64 %24, 0 + %26 = sub i64 22, 0 + %27 = getelementptr inbounds [22 x i8], [22 x i8]* %1, i64 0, i64 0 + %28 = getelementptr i8, i8* %27, i64 0 + %29 = alloca {i8*, i64, i64}, align 8 + store {i8*, i64, i64} zeroinitializer, {i8*, i64, i64}* %29 + %30 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %29, i64 0, i32 0 + store i8* %28, i8** %30 + %31 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %29, i64 0, i32 1 + store i64 %25, i64* %31 + %32 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %29, i64 0, i32 2 + store i64 %26, i64* %32 + %33 = load {i8*, i64, i64}, {i8*, i64, i64}* %29, align 8 + call void @byte_reverse({i8*, i64, i64} %33) + %34 = load i64, i64* %2, align 8 + %35 = sub i64 %34, 0 + %36 = sub i64 22, 0 + %37 = getelementptr inbounds [22 x i8], [22 x i8]* %1, i64 0, i64 0 + %38 = getelementptr i8, i8* %37, i64 0 + %39 = alloca {i8*, i64, i64}, align 8 + store {i8*, i64, i64} zeroinitializer, {i8*, i64, i64}* %39 + %40 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %39, i64 0, i32 0 + store i8* %38, i8** %40 + %41 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %39, i64 0, i32 1 + store i64 %35, i64* %41 + %42 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %39, i64 0, i32 2 + store i64 %36, i64* %42 + %43 = load {i8*, i64, i64}, {i8*, i64, i64}* %39, align 8 + %44 = alloca {i8*, i64, i64}, align 8 + store {i8*, i64, i64} zeroinitializer, {i8*, i64, i64}* %44 + store {i8*, i64, i64} %43, {i8*, i64, i64}* %44 + %45 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %44, i64 0, i32 0 + %46 = load i8*, i8** %45, align 8 + %47 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %44, i64 0, i32 1 + %48 = load i64, i64* %47, align 8 + %49 = alloca %.string, align 8 + store %.string zeroinitializer, %.string* %49 + %50 = getelementptr inbounds %.string, %.string* %49, i64 0, i32 0 + %51 = getelementptr inbounds %.string, %.string* %49, i64 0, i32 1 + store i8* %46, i8** %50 + store i64 %48, i64* %51 + %52 = load %.string, %.string* %49, align 8 + call void @print_string(%.string %52) + ret void +} declare %HANDLE @GetStdHandle(i32 %h) ; foreign declare i32 @CloseHandle(%HANDLE %h) ; foreign declare i32 @WriteFileA(%HANDLE %h, %.rawptr %buf, i32 %len, i32* %written_result, %.rawptr %overlapped) ; foreign @@ -1318,169 +1351,9 @@ declare void @glTexParameteri(i32 %target, i32 %pname, i32 %param) ; foreign declare void @glTexParameterf(i32 %target, i32 %pname, float %param) ; foreign declare void @glBindTexture(i32 %target, i32 %texture) ; foreign declare void @glTexImage2D(i32 %target, i32 %level, i32 %internal_format, i32 %width, i32 %height, i32 %border, i32 %format, i32 %_type, %.rawptr %pixels) ; foreign - -define %Bitmap @make_bitmap(%.string %filename) { -entry.-.0: - %0 = alloca %.string, align 8 ; filename - store %.string zeroinitializer, %.string* %0 - store %.string %filename, %.string* %0 - %1 = alloca [1024 x i8], align 1 ; c_buf - store [1024 x i8] zeroinitializer, [1024 x i8]* %1 - %2 = alloca {i8*, i64, i64}, align 8 ; bytes - store {i8*, i64, i64} zeroinitializer, {i8*, i64, i64}* %2 - %3 = load %.string, %.string* %0, align 8 - %4 = alloca %.string, align 8 - store %.string zeroinitializer, %.string* %4 - store %.string %3, %.string* %4 - %5 = getelementptr inbounds %.string, %.string* %4, i64 0, i32 0 - %6 = load i8*, i8** %5, align 8 - %7 = alloca i8*, align 8 - store i8* zeroinitializer, i8** %7 - store i8* %6, i8** %7 - %8 = getelementptr inbounds %.string, %.string* %4, i64 0, i32 1 - %9 = load i64, i64* %8, align 8 - %10 = sub i64 %9, 0 - %11 = sub i64 %9, 0 - %12 = load i8*, i8** %7, align 8 - %13 = getelementptr i8, i8* %12, i64 0 - %14 = alloca {i8*, i64, i64}, align 8 - store {i8*, i64, i64} zeroinitializer, {i8*, i64, i64}* %14 - %15 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %14, i64 0, i32 0 - store i8* %13, i8** %15 - %16 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %14, i64 0, i32 1 - store i64 %10, i64* %16 - %17 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %14, i64 0, i32 2 - store i64 %11, i64* %17 - %18 = load {i8*, i64, i64}, {i8*, i64, i64}* %14, align 8 - store {i8*, i64, i64} %18, {i8*, i64, i64}* %2 - %19 = alloca i64, align 8 ; str_len - store i64 zeroinitializer, i64* %19 - %20 = sub i64 1024, 0 - %21 = sub i64 1024, 0 - %22 = getelementptr inbounds [1024 x i8], [1024 x i8]* %1, i64 0, i64 0 - %23 = getelementptr i8, i8* %22, i64 0 - %24 = alloca {i8*, i64, i64}, align 8 - store {i8*, i64, i64} zeroinitializer, {i8*, i64, i64}* %24 - %25 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %24, i64 0, i32 0 - store i8* %23, i8** %25 - %26 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %24, i64 0, i32 1 - store i64 %20, i64* %26 - %27 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %24, i64 0, i32 2 - store i64 %21, i64* %27 - %28 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %24, i64 0, i32 0 - %29 = load i8*, i8** %28, align 8 - %30 = bitcast i8* %29 to %.rawptr - %31 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %2, i64 0, i32 0 - %32 = load i8*, i8** %31, align 8 - %33 = bitcast i8* %32 to %.rawptr - %34 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %24, i64 0, i32 1 - %35 = load i64, i64* %34, align 8 - %36 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %2, i64 0, i32 1 - %37 = load i64, i64* %36, align 8 - %38 = icmp slt i64 %35, %37 - %39 = select i1 %38, i64 %35, i64 %37 - %40 = mul i64 %39, 1 - call void @llvm.memmove.p0i8.p0i8.i64(i8* %30, i8* %33, i64 %40, i32 1, i1 false) - store i64 %39, i64* %19 - %41 = alloca %Bitmap, align 8 ; b - store %Bitmap zeroinitializer, %Bitmap* %41 - %42 = alloca i8*, align 8 ; pixels - store i8* zeroinitializer, i8** %42 - %43 = getelementptr inbounds [1024 x i8], [1024 x i8]* %1, i64 0, i64 0 - %44 = getelementptr i8, i8* %43, i64 0 - %45 = getelementptr inbounds i8, i8* %44 - %46 = getelementptr inbounds %Bitmap, %Bitmap* %41, i64 0, i32 0 - %47 = getelementptr inbounds i32, i32* %46 - %48 = getelementptr inbounds %Bitmap, %Bitmap* %41, i64 0, i32 1 - %49 = getelementptr inbounds i32, i32* %48 - %50 = getelementptr inbounds %Bitmap, %Bitmap* %41, i64 0, i32 2 - %51 = getelementptr inbounds i32, i32* %50 - %52 = call i8* @stbi_load(i8* %45, i32* %47, i32* %49, i32* %51, i32 4) - store i8* %52, i8** %42 - %53 = alloca i64, align 8 ; len - store i64 zeroinitializer, i64* %53 - %54 = getelementptr inbounds %Bitmap, %Bitmap* %41, i64 0, i32 2 - %55 = load i32, i32* %54, align 4 - %56 = getelementptr inbounds %Bitmap, %Bitmap* %41, i64 0, i32 1 - %57 = load i32, i32* %56, align 4 - %58 = getelementptr inbounds %Bitmap, %Bitmap* %41, i64 0, i32 0 - %59 = load i32, i32* %58, align 4 - %60 = mul i32 %59, %57 - %61 = mul i32 %60, %55 - %62 = zext i32 %61 to i64 - store i64 %62, i64* %53 - %63 = getelementptr inbounds %Bitmap, %Bitmap* %41, i64 0, i32 3 - %64 = load i64, i64* %53, align 8 - %65 = sub i64 %64, 0 - %66 = sub i64 %64, 0 - %67 = load i8*, i8** %42, align 8 - %68 = getelementptr i8, i8* %67, i64 0 - %69 = alloca {i8*, i64, i64}, align 8 - store {i8*, i64, i64} zeroinitializer, {i8*, i64, i64}* %69 - %70 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %69, i64 0, i32 0 - store i8* %68, i8** %70 - %71 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %69, i64 0, i32 1 - store i64 %65, i64* %71 - %72 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %69, i64 0, i32 2 - store i64 %66, i64* %72 - %73 = load {i8*, i64, i64}, {i8*, i64, i64}* %69, align 8 - store {i8*, i64, i64} %73, {i8*, i64, i64}* %63 - %74 = load %Bitmap, %Bitmap* %41, align 8 - ret %Bitmap %74 -} -declare i8* @stbi_load(i8* %filename, i32* %x, i32* %y, i32* %comp, i32 %req_comp) -define void @destroy_bitmap(%Bitmap* %b) { -entry.-.0: - %0 = alloca %Bitmap*, align 8 ; b - store %Bitmap* zeroinitializer, %Bitmap** %0 - store %Bitmap* %b, %Bitmap** %0 - %1 = load %Bitmap*, %Bitmap** %0, align 8 - %2 = getelementptr %Bitmap, %Bitmap* %1, i64 0 - %3 = getelementptr inbounds %Bitmap, %Bitmap* %2, i64 0, i32 3 - %4 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %3, i64 0, i32 0 - %5 = load i8*, i8** %4, align 8 - %6 = getelementptr i8, i8* %5, i64 0 - %7 = getelementptr inbounds i8, i8* %6 - call void @stbi_image_free(%.rawptr %7) - %8 = load %Bitmap*, %Bitmap** %0, align 8 - %9 = getelementptr %Bitmap, %Bitmap* %8, i64 0 - %10 = getelementptr inbounds %Bitmap, %Bitmap* %9, i64 0, i32 3 - %11 = load %Bitmap*, %Bitmap** %0, align 8 - %12 = getelementptr %Bitmap, %Bitmap* %11, i64 0 - %13 = getelementptr inbounds %Bitmap, %Bitmap* %12, i64 0, i32 3 - %14 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %13, i64 0, i32 2 - %15 = load i64, i64* %14, align 8 - %16 = sub i64 0, 0 - %17 = sub i64 %15, 0 - %18 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %13, i64 0, i32 0 - %19 = load i8*, i8** %18, align 8 - %20 = getelementptr i8, i8* %19, i64 0 - %21 = alloca {i8*, i64, i64}, align 8 - store {i8*, i64, i64} zeroinitializer, {i8*, i64, i64}* %21 - %22 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %21, i64 0, i32 0 - store i8* %20, i8** %22 - %23 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %21, i64 0, i32 1 - store i64 %16, i64* %23 - %24 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %21, i64 0, i32 2 - store i64 %17, i64* %24 - %25 = load {i8*, i64, i64}, {i8*, i64, i64}* %21, align 8 - store {i8*, i64, i64} %25, {i8*, i64, i64}* %10 - %26 = load %Bitmap*, %Bitmap** %0, align 8 - %27 = getelementptr %Bitmap, %Bitmap* %26, i64 0 - %28 = getelementptr inbounds %Bitmap, %Bitmap* %27, i64 0, i32 0 - store i32 0, i32* %28 - %29 = load %Bitmap*, %Bitmap** %0, align 8 - %30 = getelementptr %Bitmap, %Bitmap* %29, i64 0 - %31 = getelementptr inbounds %Bitmap, %Bitmap* %30, i64 0, i32 1 - store i32 0, i32* %31 - %32 = load %Bitmap*, %Bitmap** %0, align 8 - %33 = getelementptr %Bitmap, %Bitmap* %32, i64 0 - %34 = getelementptr inbounds %Bitmap, %Bitmap* %33, i64 0, i32 2 - store i32 0, i32* %34 - ret void -} -declare void @stbi_image_free(%.rawptr %retval_from_stbi_load) declare float @llvm.sqrt.f32(float %x) ; foreign -declare double @llvm.sqrt.f64(double %x) ; foreign +declare float @llvm.sqrt.f32(float %x) ; foreign +declare float @llvm.sin.f32(float %x) ; foreign +declare float @llvm.cos.f32(float %x) ; foreign define float @vec2_dot(%Vec2 %a, %Vec2 %b) { entry.-.0: @@ -1824,11 +1697,11 @@ entry.-.0: @.str1 = global [1 x i8] c"\0A" @.str2 = global [18 x i8] c"Win32-Odin-Window\00" @.str3 = global [27 x i8] c"wglCreateContextAttribsARB\00" -@.str4 = global [18 x i8] c"Odin\20Language\20Demo" +@.str4 = global [64 x i8] c"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\40$" @.str5 = global [64 x i8] c"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\40$" -@.str6 = global [64 x i8] c"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\40$" -@.str7 = global [4 x i8] c"true" -@.str8 = global [5 x i8] c"false" +@.str6 = global [4 x i8] c"true" +@.str7 = global [5 x i8] c"false" +@.str8 = global [10 x i8] c"0123456789" define void @__$startup_runtime() noinline { entry.-.0: diff --git a/examples/main.odin b/examples/main.odin index 308708323..0f8662728 100644 --- a/examples/main.odin +++ b/examples/main.odin @@ -1,9 +1,10 @@ #load "basic.odin" #load "win32.odin" #load "opengl.odin" -#load "stb_image.odin" #load "math.odin" +TWO_HEARTS :: '💕'; + win32_perf_count_freq := GetQueryPerformanceFrequency(); time_now :: proc() -> f64 { if win32_perf_count_freq == 0 { @@ -26,7 +27,7 @@ win32_print_last_error :: proc() { // Yuk! to_c_string :: proc(s: string) -> ^u8 { - c_str := heap_alloc(len(s)+1) as ^u8; + c_str: ^u8 = heap_alloc(len(s)+1); mem_copy(c_str, ^s[0], len(s)); c_str[len(s)] = 0; return c_str; @@ -38,20 +39,12 @@ type Window: struct { wc: WNDCLASSEXA, dc: HDC, hwnd: HWND, - opengl_context: HGLRC, + opengl_context: rawptr, rc: HGLRC, c_title: ^u8, } -win32_proc :: proc(hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT #no_inline { - if msg == WM_DESTROY || msg == WM_CLOSE || msg == WM_QUIT { - ExitProcess(0); - return 0; - } - return DefWindowProcA(hwnd, msg, wparam, lparam); -} - -make_window :: proc(title: string, msg, height: int) -> (Window, bool) { +make_window :: proc(title: string, msg, height: int, window_proc: WNDPROC) -> (Window, bool) { w: Window; w.width, w.height = msg, height; @@ -66,7 +59,7 @@ make_window :: proc(title: string, msg, height: int) -> (Window, bool) { style = CS_VREDRAW | CS_HREDRAW, hInstance = instance as HINSTANCE, className = c_class_name, - wndProc = win32_proc, + wndProc = window_proc, }; if RegisterClassExA(^w.wc) == 0 { @@ -126,23 +119,6 @@ destroy_window :: proc(w: ^Window) { heap_free(w.c_title); } -update_window :: proc(w: ^Window) -> bool { - msg: MSG; - for { - ok := PeekMessageA(^msg, null, 0, 0, PM_REMOVE) != 0; - if !ok { - break; - } - - if msg.message == WM_QUIT { - return true; - } - _ = TranslateMessage(^msg); - _ = DispatchMessageA(^msg); - } - return false; -} - display_window :: proc(w: ^Window) { SwapBuffers(w.dc); } @@ -151,12 +127,23 @@ display_window :: proc(w: ^Window) { main :: proc() { - window, window_success := make_window("Odin Language Demo", 854, 480); + win32_proc :: proc(hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT #no_inline { + if msg == WM_DESTROY || msg == WM_CLOSE || msg == WM_QUIT { + ExitProcess(0); + return 0; + } + return DefWindowProcA(hwnd, msg, wparam, lparam); + } + print_f64(13.37); + print_rune('\n'); +/* + window, window_success := make_window("Odin Language Demo", 854, 480, win32_proc); if !window_success { return; } defer destroy_window(^window); + prev_time := time_now(); running := true; for running { @@ -164,8 +151,13 @@ main :: proc() { dt := (curr_time - prev_time) as f32; prev_time = curr_time; - if update_window(^window) { - running = false; + msg: MSG; + for PeekMessageA(^msg, null, 0, 0, PM_REMOVE) > 0 { + if msg.message == WM_QUIT { + running = false; + } + _ = TranslateMessage(^msg); + _ = DispatchMessageA(^msg); } glClearColor(0.5, 0.7, 1.0, 1.0); @@ -176,6 +168,7 @@ main :: proc() { 0, window.height as f64, 0, 1); draw_rect :: proc(x, y, w, h: f32) { glBegin(GL_TRIANGLES); + glColor3f(1, 0, 0); glVertex3f(x, y, 0); glColor3f(0, 1, 0); glVertex3f(x+w, y, 0); glColor3f(0, 0, 1); glVertex3f(x+w, y+h, 0); @@ -187,9 +180,14 @@ main :: proc() { glEnd(); } - x, y : f32 = 100, 100; + x, y : f32 = 100+50*sinf(curr_time as f32), 100; draw_rect(x, y, 50, 50); display_window(^window); + ms_to_sleep := (16 - 1000*dt) as i32; + if ms_to_sleep > 0 { + sleep_ms(ms_to_sleep); + } } +*/ } diff --git a/examples/math.odin b/examples/math.odin index 87c0fc6f9..9551c963d 100644 --- a/examples/math.odin +++ b/examples/math.odin @@ -5,14 +5,15 @@ type Mat2: {4}f32 -sqrt_f32 :: proc(x: f32) -> f32 #foreign "llvm.sqrt.f32" -sqrt_f64 :: proc(x: f64) -> f64 #foreign "llvm.sqrt.f64" +sqrtf :: proc(x: f32) -> f32 #foreign "llvm.sqrt.f32" +sinf :: proc(x: f32) -> f32 #foreign "llvm.sin.f32" +cosf :: proc(x: f32) -> f32 #foreign "llvm.cos.f32" vec2_dot :: proc(a, b: Vec2) -> f32 { c := a*b; return c[0] + c[1]; } vec3_dot :: proc(a, b: Vec3) -> f32 { c := a*b; return c[0] + c[1] + c[2]; } lerp :: proc(a, b, t: f32) -> f32 { return a*(1-t) + b*t; } -vec2_mag :: proc(a: Vec2) -> f32 { return sqrt_f32(vec2_dot(a, a)); } -vec3_mag :: proc(a: Vec3) -> f32 { return sqrt_f32(vec3_dot(a, a)); } +vec2_mag :: proc(a: Vec2) -> f32 { return sqrtf(vec2_dot(a, a)); } +vec3_mag :: proc(a: Vec3) -> f32 { return sqrtf(vec3_dot(a, a)); } diff --git a/examples/win32.odin b/examples/win32.odin index a4a7e1e4f..1fdaeb4e8 100644 --- a/examples/win32.odin +++ b/examples/win32.odin @@ -24,20 +24,20 @@ PM_REMOVE :: 1; COLOR_BACKGROUND: rawptr : 1; // NOTE(bill): cast to HBRUSH when needed -type HANDLE: rawptr -type HWND: HANDLE -type HDC: HANDLE +type HANDLE: rawptr +type HWND: HANDLE +type HDC: HANDLE type HINSTANCE: HANDLE -type HICON: HANDLE -type HCURSOR: HANDLE -type HMENU: HANDLE -type HBRUSH: HANDLE -type WPARAM: uint -type LPARAM: int -type LRESULT: int -type ATOM: i16 +type HICON: HANDLE +type HCURSOR: HANDLE +type HMENU: HANDLE +type HBRUSH: HANDLE +type WPARAM: uint +type LPARAM: int +type LRESULT: int +type ATOM: i16 +type BOOL: i32 type POINT: struct { x, y: i32 } -type BOOL: i32 type WNDPROC: proc(hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT diff --git a/src/checker/checker.cpp b/src/checker/checker.cpp index b37effb8f..100b480bd 100644 --- a/src/checker/checker.cpp +++ b/src/checker/checker.cpp @@ -210,7 +210,7 @@ void destroy_scope(Scope *scope) { gb_for_array(i, scope->elements.entries) { Entity *e =scope->elements.entries[i].value; if (e->kind == Entity_Variable) { - if (!e->variable.used) { + if (!e->Variable.used) { #if 0 warning(e->token, "Unused variable `%.*s`", LIT(e->token.string)); #endif @@ -314,7 +314,7 @@ void add_global_constant(gbAllocator a, String name, Type *type, ExactValue valu Token token = {Token_Identifier}; token.string = name; Entity *entity = alloc_entity(a, Entity_Constant, NULL, token, type); - entity->constant.value = value; + entity->Constant.value = value; add_global_entity(entity); } @@ -346,7 +346,7 @@ void init_universal_scope(void) { Token token = {Token_Identifier}; token.string = builtin_procs[i].name; Entity *entity = alloc_entity(a, Entity_Builtin, NULL, token, t_invalid); - entity->builtin.id = id; + entity->Builtin.id = id; add_global_entity(entity); } } diff --git a/src/checker/entity.cpp b/src/checker/entity.cpp index bd784bc4d..182bc1916 100644 --- a/src/checker/entity.cpp +++ b/src/checker/entity.cpp @@ -7,7 +7,6 @@ enum BuiltinProcId; ENTITY_KIND(Constant), \ ENTITY_KIND(Variable), \ ENTITY_KIND(TypeName), \ - ENTITY_KIND(AliasName), \ ENTITY_KIND(Procedure), \ ENTITY_KIND(Builtin), \ ENTITY_KIND(Count), @@ -38,16 +37,14 @@ struct Entity { isize order; union { - struct { ExactValue value; } constant; + struct { ExactValue value; } Constant; struct { b8 visited; b8 is_field; b8 used; - } variable; - struct {} type_name; - struct {} alias_name; - struct {} procedure; - struct { BuiltinProcId id; } builtin; + } Variable; + struct { b8 used; } Procedure; + struct { BuiltinProcId id; } Builtin; }; }; @@ -74,7 +71,7 @@ Entity *make_entity_variable(gbAllocator a, Scope *parent, Token token, Type *ty Entity *make_entity_constant(gbAllocator a, Scope *parent, Token token, Type *type, ExactValue value) { Entity *entity = alloc_entity(a, Entity_Constant, parent, token, type); - entity->constant.value = value; + entity->Constant.value = value; return entity; } @@ -83,20 +80,15 @@ Entity *make_entity_type_name(gbAllocator a, Scope *parent, Token token, Type *t return entity; } -Entity *make_entity_alias_name(gbAllocator a, Scope *parent, Token token, Type *type) { - Entity *entity = alloc_entity(a, Entity_AliasName, parent, token, type); - return entity; -} - Entity *make_entity_param(gbAllocator a, Scope *parent, Token token, Type *type) { Entity *entity = make_entity_variable(a, parent, token, type); - entity->variable.used = true; + entity->Variable.used = true; return entity; } Entity *make_entity_field(gbAllocator a, Scope *parent, Token token, Type *type) { Entity *entity = make_entity_variable(a, parent, token, type); - entity->variable.is_field = true; + entity->Variable.is_field = true; return entity; } @@ -107,7 +99,7 @@ Entity *make_entity_procedure(gbAllocator a, Scope *parent, Token token, Type *s Entity *make_entity_builtin(gbAllocator a, Scope *parent, Token token, Type *type, BuiltinProcId id) { Entity *entity = alloc_entity(a, Entity_Builtin, parent, token, type); - entity->builtin.id = id; + entity->Builtin.id = id; return entity; } diff --git a/src/checker/expr.cpp b/src/checker/expr.cpp index f03de5cbe..602035803 100644 --- a/src/checker/expr.cpp +++ b/src/checker/expr.cpp @@ -162,21 +162,20 @@ void check_identifier(Checker *c, Operand *o, AstNode *n, Type *named_type) { add_declaration_dependency(c, e); if (e->type == t_invalid) return; - o->value = e->constant.value; + o->value = e->Constant.value; GB_ASSERT(o->value.kind != ExactValue_Invalid); o->mode = Addressing_Constant; break; case Entity_Variable: add_declaration_dependency(c, e); - e->variable.used = true; + e->Variable.used = true; if (e->type == t_invalid) return; o->mode = Addressing_Variable; break; case Entity_TypeName: - case Entity_AliasName: o->mode = Addressing_Type; break; @@ -186,7 +185,7 @@ void check_identifier(Checker *c, Operand *o, AstNode *n, Type *named_type) { break; case Entity_Builtin: - o->builtin_id = e->builtin.id; + o->builtin_id = e->Builtin.id; o->mode = Addressing_Builtin; break; @@ -665,7 +664,10 @@ void check_unary_expr(Checker *c, Operand *o, Token op, AstNode *node) { void check_comparison(Checker *c, Operand *x, Operand *y, Token op) { gbString err_str = NULL; - defer (gb_string_free(err_str)); + defer ({ + if (err_str != NULL) + gb_string_free(err_str); + }); if (check_is_assignable_to(c, x, y->type) || check_is_assignable_to(c, y, x->type)) { @@ -673,13 +675,13 @@ void check_comparison(Checker *c, Operand *x, Operand *y, Token op) { switch (op.kind) { case Token_CmpEq: case Token_NotEq: - defined = is_type_comparable(x->type); + defined = is_type_comparable(get_base_type(x->type)); break; case Token_Lt: case Token_Gt: case Token_LtEq: case Token_GtEq: { - defined = is_type_ordered(x->type); + defined = is_type_ordered(get_base_type(x->type)); } break; } @@ -698,7 +700,7 @@ void check_comparison(Checker *c, Operand *x, Operand *y, Token op) { gb_bprintf("mismatched types `%s` and `%s`", xt, yt)); } - if (err_str) { + if (err_str != NULL) { error(&c->error_collector, op, "Cannot compare expression, %s", err_str); return; } @@ -893,8 +895,8 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) { b32 is_const_expr = x->mode == Addressing_Constant; b32 can_convert = false; - if (is_const_expr && is_type_constant_type(type)) { - Type *base_type = get_base_type(type); + Type *base_type = get_base_type(type); + if (is_const_expr && is_type_constant_type(base_type)) { if (base_type->kind == Type_Basic) { if (check_value_is_expressible(c, x->value, base_type, &x->value)) { can_convert = true; @@ -1274,7 +1276,7 @@ Entity *lookup_field(Type *type, AstNode *field_node, isize *index = NULL) { case Type_Structure: for (isize i = 0; i < type->structure.field_count; i++) { Entity *f = type->structure.fields[i]; - GB_ASSERT(f->kind == Entity_Variable && f->variable.is_field); + GB_ASSERT(f->kind == Entity_Variable && f->Variable.is_field); String str = f->token.string; if (are_strings_equal(field_str, str)) { if (index) *index = i; diff --git a/src/checker/stmt.cpp b/src/checker/stmt.cpp index 3a059b2ab..54ef410c4 100644 --- a/src/checker/stmt.cpp +++ b/src/checker/stmt.cpp @@ -190,14 +190,14 @@ Type *check_assignment_variable(Checker *c, Operand *op_a, AstNode *lhs) { ast_node(i, Ident, node); e = scope_lookup_entity(c->context.scope, i->token.string); if (e != NULL && e->kind == Entity_Variable) { - used = e->variable.used; // TODO(bill): Make backup just in case + used = e->Variable.used; // TODO(bill): Make backup just in case } } Operand op_b = {Addressing_Invalid}; check_expr(c, &op_b, lhs); - if (e) e->variable.used = used; + if (e) e->Variable.used = used; if (op_b.mode == Addressing_Invalid || op_b.type == t_invalid) { @@ -325,18 +325,18 @@ void check_init_constant(Checker *c, Entity *e, Operand *operand) { if (operand->mode == Addressing_Invalid) return; - e->constant.value = operand->value; + e->Constant.value = operand->value; } void check_const_decl(Checker *c, Entity *e, AstNode *type_expr, AstNode *init_expr) { GB_ASSERT(e->type == NULL); - if (e->variable.visited) { + if (e->Variable.visited) { e->type = t_invalid; return; } - e->variable.visited = true; + e->Variable.visited = true; if (type_expr) { Type *t = check_type(c, type_expr); @@ -437,11 +437,11 @@ void check_var_decl(Checker *c, Entity *e, Entity **entities, isize entity_count GB_ASSERT(e->type == NULL); GB_ASSERT(e->kind == Entity_Variable); - if (e->variable.visited) { + if (e->Variable.visited) { e->type = t_invalid; return; } - e->variable.visited = true; + e->Variable.visited = true; if (type_expr != NULL) e->type = check_type(c, type_expr, NULL); @@ -791,11 +791,11 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) { for (isize i = 0; i < entity_count; i++) { Entity *e = entities[i]; GB_ASSERT(e != NULL); - if (e->variable.visited) { + if (e->Variable.visited) { e->type = t_invalid; continue; } - e->variable.visited = true; + e->Variable.visited = true; if (e->type == NULL) e->type = init_type; diff --git a/src/codegen/ssa.cpp b/src/codegen/ssa.cpp index fc927b735..be38b2c1b 100644 --- a/src/codegen/ssa.cpp +++ b/src/codegen/ssa.cpp @@ -1364,12 +1364,10 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t) { // Pointer <-> int if (is_type_pointer(src) && is_type_int_or_uint(dst)) { - ssaValue *p = ssa_emit_load(proc, value); - return ssa_emit(proc, ssa_make_instr_conv(proc, ssaConv_ptrtoint, p, src, dst)); + return ssa_emit(proc, ssa_make_instr_conv(proc, ssaConv_ptrtoint, value, src, dst)); } if (is_type_int_or_uint(src) && is_type_pointer(dst)) { - ssaValue *i = ssa_emit_load(proc, value); - return ssa_emit(proc, ssa_make_instr_conv(proc, ssaConv_inttoptr, i, src, dst)); + return ssa_emit(proc, ssa_make_instr_conv(proc, ssaConv_inttoptr, value, src, dst)); } // Pointer <-> Pointer @@ -1708,7 +1706,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue Entity **found = map_get(&proc->module->info->uses, hash_pointer(p)); if (found && (*found)->kind == Entity_Builtin) { Entity *e = *found; - switch (e->builtin.id) { + switch (e->Builtin.id) { case BuiltinProc_len: { // len :: proc(Type) -> int // NOTE(bill): len of an array is a constant expression diff --git a/src/main.cpp b/src/main.cpp index 271ddcf75..b641ac89d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -35,9 +35,8 @@ i32 win32_exec_command_line_app(char *fmt, ...) { return cast(i32)exit_code; } else { // NOTE(bill): failed to create process + return -1; } - - return 0; } int main(int argc, char **argv) { @@ -79,19 +78,19 @@ int main(int argc, char **argv) { isize base_name_len = gb_path_extension(output_name)-1 - output_name; i32 exit_code = win32_exec_command_line_app( - "opt -mem2reg %s -o %.*s.bc", + "../misc/llvm-bin/opt -mem2reg %s -o %.*s.bc", output_name, cast(int)base_name_len, output_name); if (exit_code == 0) { win32_exec_command_line_app( "clang -o %.*s.exe %.*s.bc -Wno-override-module " "-lKernel32.lib -lUser32.lib -lGdi32.lib -lOpengl32.lib " - "-l../c_libs/stb_image.lib" , cast(int)base_name_len, output_name, cast(int)base_name_len, output_name); if (run_output) { win32_exec_command_line_app("%.*s.exe", cast(int)base_name_len, output_name); } + } else { } return 0; diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index 0a10cdce3..407d502f0 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -172,7 +172,7 @@ gb_no_inline void warning(Token token, char *fmt, ...) { - +// NOTE(bill): result == priority i32 token_precedence(Token t) { switch (t.kind) { case Token_CmpOr: