mirror of
https://github.com/odin-lang/Odin.git
synced 2026-01-08 14:03:14 +00:00
windows.odin TYPE_NAME to Type_Name; More SSA work and SSA printing for debugging
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#import "atomic.odin";
|
||||
|
||||
Semaphore :: struct {
|
||||
_handle: win32.HANDLE,
|
||||
_handle: win32.Handle,
|
||||
}
|
||||
|
||||
Mutex :: struct {
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -816,7 +816,7 @@ bool add_entity(Checker *c, Scope *scope, AstNode *identifier, Entity *entity) {
|
||||
return false;
|
||||
}
|
||||
error(entity->token,
|
||||
"Redeclararation of `%.*s` in this scope through `using`\n"
|
||||
"Redeclaration of `%.*s` in this scope through `using`\n"
|
||||
"\tat %.*s(%td:%td)",
|
||||
LIT(name),
|
||||
LIT(up->token.pos.file), up->token.pos.line, up->token.pos.column);
|
||||
@@ -827,7 +827,7 @@ bool add_entity(Checker *c, Scope *scope, AstNode *identifier, Entity *entity) {
|
||||
return false;
|
||||
}
|
||||
error(entity->token,
|
||||
"Redeclararation of `%.*s` in this scope\n"
|
||||
"Redeclaration of `%.*s` in this scope\n"
|
||||
"\tat %.*s(%td:%td)",
|
||||
LIT(name),
|
||||
LIT(pos.file), pos.line, pos.column);
|
||||
@@ -1467,7 +1467,12 @@ void check_collect_entities(Checker *c, AstNodeArray nodes, bool is_file_scope)
|
||||
// TODO(bill): What if vd->type != NULL??? How to handle this case?
|
||||
d->type_expr = init;
|
||||
d->init_expr = init;
|
||||
} else if (init != NULL && up_init->kind == AstNode_ProcLit) {
|
||||
} else if (up_init != NULL && up_init->kind == AstNode_Alias) {
|
||||
error_node(up_init, "#alias declarations are not yet supported");
|
||||
continue;
|
||||
// e = make_entity_alias(c->allocator, d->scope, name->Ident, NULL, NULL);
|
||||
// d->init_expr = init->Alias.expr;
|
||||
}else if (init != NULL && up_init->kind == AstNode_ProcLit) {
|
||||
e = make_entity_procedure(c->allocator, d->scope, name->Ident, NULL, up_init->ProcLit.tags);
|
||||
d->proc_lit = up_init;
|
||||
d->type_expr = vd->type;
|
||||
|
||||
11
src/entity.c
11
src/entity.c
@@ -13,6 +13,7 @@ typedef struct Type Type;
|
||||
ENTITY_KIND(Builtin) \
|
||||
ENTITY_KIND(ImportName) \
|
||||
ENTITY_KIND(LibraryName) \
|
||||
ENTITY_KIND(Alias) \
|
||||
ENTITY_KIND(Nil) \
|
||||
ENTITY_KIND(Count)
|
||||
|
||||
@@ -95,6 +96,9 @@ struct Entity {
|
||||
String name;
|
||||
bool used;
|
||||
} LibraryName;
|
||||
struct {
|
||||
Entity *original;
|
||||
} Alias;
|
||||
i32 Nil;
|
||||
};
|
||||
};
|
||||
@@ -218,6 +222,13 @@ Entity *make_entity_library_name(gbAllocator a, Scope *scope, Token token, Type
|
||||
return entity;
|
||||
}
|
||||
|
||||
Entity *make_entity_alias(gbAllocator a, Scope *scope, Token token, Type *type,
|
||||
Entity *original) {
|
||||
Entity *entity = alloc_entity(a, Entity_Alias, scope, token, type);
|
||||
entity->Alias.original = original;
|
||||
return entity;
|
||||
}
|
||||
|
||||
Entity *make_entity_nil(gbAllocator a, String name, Type *type) {
|
||||
Token token = make_token_ident(name);
|
||||
Entity *entity = alloc_entity(a, Entity_Nil, NULL, token, type);
|
||||
|
||||
@@ -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 { \
|
||||
|
||||
52
src/ir.c
52
src/ir.c
@@ -2916,8 +2916,21 @@ irValue *ir_find_global_variable(irProcedure *proc, String name) {
|
||||
|
||||
void ir_build_stmt_list(irProcedure *proc, AstNodeArray stmts);
|
||||
|
||||
irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv) {
|
||||
|
||||
irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
|
||||
expr = unparen_expr(expr);
|
||||
|
||||
TypeAndValue *tv = map_tav_get(&proc->module->info->types, hash_pointer(expr));
|
||||
GB_ASSERT_NOT_NULL(tv);
|
||||
|
||||
if (tv->value.kind != ExactValue_Invalid) {
|
||||
return ir_add_module_constant(proc->module, tv->type, tv->value);
|
||||
}
|
||||
|
||||
if (tv->mode == Addressing_Variable) {
|
||||
return ir_addr_load(proc, ir_build_addr(proc, expr));
|
||||
}
|
||||
|
||||
switch (expr->kind) {
|
||||
case_ast_node(bl, BasicLit, expr);
|
||||
TokenPos pos = bl->pos;
|
||||
@@ -3782,27 +3795,6 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
|
||||
expr = unparen_expr(expr);
|
||||
|
||||
TypeAndValue *tv = map_tav_get(&proc->module->info->types, hash_pointer(expr));
|
||||
GB_ASSERT_NOT_NULL(tv);
|
||||
|
||||
if (tv->value.kind != ExactValue_Invalid) {
|
||||
return ir_add_module_constant(proc->module, tv->type, tv->value);
|
||||
}
|
||||
|
||||
irValue *value = NULL;
|
||||
if (tv->mode == Addressing_Variable) {
|
||||
value = ir_addr_load(proc, ir_build_addr(proc, expr));
|
||||
} else {
|
||||
value = ir_build_single_expr(proc, expr, tv);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
irValue *ir_get_using_variable(irProcedure *proc, Entity *e) {
|
||||
GB_ASSERT(e->kind == Entity_Variable && e->flags & EntityFlag_Anonymous);
|
||||
String name = e->token.string;
|
||||
@@ -5192,9 +5184,9 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
if (fs->cond != NULL) {
|
||||
loop = ir_new_block(proc, node, "for.loop");
|
||||
}
|
||||
irBlock *cont = loop;
|
||||
irBlock *post = loop;
|
||||
if (fs->post != NULL) {
|
||||
cont = ir_new_block(proc, node, "for.post");
|
||||
post = ir_new_block(proc, node, "for.post");
|
||||
}
|
||||
ir_emit_jump(proc, loop);
|
||||
ir_start_block(proc, loop);
|
||||
@@ -5204,7 +5196,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
ir_start_block(proc, body);
|
||||
}
|
||||
|
||||
ir_push_target_list(proc, done, cont, NULL);
|
||||
ir_push_target_list(proc, done, post, NULL);
|
||||
|
||||
ir_open_scope(proc);
|
||||
ir_build_stmt(proc, fs->body);
|
||||
@@ -5212,10 +5204,10 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
|
||||
ir_pop_target_list(proc);
|
||||
|
||||
ir_emit_jump(proc, cont);
|
||||
ir_emit_jump(proc, post);
|
||||
|
||||
if (fs->post != NULL) {
|
||||
ir_start_block(proc, cont);
|
||||
ir_start_block(proc, post);
|
||||
ir_build_stmt(proc, fs->post);
|
||||
ir_emit_jump(proc, loop);
|
||||
}
|
||||
@@ -5646,7 +5638,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
case_end;
|
||||
|
||||
|
||||
case_ast_node(pa, PushContext, node);
|
||||
case_ast_node(pc, PushContext, node);
|
||||
ir_emit_comment(proc, str_lit("PushContext"));
|
||||
ir_open_scope(proc);
|
||||
|
||||
@@ -5656,9 +5648,9 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
|
||||
ir_add_defer_instr(proc, proc->scope_index, ir_instr_store(proc, context_ptr, ir_emit_load(proc, prev_context)));
|
||||
|
||||
ir_emit_store(proc, context_ptr, ir_build_expr(proc, pa->expr));
|
||||
ir_emit_store(proc, context_ptr, ir_build_expr(proc, pc->expr));
|
||||
|
||||
ir_build_stmt(proc, pa->body);
|
||||
ir_build_stmt(proc, pc->body);
|
||||
|
||||
ir_close_scope(proc, irDeferExit_Default, NULL);
|
||||
case_end;
|
||||
|
||||
14
src/parser.c
14
src/parser.c
@@ -139,6 +139,10 @@ AstNodeArray make_ast_node_array(AstFile *f) {
|
||||
AstNodeArray elems; \
|
||||
Token open, close; \
|
||||
}) \
|
||||
AST_NODE_KIND(Alias, "alias", struct { \
|
||||
Token token; \
|
||||
AstNode *expr; \
|
||||
}) \
|
||||
AST_NODE_KIND(_ExprBegin, "", i32) \
|
||||
AST_NODE_KIND(BadExpr, "bad expression", struct { Token begin, end; }) \
|
||||
AST_NODE_KIND(TagExpr, "tag expression", struct { Token token, name; AstNode *expr; }) \
|
||||
@@ -445,6 +449,8 @@ Token ast_node_token(AstNode *node) {
|
||||
return ast_node_token(node->CompoundLit.type);
|
||||
}
|
||||
return node->CompoundLit.open;
|
||||
case AstNode_Alias: return node->Alias.token;
|
||||
|
||||
case AstNode_TagExpr: return node->TagExpr.token;
|
||||
case AstNode_RunExpr: return node->RunExpr.token;
|
||||
case AstNode_BadExpr: return node->BadExpr.begin;
|
||||
@@ -771,6 +777,13 @@ AstNode *ast_compound_lit(AstFile *f, AstNode *type, AstNodeArray elems, Token o
|
||||
result->CompoundLit.close = close;
|
||||
return result;
|
||||
}
|
||||
AstNode *ast_alias(AstFile *f, Token token, AstNode *expr) {
|
||||
AstNode *result = make_ast_node(f, AstNode_Alias);
|
||||
result->Alias.token = token;
|
||||
result->Alias.expr = expr;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
AstNode *ast_ternary_expr(AstFile *f, AstNode *cond, AstNode *x, AstNode *y) {
|
||||
AstNode *result = make_ast_node(f, AstNode_TernaryExpr);
|
||||
@@ -1762,6 +1775,7 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
|
||||
} else if (str_eq(name.string, str_lit("line"))) { return ast_basic_directive(f, token, name.string);
|
||||
} else if (str_eq(name.string, str_lit("procedure"))) { return ast_basic_directive(f, token, name.string);
|
||||
} else if (str_eq(name.string, str_lit("type"))) { return ast_helper_type(f, token, parse_type(f));
|
||||
} else if (!lhs && str_eq(name.string, str_lit("alias"))) { return ast_alias(f, token, parse_expr(f, false));
|
||||
} else {
|
||||
operand = ast_tag_expr(f, token, name, parse_expr(f, false));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user