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
+8 -7
View File
@@ -7,17 +7,18 @@
#import "os.odin"; #import "os.odin";
#import "strconv.odin"; #import "strconv.odin";
#import "sync.odin"; #import "sync.odin";
#import win32 "sys/windows.odin";
main :: proc() { main :: proc() {
a: i8 = -1; a := 1;
fmt.println(a, cast(u64)a, cast(i64)a); b := 2;
b: i64 = -1; c := a + b;
fmt.println(b, cast(u64)b, cast(i64)b);
if c > 0 {
c = 0;
}
when false { 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 Version 0.1.1
+36 -31
View File
@@ -27,14 +27,14 @@ Mat4 :: [4]Vec4;
sqrt :: proc(x: f32) -> f32 #foreign __llvm_core "llvm.sqrt.f32"; sqrt :: proc(x: f32) -> f32 #foreign __llvm_core "llvm.sqrt.f32";
sqrt :: proc(x: f64) -> f64 #foreign __llvm_core "llvm.sqrt.f64"; 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: f32) -> f32 #foreign __llvm_core "llvm.sin.f32";
sin :: proc(x: f64) -> f64 #foreign __llvm_core "llvm.sin.f64"; 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: f32) -> f32 #foreign __llvm_core "llvm.cos.f32";
cos :: proc(x: f64) -> f64 #foreign __llvm_core "llvm.cos.f64"; 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: f32) -> f32 #inline { return sin(x)/cos(x); }
tan :: proc(x: f64) -> f64 #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: f32) -> f32 { return a*(1-t) + b*t; }
lerp :: proc(a, b, t: f64) -> f64 { 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 { copy_sign :: proc(x, y: f32) -> f32 {
ix := transmute(u32)x; ix := transmute(u32)x;
iy := transmute(u32)y; iy := transmute(u32)y;
ix &= 0x7fffffff; ix &= 0x7fff_ffff;
ix |= iy & 0x80000000; ix |= iy & 0x8000_0000;
return transmute(f32)ix; return transmute(f32)ix;
} }
round :: proc(x: f32) -> f32 {
if x >= 0 { copy_sign :: proc(x, y: f64) -> f64 {
return floor(x + 0.5); ix := transmute(u64)x;
} iy := transmute(u64)y;
return ceil(x - 0.5); ix &= 0x7fff_ffff_ffff_ff;
} ix |= iy & 0x8000_0000_0000_0000;
floor :: proc(x: f32) -> f32 { return transmute(f64)ix;
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 { round :: proc(x: f32) -> f32 { return x >= 0 ? floor(x + 0.5) : ceil(x - 0.5); }
return x - round(x/y) * y; 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); 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 { if sign(result) < 0 {
result += y; 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: 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: 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; } dot :: proc(a, b: Vec4) -> f32 { c := a*b; return c.x + c.y + c.z + c.w; }
+44 -45
View File
@@ -1,4 +1,4 @@
#import win32 "sys/windows.odin"; #import w "sys/windows.odin";
#import "fmt.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) { open :: proc(path: string, mode: int, perm: u32) -> (Handle, Errno) {
using win32;
if path.count == 0 { if path.count == 0 {
return INVALID_HANDLE, ERROR_FILE_NOT_FOUND; return INVALID_HANDLE, ERROR_FILE_NOT_FOUND;
} }
access: u32; access: u32;
match mode & (O_RDONLY|O_WRONLY|O_RDWR) { match mode & (O_RDONLY|O_WRONLY|O_RDWR) {
case O_RDONLY: access = FILE_GENERIC_READ; case O_RDONLY: access = w.FILE_GENERIC_READ;
case O_WRONLY: access = FILE_GENERIC_WRITE; case O_WRONLY: access = w.FILE_GENERIC_WRITE;
case O_RDWR: access = FILE_GENERIC_READ | FILE_GENERIC_WRITE; case O_RDWR: access = w.FILE_GENERIC_READ | w.FILE_GENERIC_WRITE;
} }
if mode&O_CREAT != 0 { if mode&O_CREAT != 0 {
access |= FILE_GENERIC_WRITE; access |= w.FILE_GENERIC_WRITE;
} }
if mode&O_APPEND != 0 { if mode&O_APPEND != 0 {
access &~= FILE_GENERIC_WRITE; access &~= w.FILE_GENERIC_WRITE;
access |= FILE_APPEND_DATA; access |= w.FILE_APPEND_DATA;
} }
share_mode := cast(u32)(FILE_SHARE_READ|FILE_SHARE_WRITE); share_mode := cast(u32)(w.FILE_SHARE_READ|w.FILE_SHARE_WRITE);
sa: ^SECURITY_ATTRIBUTES = nil; sa: ^w.Security_Attributes = nil;
sa_inherit := SECURITY_ATTRIBUTES{length = size_of(SECURITY_ATTRIBUTES), inherit_handle = 1}; sa_inherit := w.Security_Attributes{length = size_of(w.Security_Attributes), inherit_handle = 1};
if mode&O_CLOEXEC == 0 { if mode&O_CLOEXEC == 0 {
sa = ^sa_inherit; sa = ^sa_inherit;
} }
@@ -83,37 +82,37 @@ open :: proc(path: string, mode: int, perm: u32) -> (Handle, Errno) {
create_mode: u32; create_mode: u32;
match { match {
case mode&(O_CREAT|O_EXCL) == (O_CREAT | O_EXCL): 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): 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: case mode&O_CREAT == O_CREAT:
create_mode = OPEN_ALWAYS; create_mode = w.OPEN_ALWAYS;
case mode&O_TRUNC == O_TRUNC: case mode&O_TRUNC == O_TRUNC:
create_mode = TRUNCATE_EXISTING; create_mode = w.TRUNCATE_EXISTING;
default: default:
create_mode = OPEN_EXISTING; create_mode = w.OPEN_EXISTING;
} }
buf: [300]byte; buf: [300]byte;
copy(buf[..], cast([]byte)path); 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 { if handle != INVALID_HANDLE {
return handle, ERROR_NONE; return handle, ERROR_NONE;
} }
err := GetLastError(); err := w.GetLastError();
return INVALID_HANDLE, cast(Errno)err; return INVALID_HANDLE, cast(Errno)err;
} }
close :: proc(fd: Handle) { close :: proc(fd: Handle) {
win32.CloseHandle(cast(win32.HANDLE)fd); w.CloseHandle(cast(w.Handle)fd);
} }
write :: proc(fd: Handle, data: []byte) -> (int, Errno) { write :: proc(fd: Handle, data: []byte) -> (int, Errno) {
bytes_written: i32; bytes_written: i32;
e := win32.WriteFile(cast(win32.HANDLE)fd, data.data, cast(i32)data.count, ^bytes_written, nil); e := w.WriteFile(cast(w.Handle)fd, data.data, cast(i32)data.count, ^bytes_written, nil);
if e == win32.FALSE { if e == w.FALSE {
err := win32.GetLastError(); err := w.GetLastError();
return 0, cast(Errno)err; return 0, cast(Errno)err;
} }
return cast(int)bytes_written, ERROR_NONE; 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) { read :: proc(fd: Handle, data: []byte) -> (int, Errno) {
bytes_read: i32; bytes_read: i32;
e := win32.ReadFile(cast(win32.HANDLE)fd, data.data, cast(u32)data.count, ^bytes_read, nil); e := w.ReadFile(cast(w.Handle)fd, data.data, cast(u32)data.count, ^bytes_read, nil);
if e == win32.FALSE { if e == w.FALSE {
err := win32.GetLastError(); err := w.GetLastError();
return 0, cast(Errno)err; return 0, cast(Errno)err;
} }
return cast(int)bytes_read, ERROR_NONE; return cast(int)bytes_read, ERROR_NONE;
} }
seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) { seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {
using win32; using w;
w: u32; w: u32;
match whence { match whence {
case 0: w = FILE_BEGIN; case 0: w = FILE_BEGIN;
@@ -139,11 +138,11 @@ seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {
} }
hi := cast(i32)(offset>>32); hi := cast(i32)(offset>>32);
lo := cast(i32)(offset); lo := cast(i32)(offset);
ft := GetFileType(cast(HANDLE)fd); ft := GetFileType(cast(Handle)fd);
if ft == FILE_TYPE_PIPE { if ft == FILE_TYPE_PIPE {
return 0, ERROR_FILE_IS_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 { if dw_ptr == INVALID_SET_FILE_POINTER {
err := GetLastError(); err := GetLastError();
return 0, cast(Errno)err; 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 // NOTE(bill): Uses startup to initialize it
stdin := get_std_handle(win32.STD_INPUT_HANDLE); stdin := get_std_handle(w.STD_INPUT_HANDLE);
stdout := get_std_handle(win32.STD_OUTPUT_HANDLE); stdout := get_std_handle(w.STD_OUTPUT_HANDLE);
stderr := get_std_handle(win32.STD_ERROR_HANDLE); stderr := get_std_handle(w.STD_ERROR_HANDLE);
get_std_handle :: proc(h: int) -> Handle { get_std_handle :: proc(h: int) -> Handle {
fd := win32.GetStdHandle(cast(i32)h); fd := w.GetStdHandle(cast(i32)h);
win32.SetHandleInformation(fd, win32.HANDLE_FLAG_INHERIT, 0); w.SetHandleInformation(fd, w.HANDLE_FLAG_INHERIT, 0);
return cast(Handle)fd; return cast(Handle)fd;
} }
@@ -170,23 +169,23 @@ get_std_handle :: proc(h: int) -> Handle {
last_write_time :: proc(fd: Handle) -> File_Time { last_write_time :: proc(fd: Handle) -> File_Time {
file_info: win32.BY_HANDLE_FILE_INFORMATION; file_info: w.By_Handle_File_Information;
win32.GetFileInformationByHandle(cast(win32.HANDLE)fd, ^file_info); w.GetFileInformationByHandle(cast(w.Handle)fd, ^file_info);
lo := cast(File_Time)file_info.last_write_time.lo; lo := cast(File_Time)file_info.last_write_time.lo;
hi := cast(File_Time)file_info.last_write_time.hi; hi := cast(File_Time)file_info.last_write_time.hi;
return lo | hi << 32; return lo | hi << 32;
} }
last_write_time_by_name :: proc(name: string) -> File_Time { last_write_time_by_name :: proc(name: string) -> File_Time {
last_write_time: win32.FILETIME; last_write_time: w.Filetime;
data: win32.FILE_ATTRIBUTE_DATA; data: w.File_Attribute_Data;
buf: [1024]byte; buf: [1024]byte;
assert(buf.count > name.count); assert(buf.count > name.count);
copy(buf[..], cast([]byte)name); 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; last_write_time = data.last_write_time;
} }
@@ -210,7 +209,7 @@ read_entire_file :: proc(name: string) -> ([]byte, bool) {
defer close(fd); defer close(fd);
length: i64; 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 { if !file_size_ok {
return nil, false; return nil, false;
} }
@@ -233,7 +232,7 @@ read_entire_file :: proc(name: string) -> ([]byte, bool) {
to_read = MAX; 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 { if single_read_length <= 0 {
free(data); free(data);
return nil, false; return nil, false;
@@ -249,7 +248,7 @@ read_entire_file :: proc(name: string) -> ([]byte, bool) {
heap_alloc :: proc(size: int) -> rawptr { heap_alloc :: proc(size: int) -> rawptr {
assert(size > 0); 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 { heap_resize :: proc(ptr: rawptr, new_size: int) -> rawptr {
if new_size == 0 { if new_size == 0 {
@@ -259,24 +258,24 @@ heap_resize :: proc(ptr: rawptr, new_size: int) -> rawptr {
if ptr == nil { if ptr == nil {
return heap_alloc(new_size); 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) { heap_free :: proc(ptr: rawptr) {
if ptr == nil { if ptr == nil {
return; return;
} }
win32.HeapFree(win32.GetProcessHeap(), 0, ptr); w.HeapFree(w.GetProcessHeap(), 0, ptr);
} }
exit :: proc(code: int) { exit :: proc(code: int) {
win32.ExitProcess(cast(u32)code); w.ExitProcess(cast(u32)code);
} }
current_thread_id :: proc() -> int { current_thread_id :: proc() -> int {
return cast(int)win32.GetCurrentThreadId(); return cast(int)w.GetCurrentThreadId();
} }
+1 -1
View File
@@ -2,7 +2,7 @@
#import "atomic.odin"; #import "atomic.odin";
Semaphore :: struct { Semaphore :: struct {
_handle: win32.HANDLE, _handle: win32.Handle,
} }
Mutex :: struct { Mutex :: struct {
+25 -25
View File
@@ -8,10 +8,10 @@ CONTEXT_PROFILE_MASK_ARB :: 0x9126;
CONTEXT_FORWARD_COMPATIBLE_BIT_ARB :: 0x0002; CONTEXT_FORWARD_COMPATIBLE_BIT_ARB :: 0x0002;
CONTEXT_CORE_PROFILE_BIT_ARB :: 0x00000001; CONTEXT_CORE_PROFILE_BIT_ARB :: 0x00000001;
HGLRC :: HANDLE; Hglrc :: Handle;
COLORREF :: u32; Color_Ref :: u32;
LAYERPLANEDESCRIPTOR :: struct #ordered { Layer_Plane_Descriptor :: struct #ordered {
size: u16, size: u16,
version: u16, version: u16,
flags: u32, flags: u32,
@@ -35,38 +35,38 @@ LAYERPLANEDESCRIPTOR :: struct #ordered {
aux_buffers: byte, aux_buffers: byte,
layer_type: byte, layer_type: byte,
reserved: byte, reserved: byte,
transparent: COLORREF, transparent: Color_Ref,
} }
POINTFLOAT :: struct #ordered { Point_Float :: struct #ordered {
x, y: f32, x, y: f32,
} }
GLYPHMETRICSFLOAT :: struct #ordered { Glyph_Metrics_Float :: struct #ordered {
black_box_x: f32, black_box_x: f32,
black_box_y: f32, black_box_y: f32,
glyph_origin: POINTFLOAT, glyph_origin: Point_Float,
cell_inc_x: f32, cell_inc_x: f32,
cell_inc_y: f32, cell_inc_y: f32,
} }
CreateContextAttribsARBType :: #type proc(hdc: HDC, hshareContext: rawptr, attribList: ^i32) -> HGLRC; Create_Context_Attribs_ARB_Type :: #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; 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"; CreateContext :: proc(hdc: Hdc) -> Hglrc #foreign opengl32 "wglCreateContext";
MakeCurrent :: proc(hdc: HDC, hglrc: HGLRC) -> BOOL #foreign opengl32 "wglMakeCurrent"; MakeCurrent :: proc(hdc: Hdc, hglrc: Hglrc) -> Bool #foreign opengl32 "wglMakeCurrent";
GetProcAddress :: proc(c_str: ^u8) -> PROC #foreign opengl32 "wglGetProcAddress"; GetProcAddress :: proc(c_str: ^u8) -> Proc #foreign opengl32 "wglGetProcAddress";
DeleteContext :: proc(hglrc: HGLRC) -> BOOL #foreign opengl32 "wglDeleteContext"; DeleteContext :: proc(hglrc: Hglrc) -> Bool #foreign opengl32 "wglDeleteContext";
CopyContext :: proc(src, dst: HGLRC, mask: u32) -> BOOL #foreign opengl32 "wglCopyContext"; CopyContext :: proc(src, dst: Hglrc, mask: u32) -> Bool #foreign opengl32 "wglCopyContext";
CreateLayerContext :: proc(hdc: HDC, layer_plane: i32) -> HGLRC #foreign opengl32 "wglCreateLayerContext"; 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"; 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"; GetCurrentContext :: proc() -> Hglrc #foreign opengl32 "wglGetCurrentContext";
GetCurrentDC :: proc() -> HDC #foreign opengl32 "wglGetCurrentDC"; GetCurrentDC :: proc() -> Hdc #foreign opengl32 "wglGetCurrentDC";
GetLayerPaletteEntries :: proc(hdc: HDC, layer_plane, start, entries: i32, cr: ^COLORREF) -> i32 #foreign opengl32 "wglGetLayerPaletteEntries"; 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"; 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"; 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"; ShareLists :: proc(hglrc1, hglrc2: Hglrc) -> Bool #foreign opengl32 "wglShareLists";
SwapLayerBuffers :: proc(hdc: HDC, planes: u32) -> BOOL #foreign opengl32 "wglSwapLayerBuffers"; SwapLayerBuffers :: proc(hdc: Hdc, planes: u32) -> Bool #foreign opengl32 "wglSwapLayerBuffers";
UseFontBitmaps :: proc(hdc: HDC, first, count, list_base: u32) -> BOOL #foreign opengl32 "wglUseFontBitmaps"; 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"; UseFontOutlines :: proc(hdc: Hdc, first, count, list_base: u32, deviation, extrusion: f32, format: i32, gmf: ^Glyph_Metrics_Float) -> Bool #foreign opengl32 "wglUseFontOutlines";
+124 -125
View File
@@ -3,28 +3,27 @@
#foreign_system_library "gdi32.lib" when ODIN_OS == "windows"; #foreign_system_library "gdi32.lib" when ODIN_OS == "windows";
#foreign_system_library "winmm.lib" when ODIN_OS == "windows"; #foreign_system_library "winmm.lib" when ODIN_OS == "windows";
HANDLE :: rawptr; Handle :: rawptr;
HWND :: HANDLE; Hwnd :: Handle;
HDC :: HANDLE; Hdc :: Handle;
HINSTANCE :: HANDLE; Hinstance :: Handle;
HICON :: HANDLE; Hicon :: Handle;
HCURSOR :: HANDLE; Hcursor :: Handle;
HMENU :: HANDLE; Hmenu :: Handle;
HBRUSH :: HANDLE; Hbrush :: Handle;
HGDIOBJ :: HANDLE; Hgdiobj :: Handle;
HMODULE :: HANDLE; Hmodule :: Handle;
WPARAM :: uint; Wparam :: uint;
LPARAM :: int; Lparam :: int;
LRESULT :: int; Lresult :: int;
ATOM :: i16; Bool :: i32;
BOOL :: i32; Wnd_Proc :: #type proc(Hwnd, u32, Wparam, Lparam) -> Lresult #cc_c;
WNDPROC :: #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; FALSE: Bool : 0;
TRUE: BOOL : 1; TRUE: Bool : 1;
CS_VREDRAW :: 0x0001; CS_VREDRAW :: 0x0001;
CS_HREDRAW :: 0x0002; CS_HREDRAW :: 0x0002;
@@ -56,7 +55,7 @@ WM_CHAR :: 0x0102;
PM_REMOVE :: 1; PM_REMOVE :: 1;
COLOR_BACKGROUND :: cast(HBRUSH)(cast(int)1); COLOR_BACKGROUND :: cast(Hbrush)(cast(int)1);
BLACK_BRUSH :: 4; BLACK_BRUSH :: 4;
SM_CXSCREEN :: 0; SM_CXSCREEN :: 0;
@@ -65,53 +64,53 @@ SM_CYSCREEN :: 1;
SW_SHOW :: 5; SW_SHOW :: 5;
POINT :: struct #ordered { Point :: struct #ordered {
x, y: i32, x, y: i32,
} }
WNDCLASSEXA :: struct #ordered { WndClassExA :: struct #ordered {
size, style: u32, size, style: u32,
wnd_proc: WNDPROC, wnd_proc: Wnd_Proc,
cls_extra, wnd_extra: i32, cls_extra, wnd_extra: i32,
instance: HINSTANCE, instance: Hinstance,
icon: HICON, icon: Hicon,
cursor: HCURSOR, cursor: Hcursor,
background: HBRUSH, background: Hbrush,
menu_name, class_name: ^u8, menu_name, class_name: ^u8,
sm: HICON, sm: Hicon,
} }
MSG :: struct #ordered { Msg :: struct #ordered {
hwnd: HWND, hwnd: Hwnd,
message: u32, message: u32,
wparam: WPARAM, wparam: Wparam,
lparam: LPARAM, lparam: Lparam,
time: u32, time: u32,
pt: POINT, pt: Point,
} }
RECT :: struct #ordered { Rect :: struct #ordered {
left: i32, left: i32,
top: i32, top: i32,
right: i32, right: i32,
bottom: i32, bottom: i32,
} }
FILETIME :: struct #ordered { Filetime :: struct #ordered {
lo, hi: u32, lo, hi: u32,
} }
SYSTEMTIME :: struct #ordered { Systemtime :: struct #ordered {
year, month: u16, year, month: u16,
day_of_week, day: u16, day_of_week, day: u16,
hour, minute, second, millisecond: u16, hour, minute, second, millisecond: u16,
} }
BY_HANDLE_FILE_INFORMATION :: struct #ordered { By_Handle_File_Information :: struct #ordered {
file_attributes: u32, file_attributes: u32,
creation_time, creation_time,
last_access_time, last_access_time,
last_write_time: FILETIME, last_write_time: Filetime,
volume_serial_number, volume_serial_number,
file_size_high, file_size_high,
file_size_low, file_size_low,
@@ -120,11 +119,11 @@ BY_HANDLE_FILE_INFORMATION :: struct #ordered {
file_index_low: u32, file_index_low: u32,
} }
FILE_ATTRIBUTE_DATA :: struct #ordered { File_Attribute_Data :: struct #ordered {
file_attributes: u32, file_attributes: u32,
creation_time, creation_time,
last_access_time, last_access_time,
last_write_time: FILETIME, last_write_time: Filetime,
file_size_high, file_size_high,
file_size_low: u32, file_size_low: u32,
} }
@@ -136,13 +135,13 @@ GetFileExMaxInfoLevel: GET_FILEEX_INFO_LEVELS : 1;
GetLastError :: proc() -> i32 #foreign kernel32; GetLastError :: proc() -> i32 #foreign kernel32;
ExitProcess :: proc(exit_code: u32) #foreign kernel32; ExitProcess :: proc(exit_code: u32) #foreign kernel32;
GetDesktopWindow :: proc() -> HWND #foreign user32; GetDesktopWindow :: proc() -> Hwnd #foreign user32;
GetCursorPos :: proc(p: ^POINT) -> i32 #foreign user32; GetCursorPos :: proc(p: ^Point) -> i32 #foreign user32;
ScreenToClient :: proc(h: HWND, p: ^POINT) -> i32 #foreign user32; ScreenToClient :: proc(h: Hwnd, p: ^Point) -> i32 #foreign user32;
GetModuleHandleA :: proc(module_name: ^u8) -> HINSTANCE #foreign kernel32; GetModuleHandleA :: proc(module_name: ^u8) -> Hinstance #foreign kernel32;
GetStockObject :: proc(fn_object: i32) -> HGDIOBJ #foreign gdi32; GetStockObject :: proc(fn_object: i32) -> Hgdiobj #foreign gdi32;
PostQuitMessage :: proc(exit_code: i32) #foreign user32; 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; QueryPerformanceFrequency :: proc(result: ^i64) -> i32 #foreign kernel32;
QueryPerformanceCounter :: 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; 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, CreateWindowExA :: proc(ex_style: u32,
class_name, title: ^u8, class_name, title: ^u8,
style: u32, style: u32,
x, y, w, h: i32, x, y, w, h: i32,
parent: HWND, menu: HMENU, instance: HINSTANCE, parent: Hwnd, menu: Hmenu, instance: Hinstance,
param: rawptr) -> HWND #foreign user32; param: rawptr) -> Hwnd #foreign user32;
ShowWindow :: proc(hwnd: HWND, cmd_show: i32) -> BOOL #foreign user32; ShowWindow :: proc(hwnd: Hwnd, cmd_show: i32) -> Bool #foreign user32;
TranslateMessage :: proc(msg: ^MSG) -> BOOL #foreign user32; TranslateMessage :: proc(msg: ^Msg) -> Bool #foreign user32;
DispatchMessageA :: proc(msg: ^MSG) -> LRESULT #foreign user32; DispatchMessageA :: proc(msg: ^Msg) -> Lresult #foreign user32;
UpdateWindow :: proc(hwnd: HWND) -> BOOL #foreign user32; UpdateWindow :: proc(hwnd: Hwnd) -> Bool #foreign user32;
PeekMessageA :: proc(msg: ^MSG, hwnd: HWND, PeekMessageA :: proc(msg: ^Msg, hwnd: Hwnd,
msg_filter_min, msg_filter_max, remove_msg: u32) -> BOOL #foreign user32; 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; AdjustWindowRect :: proc(rect: ^Rect, style: u32, menu: Bool) -> Bool #foreign user32;
GetActiveWindow :: proc() -> HWND #foreign user32; GetActiveWindow :: proc() -> Hwnd #foreign user32;
DestroyWindow :: proc(wnd: HWND) -> BOOL #foreign user32; DestroyWindow :: proc(wnd: Hwnd) -> Bool #foreign user32;
DescribePixelFormat :: proc(dc: HDC, pixel_format: i32, bytes : u32, pfd: ^PIXELFORMATDESCRIPTOR) -> i32 #foreign user32; DescribePixelFormat :: proc(dc: Hdc, pixel_format: i32, bytes : u32, pfd: ^PIXELFORMATDESCRIPTOR) -> i32 #foreign user32;
GetQueryPerformanceFrequency :: proc() -> i64 { GetQueryPerformanceFrequency :: proc() -> i64 {
@@ -187,29 +186,29 @@ GetSystemMetrics :: proc(index: i32) -> i32 #foreign kernel32;
GetCurrentThreadId :: proc() -> u32 #foreign kernel32; GetCurrentThreadId :: proc() -> u32 #foreign kernel32;
timeGetTime :: proc() -> u32 #foreign winmm; timeGetTime :: proc() -> u32 #foreign winmm;
GetSystemTimeAsFileTime :: proc(system_time_as_file_time: ^FILETIME) #foreign kernel32; GetSystemTimeAsFileTime :: proc(system_time_as_file_time: ^Filetime) #foreign kernel32;
FileTimeToLocalFileTime :: proc(file_time: ^FILETIME, local_file_time: ^FILETIME) -> BOOL #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; FileTimeToSystemTime :: proc(file_time: ^Filetime, system_time: ^Systemtime) -> Bool #foreign kernel32;
SystemTimeToFileTime :: proc(system_time: ^SYSTEMTIME, file_time: ^FILETIME) -> BOOL #foreign kernel32; SystemTimeToFileTime :: proc(system_time: ^Systemtime, file_time: ^Filetime) -> Bool #foreign kernel32;
// File Stuff // File Stuff
CloseHandle :: proc(h: HANDLE) -> i32 #foreign kernel32; CloseHandle :: proc(h: Handle) -> i32 #foreign kernel32;
GetStdHandle :: proc(h: i32) -> HANDLE #foreign kernel32; GetStdHandle :: proc(h: i32) -> Handle #foreign kernel32;
CreateFileA :: proc(filename: ^u8, desired_access, share_mode: u32, CreateFileA :: proc(filename: ^u8, desired_access, share_mode: u32,
security: rawptr, security: rawptr,
creation, flags_and_attribs: u32, template_file: HANDLE) -> HANDLE #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; 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; 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; 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; 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; GetFileInformationByHandle :: proc(file_handle: Handle, file_info: ^By_Handle_File_Information) -> Bool #foreign kernel32;
GetFileType :: proc(file_handle: HANDLE) -> 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; 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_INHERIT :: 1;
HANDLE_FLAG_PROTECT_FROM_CLOSE :: 2; HANDLE_FLAG_PROTECT_FROM_CLOSE :: 2;
@@ -242,13 +241,13 @@ TRUNCATE_EXISTING :: 5;
FILE_ATTRIBUTE_READONLY :: 0x00000001; FILE_ATTRIBUTE_READONLY :: 0x00000001;
FILE_ATTRIBUTE_HIDDEN :: 0x00000002; FILE_ATTRIBUTE_HIDDEN :: 0x00000002;
FILE_ATTRIBUTE_SYSTEM :: 0x00000004; FILE_ATTRIBUTE_SYSTEM :: 0x00000004;
FILE_ATTRIBUTE_DIRECTORY :: 0x00000010; FILE_ATTRIBUTE_DIRectORY :: 0x00000010;
FILE_ATTRIBUTE_ARCHIVE :: 0x00000020; FILE_ATTRIBUTE_ARCHIVE :: 0x00000020;
FILE_ATTRIBUTE_DEVICE :: 0x00000040; FILE_ATTRIBUTE_DEVICE :: 0x00000040;
FILE_ATTRIBUTE_NORMAL :: 0x00000080; FILE_ATTRIBUTE_NORMAL :: 0x00000080;
FILE_ATTRIBUTE_TEMPORARY :: 0x00000100; FILE_ATTRIBUTE_TEMPORARY :: 0x00000100;
FILE_ATTRIBUTE_SPARSE_FILE :: 0x00000200; FILE_ATTRIBUTE_SPARSE_FILE :: 0x00000200;
FILE_ATTRIBUTE_REPARSE_POINT :: 0x00000400; FILE_ATTRIBUTE_REPARSE_Point :: 0x00000400;
FILE_ATTRIBUTE_COMPRESSED :: 0x00000800; FILE_ATTRIBUTE_COMPRESSED :: 0x00000800;
FILE_ATTRIBUTE_OFFLINE :: 0x00001000; FILE_ATTRIBUTE_OFFLINE :: 0x00001000;
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED :: 0x00002000; 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; HeapAlloc :: proc (h: Handle, flags: u32, bytes: int) -> rawptr #foreign kernel32;
HeapReAlloc :: proc (h: HANDLE, flags: u32, memory: rawptr, 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; HeapFree :: proc (h: Handle, flags: u32, memory: rawptr) -> Bool #foreign kernel32;
GetProcessHeap :: proc () -> HANDLE #foreign kernel32; GetProcessHeap :: proc () -> Handle #foreign kernel32;
HEAP_ZERO_MEMORY :: 0x00000008; HEAP_ZERO_MEMORY :: 0x00000008;
// Synchronization // Synchronization
SECURITY_ATTRIBUTES :: struct #ordered { Security_Attributes :: struct #ordered {
length: u32, length: u32,
security_descriptor: rawptr, security_descriptor: rawptr,
inherit_handle: BOOL, inherit_handle: Bool,
} }
INFINITE :: 0xffffffff; INFINITE :: 0xffffffff;
CreateSemaphoreA :: proc(attributes: ^SECURITY_ATTRIBUTES, initial_count, maximum_count: i32, name: ^byte) -> HANDLE #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; ReleaseSemaphore :: proc(semaphore: Handle, release_count: i32, previous_count: ^i32) -> Bool #foreign kernel32;
WaitForSingleObject :: proc(handle: HANDLE, milliseconds: u32) -> u32 #foreign kernel32; WaitForSingleObject :: proc(handle: Handle, milliseconds: u32) -> u32 #foreign kernel32;
InterlockedCompareExchange :: proc(dst: ^i32, exchange, comparand: i32) -> i32 #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; GWL_STYLE :: -16;
HWND_TOP :: cast(HWND)cast(uint)0; Hwnd_TOP :: cast(Hwnd)cast(uint)0;
MONITOR_DEFAULTTONULL :: 0x00000000; MONITOR_DEFAULTTONULL :: 0x00000000;
MONITOR_DEFAULTTOPRIMARY :: 0x00000001; MONITOR_DEFAULTTOPRIMARY :: 0x00000001;
@@ -324,39 +323,39 @@ SWP_NOSIZE :: 0x0001;
SWP_NOMOVE :: 0x0002; SWP_NOMOVE :: 0x0002;
MONITORINFO :: struct #ordered { Monitor_Info :: struct #ordered {
size: u32, size: u32,
monitor: RECT, monitor: Rect,
work: RECT, work: Rect,
flags: u32, flags: u32,
} }
WINDOWPLACEMENT :: struct #ordered { Window_Placement :: struct #ordered {
length: u32, length: u32,
flags: u32, flags: u32,
show_cmd: u32, show_cmd: u32,
min_pos: POINT, min_pos: Point,
max_pos: POINT, max_pos: Point,
normal_pos: RECT, normal_pos: Rect,
} }
GetMonitorInfoA :: proc(monitor: HMONITOR, mi: ^MONITORINFO) -> BOOL #foreign user32; GetMonitorInfoA :: proc(monitor: Hmonitor, mi: ^Monitor_Info) -> Bool #foreign user32;
MonitorFromWindow :: proc(wnd: HWND, flags : u32) -> HMONITOR #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; GetWindowPlacement :: proc(wnd: Hwnd, wndpl: ^Window_Placement) -> Bool #foreign user32;
SetWindowPlacement :: proc(wnd: HWND, wndpl: ^WINDOWPLACEMENT) -> BOOL #foreign user32; SetWindowPlacement :: proc(wnd: Hwnd, wndpl: ^Window_Placement) -> Bool #foreign user32;
GetWindowLongPtrA :: proc(wnd: HWND, index: i32) -> i64 #foreign user32; GetWindowLongPtrA :: proc(wnd: Hwnd, index: i32) -> i64 #foreign user32;
SetWindowLongPtrA :: proc(wnd: HWND, index: i32, new: i64) -> 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(wParam: Wparam) -> u16 { return cast(u16)((cast(u32)wParam >> 16) & 0xffff); }
HIWORD :: proc(lParam: LPARAM) -> u16 { return cast(u16)((cast(u32)lParam >> 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(wParam: Wparam) -> u16 { return cast(u16)wParam; }
LOWORD :: proc(lParam: LPARAM) -> u16 { return cast(u16)lParam; } 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, size: u32,
width, height: i32, width, height: i32,
planes, bit_count: i16, planes, bit_count: i16,
@@ -378,33 +377,33 @@ BITMAPINFOHEADER :: struct #ordered {
clr_used: u32, clr_used: u32,
clr_important: u32, clr_important: u32,
} }
BITMAPINFO :: struct #ordered { Bitmap_Info :: struct #ordered {
using header: BITMAPINFOHEADER, using header: Bitmap_Info_Header,
colors: [1]RGBQUAD, colors: [1]Rgb_Quad,
} }
RGBQUAD :: struct #ordered { blue, green, red, reserved: byte } Rgb_Quad :: struct #ordered { blue, green, red, reserved: byte }
BI_RGB :: 0; BI_RGB :: 0;
DIB_RGB_COLORS :: 0x00; DIB_RGB_COLORS :: 0x00;
SRCCOPY: u32 : 0x00cc0020; SRCCOPY: u32 : 0x00cc0020;
StretchDIBits :: proc (hdc: HDC, StretchDIBits :: proc (hdc: Hdc,
x_dst, y_dst, width_dst, height_dst: i32, x_dst, y_dst, width_dst, height_dst: i32,
x_src, y_src, width_src, header_src: i32, x_src, y_src, width_src, header_src: i32,
bits: rawptr, bits_info: ^BITMAPINFO, bits: rawptr, bits_info: ^Bitmap_Info,
usage: u32, usage: u32,
rop: u32) -> i32 #foreign gdi32; rop: u32) -> i32 #foreign gdi32;
LoadLibraryA :: proc (c_str: ^u8) -> HMODULE #foreign kernel32; LoadLibraryA :: proc (c_str: ^u8) -> Hmodule #foreign kernel32;
FreeLibrary :: proc (h: HMODULE) #foreign kernel32; FreeLibrary :: proc (h: Hmodule) #foreign kernel32;
GetProcAddress :: proc (h: HMODULE, c_str: ^u8) -> PROC #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 // Windows OpenGL
PFD_TYPE_RGBA :: 0; PFD_TYPE_RGBA :: 0;
@@ -461,14 +460,14 @@ PIXELFORMATDESCRIPTOR :: struct #ordered {
damage_mask: u32, damage_mask: u32,
} }
GetDC :: proc(h: HWND) -> HDC #foreign user32; GetDC :: proc(h: Hwnd) -> Hdc #foreign user32;
SetPixelFormat :: proc(hdc: HDC, pixel_format: i32, pfd: ^PIXELFORMATDESCRIPTOR) -> BOOL #foreign gdi32; SetPixelFormat :: proc(hdc: Hdc, pixel_format: i32, pfd: ^PIXELFORMATDESCRIPTOR) -> Bool #foreign gdi32;
ChoosePixelFormat :: proc(hdc: HDC, pfd: ^PIXELFORMATDESCRIPTOR) -> i32 #foreign gdi32; ChoosePixelFormat :: proc(hdc: Hdc, pfd: ^PIXELFORMATDESCRIPTOR) -> i32 #foreign gdi32;
SwapBuffers :: proc(hdc: HDC) -> BOOL #foreign gdi32; SwapBuffers :: proc(hdc: Hdc) -> Bool #foreign gdi32;
ReleaseDC :: proc(wnd: HWND, hdc: HDC) -> i32 #foreign user32; 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; GetKeyState :: proc(v_key: i32) -> i16 #foreign user32;
@@ -611,7 +610,7 @@ Key_Code :: enum i32 {
RCONTROL = 0xA3, RCONTROL = 0xA3,
LMENU = 0xA4, LMENU = 0xA4,
RMENU = 0xA5, RMENU = 0xA5,
PROCESSKEY = 0xE5, ProcESSKEY = 0xE5,
ATTN = 0xF6, ATTN = 0xF6,
CRSEL = 0xF7, CRSEL = 0xF7,
EXSEL = 0xF8, EXSEL = 0xF8,
+53
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) { void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {
if (e->type != NULL) { if (e->type != NULL) {
return; return;
@@ -443,6 +493,9 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {
case Entity_Procedure: case Entity_Procedure:
check_proc_lit(c, e, d); check_proc_lit(c, e, d);
break; break;
case Entity_Alias:
check_alias_decl(c, e, d->init_expr);
break;
} }
c->context = prev; c->context = prev;
+30 -16
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); GB_ASSERT(n->kind == AstNode_Ident);
o->mode = Addressing_Invalid; o->mode = Addressing_Invalid;
o->expr = n; 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) { if (named_type != NULL) {
set_base_type(named_type, t_invalid); set_base_type(named_type, t_invalid);
} }
return; return NULL;
} }
bool is_overloaded = false; 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->type = t_invalid;
o->overload_count = overload_count; o->overload_count = overload_count;
o->overload_entities = procs; o->overload_entities = procs;
return; return NULL;
} }
gb_free(heap_allocator(), procs); 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) { if (e->type == NULL) {
compiler_error("Compiler error: How did this happen? type: %s; identifier: %.*s\n", type_to_string(e->type), LIT(name)); 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; Type *type = e->type;
switch (e->kind) { switch (e->kind) {
case Entity_Constant: case Entity_Constant:
if (type == t_invalid) { if (type == t_invalid) {
o->type = t_invalid; o->type = t_invalid;
return; return e;
} }
o->value = e->Constant.value; o->value = e->Constant.value;
if (o->value.kind == ExactValue_Invalid) { if (o->value.kind == ExactValue_Invalid) {
return; return e;
} }
o->mode = Addressing_Constant; o->mode = Addressing_Constant;
break; break;
@@ -1128,7 +1134,7 @@ void check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *typ
e->flags |= EntityFlag_Used; e->flags |= EntityFlag_Used;
if (type == t_invalid) { if (type == t_invalid) {
o->type = t_invalid; o->type = t_invalid;
return; return e;
} }
o->mode = Addressing_Variable; o->mode = Addressing_Variable;
if (e->Variable.is_immutable) { if (e->Variable.is_immutable) {
@@ -1151,22 +1157,25 @@ void check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *typ
break; break;
case Entity_ImportName: case Entity_ImportName:
error_node(n, "Use of import `%.*s` not in selector", LIT(e->ImportName.name)); if (!allow_import_name) {
return; error_node(n, "Use of import `%.*s` not in selector", LIT(name));
}
return e;
case Entity_LibraryName: case Entity_LibraryName:
error_node(n, "Use of library `%.*s` not in #foreign tag", LIT(e->LibraryName.name)); error_node(n, "Use of library `%.*s` not in #foreign tag", LIT(name));
return; return e;
case Entity_Nil: case Entity_Nil:
o->mode = Addressing_Value; o->mode = Addressing_Value;
break; break;
default: default:
compiler_error("Compiler error: Unknown EntityKind"); compiler_error("Unknown EntityKind");
break; break;
} }
o->type = type; o->type = type;
return e;
} }
i64 check_array_or_map_count(Checker *c, AstNode *e, bool is_map) { 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) { switch (e->kind) {
case_ast_node(i, Ident, e); case_ast_node(i, Ident, e);
Operand o = {0}; Operand o = {0};
check_ident(c, &o, e, named_type, NULL); check_ident(c, &o, e, named_type, NULL, false);
switch (o.mode) { switch (o.mode) {
case Addressing_Invalid: 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); add_entity_use(c, op_expr, e);
expr_entity = 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) { 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 // 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 // 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_end;
case_ast_node(i, Ident, node); 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_end;
case_ast_node(bl, BasicLit, node); case_ast_node(bl, BasicLit, node);
@@ -5626,7 +5640,7 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
case_end; case_end;
case_ast_node(ht, HelperType, node); 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); str = write_expr_to_string(str, ht->type);
case_end; case_end;
} }
+8 -3
View File
@@ -816,7 +816,7 @@ bool add_entity(Checker *c, Scope *scope, AstNode *identifier, Entity *entity) {
return false; return false;
} }
error(entity->token, 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)", "\tat %.*s(%td:%td)",
LIT(name), LIT(name),
LIT(up->token.pos.file), up->token.pos.line, up->token.pos.column); 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; return false;
} }
error(entity->token, error(entity->token,
"Redeclararation of `%.*s` in this scope\n" "Redeclaration of `%.*s` in this scope\n"
"\tat %.*s(%td:%td)", "\tat %.*s(%td:%td)",
LIT(name), LIT(name),
LIT(pos.file), pos.line, pos.column); 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? // TODO(bill): What if vd->type != NULL??? How to handle this case?
d->type_expr = init; d->type_expr = init;
d->init_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); e = make_entity_procedure(c->allocator, d->scope, name->Ident, NULL, up_init->ProcLit.tags);
d->proc_lit = up_init; d->proc_lit = up_init;
d->type_expr = vd->type; d->type_expr = vd->type;
+11
View File
@@ -13,6 +13,7 @@ typedef struct Type Type;
ENTITY_KIND(Builtin) \ ENTITY_KIND(Builtin) \
ENTITY_KIND(ImportName) \ ENTITY_KIND(ImportName) \
ENTITY_KIND(LibraryName) \ ENTITY_KIND(LibraryName) \
ENTITY_KIND(Alias) \
ENTITY_KIND(Nil) \ ENTITY_KIND(Nil) \
ENTITY_KIND(Count) ENTITY_KIND(Count)
@@ -95,6 +96,9 @@ struct Entity {
String name; String name;
bool used; bool used;
} LibraryName; } LibraryName;
struct {
Entity *original;
} Alias;
i32 Nil; i32 Nil;
}; };
}; };
@@ -218,6 +222,13 @@ Entity *make_entity_library_name(gbAllocator a, Scope *scope, Token token, Type
return entity; 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) { Entity *make_entity_nil(gbAllocator a, String name, Type *type) {
Token token = make_token_ident(name); Token token = make_token_ident(name);
Entity *entity = alloc_entity(a, Entity_Nil, NULL, token, type); Entity *entity = alloc_entity(a, Entity_Nil, NULL, token, type);
+4
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); 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)` // NOTE(bill): Very similar to doing `*cast(T *)(&u)`
#ifndef GB_BIT_CAST #ifndef GB_BIT_CAST
#define GB_BIT_CAST(dest, source) do { \ #define GB_BIT_CAST(dest, source) do { \
+22 -30
View File
@@ -2916,8 +2916,21 @@ irValue *ir_find_global_variable(irProcedure *proc, String name) {
void ir_build_stmt_list(irProcedure *proc, AstNodeArray stmts); 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); 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) { switch (expr->kind) {
case_ast_node(bl, BasicLit, expr); case_ast_node(bl, BasicLit, expr);
TokenPos pos = bl->pos; TokenPos pos = bl->pos;
@@ -3782,27 +3795,6 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
return NULL; 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) { irValue *ir_get_using_variable(irProcedure *proc, Entity *e) {
GB_ASSERT(e->kind == Entity_Variable && e->flags & EntityFlag_Anonymous); GB_ASSERT(e->kind == Entity_Variable && e->flags & EntityFlag_Anonymous);
String name = e->token.string; String name = e->token.string;
@@ -5192,9 +5184,9 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
if (fs->cond != NULL) { if (fs->cond != NULL) {
loop = ir_new_block(proc, node, "for.loop"); loop = ir_new_block(proc, node, "for.loop");
} }
irBlock *cont = loop; irBlock *post = loop;
if (fs->post != NULL) { 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_emit_jump(proc, loop);
ir_start_block(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_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_open_scope(proc);
ir_build_stmt(proc, fs->body); 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_pop_target_list(proc);
ir_emit_jump(proc, cont); ir_emit_jump(proc, post);
if (fs->post != NULL) { if (fs->post != NULL) {
ir_start_block(proc, cont); ir_start_block(proc, post);
ir_build_stmt(proc, fs->post); ir_build_stmt(proc, fs->post);
ir_emit_jump(proc, loop); ir_emit_jump(proc, loop);
} }
@@ -5646,7 +5638,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
case_end; case_end;
case_ast_node(pa, PushContext, node); case_ast_node(pc, PushContext, node);
ir_emit_comment(proc, str_lit("PushContext")); ir_emit_comment(proc, str_lit("PushContext"));
ir_open_scope(proc); 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_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); ir_close_scope(proc, irDeferExit_Default, NULL);
case_end; case_end;
+14
View File
@@ -139,6 +139,10 @@ AstNodeArray make_ast_node_array(AstFile *f) {
AstNodeArray elems; \ AstNodeArray elems; \
Token open, close; \ Token open, close; \
}) \ }) \
AST_NODE_KIND(Alias, "alias", struct { \
Token token; \
AstNode *expr; \
}) \
AST_NODE_KIND(_ExprBegin, "", i32) \ AST_NODE_KIND(_ExprBegin, "", i32) \
AST_NODE_KIND(BadExpr, "bad expression", struct { Token begin, end; }) \ AST_NODE_KIND(BadExpr, "bad expression", struct { Token begin, end; }) \
AST_NODE_KIND(TagExpr, "tag expression", struct { Token token, name; AstNode *expr; }) \ 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 ast_node_token(node->CompoundLit.type);
} }
return node->CompoundLit.open; return node->CompoundLit.open;
case AstNode_Alias: return node->Alias.token;
case AstNode_TagExpr: return node->TagExpr.token; case AstNode_TagExpr: return node->TagExpr.token;
case AstNode_RunExpr: return node->RunExpr.token; case AstNode_RunExpr: return node->RunExpr.token;
case AstNode_BadExpr: return node->BadExpr.begin; 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; result->CompoundLit.close = close;
return result; 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 *ast_ternary_expr(AstFile *f, AstNode *cond, AstNode *x, AstNode *y) {
AstNode *result = make_ast_node(f, AstNode_TernaryExpr); 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("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("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 (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 { } else {
operand = ast_tag_expr(f, token, name, parse_expr(f, false)); operand = ast_tag_expr(f, token, name, parse_expr(f, false));
} }
+1273 -300
View File
File diff suppressed because it is too large Load Diff