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

This commit is contained in:
Ginger Bill
2017-03-12 16:42:51 +00:00
parent 0fcbda951a
commit aaec8bf423
14 changed files with 1653 additions and 583 deletions

View File

@@ -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

View File

@@ -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);
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;
}
remainder32 :: proc(x, y: f32) -> f32 {
return x - round(x/y) * y;
}
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); }
fmod32 :: proc(x, y: f32) -> f32 {
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 := remainder32(abs(x), 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 := 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; }

View File

@@ -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();
}

View File

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

View File

@@ -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";

View File

@@ -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;
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_VALUE :: cast(HANDLE)~cast(int)0;
INVALID_HANDLE :: cast(Handle)~cast(int)0;
FALSE: BOOL : 0;
TRUE: BOOL : 1;
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,

View File

@@ -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;

View File

@@ -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;
}
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;
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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 { \

View File

@@ -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;

View File

@@ -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));
}

1573
src/ssa.c

File diff suppressed because it is too large Load Diff