mirror of
https://github.com/odin-lang/Odin.git
synced 2026-04-18 20:40:28 +00:00
#alias type declarations; core library additions; _global import name for the global scope
This commit is contained in:
@@ -37,6 +37,13 @@ foreign __llvm_core {
|
||||
cos :: proc(θ: f32) -> f32 #link_name "llvm.cos.f32" ---;
|
||||
cos :: proc(θ: f64) -> f64 #link_name "llvm.cos.f64" ---;
|
||||
|
||||
// asin :: proc(x: f32) -> f32 #link_name "llvm.asin.f32" ---;
|
||||
// asin :: proc(x: f64) -> f64 #link_name "llvm.asin.f64" ---;
|
||||
|
||||
// acos :: proc(x: f32) -> f32 #link_name "llvm.acos.f32" ---;
|
||||
// acos :: proc(x: f64) -> f64 #link_name "llvm.acos.f64" ---;
|
||||
|
||||
|
||||
pow :: proc(x, power: f32) -> f32 #link_name "llvm.pow.f32" ---;
|
||||
pow :: proc(x, power: f64) -> f64 #link_name "llvm.pow.f64" ---;
|
||||
|
||||
@@ -47,9 +54,8 @@ foreign __llvm_core {
|
||||
tan :: proc(θ: f32) -> f32 #inline do return sin(θ)/cos(θ);
|
||||
tan :: proc(θ: f64) -> f64 #inline do return sin(θ)/cos(θ);
|
||||
|
||||
lerp :: proc(a, b: $T, t: $E) -> (x: T) do return a*(1-t) + b*t;
|
||||
|
||||
lerp :: proc(a, b, t: f32) -> (x: f32) do return a*(1-t) + b*t;
|
||||
lerp :: proc(a, b, t: f64) -> (x: f64) do return a*(1-t) + b*t;
|
||||
unlerp :: proc(a, b, x: f32) -> (t: f32) do return (x-a)/(b-a);
|
||||
unlerp :: proc(a, b, x: f64) -> (t: f64) do return (x-a)/(b-a);
|
||||
|
||||
|
||||
@@ -1381,3 +1381,27 @@ DEBUG_LOGGED_MESSAGES_ARB :: 0x9145;
|
||||
DEBUG_SEVERITY_HIGH_ARB :: 0x9146;
|
||||
DEBUG_SEVERITY_MEDIUM_ARB :: 0x9147;
|
||||
DEBUG_SEVERITY_LOW_ARB :: 0x9148;
|
||||
|
||||
|
||||
SHADER_BINARY_FORMAT_SPIR_V :: 0x9551;
|
||||
SPIR_V_BINARY :: 0x9552;
|
||||
PARAMETER_BUFFER :: 0x80EE;
|
||||
PARAMETER_BUFFER_BINDING :: 0x80EF;
|
||||
CONTEXT_FLAG_NO_ERROR_BIT :: 0x00000008;
|
||||
VERTICES_SUBMITTED :: 0x82EE;
|
||||
PRIMITIVES_SUBMITTED :: 0x82EF;
|
||||
VERTEX_SHADER_INVOCATIONS :: 0x82F0;
|
||||
TESS_CONTROL_SHADER_PATCHES :: 0x82F1;
|
||||
TESS_EVALUATION_SHADER_INVOCATIONS :: 0x82F2;
|
||||
GEOMETRY_SHADER_PRIMITIVES_EMITTED :: 0x82F3;
|
||||
FRAGMENT_SHADER_INVOCATIONS :: 0x82F4;
|
||||
COMPUTE_SHADER_INVOCATIONS :: 0x82F5;
|
||||
CLIPPING_INPUT_PRIMITIVES :: 0x82F6;
|
||||
CLIPPING_OUTPUT_PRIMITIVES :: 0x82F7;
|
||||
POLYGON_OFFSET_CLAMP :: 0x8E1B;
|
||||
SPIR_V_EXTENSIONS :: 0x9553;
|
||||
NUM_SPIR_V_EXTENSIONS :: 0x9554;
|
||||
TEXTURE_MAX_ANISOTROPY :: 0x84FE;
|
||||
MAX_TEXTURE_MAX_ANISOTROPY :: 0x84FF;
|
||||
TRANSFORM_FEEDBACK_OVERFLOW :: 0x82EC;
|
||||
TRANSFORM_FEEDBACK_STREAM_OVERFLOW :: 0x82ED;
|
||||
|
||||
14
core/os.odin
14
core/os.odin
@@ -2,6 +2,8 @@ when ODIN_OS == "windows" do export "core:os_windows.odin";
|
||||
when ODIN_OS == "osx" do export "core:os_x.odin";
|
||||
when ODIN_OS == "linux" do export "core:os_linux.odin";
|
||||
|
||||
import "mem.odin";
|
||||
|
||||
write_string :: proc(fd: Handle, str: string) -> (int, Errno) {
|
||||
return write(fd, cast([]u8)str);
|
||||
}
|
||||
@@ -35,8 +37,8 @@ read_entire_file :: proc(name: string) -> (data: []u8, success: bool) {
|
||||
return data[0..bytes_read], true;
|
||||
}
|
||||
|
||||
write_entire_file :: proc(name: string, data: []u8) -> (sucess: bool) {
|
||||
fd, err := open(name, O_WRONLY|O_CREAT, 0);
|
||||
write_entire_file :: proc(name: string, data: []u8) -> (success: bool) {
|
||||
fd, err := open(name, O_WRONLY|O_CREATE, 0);
|
||||
if err != 0 {
|
||||
return false;
|
||||
}
|
||||
@@ -45,3 +47,11 @@ write_entire_file :: proc(name: string, data: []u8) -> (sucess: bool) {
|
||||
bytes_written, write_err := write(fd, data);
|
||||
return write_err != 0;
|
||||
}
|
||||
|
||||
write :: proc(fd: Handle, data: rawptr, len: int) -> (int, Errno) {
|
||||
return write(fd, mem.slice_ptr(cast(^u8)data, len));
|
||||
}
|
||||
|
||||
read :: proc(fd: Handle, data: rawptr, len: int) -> (int, Errno) {
|
||||
return read(fd, mem.slice_ptr(cast(^u8)data, len));
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ Errno :: i32;
|
||||
O_RDONLY :: 0x00000;
|
||||
O_WRONLY :: 0x00001;
|
||||
O_RDWR :: 0x00002;
|
||||
O_CREAT :: 0x00040;
|
||||
O_CREATE :: 0x00040;
|
||||
O_EXCL :: 0x00080;
|
||||
O_NOCTTY :: 0x00100;
|
||||
O_TRUNC :: 0x00200;
|
||||
|
||||
@@ -12,7 +12,7 @@ INVALID_HANDLE: Handle : -1;
|
||||
O_RDONLY :: 0x00000;
|
||||
O_WRONLY :: 0x00001;
|
||||
O_RDWR :: 0x00002;
|
||||
O_CREAT :: 0x00040;
|
||||
O_CREATE :: 0x00040;
|
||||
O_EXCL :: 0x00080;
|
||||
O_NOCTTY :: 0x00100;
|
||||
O_TRUNC :: 0x00200;
|
||||
@@ -66,7 +66,7 @@ open :: proc(path: string, mode: int = O_RDONLY, perm: u32 = 0) -> (Handle, Errn
|
||||
case O_RDWR: access = win32.FILE_GENERIC_READ | win32.FILE_GENERIC_WRITE;
|
||||
}
|
||||
|
||||
if mode&O_CREAT != 0 {
|
||||
if mode&O_CREATE != 0 {
|
||||
access |= win32.FILE_GENERIC_WRITE;
|
||||
}
|
||||
if mode&O_APPEND != 0 {
|
||||
@@ -83,11 +83,11 @@ open :: proc(path: string, mode: int = O_RDONLY, perm: u32 = 0) -> (Handle, Errn
|
||||
|
||||
create_mode: u32;
|
||||
switch {
|
||||
case mode&(O_CREAT|O_EXCL) == (O_CREAT | O_EXCL):
|
||||
case mode&(O_CREATE|O_EXCL) == (O_CREATE | O_EXCL):
|
||||
create_mode = win32.CREATE_NEW;
|
||||
case mode&(O_CREAT|O_TRUNC) == (O_CREAT | O_TRUNC):
|
||||
case mode&(O_CREATE|O_TRUNC) == (O_CREATE | O_TRUNC):
|
||||
create_mode = win32.CREATE_ALWAYS;
|
||||
case mode&O_CREAT == O_CREAT:
|
||||
case mode&O_CREATE == O_CREATE:
|
||||
create_mode = win32.OPEN_ALWAYS;
|
||||
case mode&O_TRUNC == O_TRUNC:
|
||||
create_mode = win32.TRUNCATE_EXISTING;
|
||||
|
||||
@@ -12,7 +12,7 @@ Errno :: int;
|
||||
O_RDONLY :: 0x00000;
|
||||
O_WRONLY :: 0x00001;
|
||||
O_RDWR :: 0x00002;
|
||||
O_CREAT :: 0x00040;
|
||||
O_CREATE :: 0x00040;
|
||||
O_EXCL :: 0x00080;
|
||||
O_NOCTTY :: 0x00100;
|
||||
O_TRUNC :: 0x00200;
|
||||
|
||||
@@ -14,9 +14,9 @@ new_c_string :: proc(s: string) -> ^u8 {
|
||||
return &c[0];
|
||||
}
|
||||
|
||||
to_odin_string :: proc(c: ^u8) -> string {
|
||||
if c == nil do return "";
|
||||
len := 0;
|
||||
for (c+len)^ != 0 do len+=1;
|
||||
return string(mem.slice_ptr(c, len));
|
||||
to_odin_string :: proc(str: ^u8) -> string {
|
||||
if str == nil do return "";
|
||||
end := str;
|
||||
for end^ != 0 do end+=1;
|
||||
return string(mem.slice_ptr(str, end-str));
|
||||
}
|
||||
|
||||
@@ -17,11 +17,15 @@ Hbrush :: Handle;
|
||||
Hgdiobj :: Handle;
|
||||
Hmodule :: Handle;
|
||||
Hmonitor :: Handle;
|
||||
Hrawinput :: Handle;
|
||||
HKL :: Handle;
|
||||
Wparam :: uint;
|
||||
Lparam :: int;
|
||||
Lresult :: int;
|
||||
Wnd_Proc :: proc(Hwnd, u32, Wparam, Lparam) -> Lresult #cc_c;
|
||||
|
||||
Long_Ptr :: int;
|
||||
|
||||
Bool :: i32;
|
||||
FALSE: Bool : 0;
|
||||
TRUE: Bool : 1;
|
||||
@@ -42,6 +46,19 @@ Wnd_Class_Ex_A :: struct #ordered {
|
||||
sm: Hicon,
|
||||
}
|
||||
|
||||
Wnd_Class_Ex_W :: struct #ordered {
|
||||
size, style: u32,
|
||||
wnd_proc: Wnd_Proc,
|
||||
cls_extra, wnd_extra: i32,
|
||||
instance: Hinstance,
|
||||
icon: Hicon,
|
||||
cursor: Hcursor,
|
||||
background: Hbrush,
|
||||
menu_name, class_name: ^u16,
|
||||
sm: Hicon,
|
||||
}
|
||||
|
||||
|
||||
Msg :: struct #ordered {
|
||||
hwnd: Hwnd,
|
||||
message: u32,
|
||||
@@ -167,6 +184,59 @@ Critical_Section_Debug :: struct #ordered {
|
||||
List_Entry :: struct #ordered {flink, blink: ^List_Entry};
|
||||
|
||||
|
||||
Raw_Input_Device :: struct #ordered {
|
||||
usage_page: u16,
|
||||
usage: u16,
|
||||
flags: u32,
|
||||
wnd_target: Hwnd,
|
||||
}
|
||||
|
||||
Raw_Input_Header :: struct #ordered {
|
||||
kind: u32,
|
||||
size: u32,
|
||||
device: Handle,
|
||||
wparam: Wparam,
|
||||
}
|
||||
|
||||
Raw_HID :: struct #ordered {
|
||||
size_hid: u32,
|
||||
count: u32,
|
||||
raw_data: [1]u8,
|
||||
}
|
||||
|
||||
Raw_Keyboard :: struct #ordered {
|
||||
make_code: u16,
|
||||
flags: u16,
|
||||
reserved: u16,
|
||||
vkey: u16,
|
||||
message: u32,
|
||||
extra_information: u32,
|
||||
}
|
||||
|
||||
Raw_Mouse :: struct #ordered {
|
||||
flags: u16,
|
||||
using data: struct #raw_union {
|
||||
buttons: u32,
|
||||
using _: struct #ordered {
|
||||
button_flags: u16,
|
||||
button_data: u16,
|
||||
},
|
||||
},
|
||||
raw_buttons: u32,
|
||||
last_x: i32,
|
||||
last_y: i32,
|
||||
extra_information: u32,
|
||||
}
|
||||
|
||||
Raw_Input :: struct #ordered {
|
||||
using header: Raw_Input_Header,
|
||||
data: struct #raw_union {
|
||||
mouse: Raw_Mouse,
|
||||
keyboard: Raw_Keyboard,
|
||||
hid: Raw_HID,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
MAPVK_VK_TO_VSC :: 0;
|
||||
MAPVK_VSC_TO_VK :: 1;
|
||||
@@ -199,26 +269,30 @@ WS_BORDER :: 0x00800000;
|
||||
WS_CAPTION :: 0x00C00000;
|
||||
WS_VISIBLE :: 0x10000000;
|
||||
WS_POPUP :: 0x80000000;
|
||||
WS_MAXIMIZE :: 0x01000000;
|
||||
WS_MINIMIZE :: 0x20000000;
|
||||
WS_OVERLAPPEDWINDOW :: WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX;
|
||||
WS_POPUPWINDOW :: WS_POPUP | WS_BORDER | WS_SYSMENU;
|
||||
|
||||
WM_DESTROY :: 0x0002;
|
||||
WM_SIZE :: 0x0005;
|
||||
WM_CLOSE :: 0x0010;
|
||||
WM_ACTIVATE :: 0x0006;
|
||||
WM_ACTIVATEAPP :: 0x001C;
|
||||
WM_QUIT :: 0x0012;
|
||||
WM_CHAR :: 0x0102;
|
||||
WM_CLOSE :: 0x0010;
|
||||
WM_CREATE :: 0x0001;
|
||||
WM_DESTROY :: 0x0002;
|
||||
WM_INPUT :: 0x00ff;
|
||||
WM_KEYDOWN :: 0x0100;
|
||||
WM_KEYUP :: 0x0101;
|
||||
WM_KILLFOCUS :: 0x0008;
|
||||
WM_QUIT :: 0x0012;
|
||||
WM_SETCURSOR :: 0x0020;
|
||||
WM_SETFOCUS :: 0x0007;
|
||||
WM_SIZE :: 0x0005;
|
||||
WM_SIZING :: 0x0214;
|
||||
WM_SYSKEYDOWN :: 0x0104;
|
||||
WM_SYSKEYUP :: 0x0105;
|
||||
WM_WINDOWPOSCHANGED :: 0x0047;
|
||||
WM_SETCURSOR :: 0x0020;
|
||||
WM_CHAR :: 0x0102;
|
||||
WM_ACTIVATE :: 0x0006;
|
||||
WM_SETFOCUS :: 0x0007;
|
||||
WM_KILLFOCUS :: 0x0008;
|
||||
WM_USER :: 0x0400;
|
||||
WM_WINDOWPOSCHANGED :: 0x0047;
|
||||
|
||||
WM_MOUSEWHEEL :: 0x020A;
|
||||
WM_MOUSEMOVE :: 0x0200;
|
||||
@@ -248,7 +322,12 @@ COLOR_BACKGROUND :: Hbrush(int(1));
|
||||
INVALID_SET_FILE_POINTER :: ~u32(0);
|
||||
HEAP_ZERO_MEMORY :: 0x00000008;
|
||||
INFINITE :: 0xffffffff;
|
||||
GWL_EXSTYLE :: -20;
|
||||
GWLP_HINSTANCE :: -6;
|
||||
GWLP_ID :: -12;
|
||||
GWL_STYLE :: -16;
|
||||
GWLP_USERDATA :: -21;
|
||||
GWLP_WNDPROC :: -4;
|
||||
Hwnd_TOP :: Hwnd(uint(0));
|
||||
|
||||
BI_RGB :: 0;
|
||||
@@ -267,8 +346,63 @@ SWP_NOSIZE :: 0x0001;
|
||||
SWP_NOMOVE :: 0x0002;
|
||||
|
||||
|
||||
// Raw Input
|
||||
|
||||
|
||||
RID_HEADER :: 0x10000005;
|
||||
RID_INPUT :: 0x10000003;
|
||||
|
||||
|
||||
RIDEV_APPKEYS :: 0x00000400;
|
||||
RIDEV_CAPTUREMOUSE :: 0x00000200;
|
||||
RIDEV_DEVNOTIFY :: 0x00002000;
|
||||
RIDEV_EXCLUDE :: 0x00000010;
|
||||
RIDEV_EXINPUTSINK :: 0x00001000;
|
||||
RIDEV_INPUTSINK :: 0x00000100;
|
||||
RIDEV_NOHOTKEYS :: 0x00000200;
|
||||
RIDEV_NOLEGACY :: 0x00000030;
|
||||
RIDEV_PAGEONLY :: 0x00000020;
|
||||
RIDEV_REMOVE :: 0x00000001;
|
||||
|
||||
|
||||
RIM_TYPEMOUSE :: 0;
|
||||
RIM_TYPEKEYBOARD :: 1;
|
||||
RIM_TYPEHID :: 2;
|
||||
|
||||
|
||||
MOUSE_ATTRIBUTES_CHANGED :: 0x04;
|
||||
MOUSE_MOVE_RELATIVE :: 0;
|
||||
MOUSE_MOVE_ABSOLUTE :: 1;
|
||||
MOUSE_VIRTUAL_DESKTOP :: 0x02;
|
||||
|
||||
|
||||
|
||||
RI_MOUSE_BUTTON_1_DOWN :: 0x0001;
|
||||
RI_MOUSE_BUTTON_1_UP :: 0x0002;
|
||||
RI_MOUSE_BUTTON_2_DOWN :: 0x0004;
|
||||
RI_MOUSE_BUTTON_2_UP :: 0x0008;
|
||||
RI_MOUSE_BUTTON_3_DOWN :: 0x0010;
|
||||
RI_MOUSE_BUTTON_3_UP :: 0x0020;
|
||||
RI_MOUSE_BUTTON_4_DOWN :: 0x0040;
|
||||
RI_MOUSE_BUTTON_4_UP :: 0x0080;
|
||||
RI_MOUSE_BUTTON_5_DOWN :: 0x0100;
|
||||
RI_MOUSE_BUTTON_5_UP :: 0x0200;
|
||||
RI_MOUSE_LEFT_BUTTON_DOWN :: 0x0001;
|
||||
RI_MOUSE_LEFT_BUTTON_UP :: 0x0002;
|
||||
RI_MOUSE_MIDDLE_BUTTON_DOWN :: 0x0010;
|
||||
RI_MOUSE_MIDDLE_BUTTON_UP :: 0x0020;
|
||||
RI_MOUSE_RIGHT_BUTTON_DOWN :: 0x0004;
|
||||
RI_MOUSE_RIGHT_BUTTON_UP :: 0x0008;
|
||||
RI_MOUSE_WHEEL :: 0x0400;
|
||||
|
||||
|
||||
RI_KEY_MAKE :: 0x00;
|
||||
RI_KEY_BREAK :: 0x01;
|
||||
RI_KEY_E0 :: 0x02;
|
||||
RI_KEY_E1 :: 0x04;
|
||||
RI_KEY_TERMSRV_SET_LED :: 0x08;
|
||||
RI_KEY_TERMSRV_SHADOW :: 0x10;
|
||||
|
||||
// Windows OpenGL
|
||||
|
||||
PFD_TYPE_RGBA :: 0;
|
||||
@@ -302,6 +436,7 @@ foreign kernel32 {
|
||||
get_last_error :: proc() -> i32 #cc_std #link_name "GetLastError" ---;
|
||||
exit_process :: proc(exit_code: u32) #cc_std #link_name "ExitProcess" ---;
|
||||
get_module_handle_a :: proc(module_name: ^u8) -> Hinstance #cc_std #link_name "GetModuleHandleA" ---;
|
||||
get_module_handle_w :: proc(module_name: ^u16) -> Hinstance #cc_std #link_name "GetModuleHandleW" ---;
|
||||
sleep :: proc(ms: i32) -> i32 #cc_std #link_name "Sleep" ---;
|
||||
query_performance_frequency :: proc(result: ^i64) -> i32 #cc_std #link_name "QueryPerformanceFrequency" ---;
|
||||
query_performance_counter :: proc(result: ^i64) -> i32 #cc_std #link_name "QueryPerformanceCounter" ---;
|
||||
@@ -394,11 +529,14 @@ foreign kernel32 {
|
||||
foreign user32 {
|
||||
get_desktop_window :: proc() -> Hwnd #cc_std #link_name "GetDesktopWindow" ---;
|
||||
show_cursor :: proc(show : Bool) #cc_std #link_name "ShowCursor" ---;
|
||||
get_cursor_pos :: proc(p: ^Point) -> i32 #cc_std #link_name "GetCursorPos" ---;
|
||||
screen_to_client :: proc(h: Hwnd, p: ^Point) -> i32 #cc_std #link_name "ScreenToClient" ---;
|
||||
get_cursor_pos :: proc(p: ^Point) -> Bool #cc_std #link_name "GetCursorPos" ---;
|
||||
set_cursor_pos :: proc(x, y: i32) -> Bool #cc_std #link_name "SetCursorPos" ---;
|
||||
screen_to_client :: proc(h: Hwnd, p: ^Point) -> Bool #cc_std #link_name "ScreenToClient" ---;
|
||||
client_to_screen :: proc(h: Hwnd, p: ^Point) -> Bool #cc_std #link_name "ClientToScreen" ---;
|
||||
post_quit_message :: proc(exit_code: i32) #cc_std #link_name "PostQuitMessage" ---;
|
||||
set_window_text_a :: proc(hwnd: Hwnd, c_string: ^u8) -> Bool #cc_std #link_name "SetWindowTextA" ---;
|
||||
register_class_ex_a :: proc(wc: ^Wnd_Class_Ex_A) -> i16 #cc_std #link_name "RegisterClassExA" ---;
|
||||
register_class_ex_w :: proc(wc: ^Wnd_Class_Ex_W) -> i16 #cc_std #link_name "RegisterClassExW" ---;
|
||||
|
||||
create_window_ex_a :: proc(ex_style: u32,
|
||||
class_name, title: ^u8,
|
||||
@@ -407,13 +545,24 @@ foreign user32 {
|
||||
parent: Hwnd, menu: Hmenu, instance: Hinstance,
|
||||
param: rawptr) -> Hwnd #cc_std #link_name "CreateWindowExA" ---;
|
||||
|
||||
create_window_ex_w :: proc(ex_style: u32,
|
||||
class_name, title: ^u16,
|
||||
style: u32,
|
||||
x, y, w, h: i32,
|
||||
parent: Hwnd, menu: Hmenu, instance: Hinstance,
|
||||
param: rawptr) -> Hwnd #cc_std #link_name "CreateWindowExW" ---;
|
||||
|
||||
show_window :: proc(hwnd: Hwnd, cmd_show: i32) -> Bool #cc_std #link_name "ShowWindow" ---;
|
||||
translate_message :: proc(msg: ^Msg) -> Bool #cc_std #link_name "TranslateMessage" ---;
|
||||
dispatch_message_a :: proc(msg: ^Msg) -> Lresult #cc_std #link_name "DispatchMessageA" ---;
|
||||
dispatch_message_w :: proc(msg: ^Msg) -> Lresult #cc_std #link_name "DispatchMessageW" ---;
|
||||
update_window :: proc(hwnd: Hwnd) -> Bool #cc_std #link_name "UpdateWindow" ---;
|
||||
get_message_a :: proc(msg: ^Msg, hwnd: Hwnd, msg_filter_min, msg_filter_max : u32) -> Bool #cc_std #link_name "GetMessageA" ---;
|
||||
get_message_w :: proc(msg: ^Msg, hwnd: Hwnd, msg_filter_min, msg_filter_max : u32) -> Bool #cc_std #link_name "GetMessageW" ---;
|
||||
peek_message_a :: proc(msg: ^Msg, hwnd: Hwnd,
|
||||
msg_filter_min, msg_filter_max, remove_msg: u32) -> Bool #cc_std #link_name "PeekMessageA" ---;
|
||||
msg_filter_min, msg_filter_max, remove_msg: u32) -> Bool #cc_std #link_name "PeekMessageA" ---;
|
||||
peek_message_w :: proc(msg: ^Msg, hwnd: Hwnd,
|
||||
msg_filter_min, msg_filter_max, remove_msg: u32) -> Bool #cc_std #link_name "PeekMessageW" ---;
|
||||
|
||||
|
||||
post_message :: proc(hwnd: Hwnd, msg, wparam, lparam : u32) -> Bool #cc_std #link_name "PostMessageA" ---;
|
||||
@@ -435,8 +584,10 @@ foreign user32 {
|
||||
set_window_placement :: proc(wnd: Hwnd, wndpl: ^Window_Placement) -> Bool #cc_std #link_name "SetWindowPlacement" ---;
|
||||
get_window_rect :: proc(wnd: Hwnd, rect: ^Rect) -> Bool #cc_std #link_name "GetWindowRect" ---;
|
||||
|
||||
get_window_long_ptr_a :: proc(wnd: Hwnd, index: i32) -> i64 #cc_std #link_name "GetWindowLongPtrA" ---;
|
||||
set_window_long_ptr_a :: proc(wnd: Hwnd, index: i32, new: i64) -> i64 #cc_std #link_name "SetWindowLongPtrA" ---;
|
||||
get_window_long_ptr_a :: proc(wnd: Hwnd, index: i32) -> Long_Ptr #cc_std #link_name "GetWindowLongPtrA" ---;
|
||||
set_window_long_ptr_a :: proc(wnd: Hwnd, index: i32, new: Long_Ptr) -> Long_Ptr #cc_std #link_name "SetWindowLongPtrA" ---;
|
||||
get_window_long_ptr_w :: proc(wnd: Hwnd, index: i32) -> Long_Ptr #cc_std #link_name "GetWindowLongPtrW" ---;
|
||||
set_window_long_ptr_w :: proc(wnd: Hwnd, index: i32, new: Long_Ptr) -> Long_Ptr #cc_std #link_name "SetWindowLongPtrW" ---;
|
||||
|
||||
get_window_text :: proc(wnd: Hwnd, str: ^u8, maxCount: i32) -> i32 #cc_std #link_name "GetWindowText" ---;
|
||||
|
||||
@@ -445,10 +596,23 @@ foreign user32 {
|
||||
get_dc :: proc(h: Hwnd) -> Hdc #cc_std #link_name "GetDC" ---;
|
||||
release_dc :: proc(wnd: Hwnd, hdc: Hdc) -> i32 #cc_std #link_name "ReleaseDC" ---;
|
||||
|
||||
map_virtual_key :: proc(scancode : u32, map_type : u32) -> u32 #cc_std #link_name "MapVirtualKeyA" ---;
|
||||
map_virtual_key_a :: proc(scancode : u32, map_type : u32) -> u32 #cc_std #link_name "MapVirtualKeyA" ---;
|
||||
map_virtual_key_w :: proc(scancode : u32, map_type : u32) -> u32 #cc_std #link_name "MapVirtualKeyW" ---;
|
||||
|
||||
get_key_state :: proc(v_key: i32) -> i16 #cc_std #link_name "GetKeyState" ---;
|
||||
get_async_key_state :: proc(v_key: i32) -> i16 #cc_std #link_name "GetAsyncKeyState" ---;
|
||||
|
||||
set_foreground_window :: proc(h: Hwnd) -> Bool #cc_std #link_name "SetForegroundWindow" ---;
|
||||
set_focus :: proc(h: Hwnd) -> Hwnd #cc_std #link_name "SetFocus" ---;
|
||||
|
||||
|
||||
|
||||
register_raw_input_devices :: proc(raw_input_device: ^Raw_Input_Device, num_devices, size: u32) -> Bool #cc_std #link_name "RegisterRawInputDevices" ---;
|
||||
|
||||
get_raw_input_data :: proc(raw_input: Hrawinput, command: u32, data: rawptr, size: ^u32, size_header: u32) -> u32 #cc_std #link_name "GetRawInputData" ---;
|
||||
|
||||
map_virtual_key_ex_w :: proc(code, map_type: u32, hkl: HKL) #cc_std #link_name "MapVirtualKeyExW" ---;
|
||||
map_virtual_key_ex_a :: proc(code, map_type: u32, hkl: HKL) #cc_std #link_name "MapVirtualKeyExA" ---;
|
||||
}
|
||||
|
||||
foreign gdi32 {
|
||||
@@ -493,7 +657,6 @@ is_key_down :: proc(key: Key_Code) -> bool #inline { return get_async_key_state(
|
||||
|
||||
|
||||
|
||||
|
||||
MAX_PATH :: 0x00000104;
|
||||
|
||||
HANDLE_FLAG_INHERIT :: 1;
|
||||
@@ -582,10 +745,14 @@ Rgb_Quad :: struct #ordered {blue, green, red, reserved: u8}
|
||||
|
||||
|
||||
Key_Code :: enum i32 {
|
||||
Unknown = 0x00,
|
||||
|
||||
Lbutton = 0x01,
|
||||
Rbutton = 0x02,
|
||||
Cancel = 0x03,
|
||||
Mbutton = 0x04,
|
||||
Xbutton1 = 0x05,
|
||||
Xbutton2 = 0x06,
|
||||
Back = 0x08,
|
||||
Tab = 0x09,
|
||||
Clear = 0x0C,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import "utf8.odin"
|
||||
|
||||
REPLACEMENT_CHAR :: '\uFFFD';
|
||||
MAX_RUNE :: '\U0010FFFF';
|
||||
|
||||
@@ -27,7 +29,7 @@ encode_surrogate_pair :: proc(r: rune) -> (r1, r2: rune) {
|
||||
return _surr1 + (r>>10)&0x3ff, _surr2 + r&0x3ff;
|
||||
}
|
||||
|
||||
encode :: proc(d: []u16, s: []rune) {
|
||||
encode :: proc(d: []u16, s: []rune) -> int {
|
||||
n := len(s);
|
||||
for r in s do if r >= _surr_self do n += 1;
|
||||
|
||||
@@ -51,4 +53,33 @@ encode :: proc(d: []u16, s: []rune) {
|
||||
n += 1;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
encode :: proc(d: []u16, s: string) -> int {
|
||||
n := utf8.rune_count(s);
|
||||
for r in s do if r >= _surr_self do n += 1;
|
||||
|
||||
max_n := min(len(d), n);
|
||||
n = 0;
|
||||
|
||||
for r in s {
|
||||
switch r {
|
||||
case 0.._surr1, _surr3.._surr_self:
|
||||
d[n] = u16(r);
|
||||
n += 1;
|
||||
|
||||
case _surr_self..MAX_RUNE:
|
||||
r1, r2 := encode_surrogate_pair(r);
|
||||
d[n] = u16(r1);
|
||||
d[n+1] = u16(r2);
|
||||
n += 2;
|
||||
|
||||
case:
|
||||
d[n] = u16(REPLACEMENT_CHAR);
|
||||
n += 1;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -170,8 +170,26 @@ void check_init_constant(Checker *c, Entity *e, Operand *operand) {
|
||||
e->Constant.value = operand->value;
|
||||
}
|
||||
|
||||
void check_type_decl(Checker *c, Entity *e, AstNode *type_expr, Type *def) {
|
||||
AstNode *remove_type_alias(AstNode *node) {
|
||||
for (;;) {
|
||||
if (node == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
if (node->kind == AstNode_ParenExpr) {
|
||||
node = node->ParenExpr.expr;
|
||||
} else if (node->kind == AstNode_AliasType) {
|
||||
node = node->AliasType.type;
|
||||
} else {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void check_type_decl(Checker *c, Entity *e, AstNode *type_expr, Type *def, bool is_alias) {
|
||||
GB_ASSERT(e->type == nullptr);
|
||||
AstNode *te = remove_type_alias(type_expr);
|
||||
|
||||
e->type = t_invalid;
|
||||
String name = e->token.string;
|
||||
Type *named = make_type_named(c->allocator, name, nullptr, e);
|
||||
named->Named.type_name = e;
|
||||
@@ -180,12 +198,14 @@ void check_type_decl(Checker *c, Entity *e, AstNode *type_expr, Type *def) {
|
||||
}
|
||||
e->type = named;
|
||||
|
||||
// gb_printf_err("%.*s %p\n", LIT(e->token.string), e);
|
||||
|
||||
Type *bt = check_type(c, type_expr, named);
|
||||
Type *bt = check_type(c, te, named);
|
||||
named->Named.base = base_type(bt);
|
||||
if (named->Named.base == t_invalid) {
|
||||
// gb_printf("check_type_decl: %s\n", type_to_string(named));
|
||||
if (is_alias) {
|
||||
if (is_type_named(bt)) {
|
||||
e->type = bt;
|
||||
} else {
|
||||
warning(type_expr, "Type declaration will not be an alias type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,7 +252,7 @@ void check_const_decl(Checker *c, Entity *e, AstNode *type_expr, AstNode *init,
|
||||
error(e->token, "A type declaration cannot have an type parameter");
|
||||
}
|
||||
d->type_expr = d->init_expr;
|
||||
check_type_decl(c, e, d->type_expr, named_type);
|
||||
check_type_decl(c, e, d->type_expr, named_type, false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -673,7 +693,7 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {
|
||||
check_const_decl(c, e, d->type_expr, d->init_expr, named_type);
|
||||
break;
|
||||
case Entity_TypeName:
|
||||
check_type_decl(c, e, d->type_expr, named_type);
|
||||
check_type_decl(c, e, d->type_expr, named_type, d->type_expr->kind == AstNode_AliasType);
|
||||
break;
|
||||
case Entity_Procedure:
|
||||
check_proc_decl(c, e, d);
|
||||
|
||||
@@ -57,7 +57,7 @@ ExprKind check_expr_base (Checker *c, Operand *operand, AstNode *
|
||||
void check_expr_with_type_hint (Checker *c, Operand *o, AstNode *e, Type *t);
|
||||
Type * check_type (Checker *c, AstNode *expression, Type *named_type = nullptr);
|
||||
Type * make_optional_ok_type(gbAllocator a, Type *value);
|
||||
void check_type_decl (Checker *c, Entity *e, AstNode *type_expr, Type *def);
|
||||
void check_type_decl (Checker *c, Entity *e, AstNode *type_expr, Type *def, bool alias);
|
||||
Entity * check_selector (Checker *c, Operand *operand, AstNode *node, Type *type_hint);
|
||||
Entity * check_ident (Checker *c, Operand *o, AstNode *n, Type *named_type, Type *type_hint, bool allow_import_name);
|
||||
Entity * find_polymorphic_struct_entity(Checker *c, Type *original_type, isize param_count, Array<Operand> ordered_operands);
|
||||
@@ -1421,6 +1421,14 @@ void check_unary_expr(Checker *c, Operand *o, Token op, AstNode *node) {
|
||||
if (is_type_unsigned(type)) {
|
||||
precision = cast(i32)(8 * type_size_of(c->allocator, type));
|
||||
}
|
||||
if (op.kind == Token_Xor && is_type_untyped(type)) {
|
||||
gbString err_str = expr_to_string(node);
|
||||
error(op, "Bitwise not cannot be applied to untyped constants `%s`", err_str);
|
||||
gb_string_free(err_str);
|
||||
o->mode = Addressing_Invalid;
|
||||
return;
|
||||
}
|
||||
|
||||
o->value = exact_unary_operator_value(op.kind, o->value, precision);
|
||||
|
||||
if (is_type_typed(type)) {
|
||||
@@ -5353,7 +5361,7 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
|
||||
for_array(i, cl->elems) {
|
||||
AstNode *elem = cl->elems[i];
|
||||
if (elem->kind != AstNode_FieldValue) {
|
||||
error(elem, "Mixture of `field = value` and value elements in a structure literal is not allowed");
|
||||
error(elem, "Mixture of `field = value` and value elements in a literal is not allowed");
|
||||
continue;
|
||||
}
|
||||
ast_node(fv, FieldValue, elem);
|
||||
@@ -5416,7 +5424,7 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
|
||||
for_array(index, cl->elems) {
|
||||
AstNode *elem = cl->elems[index];
|
||||
if (elem->kind == AstNode_FieldValue) {
|
||||
error(elem, "Mixture of `field = value` and value elements in a structure literal is not allowed");
|
||||
error(elem, "Mixture of `field = value` and value elements in a literal is not allowed");
|
||||
continue;
|
||||
}
|
||||
if (index >= field_count) {
|
||||
@@ -6316,6 +6324,11 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
|
||||
str = write_expr_to_string(str, ht->type);
|
||||
case_end;
|
||||
|
||||
case_ast_node(ht, AliasType, node);
|
||||
str = gb_string_appendc(str, "#alias ");
|
||||
str = write_expr_to_string(str, ht->type);
|
||||
case_end;
|
||||
|
||||
|
||||
case_ast_node(pt, PolyType, node);
|
||||
str = gb_string_append_rune(str, '$');
|
||||
|
||||
@@ -2131,6 +2131,12 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
|
||||
return check_type_internal(c, ht->type, type, named_type);
|
||||
case_end;
|
||||
|
||||
case_ast_node(at, AliasType, e);
|
||||
error(e, "Invalid use of `#alias`");
|
||||
// NOTE(bill): Treat it as a HelperType to remove errors
|
||||
return check_type_internal(c, at->type, type, named_type);
|
||||
case_end;
|
||||
|
||||
case_ast_node(pt, PolyType, e);
|
||||
AstNode *ident = pt->type;
|
||||
if (ident->kind != AstNode_Ident) {
|
||||
|
||||
@@ -1716,7 +1716,19 @@ void init_preload(Checker *c) {
|
||||
t_map_header = e->type;
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
String _global = str_lit("_global");
|
||||
|
||||
Entity *e = make_entity_import_name(c->allocator, c->global_scope->parent, make_token_ident(_global), t_invalid,
|
||||
str_lit(""), _global,
|
||||
c->global_scope);
|
||||
|
||||
add_entity(c, c->global_scope, nullptr, e);
|
||||
}
|
||||
|
||||
c->done_preload = true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -156,6 +156,7 @@ bool is_entity_exported(Entity *e) {
|
||||
return name[0] != '_';
|
||||
}
|
||||
|
||||
|
||||
gb_global u64 global_entity_id = 0;
|
||||
|
||||
Entity *alloc_entity(gbAllocator a, EntityKind kind, Scope *scope, Token token, Type *type) {
|
||||
|
||||
@@ -7954,7 +7954,7 @@ gbFileTime gb_file_last_write_time(char const *filepath) {
|
||||
time_t result = 0;
|
||||
struct stat file_stat;
|
||||
|
||||
if (stat(filepath, &file_stat)) {
|
||||
if (stat(filepath, &file_stat) == 0) {
|
||||
result = file_stat.st_mtime;
|
||||
}
|
||||
|
||||
|
||||
10
src/ir.cpp
10
src/ir.cpp
@@ -119,6 +119,7 @@ struct irProcedure {
|
||||
u64 tags;
|
||||
bool is_foreign;
|
||||
bool is_export;
|
||||
bool is_entry_point;
|
||||
|
||||
irValue * return_ptr;
|
||||
Array<irValue *> params;
|
||||
@@ -3743,6 +3744,12 @@ void ir_check_type_and_gen_for_proc_lit(irModule *m, String prefix_name, Type *t
|
||||
void ir_gen_global_type_name(irModule *m, Entity *e, String name) {
|
||||
if (e->type == nullptr) return;
|
||||
|
||||
if (e->kind == Entity_TypeName && e->type->kind == Type_Named) {
|
||||
if (e != e->type->Named.type_name) {
|
||||
// NOTE(bill): Is alias
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Type *bt = base_type(e->type);
|
||||
|
||||
@@ -8267,7 +8274,6 @@ void ir_gen_tree(irGen *s) {
|
||||
|
||||
switch (e->kind) {
|
||||
case Entity_TypeName:
|
||||
GB_ASSERT(e->type->kind == Type_Named);
|
||||
ir_gen_global_type_name(m, e, name);
|
||||
break;
|
||||
|
||||
@@ -8374,6 +8380,7 @@ void ir_gen_tree(irGen *s) {
|
||||
|
||||
irProcedure *proc = &p->Proc;
|
||||
proc->tags = ProcTag_no_inline; // TODO(bill): is no_inline a good idea?
|
||||
proc->is_entry_point = true;
|
||||
e->Procedure.link_name = name;
|
||||
|
||||
ir_begin_procedure_body(proc);
|
||||
@@ -8444,6 +8451,7 @@ void ir_gen_tree(irGen *s) {
|
||||
|
||||
irProcedure *proc = &p->Proc;
|
||||
proc->tags = ProcTag_no_inline; // TODO(bill): is no_inline a good idea?
|
||||
proc->is_entry_point = true;
|
||||
e->Procedure.link_name = name;
|
||||
|
||||
ir_begin_procedure_body(proc);
|
||||
|
||||
@@ -1678,6 +1678,9 @@ void ir_print_proc(irFileBuffer *f, irModule *m, irProcedure *proc) {
|
||||
ir_write_string(f, "dllexport ");
|
||||
}
|
||||
}
|
||||
// if (!proc->is_export && !proc->is_foreign && !proc->is_entry_point) {
|
||||
// ir_write_string(f, "internal ");
|
||||
// }
|
||||
}
|
||||
|
||||
TypeProc *proc_type = &proc->type->Proc;
|
||||
|
||||
@@ -407,6 +407,10 @@ AST_NODE_KIND(_TypeBegin, "", i32) \
|
||||
Token token; \
|
||||
AstNode *type; \
|
||||
}) \
|
||||
AST_NODE_KIND(AliasType, "alias type", struct { \
|
||||
Token token; \
|
||||
AstNode *type; \
|
||||
}) \
|
||||
AST_NODE_KIND(PolyType, "polymorphic type", struct { \
|
||||
Token token; \
|
||||
AstNode *type; \
|
||||
@@ -611,6 +615,7 @@ Token ast_node_token(AstNode *node) {
|
||||
|
||||
case AstNode_TypeType: return node->TypeType.token;
|
||||
case AstNode_HelperType: return node->HelperType.token;
|
||||
case AstNode_AliasType: return node->AliasType.token;
|
||||
case AstNode_PolyType: return node->PolyType.token;
|
||||
case AstNode_ProcType: return node->ProcType.token;
|
||||
case AstNode_PointerType: return node->PointerType.token;
|
||||
@@ -857,6 +862,9 @@ AstNode *clone_ast_node(gbAllocator a, AstNode *node) {
|
||||
case AstNode_HelperType:
|
||||
n->HelperType.type = clone_ast_node(a, n->HelperType.type);
|
||||
break;
|
||||
case AstNode_AliasType:
|
||||
n->AliasType.type = clone_ast_node(a, n->AliasType.type);
|
||||
break;
|
||||
case AstNode_ProcType:
|
||||
n->ProcType.params = clone_ast_node(a, n->ProcType.params);
|
||||
n->ProcType.results = clone_ast_node(a, n->ProcType.results);
|
||||
@@ -1411,6 +1419,13 @@ AstNode *ast_helper_type(AstFile *f, Token token, AstNode *type) {
|
||||
return result;
|
||||
}
|
||||
|
||||
AstNode *ast_alias_type(AstFile *f, Token token, AstNode *type) {
|
||||
AstNode *result = make_ast_node(f, AstNode_AliasType);
|
||||
result->AliasType.token = token;
|
||||
result->AliasType.type = type;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
AstNode *ast_poly_type(AstFile *f, Token token, AstNode *type, AstNode *specialization) {
|
||||
AstNode *result = make_ast_node(f, AstNode_PolyType);
|
||||
@@ -2256,8 +2271,10 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
|
||||
if (allow_token(f, Token_type)) {
|
||||
return ast_helper_type(f, token, parse_type(f));
|
||||
}
|
||||
Token name = expect_token(f, Token_Ident);
|
||||
if (name.string == "run") {
|
||||
Token name = expect_token(f, Token_Ident);
|
||||
if (name.string == "alias") {
|
||||
return ast_alias_type(f, token, parse_type(f));
|
||||
} else if (name.string == "run") {
|
||||
AstNode *expr = parse_expr(f, false);
|
||||
operand = ast_run_expr(f, token, name, expr);
|
||||
if (unparen_expr(expr)->kind != AstNode_CallExpr) {
|
||||
|
||||
Reference in New Issue
Block a user