Bladeren bron

windows.odin TYPE_NAME to Type_Name; More SSA work and SSA printing for debugging

Ginger Bill 8 jaren geleden
bovenliggende
commit
aaec8bf423
14 gewijzigde bestanden met toevoegingen van 1096 en 578 verwijderingen
  1. 8 7
      code/demo.odin
  2. 36 31
      core/math.odin
  3. 44 45
      core/os_windows.odin
  4. 1 1
      core/sync.odin
  5. 25 25
      core/sys/wgl.odin
  6. 127 128
      core/sys/windows.odin
  7. 53 0
      src/check_decl.c
  8. 30 16
      src/check_expr.c
  9. 8 3
      src/checker.c
  10. 11 0
      src/entity.c
  11. 4 0
      src/gb/gb.h
  12. 22 30
      src/ir.c
  13. 14 0
      src/parser.c
  14. 713 292
      src/ssa.c

+ 8 - 7
code/demo.odin

@@ -7,17 +7,18 @@
 #import "os.odin";
 #import "strconv.odin";
 #import "sync.odin";
+#import win32 "sys/windows.odin";
 
 main :: proc() {
-	a: i8 = -1;
-	fmt.println(a, cast(u64)a, cast(i64)a);
-	b: i64 = -1;
-	fmt.println(b, cast(u64)b, cast(i64)b);
+	a := 1;
+	b := 2;
+	c := a + b;
+
+	if c > 0 {
+		c = 0;
+	}
 
 when false {
-	s := new_slice(int, 0, 10);
-	append(s, 1, 2, 6, 3, 6, 5, 5, 5, 5, 1, 2);
-	fmt.println(s);
 /*
 	Version 0.1.1
 

+ 36 - 31
core/math.odin

@@ -27,14 +27,14 @@ Mat4 :: [4]Vec4;
 sqrt :: proc(x: f32) -> f32 #foreign __llvm_core "llvm.sqrt.f32";
 sqrt :: proc(x: f64) -> f64 #foreign __llvm_core "llvm.sqrt.f64";
 
-sin :: proc(x: f32) -> f32 #foreign __llvm_core "llvm.sin.f32";
-sin :: proc(x: f64) -> f64 #foreign __llvm_core "llvm.sin.f64";
+sin  :: proc(x: f32) -> f32 #foreign __llvm_core "llvm.sin.f32";
+sin  :: proc(x: f64) -> f64 #foreign __llvm_core "llvm.sin.f64";
 
-cos :: proc(x: f32) -> f32 #foreign __llvm_core "llvm.cos.f32";
-cos :: proc(x: f64) -> f64 #foreign __llvm_core "llvm.cos.f64";
+cos  :: proc(x: f32) -> f32 #foreign __llvm_core "llvm.cos.f32";
+cos  :: proc(x: f64) -> f64 #foreign __llvm_core "llvm.cos.f64";
 
-tan :: proc(x: f32) -> f32 #inline { return sin(x)/cos(x); }
-tan :: proc(x: f64) -> f64 #inline { return sin(x)/cos(x); }
+tan  :: proc(x: f32) -> f32 #inline { return sin(x)/cos(x); }
+tan  :: proc(x: f64) -> f64 #inline { return sin(x)/cos(x); }
 
 lerp :: proc(a, b, t: f32) -> f32 { return a*(1-t) + b*t; }
 lerp :: proc(a, b, t: f64) -> f64 { return a*(1-t) + b*t; }
@@ -53,36 +53,42 @@ fmuladd :: proc(a, b, c: f64) -> f64 #foreign __llvm_core "llvm.fmuladd.f64";
 copy_sign :: proc(x, y: f32) -> f32 {
 	ix := transmute(u32)x;
 	iy := transmute(u32)y;
-	ix &= 0x7fffffff;
-	ix |= iy & 0x80000000;
+	ix &= 0x7fff_ffff;
+	ix |= iy & 0x8000_0000;
 	return transmute(f32)ix;
 }
-round :: proc(x: f32) -> f32 {
-	if x >= 0 {
-		return floor(x + 0.5);
-	}
-	return ceil(x - 0.5);
-}
-floor :: proc(x: f32) -> f32 {
-	if x >= 0 {
-		return cast(f32)cast(int)x;
-	}
-	return cast(f32)cast(int)(x-0.5);
-}
-ceil :: proc(x: f32) -> f32 {
-	if x < 0 {
-		return cast(f32)cast(int)x;
-	}
-	return cast(f32)cast(int)(x+1);
-}
 
-remainder32 :: proc(x, y: f32) -> f32 {
-	return x - round(x/y) * y;
+copy_sign :: proc(x, y: f64) -> f64 {
+	ix := transmute(u64)x;
+	iy := transmute(u64)y;
+	ix &= 0x7fff_ffff_ffff_ff;
+	ix |= iy & 0x8000_0000_0000_0000;
+	return transmute(f64)ix;
 }
 
-fmod32 :: proc(x, y: f32) -> f32 {
+round     :: proc(x: f32) -> f32 { return x >= 0 ? floor(x + 0.5) : ceil(x - 0.5); }
+round     :: proc(x: f64) -> f64 { return x >= 0 ? floor(x + 0.5) : ceil(x - 0.5); }
+
+floor     :: proc(x: f32) -> f32 { return x >= 0 ? cast(f32)cast(i64)x : cast(f32)cast(i64)(x-0.5); } // TODO: Get accurate versions
+floor     :: proc(x: f64) -> f64 { return x >= 0 ? cast(f64)cast(i64)x : cast(f64)cast(i64)(x-0.5); } // TODO: Get accurate versions
+
+ceil      :: proc(x: f32) -> f32 { return x <  0 ? cast(f32)cast(i64)x : cast(f32)cast(i64)(x+1); } // TODO: Get accurate versions
+ceil      :: proc(x: f64) -> f64 { return x <  0 ? cast(f64)cast(i64)x : cast(f64)cast(i64)(x+1); } // TODO: Get accurate versions
+
+remainder :: proc(x, y: f32) -> f32 { return x - round(x/y) * y; }
+remainder :: proc(x, y: f64) -> f64 { return x - round(x/y) * y; }
+
+mod :: proc(x, y: f32) -> f32 {
+	y = abs(y);
+	result := remainder(abs(x), y);
+	if sign(result) < 0 {
+		result += y;
+	}
+	return copy_sign(result, x);
+}
+mod :: proc(x, y: f64) -> f64 {
 	y = abs(y);
-	result := remainder32(abs(x), y);
+	result := remainder(abs(x), y);
 	if sign(result) < 0 {
 		result += y;
 	}
@@ -95,7 +101,6 @@ to_degrees :: proc(radians: f32) -> f32 { return radians * 360 / TAU; }
 
 
 
-
 dot :: proc(a, b: Vec2) -> f32 { c := a*b; return c.x + c.y; }
 dot :: proc(a, b: Vec3) -> f32 { c := a*b; return c.x + c.y + c.z; }
 dot :: proc(a, b: Vec4) -> f32 { c := a*b; return c.x + c.y + c.z + c.w; }

+ 44 - 45
core/os_windows.odin

@@ -1,4 +1,4 @@
-#import win32 "sys/windows.odin";
+#import w "sys/windows.odin";
 #import "fmt.odin";
 
 
@@ -53,29 +53,28 @@ ERROR_FILE_IS_PIPE: Errno : 1<<29 + 0;
 
 
 open :: proc(path: string, mode: int, perm: u32) -> (Handle, Errno) {
-	using win32;
 	if path.count == 0 {
 		return INVALID_HANDLE, ERROR_FILE_NOT_FOUND;
 	}
 
 	access: u32;
 	match mode & (O_RDONLY|O_WRONLY|O_RDWR) {
-	case O_RDONLY: access = FILE_GENERIC_READ;
-	case O_WRONLY: access = FILE_GENERIC_WRITE;
-	case O_RDWR:   access = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
+	case O_RDONLY: access = w.FILE_GENERIC_READ;
+	case O_WRONLY: access = w.FILE_GENERIC_WRITE;
+	case O_RDWR:   access = w.FILE_GENERIC_READ | w.FILE_GENERIC_WRITE;
 	}
 
 	if mode&O_CREAT != 0 {
-		access |= FILE_GENERIC_WRITE;
+		access |= w.FILE_GENERIC_WRITE;
 	}
 	if mode&O_APPEND != 0 {
-		access &~= FILE_GENERIC_WRITE;
-		access |= FILE_APPEND_DATA;
+		access &~= w.FILE_GENERIC_WRITE;
+		access |=  w.FILE_APPEND_DATA;
 	}
 
-	share_mode := cast(u32)(FILE_SHARE_READ|FILE_SHARE_WRITE);
-	sa: ^SECURITY_ATTRIBUTES = nil;
-	sa_inherit := SECURITY_ATTRIBUTES{length = size_of(SECURITY_ATTRIBUTES), inherit_handle = 1};
+	share_mode := cast(u32)(w.FILE_SHARE_READ|w.FILE_SHARE_WRITE);
+	sa: ^w.Security_Attributes = nil;
+	sa_inherit := w.Security_Attributes{length = size_of(w.Security_Attributes), inherit_handle = 1};
 	if mode&O_CLOEXEC == 0 {
 		sa = ^sa_inherit;
 	}
@@ -83,37 +82,37 @@ open :: proc(path: string, mode: int, perm: u32) -> (Handle, Errno) {
 	create_mode: u32;
 	match {
 	case mode&(O_CREAT|O_EXCL) == (O_CREAT | O_EXCL):
-		create_mode = CREATE_NEW;
+		create_mode = w.CREATE_NEW;
 	case mode&(O_CREAT|O_TRUNC) == (O_CREAT | O_TRUNC):
-		create_mode = CREATE_ALWAYS;
+		create_mode = w.CREATE_ALWAYS;
 	case mode&O_CREAT == O_CREAT:
-		create_mode = OPEN_ALWAYS;
+		create_mode = w.OPEN_ALWAYS;
 	case mode&O_TRUNC == O_TRUNC:
-		create_mode = TRUNCATE_EXISTING;
+		create_mode = w.TRUNCATE_EXISTING;
 	default:
-		create_mode = OPEN_EXISTING;
+		create_mode = w.OPEN_EXISTING;
 	}
 
 	buf: [300]byte;
 	copy(buf[..], cast([]byte)path);
 
-	handle := cast(Handle)CreateFileA(^buf[0], access, share_mode, sa, create_mode, FILE_ATTRIBUTE_NORMAL, nil);
+	handle := cast(Handle)w.CreateFileA(^buf[0], access, share_mode, sa, create_mode, w.FILE_ATTRIBUTE_NORMAL, nil);
 	if handle != INVALID_HANDLE {
 		return handle, ERROR_NONE;
 	}
-	err := GetLastError();
+	err := w.GetLastError();
 	return INVALID_HANDLE, cast(Errno)err;
 }
 
 close :: proc(fd: Handle) {
-	win32.CloseHandle(cast(win32.HANDLE)fd);
+	w.CloseHandle(cast(w.Handle)fd);
 }
 
 write :: proc(fd: Handle, data: []byte) -> (int, Errno) {
 	bytes_written: i32;
-	e := win32.WriteFile(cast(win32.HANDLE)fd, data.data, cast(i32)data.count, ^bytes_written, nil);
-	if e == win32.FALSE {
-		err := win32.GetLastError();
+	e := w.WriteFile(cast(w.Handle)fd, data.data, cast(i32)data.count, ^bytes_written, nil);
+	if e == w.FALSE {
+		err := w.GetLastError();
 		return 0, cast(Errno)err;
 	}
 	return cast(int)bytes_written, ERROR_NONE;
@@ -121,16 +120,16 @@ write :: proc(fd: Handle, data: []byte) -> (int, Errno) {
 
 read :: proc(fd: Handle, data: []byte) -> (int, Errno) {
 	bytes_read: i32;
-	e := win32.ReadFile(cast(win32.HANDLE)fd, data.data, cast(u32)data.count, ^bytes_read, nil);
-	if e == win32.FALSE {
-		err := win32.GetLastError();
+	e := w.ReadFile(cast(w.Handle)fd, data.data, cast(u32)data.count, ^bytes_read, nil);
+	if e == w.FALSE {
+		err := w.GetLastError();
 		return 0, cast(Errno)err;
 	}
 	return cast(int)bytes_read, ERROR_NONE;
 }
 
 seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {
-	using win32;
+	using w;
 	w: u32;
 	match whence {
 	case 0: w = FILE_BEGIN;
@@ -139,11 +138,11 @@ seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {
 	}
 	hi := cast(i32)(offset>>32);
 	lo := cast(i32)(offset);
-	ft := GetFileType(cast(HANDLE)fd);
+	ft := GetFileType(cast(Handle)fd);
 	if ft == FILE_TYPE_PIPE {
 		return 0, ERROR_FILE_IS_PIPE;
 	}
-	dw_ptr := SetFilePointer(cast(HANDLE)fd, lo, ^hi, w);
+	dw_ptr := SetFilePointer(cast(Handle)fd, lo, ^hi, w);
 	if dw_ptr == INVALID_SET_FILE_POINTER {
 		err := GetLastError();
 		return 0, cast(Errno)err;
@@ -153,14 +152,14 @@ seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {
 
 
 // NOTE(bill): Uses startup to initialize it
-stdin  := get_std_handle(win32.STD_INPUT_HANDLE);
-stdout := get_std_handle(win32.STD_OUTPUT_HANDLE);
-stderr := get_std_handle(win32.STD_ERROR_HANDLE);
+stdin  := get_std_handle(w.STD_INPUT_HANDLE);
+stdout := get_std_handle(w.STD_OUTPUT_HANDLE);
+stderr := get_std_handle(w.STD_ERROR_HANDLE);
 
 
 get_std_handle :: proc(h: int) -> Handle {
-	fd := win32.GetStdHandle(cast(i32)h);
-	win32.SetHandleInformation(fd, win32.HANDLE_FLAG_INHERIT, 0);
+	fd := w.GetStdHandle(cast(i32)h);
+	w.SetHandleInformation(fd, w.HANDLE_FLAG_INHERIT, 0);
 	return cast(Handle)fd;
 }
 
@@ -170,23 +169,23 @@ get_std_handle :: proc(h: int) -> Handle {
 
 
 last_write_time :: proc(fd: Handle) -> File_Time {
-	file_info: win32.BY_HANDLE_FILE_INFORMATION;
-	win32.GetFileInformationByHandle(cast(win32.HANDLE)fd, ^file_info);
+	file_info: w.By_Handle_File_Information;
+	w.GetFileInformationByHandle(cast(w.Handle)fd, ^file_info);
 	lo := cast(File_Time)file_info.last_write_time.lo;
 	hi := cast(File_Time)file_info.last_write_time.hi;
 	return lo | hi << 32;
 }
 
 last_write_time_by_name :: proc(name: string) -> File_Time {
-	last_write_time: win32.FILETIME;
-	data: win32.FILE_ATTRIBUTE_DATA;
+	last_write_time: w.Filetime;
+	data: w.File_Attribute_Data;
 	buf: [1024]byte;
 
 	assert(buf.count > name.count);
 
 	copy(buf[..], cast([]byte)name);
 
-	if win32.GetFileAttributesExA(^buf[0], win32.GetFileExInfoStandard, ^data) != 0 {
+	if w.GetFileAttributesExA(^buf[0], w.GetFileExInfoStandard, ^data) != 0 {
 		last_write_time = data.last_write_time;
 	}
 
@@ -210,7 +209,7 @@ read_entire_file :: proc(name: string) -> ([]byte, bool) {
 	defer close(fd);
 
 	length: i64;
-	file_size_ok := win32.GetFileSizeEx(cast(win32.HANDLE)fd, ^length) != 0;
+	file_size_ok := w.GetFileSizeEx(cast(w.Handle)fd, ^length) != 0;
 	if !file_size_ok {
 		return nil, false;
 	}
@@ -233,7 +232,7 @@ read_entire_file :: proc(name: string) -> ([]byte, bool) {
 			to_read = MAX;
 		}
 
-		win32.ReadFile(cast(win32.HANDLE)fd, ^data[total_read], to_read, ^single_read_length, nil);
+		w.ReadFile(cast(w.Handle)fd, ^data[total_read], to_read, ^single_read_length, nil);
 		if single_read_length <= 0 {
 			free(data);
 			return nil, false;
@@ -249,7 +248,7 @@ read_entire_file :: proc(name: string) -> ([]byte, bool) {
 
 heap_alloc :: proc(size: int) -> rawptr {
 	assert(size > 0);
-	return win32.HeapAlloc(win32.GetProcessHeap(), win32.HEAP_ZERO_MEMORY, size);
+	return w.HeapAlloc(w.GetProcessHeap(), w.HEAP_ZERO_MEMORY, size);
 }
 heap_resize :: proc(ptr: rawptr, new_size: int) -> rawptr {
 	if new_size == 0 {
@@ -259,24 +258,24 @@ heap_resize :: proc(ptr: rawptr, new_size: int) -> rawptr {
 	if ptr == nil {
 		return heap_alloc(new_size);
 	}
-	return win32.HeapReAlloc(win32.GetProcessHeap(), win32.HEAP_ZERO_MEMORY, ptr, new_size);
+	return w.HeapReAlloc(w.GetProcessHeap(), w.HEAP_ZERO_MEMORY, ptr, new_size);
 }
 heap_free :: proc(ptr: rawptr) {
 	if ptr == nil {
 		return;
 	}
-	win32.HeapFree(win32.GetProcessHeap(), 0, ptr);
+	w.HeapFree(w.GetProcessHeap(), 0, ptr);
 }
 
 
 exit :: proc(code: int) {
-	win32.ExitProcess(cast(u32)code);
+	w.ExitProcess(cast(u32)code);
 }
 
 
 
 current_thread_id :: proc() -> int {
-	return cast(int)win32.GetCurrentThreadId();
+	return cast(int)w.GetCurrentThreadId();
 }
 
 

+ 1 - 1
core/sync.odin

@@ -2,7 +2,7 @@
 #import "atomic.odin";
 
 Semaphore :: struct {
-	_handle: win32.HANDLE,
+	_handle: win32.Handle,
 }
 
 Mutex :: struct {

+ 25 - 25
core/sys/wgl.odin

@@ -8,10 +8,10 @@ CONTEXT_PROFILE_MASK_ARB           :: 0x9126;
 CONTEXT_FORWARD_COMPATIBLE_BIT_ARB :: 0x0002;
 CONTEXT_CORE_PROFILE_BIT_ARB       :: 0x00000001;
 
-HGLRC :: HANDLE;
-COLORREF :: u32;
+Hglrc :: Handle;
+Color_Ref :: u32;
 
-LAYERPLANEDESCRIPTOR :: struct #ordered {
+Layer_Plane_Descriptor :: struct #ordered {
 	size:             u16,
 	version:          u16,
 	flags:            u32,
@@ -35,38 +35,38 @@ LAYERPLANEDESCRIPTOR :: struct #ordered {
 	aux_buffers:      byte,
 	layer_type:       byte,
 	reserved:         byte,
-	transparent:      COLORREF,
+	transparent:      Color_Ref,
 }
 
-POINTFLOAT :: struct #ordered {
+Point_Float :: struct #ordered {
 	x, y: f32,
 }
 
-GLYPHMETRICSFLOAT :: struct #ordered {
+Glyph_Metrics_Float :: struct #ordered {
 	black_box_x:  f32,
 	black_box_y:  f32,
-	glyph_origin: POINTFLOAT,
+	glyph_origin: Point_Float,
 	cell_inc_x:   f32,
 	cell_inc_y:   f32,
 }
 
-CreateContextAttribsARBType :: #type proc(hdc: HDC, hshareContext: rawptr, attribList: ^i32) -> HGLRC;
-ChoosePixelFormatARBType    :: #type proc(hdc: HDC, attrib_i_list: ^i32, attrib_f_list: ^f32, max_formats: u32, formats: ^i32, num_formats : ^u32) -> BOOL #cc_c;
+Create_Context_Attribs_ARB_Type :: #type proc(hdc: Hdc, hshareContext: rawptr, attribList: ^i32) -> Hglrc;
+Choose_Pixel_Format_ARB_Type    :: #type proc(hdc: Hdc, attrib_i_list: ^i32, attrib_f_list: ^f32, max_formats: u32, formats: ^i32, num_formats : ^u32) -> Bool #cc_c;
 
 
-CreateContext           :: proc(hdc: HDC) -> HGLRC                                                                                               #foreign opengl32 "wglCreateContext";
-MakeCurrent             :: proc(hdc: HDC, hglrc: HGLRC) -> BOOL                                                                                  #foreign opengl32 "wglMakeCurrent";
-GetProcAddress          :: proc(c_str: ^u8) -> PROC                                                                                              #foreign opengl32 "wglGetProcAddress";
-DeleteContext           :: proc(hglrc: HGLRC) -> BOOL                                                                                            #foreign opengl32 "wglDeleteContext";
-CopyContext             :: proc(src, dst: HGLRC, mask: u32) -> BOOL                                                                              #foreign opengl32 "wglCopyContext";
-CreateLayerContext      :: proc(hdc: HDC, layer_plane: i32) -> HGLRC                                                                             #foreign opengl32 "wglCreateLayerContext";
-DescribeLayerPlane      :: proc(hdc: HDC, pixel_format, layer_plane: i32, bytes: u32, pd: ^LAYERPLANEDESCRIPTOR) -> BOOL                         #foreign opengl32 "wglDescribeLayerPlane";
-GetCurrentContext       :: proc() -> HGLRC                                                                                                       #foreign opengl32 "wglGetCurrentContext";
-GetCurrentDC            :: proc() -> HDC                                                                                                         #foreign opengl32 "wglGetCurrentDC";
-GetLayerPaletteEntries  :: proc(hdc: HDC, layer_plane, start, entries: i32, cr: ^COLORREF) -> i32                                                #foreign opengl32 "wglGetLayerPaletteEntries";
-RealizeLayerPalette     :: proc(hdc: HDC, layer_plane: i32, realize: BOOL) -> BOOL                                                               #foreign opengl32 "wglRealizeLayerPalette";
-SetLayerPaletteEntries  :: proc(hdc: HDC, layer_plane, start, entries: i32, cr: ^COLORREF) -> i32                                                #foreign opengl32 "wglSetLayerPaletteEntries";
-ShareLists              :: proc(hglrc1, hglrc2: HGLRC) -> BOOL                                                                                   #foreign opengl32 "wglShareLists";
-SwapLayerBuffers        :: proc(hdc: HDC, planes: u32) -> BOOL                                                                                   #foreign opengl32 "wglSwapLayerBuffers";
-UseFontBitmaps          :: proc(hdc: HDC, first, count, list_base: u32) -> BOOL                                                                  #foreign opengl32 "wglUseFontBitmaps";
-UseFontOutlines         :: proc(hdc: HDC, first, count, list_base: u32, deviation, extrusion: f32, format: i32, gmf: ^GLYPHMETRICSFLOAT) -> BOOL #foreign opengl32 "wglUseFontOutlines";
+CreateContext           :: proc(hdc: Hdc) -> Hglrc                                                                                                 #foreign opengl32 "wglCreateContext";
+MakeCurrent             :: proc(hdc: Hdc, hglrc: Hglrc) -> Bool                                                                                    #foreign opengl32 "wglMakeCurrent";
+GetProcAddress          :: proc(c_str: ^u8) -> Proc                                                                                                #foreign opengl32 "wglGetProcAddress";
+DeleteContext           :: proc(hglrc: Hglrc) -> Bool                                                                                              #foreign opengl32 "wglDeleteContext";
+CopyContext             :: proc(src, dst: Hglrc, mask: u32) -> Bool                                                                                #foreign opengl32 "wglCopyContext";
+CreateLayerContext      :: proc(hdc: Hdc, layer_plane: i32) -> Hglrc                                                                               #foreign opengl32 "wglCreateLayerContext";
+DescribeLayerPlane      :: proc(hdc: Hdc, pixel_format, layer_plane: i32, bytes: u32, pd: ^Layer_Plane_Descriptor) -> Bool                         #foreign opengl32 "wglDescribeLayerPlane";
+GetCurrentContext       :: proc() -> Hglrc                                                                                                         #foreign opengl32 "wglGetCurrentContext";
+GetCurrentDC            :: proc() -> Hdc                                                                                                           #foreign opengl32 "wglGetCurrentDC";
+GetLayerPaletteEntries  :: proc(hdc: Hdc, layer_plane, start, entries: i32, cr: ^Color_Ref) -> i32                                                 #foreign opengl32 "wglGetLayerPaletteEntries";
+RealizeLayerPalette     :: proc(hdc: Hdc, layer_plane: i32, realize: Bool) -> Bool                                                                 #foreign opengl32 "wglRealizeLayerPalette";
+SetLayerPaletteEntries  :: proc(hdc: Hdc, layer_plane, start, entries: i32, cr: ^Color_Ref) -> i32                                                 #foreign opengl32 "wglSetLayerPaletteEntries";
+ShareLists              :: proc(hglrc1, hglrc2: Hglrc) -> Bool                                                                                     #foreign opengl32 "wglShareLists";
+SwapLayerBuffers        :: proc(hdc: Hdc, planes: u32) -> Bool                                                                                     #foreign opengl32 "wglSwapLayerBuffers";
+UseFontBitmaps          :: proc(hdc: Hdc, first, count, list_base: u32) -> Bool                                                                    #foreign opengl32 "wglUseFontBitmaps";
+UseFontOutlines         :: proc(hdc: Hdc, first, count, list_base: u32, deviation, extrusion: f32, format: i32, gmf: ^Glyph_Metrics_Float) -> Bool #foreign opengl32 "wglUseFontOutlines";

+ 127 - 128
core/sys/windows.odin

@@ -3,28 +3,27 @@
 #foreign_system_library "gdi32.lib"    when ODIN_OS == "windows";
 #foreign_system_library "winmm.lib"    when ODIN_OS == "windows";
 
-HANDLE    :: rawptr;
-HWND      :: HANDLE;
-HDC       :: HANDLE;
-HINSTANCE :: HANDLE;
-HICON     :: HANDLE;
-HCURSOR   :: HANDLE;
-HMENU     :: HANDLE;
-HBRUSH    :: HANDLE;
-HGDIOBJ   :: HANDLE;
-HMODULE   :: HANDLE;
-WPARAM    :: uint;
-LPARAM    :: int;
-LRESULT   :: int;
-ATOM      :: i16;
-BOOL      :: i32;
-WNDPROC   :: #type proc(HWND, u32, WPARAM, LPARAM) -> LRESULT #cc_c;
-
-
-INVALID_HANDLE_VALUE :: cast(HANDLE)~cast(int)0;
-
-FALSE: BOOL : 0;
-TRUE:  BOOL : 1;
+Handle    :: rawptr;
+Hwnd      :: Handle;
+Hdc       :: Handle;
+Hinstance :: Handle;
+Hicon     :: Handle;
+Hcursor   :: Handle;
+Hmenu     :: Handle;
+Hbrush    :: Handle;
+Hgdiobj   :: Handle;
+Hmodule   :: Handle;
+Wparam    :: uint;
+Lparam    :: int;
+Lresult   :: int;
+Bool      :: i32;
+Wnd_Proc  :: #type proc(Hwnd, u32, Wparam, Lparam) -> Lresult #cc_c;
+
+
+INVALID_HANDLE :: cast(Handle)~cast(int)0;
+
+FALSE: Bool : 0;
+TRUE:  Bool : 1;
 
 CS_VREDRAW    :: 0x0001;
 CS_HREDRAW    :: 0x0002;
@@ -56,7 +55,7 @@ WM_CHAR              :: 0x0102;
 
 PM_REMOVE :: 1;
 
-COLOR_BACKGROUND :: cast(HBRUSH)(cast(int)1);
+COLOR_BACKGROUND :: cast(Hbrush)(cast(int)1);
 BLACK_BRUSH :: 4;
 
 SM_CXSCREEN :: 0;
@@ -65,53 +64,53 @@ SM_CYSCREEN :: 1;
 SW_SHOW :: 5;
 
 
-POINT :: struct #ordered {
+Point :: struct #ordered {
 	x, y: i32,
 }
 
-WNDCLASSEXA :: struct #ordered {
+WndClassExA :: struct #ordered {
 	size, style:           u32,
-	wnd_proc:              WNDPROC,
+	wnd_proc:              Wnd_Proc,
 	cls_extra, wnd_extra:  i32,
-	instance:              HINSTANCE,
-	icon:                  HICON,
-	cursor:                HCURSOR,
-	background:            HBRUSH,
+	instance:              Hinstance,
+	icon:                  Hicon,
+	cursor:                Hcursor,
+	background:            Hbrush,
 	menu_name, class_name: ^u8,
-	sm:                    HICON,
+	sm:                    Hicon,
 }
 
-MSG :: struct #ordered {
-	hwnd:    HWND,
+Msg :: struct #ordered {
+	hwnd:    Hwnd,
 	message: u32,
-	wparam:  WPARAM,
-	lparam:  LPARAM,
+	wparam:  Wparam,
+	lparam:  Lparam,
 	time:    u32,
-	pt:      POINT,
+	pt:      Point,
 }
 
-RECT :: struct #ordered {
+Rect :: struct #ordered {
 	left:   i32,
 	top:    i32,
 	right:  i32,
 	bottom: i32,
 }
 
-FILETIME :: struct #ordered {
+Filetime :: struct #ordered {
 	lo, hi: u32,
 }
 
-SYSTEMTIME :: struct #ordered {
+Systemtime :: struct #ordered {
 	year, month: u16,
 	day_of_week, day: u16,
 	hour, minute, second, millisecond: u16,
 }
 
-BY_HANDLE_FILE_INFORMATION :: struct #ordered {
+By_Handle_File_Information :: struct #ordered {
 	file_attributes:      u32,
 	creation_time,
 	last_access_time,
-	last_write_time:      FILETIME,
+	last_write_time:      Filetime,
 	volume_serial_number,
 	file_size_high,
 	file_size_low,
@@ -120,11 +119,11 @@ BY_HANDLE_FILE_INFORMATION :: struct #ordered {
 	file_index_low:       u32,
 }
 
-FILE_ATTRIBUTE_DATA :: struct #ordered {
+File_Attribute_Data :: struct #ordered {
 	file_attributes:  u32,
 	creation_time,
 	last_access_time,
-	last_write_time:  FILETIME,
+	last_write_time:  Filetime,
 	file_size_high,
 	file_size_low:    u32,
 }
@@ -136,13 +135,13 @@ GetFileExMaxInfoLevel: GET_FILEEX_INFO_LEVELS : 1;
 
 GetLastError     :: proc() -> i32                            #foreign kernel32;
 ExitProcess      :: proc(exit_code: u32)                     #foreign kernel32;
-GetDesktopWindow :: proc() -> HWND                           #foreign user32;
-GetCursorPos     :: proc(p: ^POINT) -> i32                   #foreign user32;
-ScreenToClient   :: proc(h: HWND, p: ^POINT) -> i32          #foreign user32;
-GetModuleHandleA :: proc(module_name: ^u8) -> HINSTANCE      #foreign kernel32;
-GetStockObject   :: proc(fn_object: i32) -> HGDIOBJ          #foreign gdi32;
+GetDesktopWindow :: proc() -> Hwnd                           #foreign user32;
+GetCursorPos     :: proc(p: ^Point) -> i32                   #foreign user32;
+ScreenToClient   :: proc(h: Hwnd, p: ^Point) -> i32          #foreign user32;
+GetModuleHandleA :: proc(module_name: ^u8) -> Hinstance      #foreign kernel32;
+GetStockObject   :: proc(fn_object: i32) -> Hgdiobj          #foreign gdi32;
 PostQuitMessage  :: proc(exit_code: i32)                     #foreign user32;
-SetWindowTextA   :: proc(hwnd: HWND, c_string: ^u8) -> BOOL  #foreign user32;
+SetWindowTextA   :: proc(hwnd: Hwnd, c_string: ^u8) -> Bool  #foreign user32;
 
 QueryPerformanceFrequency :: proc(result: ^i64) -> i32 #foreign kernel32;
 QueryPerformanceCounter   :: proc(result: ^i64) -> i32 #foreign kernel32;
@@ -152,28 +151,28 @@ Sleep :: proc(ms: i32) -> i32 #foreign kernel32;
 OutputDebugStringA :: proc(c_str: ^u8) #foreign kernel32;
 
 
-RegisterClassExA :: proc(wc: ^WNDCLASSEXA) -> ATOM #foreign user32;
+RegisterClassExA :: proc(wc: ^WndClassExA) -> i16 #foreign user32;
 CreateWindowExA  :: proc(ex_style: u32,
                          class_name, title: ^u8,
                          style: u32,
                          x, y, w, h: i32,
-                         parent: HWND, menu: HMENU, instance: HINSTANCE,
-                         param: rawptr) -> HWND #foreign user32;
+                         parent: Hwnd, menu: Hmenu, instance: Hinstance,
+                         param: rawptr) -> Hwnd #foreign user32;
 
-ShowWindow       :: proc(hwnd: HWND, cmd_show: i32) -> BOOL #foreign user32;
-TranslateMessage :: proc(msg: ^MSG) -> BOOL                 #foreign user32;
-DispatchMessageA :: proc(msg: ^MSG) -> LRESULT              #foreign user32;
-UpdateWindow     :: proc(hwnd: HWND) -> BOOL                #foreign user32;
-PeekMessageA     :: proc(msg: ^MSG, hwnd: HWND,
-                         msg_filter_min, msg_filter_max, remove_msg: u32) -> BOOL #foreign user32;
+ShowWindow       :: proc(hwnd: Hwnd, cmd_show: i32) -> Bool #foreign user32;
+TranslateMessage :: proc(msg: ^Msg) -> Bool                 #foreign user32;
+DispatchMessageA :: proc(msg: ^Msg) -> Lresult              #foreign user32;
+UpdateWindow     :: proc(hwnd: Hwnd) -> Bool                #foreign user32;
+PeekMessageA     :: proc(msg: ^Msg, hwnd: Hwnd,
+                         msg_filter_min, msg_filter_max, remove_msg: u32) -> Bool #foreign user32;
 
-DefWindowProcA :: proc(hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT #foreign user32;
+DefWindowProcA :: proc(hwnd: Hwnd, msg: u32, wparam: Wparam, lparam: Lparam) -> Lresult #foreign user32;
 
-AdjustWindowRect :: proc(rect: ^RECT, style: u32, menu: BOOL) -> BOOL #foreign user32;
-GetActiveWindow  :: proc() -> HWND #foreign user32;
+AdjustWindowRect :: proc(rect: ^Rect, style: u32, menu: Bool) -> Bool #foreign user32;
+GetActiveWindow  :: proc() -> Hwnd #foreign user32;
 
-DestroyWindow       :: proc(wnd: HWND) -> BOOL #foreign user32;
-DescribePixelFormat :: proc(dc: HDC, pixel_format: i32, bytes : u32, pfd: ^PIXELFORMATDESCRIPTOR) -> i32 #foreign user32;
+DestroyWindow       :: proc(wnd: Hwnd) -> Bool #foreign user32;
+DescribePixelFormat :: proc(dc: Hdc, pixel_format: i32, bytes : u32, pfd: ^PIXELFORMATDESCRIPTOR) -> i32 #foreign user32;
 
 
 GetQueryPerformanceFrequency :: proc() -> i64 {
@@ -187,29 +186,29 @@ GetSystemMetrics   :: proc(index: i32) -> i32 #foreign kernel32;
 GetCurrentThreadId :: proc() -> u32 #foreign kernel32;
 
 timeGetTime             :: proc() -> u32 #foreign winmm;
-GetSystemTimeAsFileTime :: proc(system_time_as_file_time: ^FILETIME) #foreign kernel32;
-FileTimeToLocalFileTime :: proc(file_time: ^FILETIME, local_file_time: ^FILETIME) -> BOOL #foreign kernel32;
-FileTimeToSystemTime    :: proc(file_time: ^FILETIME, system_time: ^SYSTEMTIME) -> BOOL #foreign kernel32;
-SystemTimeToFileTime    :: proc(system_time: ^SYSTEMTIME, file_time: ^FILETIME) -> BOOL #foreign kernel32;
+GetSystemTimeAsFileTime :: proc(system_time_as_file_time: ^Filetime) #foreign kernel32;
+FileTimeToLocalFileTime :: proc(file_time: ^Filetime, local_file_time: ^Filetime) -> Bool #foreign kernel32;
+FileTimeToSystemTime    :: proc(file_time: ^Filetime, system_time: ^Systemtime) -> Bool #foreign kernel32;
+SystemTimeToFileTime    :: proc(system_time: ^Systemtime, file_time: ^Filetime) -> Bool #foreign kernel32;
 
 // File Stuff
 
-CloseHandle  :: proc(h: HANDLE) -> i32 #foreign kernel32;
-GetStdHandle :: proc(h: i32) -> HANDLE #foreign kernel32;
+CloseHandle  :: proc(h: Handle) -> i32 #foreign kernel32;
+GetStdHandle :: proc(h: i32) -> Handle #foreign kernel32;
 CreateFileA  :: proc(filename: ^u8, desired_access, share_mode: u32,
                      security: rawptr,
-                     creation, flags_and_attribs: u32, template_file: HANDLE) -> HANDLE #foreign kernel32;
-ReadFile  :: proc(h: HANDLE, buf: rawptr, to_read: u32, bytes_read: ^i32, overlapped: rawptr) -> BOOL #foreign kernel32;
-WriteFile :: proc(h: HANDLE, buf: rawptr, len: i32, written_result: ^i32, overlapped: rawptr) -> BOOL #foreign kernel32;
+                     creation, flags_and_attribs: u32, template_file: Handle) -> Handle #foreign kernel32;
+ReadFile  :: proc(h: Handle, buf: rawptr, to_read: u32, bytes_read: ^i32, overlapped: rawptr) -> Bool #foreign kernel32;
+WriteFile :: proc(h: Handle, buf: rawptr, len: i32, written_result: ^i32, overlapped: rawptr) -> Bool #foreign kernel32;
 
-GetFileSizeEx              :: proc(file_handle: HANDLE, file_size: ^i64) -> BOOL #foreign kernel32;
-GetFileAttributesExA       :: proc(filename: ^u8, info_level_id: GET_FILEEX_INFO_LEVELS, file_info: rawptr) -> BOOL #foreign kernel32;
-GetFileInformationByHandle :: proc(file_handle: HANDLE, file_info: ^BY_HANDLE_FILE_INFORMATION) -> BOOL #foreign kernel32;
+GetFileSizeEx              :: proc(file_handle: Handle, file_size: ^i64) -> Bool #foreign kernel32;
+GetFileAttributesExA       :: proc(filename: ^u8, info_level_id: GET_FILEEX_INFO_LEVELS, file_info: rawptr) -> Bool #foreign kernel32;
+GetFileInformationByHandle :: proc(file_handle: Handle, file_info: ^By_Handle_File_Information) -> Bool #foreign kernel32;
 
-GetFileType    :: proc(file_handle: HANDLE) -> u32 #foreign kernel32;
-SetFilePointer :: proc(file_handle: HANDLE, distance_to_move: i32, distance_to_move_high: ^i32, move_method: u32) -> u32 #foreign kernel32;
+GetFileType    :: proc(file_handle: Handle) -> u32 #foreign kernel32;
+SetFilePointer :: proc(file_handle: Handle, distance_to_move: i32, distance_to_move_high: ^i32, move_method: u32) -> u32 #foreign kernel32;
 
-SetHandleInformation :: proc(obj: HANDLE, mask, flags: u32) -> BOOL #foreign kernel32;
+SetHandleInformation :: proc(obj: Handle, mask, flags: u32) -> Bool #foreign kernel32;
 
 HANDLE_FLAG_INHERIT :: 1;
 HANDLE_FLAG_PROTECT_FROM_CLOSE :: 2;
@@ -242,13 +241,13 @@ TRUNCATE_EXISTING :: 5;
 FILE_ATTRIBUTE_READONLY             :: 0x00000001;
 FILE_ATTRIBUTE_HIDDEN               :: 0x00000002;
 FILE_ATTRIBUTE_SYSTEM               :: 0x00000004;
-FILE_ATTRIBUTE_DIRECTORY            :: 0x00000010;
+FILE_ATTRIBUTE_DIRectORY            :: 0x00000010;
 FILE_ATTRIBUTE_ARCHIVE              :: 0x00000020;
 FILE_ATTRIBUTE_DEVICE               :: 0x00000040;
 FILE_ATTRIBUTE_NORMAL               :: 0x00000080;
 FILE_ATTRIBUTE_TEMPORARY            :: 0x00000100;
 FILE_ATTRIBUTE_SPARSE_FILE          :: 0x00000200;
-FILE_ATTRIBUTE_REPARSE_POINT        :: 0x00000400;
+FILE_ATTRIBUTE_REPARSE_Point        :: 0x00000400;
 FILE_ATTRIBUTE_COMPRESSED           :: 0x00000800;
 FILE_ATTRIBUTE_OFFLINE              :: 0x00001000;
 FILE_ATTRIBUTE_NOT_CONTENT_INDEXED  :: 0x00002000;
@@ -263,27 +262,27 @@ INVALID_SET_FILE_POINTER :: ~cast(u32)0;
 
 
 
-HeapAlloc      :: proc (h: HANDLE, flags: u32, bytes: int) -> rawptr                 #foreign kernel32;
-HeapReAlloc    :: proc (h: HANDLE, flags: u32, memory: rawptr, bytes: int) -> rawptr #foreign kernel32;
-HeapFree       :: proc (h: HANDLE, flags: u32, memory: rawptr) -> BOOL               #foreign kernel32;
-GetProcessHeap :: proc () -> HANDLE #foreign kernel32;
+HeapAlloc      :: proc (h: Handle, flags: u32, bytes: int) -> rawptr                 #foreign kernel32;
+HeapReAlloc    :: proc (h: Handle, flags: u32, memory: rawptr, bytes: int) -> rawptr #foreign kernel32;
+HeapFree       :: proc (h: Handle, flags: u32, memory: rawptr) -> Bool               #foreign kernel32;
+GetProcessHeap :: proc () -> Handle #foreign kernel32;
 
 
 HEAP_ZERO_MEMORY :: 0x00000008;
 
 // Synchronization
 
-SECURITY_ATTRIBUTES :: struct #ordered {
+Security_Attributes :: struct #ordered {
 	length:              u32,
 	security_descriptor: rawptr,
-	inherit_handle:      BOOL,
+	inherit_handle:      Bool,
 }
 
 INFINITE :: 0xffffffff;
 
-CreateSemaphoreA    :: proc(attributes: ^SECURITY_ATTRIBUTES, initial_count, maximum_count: i32, name: ^byte) -> HANDLE #foreign kernel32;
-ReleaseSemaphore    :: proc(semaphore: HANDLE, release_count: i32, previous_count: ^i32) -> BOOL #foreign kernel32;
-WaitForSingleObject :: proc(handle: HANDLE, milliseconds: u32) -> u32 #foreign kernel32;
+CreateSemaphoreA    :: proc(attributes: ^Security_Attributes, initial_count, maximum_count: i32, name: ^byte) -> Handle #foreign kernel32;
+ReleaseSemaphore    :: proc(semaphore: Handle, release_count: i32, previous_count: ^i32) -> Bool #foreign kernel32;
+WaitForSingleObject :: proc(handle: Handle, milliseconds: u32) -> u32 #foreign kernel32;
 
 
 InterlockedCompareExchange :: proc(dst: ^i32, exchange, comparand: i32) -> i32 #foreign kernel32;
@@ -307,11 +306,11 @@ ReadBarrier      :: proc() #foreign kernel32;
 
 
 
-HMONITOR :: HANDLE;
+Hmonitor :: Handle;
 
 GWL_STYLE     :: -16;
 
-HWND_TOP :: cast(HWND)cast(uint)0;
+Hwnd_TOP :: cast(Hwnd)cast(uint)0;
 
 MONITOR_DEFAULTTONULL    :: 0x00000000;
 MONITOR_DEFAULTTOPRIMARY :: 0x00000001;
@@ -324,39 +323,39 @@ SWP_NOSIZE        :: 0x0001;
 SWP_NOMOVE        :: 0x0002;
 
 
-MONITORINFO :: struct #ordered {
+Monitor_Info :: struct #ordered {
 	size:      u32,
-	monitor:   RECT,
-	work:      RECT,
+	monitor:   Rect,
+	work:      Rect,
 	flags:     u32,
 }
 
-WINDOWPLACEMENT :: struct #ordered {
+Window_Placement :: struct #ordered {
 	length:     u32,
 	flags:      u32,
 	show_cmd:   u32,
-	min_pos:    POINT,
-	max_pos:    POINT,
-	normal_pos: RECT,
+	min_pos:    Point,
+	max_pos:    Point,
+	normal_pos: Rect,
 }
 
-GetMonitorInfoA    :: proc(monitor: HMONITOR, mi: ^MONITORINFO) -> BOOL #foreign user32;
-MonitorFromWindow  :: proc(wnd: HWND, flags : u32) -> HMONITOR #foreign user32;
+GetMonitorInfoA    :: proc(monitor: Hmonitor, mi: ^Monitor_Info) -> Bool #foreign user32;
+MonitorFromWindow  :: proc(wnd: Hwnd, flags : u32) -> Hmonitor #foreign user32;
 
-SetWindowPos       :: proc(wnd: HWND, wndInsertAfter: HWND, x, y, width, height: i32, flags: u32) #foreign user32 "SetWindowPos";
+SetWindowPos       :: proc(wnd: Hwnd, wndInsertAfter: Hwnd, x, y, width, height: i32, flags: u32) #foreign user32 "SetWindowPos";
 
-GetWindowPlacement :: proc(wnd: HWND, wndpl: ^WINDOWPLACEMENT) -> BOOL #foreign user32;
-SetWindowPlacement :: proc(wnd: HWND, wndpl: ^WINDOWPLACEMENT) -> BOOL #foreign user32;
+GetWindowPlacement :: proc(wnd: Hwnd, wndpl: ^Window_Placement) -> Bool #foreign user32;
+SetWindowPlacement :: proc(wnd: Hwnd, wndpl: ^Window_Placement) -> Bool #foreign user32;
 
-GetWindowLongPtrA :: proc(wnd: HWND, index: i32) -> i64 #foreign user32;
-SetWindowLongPtrA :: proc(wnd: HWND, index: i32, new: i64) -> i64 #foreign user32;
+GetWindowLongPtrA :: proc(wnd: Hwnd, index: i32) -> i64 #foreign user32;
+SetWindowLongPtrA :: proc(wnd: Hwnd, index: i32, new: i64) -> i64 #foreign user32;
 
-GetWindowText :: proc(wnd: HWND, str: ^byte, maxCount: i32) -> i32 #foreign user32;
+GetWindowText :: proc(wnd: Hwnd, str: ^byte, maxCount: i32) -> i32 #foreign user32;
 
-HIWORD :: proc(wParam: WPARAM) -> u16 { return cast(u16)((cast(u32)wParam >> 16) & 0xffff); }
-HIWORD :: proc(lParam: LPARAM) -> u16 { return cast(u16)((cast(u32)lParam >> 16) & 0xffff); }
-LOWORD :: proc(wParam: WPARAM) -> u16 { return cast(u16)wParam; }
-LOWORD :: proc(lParam: LPARAM) -> u16 { return cast(u16)lParam; }
+HIWORD :: proc(wParam: Wparam) -> u16 { return cast(u16)((cast(u32)wParam >> 16) & 0xffff); }
+HIWORD :: proc(lParam: Lparam) -> u16 { return cast(u16)((cast(u32)lParam >> 16) & 0xffff); }
+LOWORD :: proc(wParam: Wparam) -> u16 { return cast(u16)wParam; }
+LOWORD :: proc(lParam: Lparam) -> u16 { return cast(u16)lParam; }
 
 
 
@@ -367,7 +366,7 @@ LOWORD :: proc(lParam: LPARAM) -> u16 { return cast(u16)lParam; }
 
 
 
-BITMAPINFOHEADER :: struct #ordered {
+Bitmap_Info_Header :: struct #ordered {
 	size:              u32,
 	width, height:     i32,
 	planes, bit_count: i16,
@@ -378,33 +377,33 @@ BITMAPINFOHEADER :: struct #ordered {
 	clr_used:          u32,
 	clr_important:     u32,
 }
-BITMAPINFO :: struct #ordered {
-	using header: BITMAPINFOHEADER,
-	colors:       [1]RGBQUAD,
+Bitmap_Info :: struct #ordered {
+	using header: Bitmap_Info_Header,
+	colors:       [1]Rgb_Quad,
 }
 
 
-RGBQUAD :: struct #ordered { blue, green, red, reserved: byte }
+Rgb_Quad :: struct #ordered { blue, green, red, reserved: byte }
 
 BI_RGB         :: 0;
 DIB_RGB_COLORS :: 0x00;
 SRCCOPY: u32    : 0x00cc0020;
 
 
-StretchDIBits :: proc (hdc: HDC,
+StretchDIBits :: proc (hdc: Hdc,
                        x_dst, y_dst, width_dst, height_dst: i32,
                        x_src, y_src, width_src, header_src: i32,
-                       bits: rawptr, bits_info: ^BITMAPINFO,
+                       bits: rawptr, bits_info: ^Bitmap_Info,
                        usage: u32,
                        rop: u32) -> i32 #foreign gdi32;
 
 
 
-LoadLibraryA   :: proc (c_str: ^u8) -> HMODULE #foreign kernel32;
-FreeLibrary    :: proc (h: HMODULE) #foreign kernel32;
-GetProcAddress :: proc (h: HMODULE, c_str: ^u8) -> PROC #foreign kernel32;
+LoadLibraryA   :: proc (c_str: ^u8) -> Hmodule #foreign kernel32;
+FreeLibrary    :: proc (h: Hmodule) #foreign kernel32;
+GetProcAddress :: proc (h: Hmodule, c_str: ^u8) -> Proc #foreign kernel32;
 
-GetClientRect :: proc(hwnd: HWND, rect: ^RECT) -> BOOL #foreign user32;
+GetClientRect :: proc(hwnd: Hwnd, rect: ^Rect) -> Bool #foreign user32;
 
 // Windows OpenGL
 PFD_TYPE_RGBA             :: 0;
@@ -461,14 +460,14 @@ PIXELFORMATDESCRIPTOR :: struct #ordered {
 	damage_mask: u32,
 }
 
-GetDC             :: proc(h: HWND) -> HDC #foreign user32;
-SetPixelFormat    :: proc(hdc: HDC, pixel_format: i32, pfd: ^PIXELFORMATDESCRIPTOR) -> BOOL #foreign gdi32;
-ChoosePixelFormat :: proc(hdc: HDC, pfd: ^PIXELFORMATDESCRIPTOR) -> i32 #foreign gdi32;
-SwapBuffers       :: proc(hdc: HDC) -> BOOL #foreign gdi32;
-ReleaseDC         :: proc(wnd: HWND, hdc: HDC) -> i32 #foreign user32;
+GetDC             :: proc(h: Hwnd) -> Hdc #foreign user32;
+SetPixelFormat    :: proc(hdc: Hdc, pixel_format: i32, pfd: ^PIXELFORMATDESCRIPTOR) -> Bool #foreign gdi32;
+ChoosePixelFormat :: proc(hdc: Hdc, pfd: ^PIXELFORMATDESCRIPTOR) -> i32 #foreign gdi32;
+SwapBuffers       :: proc(hdc: Hdc) -> Bool #foreign gdi32;
+ReleaseDC         :: proc(wnd: Hwnd, hdc: Hdc) -> i32 #foreign user32;
 
 
-PROC  :: #type proc() #cc_c;
+Proc  :: #type proc() #cc_c;
 
 
 GetKeyState      :: proc(v_key: i32) -> i16 #foreign user32;
@@ -611,7 +610,7 @@ Key_Code :: enum i32 {
 	RCONTROL   = 0xA3,
 	LMENU      = 0xA4,
 	RMENU      = 0xA5,
-	PROCESSKEY = 0xE5,
+	ProcESSKEY = 0xE5,
 	ATTN       = 0xF6,
 	CRSEL      = 0xF7,
 	EXSEL      = 0xF8,

+ 53 - 0
src/check_decl.c

@@ -408,6 +408,56 @@ void check_var_decl(Checker *c, Entity *e, Entity **entities, isize entity_count
 }
 
 
+void check_alias_decl(Checker *c, Entity *e, AstNode *expr) {
+	GB_ASSERT(e->type == NULL);
+	GB_ASSERT(e->kind == Entity_Alias);
+
+	if (e->flags & EntityFlag_Visited) {
+		e->type = t_invalid;
+		return;
+	}
+	e->flags |= EntityFlag_Visited;
+	e->type = t_invalid;
+
+	expr = unparen_expr(expr);
+
+	if (expr->kind == AstNode_Alias) {
+		error_node(expr, "#alias of an #alias is not allowed");
+		return;
+	}
+
+	if (expr->kind == AstNode_Ident) {
+		Operand o = {0};
+		Entity *f = check_ident(c, &o, expr, NULL, NULL, true);
+		if (f != NULL) {
+			e->Alias.original = f;
+			e->type = f->type;
+		}
+		return;
+	} else if (expr->kind == AstNode_SelectorExpr) {
+		Operand o = {0};
+		Entity *f = check_selector(c, &o, expr, NULL);
+		if (f != NULL) {
+			e->Alias.original = f;
+			e->type = f->type;
+		}
+		return;
+	}
+
+	Operand o = {0};
+	check_expr_or_type(c, &o, expr);
+	if (o.mode == Addressing_Invalid) {
+		return;
+	}
+	switch (o.mode) {
+	case Addressing_Type:
+		e->type = o.type;
+		break;
+	default:
+		error_node(expr, "#alias declarations only allow types");
+	}
+}
+
 void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {
 	if (e->type != NULL) {
 		return;
@@ -443,6 +493,9 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {
 	case Entity_Procedure:
 		check_proc_lit(c, e, d);
 		break;
+	case Entity_Alias:
+		check_alias_decl(c, e, d->init_expr);
+		break;
 	}
 
 	c->context = prev;

+ 30 - 16
src/check_expr.c

@@ -1028,7 +1028,7 @@ void check_procedure_type(Checker *c, Type *type, AstNode *proc_type_node) {
 }
 
 
-void check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *type_hint) {
+Entity *check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *type_hint, bool allow_import_name) {
 	GB_ASSERT(n->kind == AstNode_Ident);
 	o->mode = Addressing_Invalid;
 	o->expr = n;
@@ -1046,7 +1046,7 @@ void check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *typ
 		if (named_type != NULL) {
 			set_base_type(named_type, t_invalid);
 		}
-		return;
+		return NULL;
 	}
 
 	bool is_overloaded = false;
@@ -1095,7 +1095,7 @@ void check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *typ
 			o->type              = t_invalid;
 			o->overload_count    = overload_count;
 			o->overload_entities = procs;
-			return;
+			return NULL;
 		}
 		gb_free(heap_allocator(), procs);
 	}
@@ -1106,20 +1106,26 @@ void check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *typ
 
 	if (e->type == NULL) {
 		compiler_error("Compiler error: How did this happen? type: %s; identifier: %.*s\n", type_to_string(e->type), LIT(name));
-		return;
+		return NULL;
 	}
 
-	Type *type = e->type;
+	e->flags |= EntityFlag_Used;
+
+	Entity *original_e = e;
+	while (e->kind == Entity_Alias && e->Alias.original != NULL) {
+		e = e->Alias.original;
+	}
 
+	Type *type = e->type;
 	switch (e->kind) {
 	case Entity_Constant:
 		if (type == t_invalid) {
 			o->type = t_invalid;
-			return;
+			return e;
 		}
 		o->value = e->Constant.value;
 		if (o->value.kind == ExactValue_Invalid) {
-			return;
+			return e;
 		}
 		o->mode = Addressing_Constant;
 		break;
@@ -1128,7 +1134,7 @@ void check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *typ
 		e->flags |= EntityFlag_Used;
 		if (type == t_invalid) {
 			o->type = t_invalid;
-			return;
+			return e;
 		}
 		o->mode = Addressing_Variable;
 		if (e->Variable.is_immutable) {
@@ -1151,22 +1157,25 @@ void check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *typ
 		break;
 
 	case Entity_ImportName:
-		error_node(n, "Use of import `%.*s` not in selector", LIT(e->ImportName.name));
-		return;
+		if (!allow_import_name) {
+			error_node(n, "Use of import `%.*s` not in selector", LIT(name));
+		}
+		return e;
 	case Entity_LibraryName:
-		error_node(n, "Use of library `%.*s` not in #foreign tag", LIT(e->LibraryName.name));
-		return;
+		error_node(n, "Use of library `%.*s` not in #foreign tag", LIT(name));
+		return e;
 
 	case Entity_Nil:
 		o->mode = Addressing_Value;
 		break;
 
 	default:
-		compiler_error("Compiler error: Unknown EntityKind");
+		compiler_error("Unknown EntityKind");
 		break;
 	}
 
 	o->type = type;
+	return e;
 }
 
 i64 check_array_or_map_count(Checker *c, AstNode *e, bool is_map) {
@@ -1342,7 +1351,7 @@ Type *check_type_extra(Checker *c, AstNode *e, Type *named_type) {
 	switch (e->kind) {
 	case_ast_node(i, Ident, e);
 		Operand o = {0};
-		check_ident(c, &o, e, named_type, NULL);
+		check_ident(c, &o, e, named_type, NULL, false);
 
 		switch (o.mode) {
 		case Addressing_Invalid:
@@ -2679,6 +2688,11 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
 		add_entity_use(c, op_expr, e);
 		expr_entity = e;
 
+		Entity *original_e = e;
+		while (e->kind == Entity_Alias && e->Alias.original != NULL) {
+			e = e->Alias.original;
+		}
+
 		if (e != NULL && e->kind == Entity_ImportName && selector->kind == AstNode_Ident) {
 			// IMPORTANT NOTE(bill): This is very sloppy code but it's also very fragile
 			// It pretty much needs to be in this order and this way
@@ -4413,7 +4427,7 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
 	case_end;
 
 	case_ast_node(i, Ident, node);
-		check_ident(c, o, node, NULL, type_hint);
+		check_ident(c, o, node, NULL, type_hint, false);
 	case_end;
 
 	case_ast_node(bl, BasicLit, node);
@@ -5626,7 +5640,7 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
 	case_end;
 
 	case_ast_node(ht, HelperType, node);
-		str = gb_string_appendc(str, "type ");
+		str = gb_string_appendc(str, "#type ");
 		str = write_expr_to_string(str, ht->type);
 	case_end;
 	}

+ 8 - 3
src/checker.c

@@ -816,7 +816,7 @@ bool add_entity(Checker *c, Scope *scope, AstNode *identifier, Entity *entity) {
 					return false;
 				}
 				error(entity->token,
-				      "Redeclararation of `%.*s` in this scope through `using`\n"
+				      "Redeclaration of `%.*s` in this scope through `using`\n"
 				      "\tat %.*s(%td:%td)",
 				      LIT(name),
 				      LIT(up->token.pos.file), up->token.pos.line, up->token.pos.column);
@@ -827,7 +827,7 @@ bool add_entity(Checker *c, Scope *scope, AstNode *identifier, Entity *entity) {
 					return false;
 				}
 				error(entity->token,
-				      "Redeclararation of `%.*s` in this scope\n"
+				      "Redeclaration of `%.*s` in this scope\n"
 				      "\tat %.*s(%td:%td)",
 				      LIT(name),
 				      LIT(pos.file), pos.line, pos.column);
@@ -1467,7 +1467,12 @@ void check_collect_entities(Checker *c, AstNodeArray nodes, bool is_file_scope)
 						// TODO(bill): What if vd->type != NULL??? How to handle this case?
 						d->type_expr = init;
 						d->init_expr = init;
-					} else if (init != NULL && up_init->kind == AstNode_ProcLit) {
+					} else if (up_init != NULL && up_init->kind == AstNode_Alias) {
+						error_node(up_init, "#alias declarations are not yet supported");
+						continue;
+						// e = make_entity_alias(c->allocator, d->scope, name->Ident, NULL, NULL);
+						// d->init_expr = init->Alias.expr;
+					}else if (init != NULL && up_init->kind == AstNode_ProcLit) {
 						e = make_entity_procedure(c->allocator, d->scope, name->Ident, NULL, up_init->ProcLit.tags);
 						d->proc_lit = up_init;
 						d->type_expr = vd->type;

+ 11 - 0
src/entity.c

@@ -13,6 +13,7 @@ typedef struct Type Type;
 	ENTITY_KIND(Builtin) \
 	ENTITY_KIND(ImportName) \
 	ENTITY_KIND(LibraryName) \
+	ENTITY_KIND(Alias) \
 	ENTITY_KIND(Nil) \
 	ENTITY_KIND(Count)
 
@@ -95,6 +96,9 @@ struct Entity {
 			String name;
 			bool   used;
 		} LibraryName;
+		struct {
+			Entity *original;
+		} Alias;
 		i32 Nil;
 	};
 };
@@ -218,6 +222,13 @@ Entity *make_entity_library_name(gbAllocator a, Scope *scope, Token token, Type
 	return entity;
 }
 
+Entity *make_entity_alias(gbAllocator a, Scope *scope, Token token, Type *type,
+                          Entity *original) {
+	Entity *entity = alloc_entity(a, Entity_Alias, scope, token, type);
+	entity->Alias.original = original;
+	return entity;
+}
+
 Entity *make_entity_nil(gbAllocator a, String name, Type *type) {
 	Token token = make_token_ident(name);
 	Entity *entity = alloc_entity(a, Entity_Nil, NULL, token, type);

+ 4 - 0
src/gb/gb.h

@@ -806,6 +806,10 @@ GB_DEF void const *gb_memchr    (void const *data, u8 byte_value, isize size);
 GB_DEF void const *gb_memrchr   (void const *data, u8 byte_value, isize size);
 
 
+#ifndef gb_memcopy_array
+#define gb_memcopy_array(dst, src, count) gb_memcopy((dst), (src), gb_size_of(*(dst))*(count))
+#endif
+
 // NOTE(bill): Very similar to doing `*cast(T *)(&u)`
 #ifndef GB_BIT_CAST
 #define GB_BIT_CAST(dest, source) do { \

+ 22 - 30
src/ir.c

@@ -2916,8 +2916,21 @@ irValue *ir_find_global_variable(irProcedure *proc, String name) {
 
 void ir_build_stmt_list(irProcedure *proc, AstNodeArray stmts);
 
-irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv) {
+
+irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
 	expr = unparen_expr(expr);
+
+	TypeAndValue *tv = map_tav_get(&proc->module->info->types, hash_pointer(expr));
+	GB_ASSERT_NOT_NULL(tv);
+
+	if (tv->value.kind != ExactValue_Invalid) {
+		return ir_add_module_constant(proc->module, tv->type, tv->value);
+	}
+
+	if (tv->mode == Addressing_Variable) {
+		return ir_addr_load(proc, ir_build_addr(proc, expr));
+	}
+
 	switch (expr->kind) {
 	case_ast_node(bl, BasicLit, expr);
 		TokenPos pos = bl->pos;
@@ -3782,27 +3795,6 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
 	return NULL;
 }
 
-
-irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
-	expr = unparen_expr(expr);
-
-	TypeAndValue *tv = map_tav_get(&proc->module->info->types, hash_pointer(expr));
-	GB_ASSERT_NOT_NULL(tv);
-
-	if (tv->value.kind != ExactValue_Invalid) {
-		return ir_add_module_constant(proc->module, tv->type, tv->value);
-	}
-
-	irValue *value = NULL;
-	if (tv->mode == Addressing_Variable) {
-		value = ir_addr_load(proc, ir_build_addr(proc, expr));
-	} else {
-		value = ir_build_single_expr(proc, expr, tv);
-	}
-
-	return value;
-}
-
 irValue *ir_get_using_variable(irProcedure *proc, Entity *e) {
 	GB_ASSERT(e->kind == Entity_Variable && e->flags & EntityFlag_Anonymous);
 	String name = e->token.string;
@@ -5192,9 +5184,9 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
 		if (fs->cond != NULL) {
 			loop = ir_new_block(proc, node, "for.loop");
 		}
-		irBlock *cont = loop;
+		irBlock *post = loop;
 		if (fs->post != NULL) {
-			cont = ir_new_block(proc, node, "for.post");
+			post = ir_new_block(proc, node, "for.post");
 		}
 		ir_emit_jump(proc, loop);
 		ir_start_block(proc, loop);
@@ -5204,7 +5196,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
 			ir_start_block(proc, body);
 		}
 
-		ir_push_target_list(proc, done, cont, NULL);
+		ir_push_target_list(proc, done, post, NULL);
 
 		ir_open_scope(proc);
 		ir_build_stmt(proc, fs->body);
@@ -5212,10 +5204,10 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
 
 		ir_pop_target_list(proc);
 
-		ir_emit_jump(proc, cont);
+		ir_emit_jump(proc, post);
 
 		if (fs->post != NULL) {
-			ir_start_block(proc, cont);
+			ir_start_block(proc, post);
 			ir_build_stmt(proc, fs->post);
 			ir_emit_jump(proc, loop);
 		}
@@ -5646,7 +5638,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
 	case_end;
 
 
-	case_ast_node(pa, PushContext, node);
+	case_ast_node(pc, PushContext, node);
 		ir_emit_comment(proc, str_lit("PushContext"));
 		ir_open_scope(proc);
 
@@ -5656,9 +5648,9 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
 
 		ir_add_defer_instr(proc, proc->scope_index, ir_instr_store(proc, context_ptr, ir_emit_load(proc, prev_context)));
 
-		ir_emit_store(proc, context_ptr, ir_build_expr(proc, pa->expr));
+		ir_emit_store(proc, context_ptr, ir_build_expr(proc, pc->expr));
 
-		ir_build_stmt(proc, pa->body);
+		ir_build_stmt(proc, pc->body);
 
 		ir_close_scope(proc, irDeferExit_Default, NULL);
 	case_end;

+ 14 - 0
src/parser.c

@@ -139,6 +139,10 @@ AstNodeArray make_ast_node_array(AstFile *f) {
 		AstNodeArray elems; \
 		Token open, close; \
 	}) \
+	AST_NODE_KIND(Alias, "alias", struct { \
+		Token token; \
+		AstNode *expr; \
+	}) \
 AST_NODE_KIND(_ExprBegin,  "",  i32) \
 	AST_NODE_KIND(BadExpr,      "bad expression",         struct { Token begin, end; }) \
 	AST_NODE_KIND(TagExpr,      "tag expression",         struct { Token token, name; AstNode *expr; }) \
@@ -445,6 +449,8 @@ Token ast_node_token(AstNode *node) {
 			return ast_node_token(node->CompoundLit.type);
 		}
 		return node->CompoundLit.open;
+	case AstNode_Alias:         return node->Alias.token;
+
 	case AstNode_TagExpr:       return node->TagExpr.token;
 	case AstNode_RunExpr:       return node->RunExpr.token;
 	case AstNode_BadExpr:       return node->BadExpr.begin;
@@ -771,6 +777,13 @@ AstNode *ast_compound_lit(AstFile *f, AstNode *type, AstNodeArray elems, Token o
 	result->CompoundLit.close = close;
 	return result;
 }
+AstNode *ast_alias(AstFile *f, Token token, AstNode *expr) {
+	AstNode *result = make_ast_node(f, AstNode_Alias);
+	result->Alias.token = token;
+	result->Alias.expr  = expr;
+	return result;
+}
+
 
 AstNode *ast_ternary_expr(AstFile *f, AstNode *cond, AstNode *x, AstNode *y) {
 	AstNode *result = make_ast_node(f, AstNode_TernaryExpr);
@@ -1762,6 +1775,7 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
 		} else if (str_eq(name.string, str_lit("line"))) { return ast_basic_directive(f, token, name.string);
 		} else if (str_eq(name.string, str_lit("procedure"))) { return ast_basic_directive(f, token, name.string);
 		} else if (str_eq(name.string, str_lit("type"))) { return ast_helper_type(f, token, parse_type(f));
+		} else if (!lhs && str_eq(name.string, str_lit("alias"))) { return ast_alias(f, token, parse_expr(f, false));
 		} else {
 			operand = ast_tag_expr(f, token, name, parse_expr(f, false));
 		}

File diff suppressed because it is too large
+ 713 - 292
src/ssa.c


Some files were not shown because too many files changed in this diff