mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 15:18:49 +00:00
Fix pointer differences (issue #11); remove #dll_import
This commit is contained in:
+18
-1
@@ -11,6 +11,22 @@
|
|||||||
|
|
||||||
|
|
||||||
main :: proc() {
|
main :: proc() {
|
||||||
|
b : [1000]byte;
|
||||||
|
|
||||||
|
using fmt;
|
||||||
|
|
||||||
|
println();
|
||||||
|
println("Pointer of Address 0");
|
||||||
|
println(^b[0]);
|
||||||
|
println();
|
||||||
|
println("Pointer of Address 50");
|
||||||
|
println(^b[50]);
|
||||||
|
println();
|
||||||
|
println("Difference between 50 and 0");
|
||||||
|
println(^b[50] - ^b[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
foo :: proc(x: ^i32) -> (int, int) {
|
foo :: proc(x: ^i32) -> (int, int) {
|
||||||
fmt.println("^int");
|
fmt.println("^int");
|
||||||
return 123, cast(int)(x^);
|
return 123, cast(int)(x^);
|
||||||
@@ -22,7 +38,7 @@ main :: proc() {
|
|||||||
THINGI :: 14451;
|
THINGI :: 14451;
|
||||||
THINGF :: 14451.1;
|
THINGF :: 14451.1;
|
||||||
|
|
||||||
a: i32 = 111111;
|
a: i32 = #line;
|
||||||
b: f32;
|
b: f32;
|
||||||
c: rawptr;
|
c: rawptr;
|
||||||
fmt.println(foo(^a));
|
fmt.println(foo(^a));
|
||||||
@@ -53,3 +69,4 @@ main :: proc() {
|
|||||||
f = foo;
|
f = foo;
|
||||||
f();
|
f();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|||||||
@@ -265,7 +265,7 @@ exit :: proc(code: int) {
|
|||||||
|
|
||||||
|
|
||||||
current_thread_id :: proc() -> int {
|
current_thread_id :: proc() -> int {
|
||||||
GetCurrentThreadId :: proc() -> u32 #foreign #dll_import
|
GetCurrentThreadId :: proc() -> u32 #foreign
|
||||||
return cast(int)GetCurrentThreadId();
|
return cast(int)GetCurrentThreadId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+67
-55
@@ -91,6 +91,12 @@ FILETIME :: struct #ordered {
|
|||||||
lo, hi: u32,
|
lo, hi: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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,
|
file_attributes: u32,
|
||||||
creation_time,
|
creation_time,
|
||||||
@@ -118,43 +124,43 @@ GET_FILEEX_INFO_LEVELS :: i32;
|
|||||||
GetFileExInfoStandard: GET_FILEEX_INFO_LEVELS : 0;
|
GetFileExInfoStandard: GET_FILEEX_INFO_LEVELS : 0;
|
||||||
GetFileExMaxInfoLevel: GET_FILEEX_INFO_LEVELS : 1;
|
GetFileExMaxInfoLevel: GET_FILEEX_INFO_LEVELS : 1;
|
||||||
|
|
||||||
GetLastError :: proc() -> i32 #foreign #dll_import
|
GetLastError :: proc() -> i32 #foreign
|
||||||
ExitProcess :: proc(exit_code: u32) #foreign #dll_import
|
ExitProcess :: proc(exit_code: u32) #foreign
|
||||||
GetDesktopWindow :: proc() -> HWND #foreign #dll_import
|
GetDesktopWindow :: proc() -> HWND #foreign
|
||||||
GetCursorPos :: proc(p: ^POINT) -> i32 #foreign #dll_import
|
GetCursorPos :: proc(p: ^POINT) -> i32 #foreign
|
||||||
ScreenToClient :: proc(h: HWND, p: ^POINT) -> i32 #foreign #dll_import
|
ScreenToClient :: proc(h: HWND, p: ^POINT) -> i32 #foreign
|
||||||
GetModuleHandleA :: proc(module_name: ^u8) -> HINSTANCE #foreign #dll_import
|
GetModuleHandleA :: proc(module_name: ^u8) -> HINSTANCE #foreign
|
||||||
GetStockObject :: proc(fn_object: i32) -> HGDIOBJ #foreign #dll_import
|
GetStockObject :: proc(fn_object: i32) -> HGDIOBJ #foreign
|
||||||
PostQuitMessage :: proc(exit_code: i32) #foreign #dll_import
|
PostQuitMessage :: proc(exit_code: i32) #foreign
|
||||||
SetWindowTextA :: proc(hwnd: HWND, c_string: ^u8) -> BOOL #foreign #dll_import
|
SetWindowTextA :: proc(hwnd: HWND, c_string: ^u8) -> BOOL #foreign
|
||||||
|
|
||||||
QueryPerformanceFrequency :: proc(result: ^i64) -> i32 #foreign #dll_import
|
QueryPerformanceFrequency :: proc(result: ^i64) -> i32 #foreign
|
||||||
QueryPerformanceCounter :: proc(result: ^i64) -> i32 #foreign #dll_import
|
QueryPerformanceCounter :: proc(result: ^i64) -> i32 #foreign
|
||||||
|
|
||||||
Sleep :: proc(ms: i32) -> i32 #foreign #dll_import
|
Sleep :: proc(ms: i32) -> i32 #foreign
|
||||||
|
|
||||||
OutputDebugStringA :: proc(c_str: ^u8) #foreign #dll_import
|
OutputDebugStringA :: proc(c_str: ^u8) #foreign
|
||||||
|
|
||||||
|
|
||||||
RegisterClassExA :: proc(wc: ^WNDCLASSEXA) -> ATOM #foreign #dll_import
|
RegisterClassExA :: proc(wc: ^WNDCLASSEXA) -> ATOM #foreign
|
||||||
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 #dll_import
|
param: rawptr) -> HWND #foreign
|
||||||
|
|
||||||
ShowWindow :: proc(hwnd: HWND, cmd_show: i32) -> BOOL #foreign #dll_import
|
ShowWindow :: proc(hwnd: HWND, cmd_show: i32) -> BOOL #foreign
|
||||||
TranslateMessage :: proc(msg: ^MSG) -> BOOL #foreign #dll_import
|
TranslateMessage :: proc(msg: ^MSG) -> BOOL #foreign
|
||||||
DispatchMessageA :: proc(msg: ^MSG) -> LRESULT #foreign #dll_import
|
DispatchMessageA :: proc(msg: ^MSG) -> LRESULT #foreign
|
||||||
UpdateWindow :: proc(hwnd: HWND) -> BOOL #foreign #dll_import
|
UpdateWindow :: proc(hwnd: HWND) -> BOOL #foreign
|
||||||
PeekMessageA :: proc(msg: ^MSG, hwnd: HWND,
|
PeekMessageA :: proc(msg: ^MSG, hwnd: HWND,
|
||||||
msg_filter_min, msg_filter_max, remove_msg: u32) -> BOOL #foreign #dll_import
|
msg_filter_min, msg_filter_max, remove_msg: u32) -> BOOL #foreign
|
||||||
|
|
||||||
DefWindowProcA :: proc(hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT #foreign #dll_import
|
DefWindowProcA :: proc(hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT #foreign
|
||||||
|
|
||||||
AdjustWindowRect :: proc(rect: ^RECT, style: u32, menu: BOOL) -> BOOL #foreign #dll_import
|
AdjustWindowRect :: proc(rect: ^RECT, style: u32, menu: BOOL) -> BOOL #foreign
|
||||||
GetActiveWindow :: proc() -> HWND #foreign #dll_import
|
GetActiveWindow :: proc() -> HWND #foreign
|
||||||
|
|
||||||
|
|
||||||
GetQueryPerformanceFrequency :: proc() -> i64 {
|
GetQueryPerformanceFrequency :: proc() -> i64 {
|
||||||
@@ -163,28 +169,34 @@ GetQueryPerformanceFrequency :: proc() -> i64 {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
GetCommandLineA :: proc() -> ^u8 #foreign #dll_import
|
GetCommandLineA :: proc() -> ^u8 #foreign
|
||||||
GetSystemMetrics :: proc(index: i32) -> i32 #foreign #dll_import
|
GetSystemMetrics :: proc(index: i32) -> i32 #foreign
|
||||||
GetCurrentThreadId :: proc() -> u32 #foreign #dll_import
|
GetCurrentThreadId :: proc() -> u32 #foreign
|
||||||
|
|
||||||
|
timeGetTime :: proc() -> u32 #foreign
|
||||||
|
GetSystemTimeAsFileTime :: proc(system_time_as_file_time: ^FILETIME) #foreign
|
||||||
|
FileTimeToLocalFileTime :: proc(file_time: ^FILETIME, local_file_time: ^FILETIME) -> BOOL #foreign
|
||||||
|
FileTimeToSystemTime :: proc(file_time: ^FILETIME, system_time: ^SYSTEMTIME) -> BOOL #foreign
|
||||||
|
SystemTimeToFileTime :: proc(system_time: ^SYSTEMTIME, file_time: ^FILETIME) -> BOOL #foreign
|
||||||
|
|
||||||
// File Stuff
|
// File Stuff
|
||||||
|
|
||||||
CloseHandle :: proc(h: HANDLE) -> i32 #foreign #dll_import
|
CloseHandle :: proc(h: HANDLE) -> i32 #foreign
|
||||||
GetStdHandle :: proc(h: i32) -> HANDLE #foreign #dll_import
|
GetStdHandle :: proc(h: i32) -> HANDLE #foreign
|
||||||
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 #dll_import
|
creation, flags_and_attribs: u32, template_file: HANDLE) -> HANDLE #foreign
|
||||||
ReadFile :: proc(h: HANDLE, buf: rawptr, to_read: u32, bytes_read: ^i32, overlapped: rawptr) -> BOOL #foreign #dll_import
|
ReadFile :: proc(h: HANDLE, buf: rawptr, to_read: u32, bytes_read: ^i32, overlapped: rawptr) -> BOOL #foreign
|
||||||
WriteFile :: proc(h: HANDLE, buf: rawptr, len: i32, written_result: ^i32, overlapped: rawptr) -> BOOL #foreign #dll_import
|
WriteFile :: proc(h: HANDLE, buf: rawptr, len: i32, written_result: ^i32, overlapped: rawptr) -> BOOL #foreign
|
||||||
|
|
||||||
GetFileSizeEx :: proc(file_handle: HANDLE, file_size: ^i64) -> BOOL #foreign #dll_import
|
GetFileSizeEx :: proc(file_handle: HANDLE, file_size: ^i64) -> BOOL #foreign
|
||||||
GetFileAttributesExA :: proc(filename: ^u8, info_level_id: GET_FILEEX_INFO_LEVELS, file_info: rawptr) -> BOOL #foreign #dll_import
|
GetFileAttributesExA :: proc(filename: ^u8, info_level_id: GET_FILEEX_INFO_LEVELS, file_info: rawptr) -> BOOL #foreign
|
||||||
GetFileInformationByHandle :: proc(file_handle: HANDLE, file_info: ^BY_HANDLE_FILE_INFORMATION) -> BOOL #foreign #dll_import
|
GetFileInformationByHandle :: proc(file_handle: HANDLE, file_info: ^BY_HANDLE_FILE_INFORMATION) -> BOOL #foreign
|
||||||
|
|
||||||
GetFileType :: proc(file_handle: HANDLE) -> u32 #foreign #dll_import
|
GetFileType :: proc(file_handle: HANDLE) -> u32 #foreign
|
||||||
SetFilePointer :: proc(file_handle: HANDLE, distance_to_move: i32, distance_to_move_high: ^i32, move_method: u32) -> u32 #foreign #dll_import
|
SetFilePointer :: proc(file_handle: HANDLE, distance_to_move: i32, distance_to_move_high: ^i32, move_method: u32) -> u32 #foreign
|
||||||
|
|
||||||
SetHandleInformation :: proc(obj: HANDLE, mask, flags: u32) -> BOOL #foreign #dll_import
|
SetHandleInformation :: proc(obj: HANDLE, mask, flags: u32) -> BOOL #foreign
|
||||||
|
|
||||||
HANDLE_FLAG_INHERIT :: 1;
|
HANDLE_FLAG_INHERIT :: 1;
|
||||||
HANDLE_FLAG_PROTECT_FROM_CLOSE :: 2;
|
HANDLE_FLAG_PROTECT_FROM_CLOSE :: 2;
|
||||||
@@ -238,10 +250,10 @@ INVALID_SET_FILE_POINTER :: ~cast(u32)0;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
HeapAlloc :: proc (h: HANDLE, flags: u32, bytes: int) -> rawptr #foreign #dll_import
|
HeapAlloc :: proc (h: HANDLE, flags: u32, bytes: int) -> rawptr #foreign
|
||||||
HeapReAlloc :: proc (h: HANDLE, flags: u32, memory: rawptr, bytes: int) -> rawptr #foreign #dll_import
|
HeapReAlloc :: proc (h: HANDLE, flags: u32, memory: rawptr, bytes: int) -> rawptr #foreign
|
||||||
HeapFree :: proc (h: HANDLE, flags: u32, memory: rawptr) -> BOOL #foreign #dll_import
|
HeapFree :: proc (h: HANDLE, flags: u32, memory: rawptr) -> BOOL #foreign
|
||||||
GetProcessHeap :: proc () -> HANDLE #foreign #dll_import
|
GetProcessHeap :: proc () -> HANDLE #foreign
|
||||||
|
|
||||||
|
|
||||||
HEAP_ZERO_MEMORY :: 0x00000008;
|
HEAP_ZERO_MEMORY :: 0x00000008;
|
||||||
@@ -256,9 +268,9 @@ SECURITY_ATTRIBUTES :: struct #ordered {
|
|||||||
|
|
||||||
INFINITE :: 0xffffffff;
|
INFINITE :: 0xffffffff;
|
||||||
|
|
||||||
CreateSemaphoreA :: proc(attributes: ^SECURITY_ATTRIBUTES, initial_count, maximum_count: i32, name: ^byte) -> HANDLE #foreign #dll_import
|
CreateSemaphoreA :: proc(attributes: ^SECURITY_ATTRIBUTES, initial_count, maximum_count: i32, name: ^byte) -> HANDLE #foreign
|
||||||
ReleaseSemaphore :: proc(semaphore: HANDLE, release_count: i32, previous_count: ^i32) -> BOOL #foreign #dll_import
|
ReleaseSemaphore :: proc(semaphore: HANDLE, release_count: i32, previous_count: ^i32) -> BOOL #foreign
|
||||||
WaitForSingleObject :: proc(handle: HANDLE, milliseconds: u32) -> u32 #foreign #dll_import
|
WaitForSingleObject :: proc(handle: HANDLE, milliseconds: u32) -> u32 #foreign
|
||||||
|
|
||||||
|
|
||||||
InterlockedCompareExchange :: proc(dst: ^i32, exchange, comparand: i32) -> i32 #foreign
|
InterlockedCompareExchange :: proc(dst: ^i32, exchange, comparand: i32) -> i32 #foreign
|
||||||
@@ -309,7 +321,7 @@ StretchDIBits :: proc (hdc: HDC,
|
|||||||
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: ^BITMAPINFO,
|
||||||
usage: u32,
|
usage: u32,
|
||||||
rop: u32) -> i32 #foreign #dll_import
|
rop: u32) -> i32 #foreign
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -381,10 +393,10 @@ PIXELFORMATDESCRIPTOR :: struct #ordered {
|
|||||||
}
|
}
|
||||||
|
|
||||||
GetDC :: proc(h: HANDLE) -> HDC #foreign
|
GetDC :: proc(h: HANDLE) -> HDC #foreign
|
||||||
SetPixelFormat :: proc(hdc: HDC, pixel_format: i32, pfd: ^PIXELFORMATDESCRIPTOR ) -> BOOL #foreign #dll_import
|
SetPixelFormat :: proc(hdc: HDC, pixel_format: i32, pfd: ^PIXELFORMATDESCRIPTOR ) -> BOOL #foreign
|
||||||
ChoosePixelFormat :: proc(hdc: HDC, pfd: ^PIXELFORMATDESCRIPTOR) -> i32 #foreign #dll_import
|
ChoosePixelFormat :: proc(hdc: HDC, pfd: ^PIXELFORMATDESCRIPTOR) -> i32 #foreign
|
||||||
SwapBuffers :: proc(hdc: HDC) -> BOOL #foreign #dll_import
|
SwapBuffers :: proc(hdc: HDC) -> BOOL #foreign
|
||||||
ReleaseDC :: proc(wnd: HWND, hdc: HDC) -> i32 #foreign #dll_import
|
ReleaseDC :: proc(wnd: HWND, hdc: HDC) -> i32 #foreign
|
||||||
|
|
||||||
WGL_CONTEXT_MAJOR_VERSION_ARB :: 0x2091;
|
WGL_CONTEXT_MAJOR_VERSION_ARB :: 0x2091;
|
||||||
WGL_CONTEXT_MINOR_VERSION_ARB :: 0x2092;
|
WGL_CONTEXT_MINOR_VERSION_ARB :: 0x2092;
|
||||||
@@ -392,15 +404,15 @@ WGL_CONTEXT_PROFILE_MASK_ARB :: 0x9126;
|
|||||||
WGL_CONTEXT_CORE_PROFILE_BIT_ARB :: 0x0001;
|
WGL_CONTEXT_CORE_PROFILE_BIT_ARB :: 0x0001;
|
||||||
WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB :: 0x0002;
|
WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB :: 0x0002;
|
||||||
|
|
||||||
wglCreateContext :: proc(hdc: HDC) -> HGLRC #foreign #dll_import
|
wglCreateContext :: proc(hdc: HDC) -> HGLRC #foreign
|
||||||
wglMakeCurrent :: proc(hdc: HDC, hglrc: HGLRC) -> BOOL #foreign #dll_import
|
wglMakeCurrent :: proc(hdc: HDC, hglrc: HGLRC) -> BOOL #foreign
|
||||||
wglGetProcAddress :: proc(c_str: ^u8) -> PROC #foreign #dll_import
|
wglGetProcAddress :: proc(c_str: ^u8) -> PROC #foreign
|
||||||
wglDeleteContext :: proc(hglrc: HGLRC) -> BOOL #foreign #dll_import
|
wglDeleteContext :: proc(hglrc: HGLRC) -> BOOL #foreign
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GetKeyState :: proc(v_key: i32) -> i16 #foreign #dll_import
|
GetKeyState :: proc(v_key: i32) -> i16 #foreign
|
||||||
GetAsyncKeyState :: proc(v_key: i32) -> i16 #foreign #dll_import
|
GetAsyncKeyState :: proc(v_key: i32) -> i16 #foreign
|
||||||
|
|
||||||
is_key_down :: proc(key: Key_Code) -> bool #inline { return GetAsyncKeyState(cast(i32)key) < 0; }
|
is_key_down :: proc(key: Key_Code) -> bool #inline { return GetAsyncKeyState(cast(i32)key) < 0; }
|
||||||
|
|
||||||
|
|||||||
@@ -3882,6 +3882,19 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
|
|||||||
o->value = make_exact_value_from_basic_literal(*bl);
|
o->value = make_exact_value_from_basic_literal(*bl);
|
||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
|
case_ast_node(bd, BasicDirective, node);
|
||||||
|
if (str_eq(bd->name, str_lit("file"))) {
|
||||||
|
o->type = t_untyped_string;
|
||||||
|
o->value = make_exact_value_string(bd->token.pos.file);
|
||||||
|
} else if (str_eq(bd->name, str_lit("line"))) {
|
||||||
|
o->type = t_untyped_integer;
|
||||||
|
o->value = make_exact_value_integer(bd->token.pos.line);
|
||||||
|
} else {
|
||||||
|
GB_PANIC("Unknown basic basic directive");
|
||||||
|
}
|
||||||
|
o->mode = Addressing_Constant;
|
||||||
|
case_end;
|
||||||
|
|
||||||
case_ast_node(pl, ProcLit, node);
|
case_ast_node(pl, ProcLit, node);
|
||||||
Type *type = check_type(c, pl->type);
|
Type *type = check_type(c, pl->type);
|
||||||
if (type == NULL || !is_type_proc(type)) {
|
if (type == NULL || !is_type_proc(type)) {
|
||||||
|
|||||||
+4
-4
@@ -527,7 +527,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
|||||||
case_ast_node(rs, ReturnStmt, node);
|
case_ast_node(rs, ReturnStmt, node);
|
||||||
GB_ASSERT(c->proc_stack.count > 0);
|
GB_ASSERT(c->proc_stack.count > 0);
|
||||||
|
|
||||||
if (c->in_defer) {
|
if (c->context.in_defer) {
|
||||||
error(rs->token, "You cannot `return` within a defer statement");
|
error(rs->token, "You cannot `return` within a defer statement");
|
||||||
// TODO(bill): Should I break here?
|
// TODO(bill): Should I break here?
|
||||||
break;
|
break;
|
||||||
@@ -1046,10 +1046,10 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
|||||||
if (is_ast_node_decl(ds->stmt)) {
|
if (is_ast_node_decl(ds->stmt)) {
|
||||||
error(ds->token, "You cannot defer a declaration");
|
error(ds->token, "You cannot defer a declaration");
|
||||||
} else {
|
} else {
|
||||||
bool out_in_defer = c->in_defer;
|
bool out_in_defer = c->context.in_defer;
|
||||||
c->in_defer = true;
|
c->context.in_defer = true;
|
||||||
check_stmt(c, ds->stmt, 0);
|
check_stmt(c, ds->stmt, 0);
|
||||||
c->in_defer = out_in_defer;
|
c->context.in_defer = out_in_defer;
|
||||||
}
|
}
|
||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -250,6 +250,7 @@ typedef struct CheckerContext {
|
|||||||
Scope * scope;
|
Scope * scope;
|
||||||
DeclInfo * decl;
|
DeclInfo * decl;
|
||||||
u32 stmt_state_flags;
|
u32 stmt_state_flags;
|
||||||
|
bool in_defer; // TODO(bill): Actually handle correctly
|
||||||
} CheckerContext;
|
} CheckerContext;
|
||||||
|
|
||||||
// NOTE(bill): Symbol tables
|
// NOTE(bill): Symbol tables
|
||||||
@@ -288,7 +289,6 @@ typedef struct Checker {
|
|||||||
CheckerContext context;
|
CheckerContext context;
|
||||||
|
|
||||||
Array(Type *) proc_stack;
|
Array(Type *) proc_stack;
|
||||||
bool in_defer; // TODO(bill): Actually handle correctly
|
|
||||||
bool done_preload;
|
bool done_preload;
|
||||||
} Checker;
|
} Checker;
|
||||||
|
|
||||||
|
|||||||
@@ -1479,12 +1479,13 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue *
|
|||||||
return ir_emit_ptr_offset(proc, ptr, offset);
|
return ir_emit_ptr_offset(proc, ptr, offset);
|
||||||
} else if (is_type_pointer(t_left) && is_type_pointer(t_right)) {
|
} else if (is_type_pointer(t_left) && is_type_pointer(t_right)) {
|
||||||
GB_ASSERT(is_type_integer(type));
|
GB_ASSERT(is_type_integer(type));
|
||||||
Type *ptr_type = t_left;
|
|
||||||
irModule *m = proc->module;
|
irModule *m = proc->module;
|
||||||
|
Type *ptr_type = base_type(t_left);
|
||||||
|
GB_ASSERT(!is_type_rawptr(ptr_type));
|
||||||
|
irValue *elem_size = ir_make_const_int(m->allocator, type_size_of(m->sizes, m->allocator, ptr_type->Pointer.elem));
|
||||||
irValue *x = ir_emit_conv(proc, left, type);
|
irValue *x = ir_emit_conv(proc, left, type);
|
||||||
irValue *y = ir_emit_conv(proc, right, type);
|
irValue *y = ir_emit_conv(proc, right, type);
|
||||||
irValue *diff = ir_emit_arith(proc, op, x, y, type);
|
irValue *diff = ir_emit_arith(proc, op, x, y, type);
|
||||||
irValue *elem_size = ir_make_const_int(m->allocator, type_size_of(m->sizes, m->allocator, ptr_type));
|
|
||||||
return ir_emit_arith(proc, Token_Quo, diff, elem_size, type);
|
return ir_emit_arith(proc, Token_Quo, diff, elem_size, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2547,6 +2548,11 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
|
|||||||
GB_PANIC("Non-constant basic literal %.*s(%td:%td) - %.*s", LIT(pos.file), pos.line, pos.column, LIT(token_strings[bl->kind]));
|
GB_PANIC("Non-constant basic literal %.*s(%td:%td) - %.*s", LIT(pos.file), pos.line, pos.column, LIT(token_strings[bl->kind]));
|
||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
|
case_ast_node(bd, BasicDirective, expr);
|
||||||
|
TokenPos pos = bd->token.pos;
|
||||||
|
GB_PANIC("Non-constant basic literal %.*s(%td:%td) - %.*s", LIT(pos.file), pos.line, pos.column, LIT(bd->name));
|
||||||
|
case_end;
|
||||||
|
|
||||||
case_ast_node(i, Ident, expr);
|
case_ast_node(i, Ident, expr);
|
||||||
Entity *e = *map_entity_get(&proc->module->info->uses, hash_pointer(expr));
|
Entity *e = *map_entity_get(&proc->module->info->uses, hash_pointer(expr));
|
||||||
if (e->kind == Entity_Builtin) {
|
if (e->kind == Entity_Builtin) {
|
||||||
|
|||||||
+3
-3
@@ -1235,9 +1235,9 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
|
|||||||
void ir_print_proc(irFileBuffer *f, irModule *m, irProcedure *proc) {
|
void ir_print_proc(irFileBuffer *f, irModule *m, irProcedure *proc) {
|
||||||
if (proc->body == NULL) {
|
if (proc->body == NULL) {
|
||||||
ir_fprintf(f, "declare ");
|
ir_fprintf(f, "declare ");
|
||||||
if (proc->tags & ProcTag_dll_import) {
|
// if (proc->tags & ProcTag_dll_import) {
|
||||||
ir_fprintf(f, "dllimport ");
|
// ir_fprintf(f, "dllimport ");
|
||||||
}
|
// }
|
||||||
} else {
|
} else {
|
||||||
ir_fprintf(f, "\n");
|
ir_fprintf(f, "\n");
|
||||||
ir_fprintf(f, "define ");
|
ir_fprintf(f, "define ");
|
||||||
|
|||||||
+30
-24
@@ -70,7 +70,7 @@ typedef enum ProcTag {
|
|||||||
ProcTag_link_name = 1<<12,
|
ProcTag_link_name = 1<<12,
|
||||||
ProcTag_inline = 1<<13,
|
ProcTag_inline = 1<<13,
|
||||||
ProcTag_no_inline = 1<<14,
|
ProcTag_no_inline = 1<<14,
|
||||||
ProcTag_dll_import = 1<<15,
|
// ProcTag_dll_import = 1<<15,
|
||||||
// ProcTag_dll_export = 1<<16,
|
// ProcTag_dll_export = 1<<16,
|
||||||
} ProcTag;
|
} ProcTag;
|
||||||
|
|
||||||
@@ -113,9 +113,13 @@ AstNodeArray make_ast_node_array(AstFile *f) {
|
|||||||
|
|
||||||
|
|
||||||
#define AST_NODE_KINDS \
|
#define AST_NODE_KINDS \
|
||||||
AST_NODE_KIND(BasicLit, "basic literal", Token) \
|
AST_NODE_KIND(Ident, "identifier", Token) \
|
||||||
AST_NODE_KIND(Ident, "identifier", Token) \
|
AST_NODE_KIND(BasicLit, "basic literal", Token) \
|
||||||
AST_NODE_KIND(Ellipsis, "ellipsis", struct { \
|
AST_NODE_KIND(BasicDirective, "basic directive", struct { \
|
||||||
|
Token token; \
|
||||||
|
String name; \
|
||||||
|
}) \
|
||||||
|
AST_NODE_KIND(Ellipsis, "ellipsis", struct { \
|
||||||
Token token; \
|
Token token; \
|
||||||
AstNode *expr; \
|
AstNode *expr; \
|
||||||
}) \
|
}) \
|
||||||
@@ -420,10 +424,12 @@ gb_inline bool is_ast_node_when_stmt(AstNode *node) {
|
|||||||
|
|
||||||
Token ast_node_token(AstNode *node) {
|
Token ast_node_token(AstNode *node) {
|
||||||
switch (node->kind) {
|
switch (node->kind) {
|
||||||
case AstNode_BasicLit:
|
|
||||||
return node->BasicLit;
|
|
||||||
case AstNode_Ident:
|
case AstNode_Ident:
|
||||||
return node->Ident;
|
return node->Ident;
|
||||||
|
case AstNode_BasicLit:
|
||||||
|
return node->BasicLit;
|
||||||
|
case AstNode_BasicDirective:
|
||||||
|
return node->BasicDirective.token;
|
||||||
case AstNode_ProcLit:
|
case AstNode_ProcLit:
|
||||||
return ast_node_token(node->ProcLit.type);
|
return ast_node_token(node->ProcLit.type);
|
||||||
case AstNode_CompoundLit:
|
case AstNode_CompoundLit:
|
||||||
@@ -741,15 +747,22 @@ AstNode *make_interval_expr(AstFile *f, Token op, AstNode *left, AstNode *right)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AstNode *make_ident(AstFile *f, Token token) {
|
||||||
|
AstNode *result = make_node(f, AstNode_Ident);
|
||||||
|
result->Ident = token;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
AstNode *make_basic_lit(AstFile *f, Token basic_lit) {
|
AstNode *make_basic_lit(AstFile *f, Token basic_lit) {
|
||||||
AstNode *result = make_node(f, AstNode_BasicLit);
|
AstNode *result = make_node(f, AstNode_BasicLit);
|
||||||
result->BasicLit = basic_lit;
|
result->BasicLit = basic_lit;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
AstNode *make_ident(AstFile *f, Token token) {
|
AstNode *make_basic_directive(AstFile *f, Token token, String name) {
|
||||||
AstNode *result = make_node(f, AstNode_Ident);
|
AstNode *result = make_node(f, AstNode_BasicDirective);
|
||||||
result->Ident = token;
|
result->BasicDirective.token = token;
|
||||||
|
result->BasicDirective.name = name;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1543,7 +1556,7 @@ void parse_proc_tags(AstFile *f, u64 *tags, String *foreign_name, String *link_n
|
|||||||
ELSE_IF_ADD_TAG(no_bounds_check)
|
ELSE_IF_ADD_TAG(no_bounds_check)
|
||||||
ELSE_IF_ADD_TAG(inline)
|
ELSE_IF_ADD_TAG(inline)
|
||||||
ELSE_IF_ADD_TAG(no_inline)
|
ELSE_IF_ADD_TAG(no_inline)
|
||||||
ELSE_IF_ADD_TAG(dll_import)
|
// ELSE_IF_ADD_TAG(dll_import)
|
||||||
// ELSE_IF_ADD_TAG(dll_export)
|
// ELSE_IF_ADD_TAG(dll_export)
|
||||||
else if (str_eq(tag_name, str_lit("cc_odin"))) {
|
else if (str_eq(tag_name, str_lit("cc_odin"))) {
|
||||||
if (cc == ProcCC_Invalid) {
|
if (cc == ProcCC_Invalid) {
|
||||||
@@ -1570,7 +1583,7 @@ void parse_proc_tags(AstFile *f, u64 *tags, String *foreign_name, String *link_n
|
|||||||
syntax_error_node(tag_expr, "Multiple calling conventions for procedure type");
|
syntax_error_node(tag_expr, "Multiple calling conventions for procedure type");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
syntax_error_node(tag_expr, "Unknown procedure tag");
|
syntax_error_node(tag_expr, "Unknown procedure tag #%.*s\n", LIT(tag_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef ELSE_IF_ADD_TAG
|
#undef ELSE_IF_ADD_TAG
|
||||||
@@ -1752,17 +1765,9 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
|
|||||||
Token token = expect_token(f, Token_Hash);
|
Token token = expect_token(f, Token_Hash);
|
||||||
Token name = expect_token(f, Token_Ident);
|
Token name = expect_token(f, Token_Ident);
|
||||||
if (str_eq(name.string, str_lit("file"))) {
|
if (str_eq(name.string, str_lit("file"))) {
|
||||||
Token token = name;
|
return make_basic_directive(f, token, name.string);
|
||||||
token.kind = Token_String;
|
|
||||||
token.string = token.pos.file;
|
|
||||||
return make_basic_lit(f, token);
|
|
||||||
} else if (str_eq(name.string, str_lit("line"))) {
|
} else if (str_eq(name.string, str_lit("line"))) {
|
||||||
Token token = name;
|
return make_basic_directive(f, token, name.string);
|
||||||
token.kind = Token_Integer;
|
|
||||||
char *str = gb_alloc_array(gb_arena_allocator(&f->arena), char, 20);
|
|
||||||
gb_i64_to_str(token.pos.line, str, 10);
|
|
||||||
token.string = make_string_c(str);
|
|
||||||
return make_basic_lit(f, token);
|
|
||||||
} else if (str_eq(name.string, str_lit("run"))) {
|
} else if (str_eq(name.string, str_lit("run"))) {
|
||||||
AstNode *expr = parse_expr(f, false);
|
AstNode *expr = parse_expr(f, false);
|
||||||
operand = make_run_expr(f, token, name, expr);
|
operand = make_run_expr(f, token, name, expr);
|
||||||
@@ -3077,20 +3082,21 @@ AstNode *parse_defer_stmt(AstFile *f) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Token token = expect_token(f, Token_defer);
|
Token token = expect_token(f, Token_defer);
|
||||||
AstNode *statement = parse_stmt(f);
|
AstNode *stmt = parse_stmt(f);
|
||||||
switch (statement->kind) {
|
switch (stmt->kind) {
|
||||||
case AstNode_EmptyStmt:
|
case AstNode_EmptyStmt:
|
||||||
syntax_error(token, "Empty statement after defer (e.g. `;`)");
|
syntax_error(token, "Empty statement after defer (e.g. `;`)");
|
||||||
break;
|
break;
|
||||||
case AstNode_DeferStmt:
|
case AstNode_DeferStmt:
|
||||||
syntax_error(token, "You cannot defer a defer statement");
|
syntax_error(token, "You cannot defer a defer statement");
|
||||||
|
stmt = stmt->DeferStmt.stmt;
|
||||||
break;
|
break;
|
||||||
case AstNode_ReturnStmt:
|
case AstNode_ReturnStmt:
|
||||||
syntax_error(token, "You cannot a return statement");
|
syntax_error(token, "You cannot a return statement");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return make_defer_stmt(f, token, statement);
|
return make_defer_stmt(f, token, stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
AstNode *parse_asm_stmt(AstFile *f) {
|
AstNode *parse_asm_stmt(AstFile *f) {
|
||||||
|
|||||||
Reference in New Issue
Block a user