mirror of
https://github.com/odin-lang/Odin.git
synced 2026-05-04 03:54:41 +00:00
Code will compile as 32 bit but will causes errors in the linker on Windows
This commit is contained in:
@@ -32,10 +32,11 @@ type (
|
||||
}
|
||||
// NOTE(bill): This must match the compiler's
|
||||
CallingConvention enum {
|
||||
Odin = 0,
|
||||
C = 1,
|
||||
Std = 2,
|
||||
Fast = 3,
|
||||
Invalid = 0,
|
||||
Odin = 1,
|
||||
C = 2,
|
||||
Std = 3,
|
||||
Fast = 4,
|
||||
}
|
||||
|
||||
TypeInfoRecord struct #ordered {
|
||||
|
||||
@@ -1,26 +1,61 @@
|
||||
#shared_global_scope;
|
||||
|
||||
proc __u128_mod(a, b: u128) -> u128 #cc_odin #link_name "__umodti3" {
|
||||
proc __multi3(a, b: u128) -> u128 #cc_c #link_name "__multi3" {
|
||||
const bits_in_dword_2 = size_of(i64) * 4;
|
||||
const lower_mask = u128(~u64(0) >> bits_in_dword_2);
|
||||
|
||||
|
||||
when ODIN_ENDIAN == "bit" {
|
||||
type TWords raw_union {
|
||||
all: u128,
|
||||
using _: struct {lo, hi: u64},
|
||||
};
|
||||
} else {
|
||||
type TWords raw_union {
|
||||
all: u128,
|
||||
using _: struct {hi, lo: u64},
|
||||
};
|
||||
}
|
||||
|
||||
var r: TWords;
|
||||
var t: u64;
|
||||
|
||||
r.lo = u64(a & lower_mask) * u64(b & lower_mask);
|
||||
t = r.lo >> bits_in_dword_2;
|
||||
r.lo &= u64(lower_mask);
|
||||
t += u64(a >> bits_in_dword_2) * u64(b & lower_mask);
|
||||
r.lo += u64(t & u64(lower_mask)) << bits_in_dword_2;
|
||||
r.hi = t >> bits_in_dword_2;
|
||||
t = r.lo >> bits_in_dword_2;
|
||||
r.lo &= u64(lower_mask);
|
||||
t += u64(b >> bits_in_dword_2) * u64(a & lower_mask);
|
||||
r.lo += u64(t & u64(lower_mask)) << bits_in_dword_2;
|
||||
r.hi += t >> bits_in_dword_2;
|
||||
r.hi += u64(a >> bits_in_dword_2) * u64(b >> bits_in_dword_2);
|
||||
return r.all;
|
||||
}
|
||||
|
||||
proc __u128_mod(a, b: u128) -> u128 #cc_c #link_name "__umodti3" {
|
||||
var r: u128;
|
||||
__u128_quo_mod(a, b, &r);
|
||||
return r;
|
||||
}
|
||||
|
||||
proc __u128_quo(a, b: u128) -> u128 #cc_odin #link_name "__udivti3" {
|
||||
proc __u128_quo(a, b: u128) -> u128 #cc_c #link_name "__udivti3" {
|
||||
return __u128_quo_mod(a, b, nil);
|
||||
}
|
||||
|
||||
proc __i128_mod(a, b: i128) -> i128 #cc_odin #link_name "__modti3" {
|
||||
proc __i128_mod(a, b: i128) -> i128 #cc_c #link_name "__modti3" {
|
||||
var r: i128;
|
||||
__i128_quo_mod(a, b, &r);
|
||||
return r;
|
||||
}
|
||||
|
||||
proc __i128_quo(a, b: i128) -> i128 #cc_odin #link_name "__divti3" {
|
||||
proc __i128_quo(a, b: i128) -> i128 #cc_c #link_name "__divti3" {
|
||||
return __i128_quo_mod(a, b, nil);
|
||||
}
|
||||
|
||||
proc __i128_quo_mod(a, b: i128, rem: ^i128) -> (quo: i128) #cc_odin #link_name "__divmodti4" {
|
||||
proc __i128_quo_mod(a, b: i128, rem: ^i128) -> (quo: i128) #cc_c #link_name "__divmodti4" {
|
||||
var s: i128;
|
||||
s = b >> 127;
|
||||
b = (b~s) - s;
|
||||
@@ -39,7 +74,7 @@ proc __i128_quo_mod(a, b: i128, rem: ^i128) -> (quo: i128) #cc_odin #link_name "
|
||||
}
|
||||
|
||||
|
||||
proc __u128_quo_mod(a, b: u128, rem: ^u128) -> (quo: u128) #cc_odin #link_name "__udivmodti4" {
|
||||
proc __u128_quo_mod(a, b: u128, rem: ^u128) -> (quo: u128) #cc_c #link_name "__udivmodti4" {
|
||||
var alo, ahi = u64(a), u64(a>>64);
|
||||
var blo, bhi = u64(b), u64(b>>64);
|
||||
if b == 0 {
|
||||
@@ -68,7 +103,7 @@ proc __u128_quo_mod(a, b: u128, rem: ^u128) -> (quo: u128) #cc_odin #link_name "
|
||||
}
|
||||
|
||||
/*
|
||||
proc __f16_to_f32(f: f16) -> f32 #cc_odin #no_inline #link_name "__gnu_h2f_ieee" {
|
||||
proc __f16_to_f32(f: f16) -> f32 #cc_c #no_inline #link_name "__gnu_h2f_ieee" {
|
||||
when true {
|
||||
// Source: https://fgiesen.wordpress.com/2012/03/28/half-to-float-done-quic/
|
||||
const FP32 = raw_union {u: u32, f: f32};
|
||||
@@ -92,7 +127,7 @@ proc __f16_to_f32(f: f16) -> f32 #cc_odin #no_inline #link_name "__gnu_h2f_ieee"
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
proc __f32_to_f16(f_: f32) -> f16 #cc_odin #no_inline #link_name "__gnu_f2h_ieee" {
|
||||
proc __f32_to_f16(f_: f32) -> f16 #cc_c #no_inline #link_name "__gnu_f2h_ieee" {
|
||||
when false {
|
||||
// Source: https://gist.github.com/rygorous/2156668
|
||||
const FP16 = raw_union {u: u16, f: f16};
|
||||
@@ -182,11 +217,11 @@ proc __f32_to_f16(f_: f32) -> f16 #cc_odin #no_inline #link_name "__gnu_f2h_ieee
|
||||
}
|
||||
}
|
||||
|
||||
proc __f64_to_f16(f: f64) -> f16 #cc_odin #no_inline #link_name "__truncdfhf2" {
|
||||
proc __f64_to_f16(f: f64) -> f16 #cc_c #no_inline #link_name "__truncdfhf2" {
|
||||
return __f32_to_f16(f32(f));
|
||||
}
|
||||
|
||||
proc __f16_to_f64(f: f16) -> f64 #cc_odin #no_inline {
|
||||
proc __f16_to_f64(f: f16) -> f64 #cc_c #no_inline {
|
||||
return f64(__f16_to_f32(f));
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -285,164 +285,164 @@ const (
|
||||
)
|
||||
|
||||
foreign kernel32 {
|
||||
proc get_last_error () -> i32 #link_name "GetLastError";
|
||||
proc exit_process (exit_code: u32) #link_name "ExitProcess";
|
||||
proc get_module_handle_a(module_name: ^u8) -> Hinstance #link_name "GetModuleHandleA";
|
||||
proc sleep(ms: i32) -> i32 #link_name "Sleep";
|
||||
proc query_performance_frequency(result: ^i64) -> i32 #link_name "QueryPerformanceFrequency";
|
||||
proc query_performance_counter (result: ^i64) -> i32 #link_name "QueryPerformanceCounter";
|
||||
proc output_debug_string_a(c_str: ^u8) #link_name "OutputDebugStringA";
|
||||
proc get_last_error () -> i32 #cc_c #link_name "GetLastError";
|
||||
proc exit_process (exit_code: u32) #cc_c #link_name "ExitProcess";
|
||||
proc get_module_handle_a(module_name: ^u8) -> Hinstance #cc_c #link_name "GetModuleHandleA";
|
||||
proc sleep(ms: i32) -> i32 #cc_c #link_name "Sleep";
|
||||
proc query_performance_frequency(result: ^i64) -> i32 #cc_c #link_name "QueryPerformanceFrequency";
|
||||
proc query_performance_counter (result: ^i64) -> i32 #cc_c #link_name "QueryPerformanceCounter";
|
||||
proc output_debug_string_a(c_str: ^u8) #cc_c #link_name "OutputDebugStringA";
|
||||
|
||||
proc get_command_line_a () -> ^u8 #link_name "GetCommandLineA";
|
||||
proc get_command_line_w () -> ^u16 #link_name "GetCommandLineW";
|
||||
proc get_system_metrics (index: i32) -> i32 #link_name "GetSystemMetrics";
|
||||
proc get_current_thread_id () -> u32 #link_name "GetCurrentThreadId";
|
||||
proc get_command_line_a () -> ^u8 #cc_c #link_name "GetCommandLineA";
|
||||
proc get_command_line_w () -> ^u16 #cc_c #link_name "GetCommandLineW";
|
||||
proc get_system_metrics (index: i32) -> i32 #cc_c #link_name "GetSystemMetrics";
|
||||
proc get_current_thread_id () -> u32 #cc_c #link_name "GetCurrentThreadId";
|
||||
|
||||
proc get_system_time_as_file_time(system_time_as_file_time: ^Filetime) #link_name "GetSystemTimeAsFileTime";
|
||||
proc file_time_to_local_file_time(file_time: ^Filetime, local_file_time: ^Filetime) -> Bool #link_name "FileTimeToLocalFileTime";
|
||||
proc file_time_to_system_time (file_time: ^Filetime, system_time: ^Systemtime) -> Bool #link_name "FileTimeToSystemTime";
|
||||
proc system_time_to_file_time (system_time: ^Systemtime, file_time: ^Filetime) -> Bool #link_name "SystemTimeToFileTime";
|
||||
proc get_system_time_as_file_time(system_time_as_file_time: ^Filetime) #cc_c #link_name "GetSystemTimeAsFileTime";
|
||||
proc file_time_to_local_file_time(file_time: ^Filetime, local_file_time: ^Filetime) -> Bool #cc_c #link_name "FileTimeToLocalFileTime";
|
||||
proc file_time_to_system_time (file_time: ^Filetime, system_time: ^Systemtime) -> Bool #cc_c #link_name "FileTimeToSystemTime";
|
||||
proc system_time_to_file_time (system_time: ^Systemtime, file_time: ^Filetime) -> Bool #cc_c #link_name "SystemTimeToFileTime";
|
||||
|
||||
proc close_handle (h: Handle) -> i32 #link_name "CloseHandle";
|
||||
proc get_std_handle(h: i32) -> Handle #link_name "GetStdHandle";
|
||||
proc close_handle (h: Handle) -> i32 #cc_c #link_name "CloseHandle";
|
||||
proc get_std_handle(h: i32) -> Handle #cc_c #link_name "GetStdHandle";
|
||||
proc create_file_a (filename: ^u8, desired_access, share_mode: u32,
|
||||
security: rawptr,
|
||||
creation, flags_and_attribs: u32, template_file: Handle) -> Handle #link_name "CreateFileA";
|
||||
proc read_file (h: Handle, buf: rawptr, to_read: u32, bytes_read: ^i32, overlapped: rawptr) -> Bool #link_name "ReadFile";
|
||||
proc write_file(h: Handle, buf: rawptr, len: i32, written_result: ^i32, overlapped: rawptr) -> Bool #link_name "WriteFile";
|
||||
creation, flags_and_attribs: u32, template_file: Handle) -> Handle #cc_c #link_name "CreateFileA";
|
||||
proc read_file (h: Handle, buf: rawptr, to_read: u32, bytes_read: ^i32, overlapped: rawptr) -> Bool #cc_c #link_name "ReadFile";
|
||||
proc write_file(h: Handle, buf: rawptr, len: i32, written_result: ^i32, overlapped: rawptr) -> Bool #cc_c #link_name "WriteFile";
|
||||
|
||||
proc get_file_size_ex (file_handle: Handle, file_size: ^i64) -> Bool #link_name "GetFileSizeEx";
|
||||
proc get_file_attributes_a (filename: ^u8) -> u32 #link_name "GetFileAttributesA";
|
||||
proc get_file_attributes_ex_a (filename: ^u8, info_level_id: GET_FILEEX_INFO_LEVELS, file_info: rawptr) -> Bool #link_name "GetFileAttributesExA";
|
||||
proc get_file_information_by_handle(file_handle: Handle, file_info: ^ByHandleFileInformation) -> Bool #link_name "GetFileInformationByHandle";
|
||||
proc get_file_size_ex (file_handle: Handle, file_size: ^i64) -> Bool #cc_c #link_name "GetFileSizeEx";
|
||||
proc get_file_attributes_a (filename: ^u8) -> u32 #cc_c #link_name "GetFileAttributesA";
|
||||
proc get_file_attributes_ex_a (filename: ^u8, info_level_id: GET_FILEEX_INFO_LEVELS, file_info: rawptr) -> Bool #cc_c #link_name "GetFileAttributesExA";
|
||||
proc get_file_information_by_handle(file_handle: Handle, file_info: ^ByHandleFileInformation) -> Bool #cc_c #link_name "GetFileInformationByHandle";
|
||||
|
||||
proc get_file_type (file_handle: Handle) -> u32 #link_name "GetFileType";
|
||||
proc set_file_pointer(file_handle: Handle, distance_to_move: i32, distance_to_move_high: ^i32, move_method: u32) -> u32 #link_name "SetFilePointer";
|
||||
proc get_file_type (file_handle: Handle) -> u32 #cc_c #link_name "GetFileType";
|
||||
proc set_file_pointer(file_handle: Handle, distance_to_move: i32, distance_to_move_high: ^i32, move_method: u32) -> u32 #cc_c #link_name "SetFilePointer";
|
||||
|
||||
proc set_handle_information(obj: Handle, mask, flags: u32) -> Bool #link_name "SetHandleInformation";
|
||||
proc set_handle_information(obj: Handle, mask, flags: u32) -> Bool #cc_c #link_name "SetHandleInformation";
|
||||
|
||||
proc find_first_file_a(file_name : ^u8, data : ^FindData) -> Handle #link_name "FindFirstFileA";
|
||||
proc find_next_file_a (file : Handle, data : ^FindData) -> Bool #link_name "FindNextFileA";
|
||||
proc find_close (file : Handle) -> Bool #link_name "FindClose";
|
||||
proc find_first_file_a(file_name : ^u8, data : ^FindData) -> Handle #cc_c #link_name "FindFirstFileA";
|
||||
proc find_next_file_a (file : Handle, data : ^FindData) -> Bool #cc_c #link_name "FindNextFileA";
|
||||
proc find_close (file : Handle) -> Bool #cc_c #link_name "FindClose";
|
||||
|
||||
|
||||
proc heap_alloc (h: Handle, flags: u32, bytes: int) -> rawptr #link_name "HeapAlloc";
|
||||
proc heap_realloc (h: Handle, flags: u32, memory: rawptr, bytes: int) -> rawptr #link_name "HeapReAlloc";
|
||||
proc heap_free (h: Handle, flags: u32, memory: rawptr) -> Bool #link_name "HeapFree";
|
||||
proc get_process_heap() -> Handle #link_name "GetProcessHeap";
|
||||
proc heap_alloc (h: Handle, flags: u32, bytes: int) -> rawptr #cc_c #link_name "HeapAlloc";
|
||||
proc heap_realloc (h: Handle, flags: u32, memory: rawptr, bytes: int) -> rawptr #cc_c #link_name "HeapReAlloc";
|
||||
proc heap_free (h: Handle, flags: u32, memory: rawptr) -> Bool #cc_c #link_name "HeapFree";
|
||||
proc get_process_heap() -> Handle #cc_c #link_name "GetProcessHeap";
|
||||
|
||||
|
||||
proc create_semaphore_a (attributes: ^Security_Attributes, initial_count, maximum_count: i32, name: ^u8) -> Handle #link_name "CreateSemaphoreA";
|
||||
proc release_semaphore (semaphore: Handle, release_count: i32, previous_count: ^i32) -> Bool #link_name "ReleaseSemaphore";
|
||||
proc wait_for_single_object(handle: Handle, milliseconds: u32) -> u32 #link_name "WaitForSingleObject";
|
||||
proc create_semaphore_a (attributes: ^Security_Attributes, initial_count, maximum_count: i32, name: ^u8) -> Handle #cc_c #link_name "CreateSemaphoreA";
|
||||
proc release_semaphore (semaphore: Handle, release_count: i32, previous_count: ^i32) -> Bool #cc_c #link_name "ReleaseSemaphore";
|
||||
proc wait_for_single_object(handle: Handle, milliseconds: u32) -> u32 #cc_c #link_name "WaitForSingleObject";
|
||||
|
||||
|
||||
proc interlocked_compare_exchange (dst: ^i32, exchange, comparand: i32) -> i32 #link_name "InterlockedCompareExchange";
|
||||
proc interlocked_exchange (dst: ^i32, desired: i32) -> i32 #link_name "InterlockedExchange";
|
||||
proc interlocked_exchange_add (dst: ^i32, desired: i32) -> i32 #link_name "InterlockedExchangeAdd";
|
||||
proc interlocked_and (dst: ^i32, desired: i32) -> i32 #link_name "InterlockedAnd";
|
||||
proc interlocked_or (dst: ^i32, desired: i32) -> i32 #link_name "InterlockedOr";
|
||||
proc interlocked_compare_exchange (dst: ^i32, exchange, comparand: i32) -> i32 #cc_c #link_name "InterlockedCompareExchange";
|
||||
proc interlocked_exchange (dst: ^i32, desired: i32) -> i32 #cc_c #link_name "InterlockedExchange";
|
||||
proc interlocked_exchange_add (dst: ^i32, desired: i32) -> i32 #cc_c #link_name "InterlockedExchangeAdd";
|
||||
proc interlocked_and (dst: ^i32, desired: i32) -> i32 #cc_c #link_name "InterlockedAnd";
|
||||
proc interlocked_or (dst: ^i32, desired: i32) -> i32 #cc_c #link_name "InterlockedOr";
|
||||
|
||||
proc interlocked_compare_exchange64(dst: ^i64, exchange, comparand: i64) -> i64 #link_name "InterlockedCompareExchange64";
|
||||
proc interlocked_exchange64 (dst: ^i64, desired: i64) -> i64 #link_name "InterlockedExchange64";
|
||||
proc interlocked_exchange_add64 (dst: ^i64, desired: i64) -> i64 #link_name "InterlockedExchangeAdd64";
|
||||
proc interlocked_and64 (dst: ^i64, desired: i64) -> i64 #link_name "InterlockedAnd64";
|
||||
proc interlocked_or64 (dst: ^i64, desired: i64) -> i64 #link_name "InterlockedOr64";
|
||||
proc interlocked_compare_exchange64(dst: ^i64, exchange, comparand: i64) -> i64 #cc_c #link_name "InterlockedCompareExchange64";
|
||||
proc interlocked_exchange64 (dst: ^i64, desired: i64) -> i64 #cc_c #link_name "InterlockedExchange64";
|
||||
proc interlocked_exchange_add64 (dst: ^i64, desired: i64) -> i64 #cc_c #link_name "InterlockedExchangeAdd64";
|
||||
proc interlocked_and64 (dst: ^i64, desired: i64) -> i64 #cc_c #link_name "InterlockedAnd64";
|
||||
proc interlocked_or64 (dst: ^i64, desired: i64) -> i64 #cc_c #link_name "InterlockedOr64";
|
||||
|
||||
proc mm_pause () #link_name "_mm_pause";
|
||||
proc read_write_barrier() #link_name "ReadWriteBarrier";
|
||||
proc write_barrier () #link_name "WriteBarrier";
|
||||
proc read_barrier () #link_name "ReadBarrier";
|
||||
proc mm_pause () #cc_c #link_name "_mm_pause";
|
||||
proc read_write_barrier() #cc_c #link_name "ReadWriteBarrier";
|
||||
proc write_barrier () #cc_c #link_name "WriteBarrier";
|
||||
proc read_barrier () #cc_c #link_name "ReadBarrier";
|
||||
|
||||
|
||||
proc load_library_a (c_str: ^u8) -> Hmodule #link_name "LoadLibraryA";
|
||||
proc free_library (h: Hmodule) #link_name "FreeLibrary";
|
||||
proc get_proc_address(h: Hmodule, c_str: ^u8) -> Proc #link_name "GetProcAddress";
|
||||
proc load_library_a (c_str: ^u8) -> Hmodule #cc_c #link_name "LoadLibraryA";
|
||||
proc free_library (h: Hmodule) #cc_c #link_name "FreeLibrary";
|
||||
proc get_proc_address(h: Hmodule, c_str: ^u8) -> Proc #cc_c #link_name "GetProcAddress";
|
||||
|
||||
}
|
||||
|
||||
foreign user32 {
|
||||
proc get_desktop_window () -> Hwnd #link_name "GetDesktopWindow";
|
||||
proc show_cursor (show : Bool) #link_name "ShowCursor";
|
||||
proc get_cursor_pos (p: ^Point) -> i32 #link_name "GetCursorPos";
|
||||
proc screen_to_client (h: Hwnd, p: ^Point) -> i32 #link_name "ScreenToClient";
|
||||
proc post_quit_message (exit_code: i32) #link_name "PostQuitMessage";
|
||||
proc set_window_text_a (hwnd: Hwnd, c_string: ^u8) -> Bool #link_name "SetWindowTextA";
|
||||
proc register_class_ex_a (wc: ^WndClassExA) -> i16 #link_name "RegisterClassExA";
|
||||
proc get_desktop_window () -> Hwnd #cc_c #link_name "GetDesktopWindow";
|
||||
proc show_cursor (show : Bool) #cc_c #link_name "ShowCursor";
|
||||
proc get_cursor_pos (p: ^Point) -> i32 #cc_c #link_name "GetCursorPos";
|
||||
proc screen_to_client (h: Hwnd, p: ^Point) -> i32 #cc_c #link_name "ScreenToClient";
|
||||
proc post_quit_message (exit_code: i32) #cc_c #link_name "PostQuitMessage";
|
||||
proc set_window_text_a (hwnd: Hwnd, c_string: ^u8) -> Bool #cc_c #link_name "SetWindowTextA";
|
||||
proc register_class_ex_a (wc: ^WndClassExA) -> i16 #cc_c #link_name "RegisterClassExA";
|
||||
|
||||
proc create_window_ex_a (ex_style: u32,
|
||||
class_name, title: ^u8,
|
||||
style: u32,
|
||||
x, y, w, h: i32,
|
||||
parent: Hwnd, menu: Hmenu, instance: Hinstance,
|
||||
param: rawptr) -> Hwnd #link_name "CreateWindowExA";
|
||||
param: rawptr) -> Hwnd #cc_c #link_name "CreateWindowExA";
|
||||
|
||||
proc show_window (hwnd: Hwnd, cmd_show: i32) -> Bool #link_name "ShowWindow";
|
||||
proc translate_message (msg: ^Msg) -> Bool #link_name "TranslateMessage";
|
||||
proc dispatch_message_a (msg: ^Msg) -> Lresult #link_name "DispatchMessageA";
|
||||
proc update_window (hwnd: Hwnd) -> Bool #link_name "UpdateWindow";
|
||||
proc get_message_a (msg: ^Msg, hwnd: Hwnd, msg_filter_min, msg_filter_max : u32) -> Bool #link_name "GetMessageA";
|
||||
proc show_window (hwnd: Hwnd, cmd_show: i32) -> Bool #cc_c #link_name "ShowWindow";
|
||||
proc translate_message (msg: ^Msg) -> Bool #cc_c #link_name "TranslateMessage";
|
||||
proc dispatch_message_a (msg: ^Msg) -> Lresult #cc_c #link_name "DispatchMessageA";
|
||||
proc update_window (hwnd: Hwnd) -> Bool #cc_c #link_name "UpdateWindow";
|
||||
proc get_message_a (msg: ^Msg, hwnd: Hwnd, msg_filter_min, msg_filter_max : u32) -> Bool #cc_c #link_name "GetMessageA";
|
||||
proc peek_message_a (msg: ^Msg, hwnd: Hwnd,
|
||||
msg_filter_min, msg_filter_max, remove_msg: u32) -> Bool #link_name "PeekMessageA";
|
||||
msg_filter_min, msg_filter_max, remove_msg: u32) -> Bool #cc_c #link_name "PeekMessageA";
|
||||
|
||||
|
||||
proc post_message (hwnd: Hwnd, msg, wparam, lparam : u32) -> Bool #link_name "PostMessageA";
|
||||
proc post_message (hwnd: Hwnd, msg, wparam, lparam : u32) -> Bool #cc_c #link_name "PostMessageA";
|
||||
|
||||
proc def_window_proc_a (hwnd: Hwnd, msg: u32, wparam: Wparam, lparam: Lparam) -> Lresult #link_name "DefWindowProcA";
|
||||
proc def_window_proc_a (hwnd: Hwnd, msg: u32, wparam: Wparam, lparam: Lparam) -> Lresult #cc_c #link_name "DefWindowProcA";
|
||||
|
||||
proc adjust_window_rect (rect: ^Rect, style: u32, menu: Bool) -> Bool #link_name "AdjustWindowRect";
|
||||
proc get_active_window () -> Hwnd #link_name "GetActiveWindow";
|
||||
proc adjust_window_rect (rect: ^Rect, style: u32, menu: Bool) -> Bool #cc_c #link_name "AdjustWindowRect";
|
||||
proc get_active_window () -> Hwnd #cc_c #link_name "GetActiveWindow";
|
||||
|
||||
proc destroy_window (wnd: Hwnd) -> Bool #link_name "DestroyWindow";
|
||||
proc describe_pixel_format(dc: Hdc, pixel_format: i32, bytes : u32, pfd: ^PixelFormatDescriptor) -> i32 #link_name "DescribePixelFormat";
|
||||
proc destroy_window (wnd: Hwnd) -> Bool #cc_c #link_name "DestroyWindow";
|
||||
proc describe_pixel_format(dc: Hdc, pixel_format: i32, bytes : u32, pfd: ^PixelFormatDescriptor) -> i32 #cc_c #link_name "DescribePixelFormat";
|
||||
|
||||
proc get_monitor_info_a (monitor: Hmonitor, mi: ^MonitorInfo) -> Bool #link_name "GetMonitorInfoA";
|
||||
proc monitor_from_window (wnd: Hwnd, flags : u32) -> Hmonitor #link_name "MonitorFromWindow";
|
||||
proc get_monitor_info_a (monitor: Hmonitor, mi: ^MonitorInfo) -> Bool #cc_c #link_name "GetMonitorInfoA";
|
||||
proc monitor_from_window (wnd: Hwnd, flags : u32) -> Hmonitor #cc_c #link_name "MonitorFromWindow";
|
||||
|
||||
proc set_window_pos (wnd: Hwnd, wndInsertAfter: Hwnd, x, y, width, height: i32, flags: u32) #link_name "SetWindowPos";
|
||||
proc set_window_pos (wnd: Hwnd, wndInsertAfter: Hwnd, x, y, width, height: i32, flags: u32) #cc_c #link_name "SetWindowPos";
|
||||
|
||||
proc get_window_placement (wnd: Hwnd, wndpl: ^WindowPlacement) -> Bool #link_name "GetWindowPlacement";
|
||||
proc set_window_placement (wnd: Hwnd, wndpl: ^WindowPlacement) -> Bool #link_name "SetWindowPlacement";
|
||||
proc get_window_rect (wnd: Hwnd, rect: ^Rect) -> Bool #link_name "GetWindowRect";
|
||||
proc get_window_placement (wnd: Hwnd, wndpl: ^WindowPlacement) -> Bool #cc_c #link_name "GetWindowPlacement";
|
||||
proc set_window_placement (wnd: Hwnd, wndpl: ^WindowPlacement) -> Bool #cc_c #link_name "SetWindowPlacement";
|
||||
proc get_window_rect (wnd: Hwnd, rect: ^Rect) -> Bool #cc_c #link_name "GetWindowRect";
|
||||
|
||||
proc get_window_long_ptr_a(wnd: Hwnd, index: i32) -> i64 #link_name "GetWindowLongPtrA";
|
||||
proc set_window_long_ptr_a(wnd: Hwnd, index: i32, new: i64) -> i64 #link_name "SetWindowLongPtrA";
|
||||
proc get_window_long_ptr_a(wnd: Hwnd, index: i32) -> i64 #cc_c #link_name "GetWindowLongPtrA";
|
||||
proc set_window_long_ptr_a(wnd: Hwnd, index: i32, new: i64) -> i64 #cc_c #link_name "SetWindowLongPtrA";
|
||||
|
||||
proc get_window_text (wnd: Hwnd, str: ^u8, maxCount: i32) -> i32 #link_name "GetWindowText";
|
||||
proc get_window_text (wnd: Hwnd, str: ^u8, maxCount: i32) -> i32 #cc_c #link_name "GetWindowText";
|
||||
|
||||
proc get_client_rect (hwnd: Hwnd, rect: ^Rect) -> Bool #link_name "GetClientRect";
|
||||
proc get_client_rect (hwnd: Hwnd, rect: ^Rect) -> Bool #cc_c #link_name "GetClientRect";
|
||||
|
||||
proc get_dc (h: Hwnd) -> Hdc #link_name "GetDC";
|
||||
proc release_dc (wnd: Hwnd, hdc: Hdc) -> i32 #link_name "ReleaseDC";
|
||||
proc get_dc (h: Hwnd) -> Hdc #cc_c #link_name "GetDC";
|
||||
proc release_dc (wnd: Hwnd, hdc: Hdc) -> i32 #cc_c #link_name "ReleaseDC";
|
||||
|
||||
proc map_virtual_key(scancode : u32, map_type : u32) -> u32 #link_name "MapVirtualKeyA";
|
||||
proc map_virtual_key(scancode : u32, map_type : u32) -> u32 #cc_c #link_name "MapVirtualKeyA";
|
||||
|
||||
proc get_key_state (v_key: i32) -> i16 #link_name "GetKeyState";
|
||||
proc get_async_key_state(v_key: i32) -> i16 #link_name "GetAsyncKeyState";
|
||||
proc get_key_state (v_key: i32) -> i16 #cc_c #link_name "GetKeyState";
|
||||
proc get_async_key_state(v_key: i32) -> i16 #cc_c #link_name "GetAsyncKeyState";
|
||||
}
|
||||
|
||||
foreign gdi32 {
|
||||
proc get_stock_object(fn_object: i32) -> Hgdiobj #link_name "GetStockObject";
|
||||
proc get_stock_object(fn_object: i32) -> Hgdiobj #cc_c #link_name "GetStockObject";
|
||||
|
||||
proc stretch_dibits( 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,
|
||||
usage: u32,
|
||||
rop: u32) -> i32 #link_name "StretchDIBits";
|
||||
rop: u32) -> i32 #cc_c #link_name "StretchDIBits";
|
||||
|
||||
proc set_pixel_format (hdc: Hdc, pixel_format: i32, pfd: ^PixelFormatDescriptor) -> Bool #link_name "SetPixelFormat";
|
||||
proc choose_pixel_format(hdc: Hdc, pfd: ^PixelFormatDescriptor) -> i32 #link_name "ChoosePixelFormat";
|
||||
proc swap_buffers (hdc: Hdc) -> Bool #link_name "SwapBuffers";
|
||||
proc set_pixel_format (hdc: Hdc, pixel_format: i32, pfd: ^PixelFormatDescriptor) -> Bool #cc_c #link_name "SetPixelFormat";
|
||||
proc choose_pixel_format(hdc: Hdc, pfd: ^PixelFormatDescriptor) -> i32 #cc_c #link_name "ChoosePixelFormat";
|
||||
proc swap_buffers (hdc: Hdc) -> Bool #cc_c #link_name "SwapBuffers";
|
||||
|
||||
}
|
||||
|
||||
foreign shell32 {
|
||||
proc command_line_to_argv_w(cmd_list: ^u16, num_args: ^i32) -> ^^u16 #link_name "CommandLineToArgvW";
|
||||
proc command_line_to_argv_w(cmd_list: ^u16, num_args: ^i32) -> ^^u16 #cc_c #link_name "CommandLineToArgvW";
|
||||
}
|
||||
|
||||
foreign winmm {
|
||||
proc time_get_time() -> u32 #link_name "timeGetTime";
|
||||
proc time_get_time() -> u32 #cc_c #link_name "timeGetTime";
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -269,7 +269,11 @@ void init_build_context(void) {
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
bc->ODIN_OS = str_lit("windows");
|
||||
bc->ODIN_ARCH = str_lit("amd64");
|
||||
#if defined(GB_ARCH_64_BIT)
|
||||
bc->ODIN_ARCH = str_lit("amd64");
|
||||
#else
|
||||
bc->ODIN_ARCH = str_lit("x86");
|
||||
#endif
|
||||
bc->ODIN_ENDIAN = str_lit("little");
|
||||
#elif defined(GB_SYSTEM_OSX)
|
||||
bc->ODIN_OS = str_lit("osx");
|
||||
@@ -287,29 +291,27 @@ void init_build_context(void) {
|
||||
// across OSs. It doesn't make sense to allocate extra data on the heap
|
||||
// here, so I just #defined the linker flags to keep things concise.
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
|
||||
#define LINK_FLAG_X64 "/machine:x64"
|
||||
#define LINK_FLAG_X86 "/machine:x86"
|
||||
#define LINK_FLAG_X64 "/machine:x64"
|
||||
#define LINK_FLAG_X86 "/machine:x86"
|
||||
|
||||
#elif defined(GB_SYSTEM_OSX)
|
||||
// NOTE(zangent): MacOS systems are x64 only, so ld doesn't have
|
||||
// an architecture option. All compilation done on MacOS must be x64.
|
||||
GB_ASSERT(bc->ODIN_ARCH == "amd64");
|
||||
|
||||
// NOTE(zangent): MacOS systems are x64 only, so ld doesn't have
|
||||
// an architecture option. All compilation done on MacOS must be x64.
|
||||
GB_ASSERT(bc->ODIN_ARCH == "amd64");
|
||||
|
||||
#define LINK_FLAG_X64 ""
|
||||
#define LINK_FLAG_X86 ""
|
||||
#define LINK_FLAG_X64 ""
|
||||
#define LINK_FLAG_X86 ""
|
||||
#else
|
||||
// Linux, but also BSDs and the like.
|
||||
// NOTE(zangent): When clang is swapped out with ld as the linker,
|
||||
// the commented flags here should be used. Until then, we'll have
|
||||
// to use alternative build flags made for clang.
|
||||
/*
|
||||
#define LINK_FLAG_X64 "-m elf_x86_64"
|
||||
#define LINK_FLAG_X86 "-m elf_i386"
|
||||
*/
|
||||
#define LINK_FLAG_X64 "-arch x86-64"
|
||||
#define LINK_FLAG_X86 "-arch x86"
|
||||
// Linux, but also BSDs and the like.
|
||||
// NOTE(zangent): When clang is swapped out with ld as the linker,
|
||||
// the commented flags here should be used. Until then, we'll have
|
||||
// to use alternative build flags made for clang.
|
||||
/*
|
||||
#define LINK_FLAG_X64 "-m elf_x86_64"
|
||||
#define LINK_FLAG_X86 "-m elf_i386"
|
||||
*/
|
||||
#define LINK_FLAG_X64 "-arch x86-64"
|
||||
#define LINK_FLAG_X86 "-arch x86"
|
||||
#endif
|
||||
|
||||
if (bc->ODIN_ARCH == "amd64") {
|
||||
|
||||
@@ -12,7 +12,7 @@ Type *check_init_variable(Checker *c, Entity *e, Operand *operand, String contex
|
||||
|
||||
// TODO(bill): is this a good enough error message?
|
||||
// TODO(bill): Actually allow built in procedures to be passed around and thus be created on use
|
||||
error_node(operand->expr,
|
||||
error(operand->expr,
|
||||
"Cannot assign built-in procedure `%s` in %.*s",
|
||||
expr_str,
|
||||
LIT(context_name));
|
||||
@@ -108,7 +108,7 @@ void check_init_constant(Checker *c, Entity *e, Operand *operand) {
|
||||
if (operand->mode != Addressing_Constant) {
|
||||
// TODO(bill): better error
|
||||
gbString str = expr_to_string(operand->expr);
|
||||
error_node(operand->expr, "`%s` is not a constant", str);
|
||||
error(operand->expr, "`%s` is not a constant", str);
|
||||
gb_string_free(str);
|
||||
if (e->type == NULL) {
|
||||
e->type = t_invalid;
|
||||
@@ -117,7 +117,7 @@ void check_init_constant(Checker *c, Entity *e, Operand *operand) {
|
||||
}
|
||||
if (!is_type_constant_type(operand->type)) {
|
||||
gbString type_str = type_to_string(operand->type);
|
||||
error_node(operand->expr, "Invalid constant type: `%s`", type_str);
|
||||
error(operand->expr, "Invalid constant type: `%s`", type_str);
|
||||
gb_string_free(type_str);
|
||||
if (e->type == NULL) {
|
||||
e->type = t_invalid;
|
||||
@@ -172,7 +172,7 @@ void check_const_decl(Checker *c, Entity *e, AstNode *type_expr, AstNode *init,
|
||||
Type *t = check_type(c, type_expr);
|
||||
if (!is_type_constant_type(t)) {
|
||||
gbString str = type_to_string(t);
|
||||
error_node(type_expr, "Invalid constant type `%s`", str);
|
||||
error(type_expr, "Invalid constant type `%s`", str);
|
||||
gb_string_free(str);
|
||||
e->type = t_invalid;
|
||||
return;
|
||||
@@ -279,18 +279,18 @@ void init_entity_foreign_library(Checker *c, Entity *e) {
|
||||
if (ident == NULL) {
|
||||
error(e->token, "foreign entiies must declare which library they are from");
|
||||
} else if (ident->kind != AstNode_Ident) {
|
||||
error_node(ident, "foreign library names must be an identifier");
|
||||
error(ident, "foreign library names must be an identifier");
|
||||
} else {
|
||||
String name = ident->Ident.string;
|
||||
Entity *found = scope_lookup_entity(c->context.scope, name);
|
||||
if (found == NULL) {
|
||||
if (name == "_") {
|
||||
error_node(ident, "`_` cannot be used as a value type");
|
||||
error(ident, "`_` cannot be used as a value type");
|
||||
} else {
|
||||
error_node(ident, "Undeclared name: %.*s", LIT(name));
|
||||
error(ident, "Undeclared name: %.*s", LIT(name));
|
||||
}
|
||||
} else if (found->kind != Entity_LibraryName) {
|
||||
error_node(ident, "`%.*s` cannot be used as a library name", LIT(name));
|
||||
error(ident, "`%.*s` cannot be used as a library name", LIT(name));
|
||||
} else {
|
||||
// TODO(bill): Extra stuff to do with library names?
|
||||
*foreign_library = found;
|
||||
@@ -303,7 +303,7 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
|
||||
GB_ASSERT(e->type == NULL);
|
||||
if (d->proc_decl->kind != AstNode_ProcDecl) {
|
||||
// TOOD(bill): Better error message
|
||||
error_node(d->proc_decl, "Expected a procedure to check");
|
||||
error(d->proc_decl, "Expected a procedure to check");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -336,11 +336,11 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
|
||||
}
|
||||
|
||||
if (is_inline && is_no_inline) {
|
||||
error_node(pd->type, "You cannot apply both `inline` and `no_inline` to a procedure");
|
||||
error(pd->type, "You cannot apply both `inline` and `no_inline` to a procedure");
|
||||
}
|
||||
|
||||
if (is_foreign && is_export) {
|
||||
error_node(pd->type, "A foreign procedure cannot have an `export` tag");
|
||||
error(pd->type, "A foreign procedure cannot have an `export` tag");
|
||||
}
|
||||
|
||||
|
||||
@@ -352,10 +352,10 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
|
||||
|
||||
if (pd->body != NULL) {
|
||||
if (is_foreign) {
|
||||
error_node(pd->body, "A foreign procedure cannot have a body");
|
||||
error(pd->body, "A foreign procedure cannot have a body");
|
||||
}
|
||||
if (proc_type->Proc.c_vararg) {
|
||||
error_node(pd->body, "A procedure with a `#c_vararg` field cannot have a body");
|
||||
error(pd->body, "A procedure with a `#c_vararg` field cannot have a body");
|
||||
}
|
||||
|
||||
d->scope = c->context.scope;
|
||||
@@ -367,7 +367,7 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
|
||||
}
|
||||
|
||||
if (pt->result_count == 0 && is_require_results) {
|
||||
error_node(pd->type, "`#require_results` is not needed on a procedure with no results");
|
||||
error(pd->type, "`#require_results` is not needed on a procedure with no results");
|
||||
} else {
|
||||
pt->require_results = is_require_results;
|
||||
}
|
||||
@@ -393,13 +393,13 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
|
||||
Type *other_type = base_type(f->type);
|
||||
if (is_type_proc(this_type) && is_type_proc(other_type)) {
|
||||
if (!are_signatures_similar_enough(this_type, other_type)) {
|
||||
error_node(d->proc_decl,
|
||||
error(d->proc_decl,
|
||||
"Redeclaration of foreign procedure `%.*s` with different type signatures\n"
|
||||
"\tat %.*s(%td:%td)",
|
||||
LIT(name), LIT(pos.file), pos.line, pos.column);
|
||||
}
|
||||
} else if (!are_types_identical(this_type, other_type)) {
|
||||
error_node(d->proc_decl,
|
||||
error(d->proc_decl,
|
||||
"Foreign entity `%.*s` previously declared elsewhere with a different type\n"
|
||||
"\tat %.*s(%td:%td)",
|
||||
LIT(name), LIT(pos.file), pos.line, pos.column);
|
||||
@@ -424,7 +424,7 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
|
||||
Entity *f = *found;
|
||||
TokenPos pos = f->token.pos;
|
||||
// TODO(bill): Better error message?
|
||||
error_node(d->proc_decl,
|
||||
error(d->proc_decl,
|
||||
"Non unique linking name for procedure `%.*s`\n"
|
||||
"\tother at %.*s(%td:%td)",
|
||||
LIT(name), LIT(pos.file), pos.line, pos.column);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -30,7 +30,7 @@ void check_stmt_list(Checker *c, Array<AstNode *> stmts, u32 flags) {
|
||||
if (i+1 < max) {
|
||||
switch (n->kind) {
|
||||
case AstNode_ReturnStmt:
|
||||
error_node(n, "Statements after this `return` are never executed");
|
||||
error(n, "Statements after this `return` are never executed");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -283,7 +283,7 @@ Type *check_assignment_variable(Checker *c, Operand *rhs, AstNode *lhs_node) {
|
||||
}
|
||||
gbString lhs_expr = expr_to_string(lhs.expr);
|
||||
gbString rhs_expr = expr_to_string(rhs->expr);
|
||||
error_node(rhs->expr, "Cannot assign `%s` to bit field `%s`", rhs_expr, lhs_expr);
|
||||
error(rhs->expr, "Cannot assign `%s` to bit field `%s`", rhs_expr, lhs_expr);
|
||||
gb_string_free(rhs_expr);
|
||||
gb_string_free(lhs_expr);
|
||||
return NULL;
|
||||
@@ -300,7 +300,7 @@ Type *check_assignment_variable(Checker *c, Operand *rhs, AstNode *lhs_node) {
|
||||
if (tav.mode != Addressing_Variable) {
|
||||
if (!is_type_pointer(tav.type)) {
|
||||
gbString str = expr_to_string(lhs.expr);
|
||||
error_node(lhs.expr, "Cannot assign to the value of a map `%s`", str);
|
||||
error(lhs.expr, "Cannot assign to the value of a map `%s`", str);
|
||||
gb_string_free(str);
|
||||
return NULL;
|
||||
}
|
||||
@@ -316,7 +316,7 @@ Type *check_assignment_variable(Checker *c, Operand *rhs, AstNode *lhs_node) {
|
||||
check_expr(c, &op_c, se->expr);
|
||||
if (op_c.mode == Addressing_MapIndex) {
|
||||
gbString str = expr_to_string(lhs.expr);
|
||||
error_node(lhs.expr, "Cannot assign to record field `%s` in map", str);
|
||||
error(lhs.expr, "Cannot assign to record field `%s` in map", str);
|
||||
gb_string_free(str);
|
||||
return NULL;
|
||||
}
|
||||
@@ -324,9 +324,9 @@ Type *check_assignment_variable(Checker *c, Operand *rhs, AstNode *lhs_node) {
|
||||
|
||||
gbString str = expr_to_string(lhs.expr);
|
||||
if (lhs.mode == Addressing_Immutable) {
|
||||
error_node(lhs.expr, "Cannot assign to an immutable: `%s`", str);
|
||||
error(lhs.expr, "Cannot assign to an immutable: `%s`", str);
|
||||
} else {
|
||||
error_node(lhs.expr, "Cannot assign to `%s`", str);
|
||||
error(lhs.expr, "Cannot assign to `%s`", str);
|
||||
}
|
||||
gb_string_free(str);
|
||||
} break;
|
||||
@@ -394,11 +394,11 @@ void check_when_stmt(Checker *c, AstNodeWhenStmt *ws, u32 flags) {
|
||||
Operand operand = {Addressing_Invalid};
|
||||
check_expr(c, &operand, ws->cond);
|
||||
if (operand.mode != Addressing_Constant || !is_type_boolean(operand.type)) {
|
||||
error_node(ws->cond, "Non-constant boolean `when` condition");
|
||||
error(ws->cond, "Non-constant boolean `when` condition");
|
||||
return;
|
||||
}
|
||||
if (ws->body == NULL || ws->body->kind != AstNode_BlockStmt) {
|
||||
error_node(ws->cond, "Invalid body for `when` statement");
|
||||
error(ws->cond, "Invalid body for `when` statement");
|
||||
return;
|
||||
}
|
||||
if (operand.value.kind == ExactValue_Bool &&
|
||||
@@ -413,7 +413,7 @@ void check_when_stmt(Checker *c, AstNodeWhenStmt *ws, u32 flags) {
|
||||
check_when_stmt(c, &ws->else_stmt->WhenStmt, flags);
|
||||
break;
|
||||
default:
|
||||
error_node(ws->else_stmt, "Invalid `else` statement in `when` statement");
|
||||
error(ws->else_stmt, "Invalid `else` statement in `when` statement");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -425,18 +425,18 @@ void check_label(Checker *c, AstNode *label) {
|
||||
}
|
||||
ast_node(l, Label, label);
|
||||
if (l->name->kind != AstNode_Ident) {
|
||||
error_node(l->name, "A label's name must be an identifier");
|
||||
error(l->name, "A label's name must be an identifier");
|
||||
return;
|
||||
}
|
||||
String name = l->name->Ident.string;
|
||||
if (name == "_") {
|
||||
error_node(l->name, "A label's name cannot be a blank identifier");
|
||||
error(l->name, "A label's name cannot be a blank identifier");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (c->proc_stack.count == 0) {
|
||||
error_node(l->name, "A label is only allowed within a procedure");
|
||||
error(l->name, "A label is only allowed within a procedure");
|
||||
return;
|
||||
}
|
||||
GB_ASSERT(c->context.decl != NULL);
|
||||
@@ -445,7 +445,7 @@ void check_label(Checker *c, AstNode *label) {
|
||||
for_array(i, c->context.decl->labels) {
|
||||
BlockLabel bl = c->context.decl->labels[i];
|
||||
if (bl.name == name) {
|
||||
error_node(label, "Duplicate label with the name `%.*s`", LIT(name));
|
||||
error(label, "Duplicate label with the name `%.*s`", LIT(name));
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
@@ -594,7 +594,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
switch (operand.mode) {
|
||||
case Addressing_Type: {
|
||||
gbString str = type_to_string(operand.type);
|
||||
error_node(node, "`%s` is not an expression", str);
|
||||
error(node, "`%s` is not an expression", str);
|
||||
gb_string_free(str);
|
||||
} break;
|
||||
case Addressing_NoValue:
|
||||
@@ -609,14 +609,14 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
if (is_type_proc(t)) {
|
||||
if (t->Proc.require_results) {
|
||||
gbString expr_str = expr_to_string(ce->proc);
|
||||
error_node(node, "`%s` requires that its results must be handled", expr_str);
|
||||
error(node, "`%s` requires that its results must be handled", expr_str);
|
||||
gb_string_free(expr_str);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
gbString expr_str = expr_to_string(operand.expr);
|
||||
error_node(node, "Expression is not used: `%s`", expr_str);
|
||||
error(node, "Expression is not used: `%s`", expr_str);
|
||||
gb_string_free(expr_str);
|
||||
} break;
|
||||
}
|
||||
@@ -624,7 +624,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
|
||||
case_ast_node(ts, TagStmt, node);
|
||||
// TODO(bill): Tag Statements
|
||||
error_node(node, "Tag statements are not supported yet");
|
||||
error(node, "Tag statements are not supported yet");
|
||||
check_stmt(c, ts->stmt, flags);
|
||||
case_end;
|
||||
|
||||
@@ -634,7 +634,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
case Token_Inc: op = Token_Add; break;
|
||||
case Token_Dec: op = Token_Sub; break;
|
||||
default:
|
||||
error_node(node, "Invalid inc/dec operation");
|
||||
error(node, "Invalid inc/dec operation");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -646,7 +646,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
if (!is_type_integer(x.type) && !is_type_float(x.type)) {
|
||||
gbString e = expr_to_string(s->expr);
|
||||
gbString t = type_to_string(x.type);
|
||||
error_node(node, "%s%.*s used on non-numeric type %s", e, LIT(s->op.string), t);
|
||||
error(node, "%s%.*s used on non-numeric type %s", e, LIT(s->op.string), t);
|
||||
gb_string_free(t);
|
||||
gb_string_free(e);
|
||||
return;
|
||||
@@ -702,7 +702,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
check_assignment_variable(c, &operands[i], as->lhs[i]);
|
||||
}
|
||||
if (lhs_count != rhs_count) {
|
||||
error_node(as->lhs[0], "Assignment count mismatch `%td` = `%td`", lhs_count, rhs_count);
|
||||
error(as->lhs[0], "Assignment count mismatch `%td` = `%td`", lhs_count, rhs_count);
|
||||
}
|
||||
|
||||
gb_temp_arena_memory_end(tmp);
|
||||
@@ -754,7 +754,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
Operand operand = {Addressing_Invalid};
|
||||
check_expr(c, &operand, is->cond);
|
||||
if (operand.mode != Addressing_Invalid && !is_type_boolean(operand.type)) {
|
||||
error_node(is->cond, "Non-boolean condition in `if` statement");
|
||||
error(is->cond, "Non-boolean condition in `if` statement");
|
||||
}
|
||||
|
||||
check_stmt(c, is->body, mod_flags);
|
||||
@@ -766,7 +766,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
check_stmt(c, is->else_stmt, mod_flags);
|
||||
break;
|
||||
default:
|
||||
error_node(is->else_stmt, "Invalid `else` statement in `if` statement");
|
||||
error(is->else_stmt, "Invalid `else` statement in `if` statement");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -800,7 +800,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
variables = tuple->variables;
|
||||
}
|
||||
if (rs->results.count == 0) {
|
||||
error_node(node, "Expected %td return values, got 0", result_count);
|
||||
error(node, "Expected %td return values, got 0", result_count);
|
||||
} else {
|
||||
// TokenPos pos = rs->token.pos;
|
||||
// if (pos.line == 10) {
|
||||
@@ -815,7 +815,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
// }
|
||||
}
|
||||
} else if (rs->results.count > 0) {
|
||||
error_node(rs->results[0], "No return values expected");
|
||||
error(rs->results[0], "No return values expected");
|
||||
}
|
||||
case_end;
|
||||
|
||||
@@ -832,7 +832,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
Operand o = {Addressing_Invalid};
|
||||
check_expr(c, &o, fs->cond);
|
||||
if (o.mode != Addressing_Invalid && !is_type_boolean(o.type)) {
|
||||
error_node(fs->cond, "Non-boolean condition in `for` statement");
|
||||
error(fs->cond, "Non-boolean condition in `for` statement");
|
||||
}
|
||||
}
|
||||
if (fs->post != NULL) {
|
||||
@@ -840,7 +840,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
|
||||
if (fs->post->kind != AstNode_AssignStmt &&
|
||||
fs->post->kind != AstNode_IncDecStmt) {
|
||||
error_node(fs->post, "`for` statement post statement must be a simple statement");
|
||||
error(fs->post, "`for` statement post statement must be a simple statement");
|
||||
}
|
||||
}
|
||||
check_stmt(c, fs->body, new_flags);
|
||||
@@ -954,7 +954,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
if (operand.mode == Addressing_Type) {
|
||||
if (!is_type_enum(operand.type)) {
|
||||
gbString t = type_to_string(operand.type);
|
||||
error_node(operand.expr, "Cannot iterate over the type `%s`", t);
|
||||
error(operand.expr, "Cannot iterate over the type `%s`", t);
|
||||
gb_string_free(t);
|
||||
goto skip_expr;
|
||||
} else {
|
||||
@@ -1002,7 +1002,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
if (val == NULL) {
|
||||
gbString s = expr_to_string(operand.expr);
|
||||
gbString t = type_to_string(operand.type);
|
||||
error_node(operand.expr, "Cannot iterate over `%s` of type `%s`", s, t);
|
||||
error(operand.expr, "Cannot iterate over `%s` of type `%s`", s, t);
|
||||
gb_string_free(t);
|
||||
gb_string_free(s);
|
||||
}
|
||||
@@ -1040,7 +1040,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
entity = found;
|
||||
}
|
||||
} else {
|
||||
error_node(name, "A variable declaration must be an identifier");
|
||||
error(name, "A variable declaration must be an identifier");
|
||||
}
|
||||
|
||||
if (entity == NULL) {
|
||||
@@ -1089,7 +1089,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
}
|
||||
if (is_type_vector(x.type)) {
|
||||
gbString str = type_to_string(x.type);
|
||||
error_node(x.expr, "Invalid match expression type: %s", str);
|
||||
error(x.expr, "Invalid match expression type: %s", str);
|
||||
gb_string_free(str);
|
||||
break;
|
||||
}
|
||||
@@ -1107,13 +1107,13 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
default_stmt = stmt;
|
||||
}
|
||||
} else {
|
||||
error_node(stmt, "Invalid AST - expected case clause");
|
||||
error(stmt, "Invalid AST - expected case clause");
|
||||
}
|
||||
|
||||
if (default_stmt != NULL) {
|
||||
if (first_default != NULL) {
|
||||
TokenPos pos = ast_node_token(first_default).pos;
|
||||
error_node(stmt,
|
||||
error(stmt,
|
||||
"multiple `default` clauses\n"
|
||||
"\tfirst at %.*s(%td:%td)",
|
||||
LIT(pos.file), pos.line, pos.column);
|
||||
@@ -1155,7 +1155,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
|
||||
if (!is_type_ordered(x.type)) {
|
||||
gbString str = type_to_string(x.type);
|
||||
error_node(x.expr, "Unordered type `%s`, is invalid for an interval expression", str);
|
||||
error(x.expr, "Unordered type `%s`, is invalid for an interval expression", str);
|
||||
gb_string_free(str);
|
||||
continue;
|
||||
}
|
||||
@@ -1229,7 +1229,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
if (are_types_identical(y.type, tap.type)) {
|
||||
TokenPos pos = tap.token.pos;
|
||||
gbString expr_str = expr_to_string(y.expr);
|
||||
error_node(y.expr,
|
||||
error(y.expr,
|
||||
"Duplicate case `%s`\n"
|
||||
"\tprevious case at %.*s(%td:%td)",
|
||||
expr_str,
|
||||
@@ -1276,7 +1276,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
MatchTypeKind match_type_kind = MatchType_Invalid;
|
||||
|
||||
if (ms->tag->kind != AstNode_AssignStmt) {
|
||||
error_node(ms->tag, "Expected an `in` assignment for this type match statement");
|
||||
error(ms->tag, "Expected an `in` assignment for this type match statement");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1298,7 +1298,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
match_type_kind = check_valid_type_match_type(x.type);
|
||||
if (check_valid_type_match_type(x.type) == MatchType_Invalid) {
|
||||
gbString str = type_to_string(x.type);
|
||||
error_node(x.expr, "Invalid type for this type match expression, got `%s`", str);
|
||||
error(x.expr, "Invalid type for this type match expression, got `%s`", str);
|
||||
gb_string_free(str);
|
||||
break;
|
||||
}
|
||||
@@ -1317,13 +1317,13 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
default_stmt = stmt;
|
||||
}
|
||||
} else {
|
||||
error_node(stmt, "Invalid AST - expected case clause");
|
||||
error(stmt, "Invalid AST - expected case clause");
|
||||
}
|
||||
|
||||
if (default_stmt != NULL) {
|
||||
if (first_default != NULL) {
|
||||
TokenPos pos = ast_node_token(first_default).pos;
|
||||
error_node(stmt,
|
||||
error(stmt,
|
||||
"Multiple `default` clauses\n"
|
||||
"\tfirst at %.*s(%td:%td)", LIT(pos.file), pos.line, pos.column);
|
||||
} else {
|
||||
@@ -1334,7 +1334,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
|
||||
|
||||
if (lhs->kind != AstNode_Ident) {
|
||||
error_node(rhs, "Expected an identifier, got `%.*s`", LIT(ast_node_strings[rhs->kind]));
|
||||
error(rhs, "Expected an identifier, got `%.*s`", LIT(ast_node_strings[rhs->kind]));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1372,7 +1372,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
}
|
||||
if (!tag_type_found) {
|
||||
gbString type_str = type_to_string(y.type);
|
||||
error_node(y.expr, "Unknown tag type, got `%s`", type_str);
|
||||
error(y.expr, "Unknown tag type, got `%s`", type_str);
|
||||
gb_string_free(type_str);
|
||||
continue;
|
||||
}
|
||||
@@ -1388,7 +1388,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
if (found) {
|
||||
TokenPos pos = cc->token.pos;
|
||||
gbString expr_str = expr_to_string(y.expr);
|
||||
error_node(y.expr,
|
||||
error(y.expr,
|
||||
"Duplicate type case `%s`\n"
|
||||
"\tprevious type case at %.*s(%td:%td)",
|
||||
expr_str,
|
||||
@@ -1469,7 +1469,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
|
||||
if (bs->label != NULL) {
|
||||
if (bs->label->kind != AstNode_Ident) {
|
||||
error_node(bs->label, "A branch statement's label name must be an identifier");
|
||||
error(bs->label, "A branch statement's label name must be an identifier");
|
||||
return;
|
||||
}
|
||||
AstNode *ident = bs->label;
|
||||
@@ -1477,12 +1477,12 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
Operand o = {};
|
||||
Entity *e = check_ident(c, &o, ident, NULL, NULL, false);
|
||||
if (e == NULL) {
|
||||
error_node(ident, "Undeclared label name: %.*s", LIT(name));
|
||||
error(ident, "Undeclared label name: %.*s", LIT(name));
|
||||
return;
|
||||
}
|
||||
add_entity_use(c, ident, e);
|
||||
if (e->kind != Entity_Label) {
|
||||
error_node(ident, "`%.*s` is not a label", LIT(name));
|
||||
error(ident, "`%.*s` is not a label", LIT(name));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1537,7 +1537,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
AstNode *foreign_library = fb->foreign_library;
|
||||
bool ok = true;
|
||||
if (foreign_library->kind != AstNode_Ident) {
|
||||
error_node(foreign_library, "foreign library name must be an identifier");
|
||||
error(foreign_library, "foreign library name must be an identifier");
|
||||
ok = false;
|
||||
}
|
||||
|
||||
@@ -1576,14 +1576,14 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
|
||||
if (gd->flags & VarDeclFlag_thread_local) {
|
||||
gd->flags &= ~VarDeclFlag_thread_local;
|
||||
error_node(node, "`thread_local` may only be applied to a variable declaration");
|
||||
error(node, "`thread_local` may only be applied to a variable declaration");
|
||||
}
|
||||
|
||||
for_array(i, vd->names) {
|
||||
AstNode *name = vd->names[i];
|
||||
Entity *entity = NULL;
|
||||
if (name->kind != AstNode_Ident) {
|
||||
error_node(name, "A variable declaration must be an identifier");
|
||||
error(name, "A variable declaration must be an identifier");
|
||||
} else {
|
||||
Token token = name->Ident;
|
||||
String str = token.string;
|
||||
|
||||
@@ -1438,23 +1438,23 @@ bool check_arity_match(Checker *c, AstNodeValueSpec *spec) {
|
||||
|
||||
if (rhs == 0) {
|
||||
if (spec->type == NULL) {
|
||||
error_node(spec->names[0], "Missing type or initial expression");
|
||||
error(spec->names[0], "Missing type or initial expression");
|
||||
return false;
|
||||
}
|
||||
} else if (lhs < rhs) {
|
||||
if (lhs < spec->values.count) {
|
||||
AstNode *n = spec->values[lhs];
|
||||
gbString str = expr_to_string(n);
|
||||
error_node(n, "Extra initial expression `%s`", str);
|
||||
error(n, "Extra initial expression `%s`", str);
|
||||
gb_string_free(str);
|
||||
} else {
|
||||
error_node(spec->names[0], "Extra initial expression");
|
||||
error(spec->names[0], "Extra initial expression");
|
||||
}
|
||||
return false;
|
||||
} else if (lhs > rhs && rhs != 1) {
|
||||
AstNode *n = spec->names[rhs];
|
||||
gbString str = expr_to_string(n);
|
||||
error_node(n, "Missing expression for `%s`", str);
|
||||
error(n, "Missing expression for `%s`", str);
|
||||
gb_string_free(str);
|
||||
return false;
|
||||
}
|
||||
@@ -1466,13 +1466,13 @@ void check_collect_entities_from_when_stmt(Checker *c, AstNodeWhenStmt *ws, bool
|
||||
Operand operand = {Addressing_Invalid};
|
||||
check_expr(c, &operand, ws->cond);
|
||||
if (operand.mode != Addressing_Invalid && !is_type_boolean(operand.type)) {
|
||||
error_node(ws->cond, "Non-boolean condition in `when` statement");
|
||||
error(ws->cond, "Non-boolean condition in `when` statement");
|
||||
}
|
||||
if (operand.mode != Addressing_Constant) {
|
||||
error_node(ws->cond, "Non-constant condition in `when` statement");
|
||||
error(ws->cond, "Non-constant condition in `when` statement");
|
||||
}
|
||||
if (ws->body == NULL || ws->body->kind != AstNode_BlockStmt) {
|
||||
error_node(ws->cond, "Invalid body for `when` statement");
|
||||
error(ws->cond, "Invalid body for `when` statement");
|
||||
} else {
|
||||
if (operand.value.kind == ExactValue_Bool &&
|
||||
operand.value.value_bool) {
|
||||
@@ -1486,7 +1486,7 @@ void check_collect_entities_from_when_stmt(Checker *c, AstNodeWhenStmt *ws, bool
|
||||
check_collect_entities_from_when_stmt(c, &ws->else_stmt->WhenStmt, is_file_scope);
|
||||
break;
|
||||
default:
|
||||
error_node(ws->else_stmt, "Invalid `else` statement in `when` statement");
|
||||
error(ws->else_stmt, "Invalid `else` statement in `when` statement");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1514,7 +1514,7 @@ void check_collect_entities(Checker *c, Array<AstNode *> nodes, bool is_file_sco
|
||||
|
||||
case_ast_node(ws, WhenStmt, decl);
|
||||
if (c->context.scope->is_file) {
|
||||
error_node(decl, "`when` statements are not allowed at file scope");
|
||||
error(decl, "`when` statements are not allowed at file scope");
|
||||
} else {
|
||||
// Will be handled later
|
||||
}
|
||||
@@ -1538,7 +1538,7 @@ void check_collect_entities(Checker *c, Array<AstNode *> nodes, bool is_file_sco
|
||||
for_array(i, vs->names) {
|
||||
AstNode *name = vs->names[i];
|
||||
if (name->kind != AstNode_Ident) {
|
||||
error_node(name, "A declaration's name must be an identifier, got %.*s", LIT(ast_node_strings[name->kind]));
|
||||
error(name, "A declaration's name must be an identifier, got %.*s", LIT(ast_node_strings[name->kind]));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1580,7 +1580,7 @@ void check_collect_entities(Checker *c, Array<AstNode *> nodes, bool is_file_sco
|
||||
|
||||
|
||||
if (gd->flags & VarDeclFlag_thread_local) {
|
||||
error_node(decl, "#thread_local variable declarations cannot have initialization values");
|
||||
error(decl, "#thread_local variable declarations cannot have initialization values");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1592,7 +1592,7 @@ void check_collect_entities(Checker *c, Array<AstNode *> nodes, bool is_file_sco
|
||||
value = vs->values[i];
|
||||
}
|
||||
if (name->kind != AstNode_Ident) {
|
||||
error_node(name, "A declaration's name must be an identifier, got %.*s", LIT(ast_node_strings[name->kind]));
|
||||
error(name, "A declaration's name must be an identifier, got %.*s", LIT(ast_node_strings[name->kind]));
|
||||
continue;
|
||||
}
|
||||
Entity *e = make_entity_variable(c->allocator, c->context.scope, name->Ident, NULL, gd->token.kind == Token_let);
|
||||
@@ -1601,7 +1601,7 @@ void check_collect_entities(Checker *c, Array<AstNode *> nodes, bool is_file_sco
|
||||
|
||||
if (gd->flags & VarDeclFlag_using) {
|
||||
gd->flags &= ~VarDeclFlag_using; // NOTE(bill): This error will be only caught once
|
||||
error_node(name, "`using` is not allowed at the file scope");
|
||||
error(name, "`using` is not allowed at the file scope");
|
||||
}
|
||||
|
||||
AstNode *fl = c->context.curr_foreign_library;
|
||||
@@ -1636,7 +1636,7 @@ void check_collect_entities(Checker *c, Array<AstNode *> nodes, bool is_file_sco
|
||||
|
||||
AstNode *name = ts->name;
|
||||
if (name->kind != AstNode_Ident) {
|
||||
error_node(name, "A declaration's name must be an identifier, got %.*s", LIT(ast_node_strings[name->kind]));
|
||||
error(name, "A declaration's name must be an identifier, got %.*s", LIT(ast_node_strings[name->kind]));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1658,9 +1658,9 @@ void check_collect_entities(Checker *c, Array<AstNode *> nodes, bool is_file_sco
|
||||
ast_node(ts, ImportSpec, spec);
|
||||
if (!c->context.scope->is_file) {
|
||||
if (ts->is_import) {
|
||||
error_node(decl, "import declarations are only allowed in the file scope");
|
||||
error(decl, "import declarations are only allowed in the file scope");
|
||||
} else {
|
||||
error_node(decl, "import_load declarations are only allowed in the file scope");
|
||||
error(decl, "import_load declarations are only allowed in the file scope");
|
||||
}
|
||||
// NOTE(bill): _Should_ be caught by the parser
|
||||
// TODO(bill): Better error handling if it isn't
|
||||
@@ -1675,9 +1675,9 @@ void check_collect_entities(Checker *c, Array<AstNode *> nodes, bool is_file_sco
|
||||
ast_node(fl, ForeignLibrarySpec, spec);
|
||||
if (!c->context.scope->is_file) {
|
||||
if (fl->is_system) {
|
||||
error_node(spec, "foreign_system_library declarations are only allowed in the file scope");
|
||||
error(spec, "foreign_system_library declarations are only allowed in the file scope");
|
||||
} else {
|
||||
error_node(spec, "foreign_library declarations are only allowed in the file scope");
|
||||
error(spec, "foreign_library declarations are only allowed in the file scope");
|
||||
}
|
||||
// NOTE(bill): _Should_ be caught by the parser
|
||||
// TODO(bill): Better error handling if it isn't
|
||||
@@ -1688,7 +1688,7 @@ void check_collect_entities(Checker *c, Array<AstNode *> nodes, bool is_file_sco
|
||||
Operand operand = {Addressing_Invalid};
|
||||
check_expr(c, &operand, fl->cond);
|
||||
if (operand.mode != Addressing_Constant || !is_type_boolean(operand.type)) {
|
||||
error_node(fl->cond, "Non-constant boolean `when` condition");
|
||||
error(fl->cond, "Non-constant boolean `when` condition");
|
||||
continue;
|
||||
}
|
||||
if (operand.value.kind == ExactValue_Bool &&
|
||||
@@ -1707,7 +1707,7 @@ void check_collect_entities(Checker *c, Array<AstNode *> nodes, bool is_file_sco
|
||||
case_ast_node(fb, ForeignBlockDecl, decl);
|
||||
AstNode *foreign_library = fb->foreign_library;
|
||||
if (foreign_library->kind != AstNode_Ident) {
|
||||
error_node(foreign_library, "foreign library name must be an identifier");
|
||||
error(foreign_library, "foreign library name must be an identifier");
|
||||
foreign_library = NULL;
|
||||
}
|
||||
|
||||
@@ -1720,7 +1720,7 @@ void check_collect_entities(Checker *c, Array<AstNode *> nodes, bool is_file_sco
|
||||
case_ast_node(pd, ProcDecl, decl);
|
||||
AstNode *name = pd->name;
|
||||
if (name->kind != AstNode_Ident) {
|
||||
error_node(name, "A declaration's name must be an identifier, got %.*s", LIT(ast_node_strings[name->kind]));
|
||||
error(name, "A declaration's name must be an identifier, got %.*s", LIT(ast_node_strings[name->kind]));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1743,7 +1743,7 @@ void check_collect_entities(Checker *c, Array<AstNode *> nodes, bool is_file_sco
|
||||
|
||||
default:
|
||||
if (c->context.scope->is_file) {
|
||||
error_node(decl, "Only declarations are allowed at file scope");
|
||||
error(decl, "Only declarations are allowed at file scope");
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2011,7 +2011,7 @@ void check_import_entities(Checker *c, Map<Scope *> *file_scopes) {
|
||||
Operand operand = {Addressing_Invalid};
|
||||
check_expr(c, &operand, id->cond);
|
||||
if (operand.mode != Addressing_Constant || !is_type_boolean(operand.type)) {
|
||||
error_node(id->cond, "Non-constant boolean `when` condition");
|
||||
error(id->cond, "Non-constant boolean `when` condition");
|
||||
continue;
|
||||
}
|
||||
if (operand.value.kind == ExactValue_Bool &&
|
||||
@@ -2104,7 +2104,7 @@ void check_import_entities(Checker *c, Map<Scope *> *file_scopes) {
|
||||
Operand operand = {Addressing_Invalid};
|
||||
check_expr(c, &operand, fl->cond);
|
||||
if (operand.mode != Addressing_Constant || !is_type_boolean(operand.type)) {
|
||||
error_node(fl->cond, "Non-constant boolean `when` condition");
|
||||
error(fl->cond, "Non-constant boolean `when` condition");
|
||||
continue;
|
||||
}
|
||||
if (operand.value.kind == ExactValue_Bool &&
|
||||
@@ -2116,7 +2116,7 @@ void check_import_entities(Checker *c, Map<Scope *> *file_scopes) {
|
||||
|
||||
String library_name = path_to_entity_name(fl->library_name.string, file_str);
|
||||
if (library_name == "_") {
|
||||
error_node(spec, "File name, %.*s, cannot be as a library name as it is not a valid identifier", LIT(fl->library_name.string));
|
||||
error(spec, "File name, %.*s, cannot be as a library name as it is not a valid identifier", LIT(fl->library_name.string));
|
||||
} else {
|
||||
GB_ASSERT(fl->library_name.pos.line != 0);
|
||||
fl->library_name.string = library_name;
|
||||
|
||||
11
src/ir.cpp
11
src/ir.cpp
@@ -2262,6 +2262,17 @@ irValue *ir_emit_comp(irProcedure *proc, TokenKind op_kind, irValue *left, irVal
|
||||
left = ir_emit_conv(proc, left, ir_type(right));
|
||||
} else if (right->kind == irValue_Constant || right->kind == irValue_Nil) {
|
||||
right = ir_emit_conv(proc, right, ir_type(left));
|
||||
} else {
|
||||
gbAllocator a = proc->module->allocator;
|
||||
i64 ls = type_size_of(a, ir_type(left));
|
||||
i64 rs = type_size_of(a, ir_type(right));
|
||||
if (ls < rs) {
|
||||
left = ir_emit_conv(proc, left, ir_type(right));
|
||||
} else if (ls > rs) {
|
||||
right = ir_emit_conv(proc, right, ir_type(left));
|
||||
} else {
|
||||
right = ir_emit_conv(proc, right, ir_type(left));
|
||||
}
|
||||
}
|
||||
|
||||
Type *result = t_bool;
|
||||
|
||||
296
src/main.cpp
296
src/main.cpp
@@ -305,166 +305,166 @@ int main(int argc, char **argv) {
|
||||
#endif
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
timings_start_section(&timings, str_lit("llvm-llc"));
|
||||
// For more arguments: http://llvm.org/docs/CommandGuide/llc.html
|
||||
exit_code = system_exec_command_line_app("llvm-llc", false,
|
||||
"\"%.*sbin/llc\" \"%.*s.bc\" -filetype=obj -O%d "
|
||||
"%.*s "
|
||||
// "-debug-pass=Arguments "
|
||||
"",
|
||||
LIT(build_context.ODIN_ROOT),
|
||||
LIT(output_base),
|
||||
optimization_level,
|
||||
LIT(build_context.llc_flags));
|
||||
if (exit_code != 0) {
|
||||
return exit_code;
|
||||
}
|
||||
timings_start_section(&timings, str_lit("llvm-llc"));
|
||||
// For more arguments: http://llvm.org/docs/CommandGuide/llc.html
|
||||
exit_code = system_exec_command_line_app("llvm-llc", false,
|
||||
"\"%.*sbin/llc\" \"%.*s.bc\" -filetype=obj -O%d "
|
||||
"%.*s "
|
||||
// "-debug-pass=Arguments "
|
||||
"",
|
||||
LIT(build_context.ODIN_ROOT),
|
||||
LIT(output_base),
|
||||
optimization_level,
|
||||
LIT(build_context.llc_flags));
|
||||
if (exit_code != 0) {
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
timings_start_section(&timings, str_lit("msvc-link"));
|
||||
timings_start_section(&timings, str_lit("msvc-link"));
|
||||
|
||||
gbString lib_str = gb_string_make(heap_allocator(), "");
|
||||
// defer (gb_string_free(lib_str));
|
||||
char lib_str_buf[1024] = {0};
|
||||
for_array(i, ir_gen.module.foreign_library_paths) {
|
||||
String lib = ir_gen.module.foreign_library_paths[i];
|
||||
// gb_printf_err("Linking lib: %.*s\n", LIT(lib));
|
||||
isize len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf),
|
||||
" \"%.*s\"", LIT(lib));
|
||||
lib_str = gb_string_appendc(lib_str, lib_str_buf);
|
||||
}
|
||||
|
||||
char *output_ext = "exe";
|
||||
char *link_settings = "";
|
||||
if (build_context.is_dll) {
|
||||
output_ext = "dll";
|
||||
link_settings = "/DLL";
|
||||
} else {
|
||||
link_settings = "/ENTRY:mainCRTStartup";
|
||||
}
|
||||
|
||||
exit_code = system_exec_command_line_app("msvc-link", true,
|
||||
"link \"%.*s\".obj -OUT:\"%.*s.%s\" %s "
|
||||
"/defaultlib:libcmt "
|
||||
"/nologo /incremental:no /opt:ref /subsystem:CONSOLE "
|
||||
" %.*s "
|
||||
" %s "
|
||||
"",
|
||||
LIT(output_base), LIT(output_base), output_ext,
|
||||
lib_str, LIT(build_context.link_flags),
|
||||
link_settings
|
||||
);
|
||||
if (exit_code != 0) {
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
// timings_print_all(&timings);
|
||||
|
||||
if (run_output) {
|
||||
system_exec_command_line_app("odin run", false, "%.*s.exe", LIT(output_base));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// NOTE(zangent): Linux / Unix is unfinished and not tested very well.
|
||||
|
||||
|
||||
timings_start_section(&timings, str_lit("llvm-llc"));
|
||||
// For more arguments: http://llvm.org/docs/CommandGuide/llc.html
|
||||
exit_code = system_exec_command_line_app("llc", false,
|
||||
"llc \"%.*s.bc\" -filetype=obj -relocation-model=pic -O%d "
|
||||
"%.*s "
|
||||
// "-debug-pass=Arguments "
|
||||
"",
|
||||
LIT(output_base),
|
||||
optimization_level,
|
||||
LIT(build_context.llc_flags));
|
||||
if (exit_code != 0) {
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
timings_start_section(&timings, str_lit("ld-link"));
|
||||
|
||||
gbString lib_str = gb_string_make(heap_allocator(), "");
|
||||
// defer (gb_string_free(lib_str));
|
||||
char lib_str_buf[1024] = {0};
|
||||
for_array(i, ir_gen.module.foreign_library_paths) {
|
||||
String lib = ir_gen.module.foreign_library_paths[i];
|
||||
|
||||
// NOTE(zangent): Sometimes, you have to use -framework on MacOS.
|
||||
// This allows you to specify '-f' in a #foreign_system_library,
|
||||
// without having to implement any new syntax specifically for MacOS.
|
||||
#if defined(GB_SYSTEM_OSX)
|
||||
isize len;
|
||||
if(lib.len > 2 && lib[0] == '-' && lib[1] == 'f') {
|
||||
len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf),
|
||||
" -framework %.*s ", (int)(lib.len) - 2, lib.text + 2);
|
||||
} else {
|
||||
len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf),
|
||||
" -l%.*s ", LIT(lib));
|
||||
}
|
||||
#else
|
||||
gbString lib_str = gb_string_make(heap_allocator(), "");
|
||||
// defer (gb_string_free(lib_str));
|
||||
char lib_str_buf[1024] = {0};
|
||||
for_array(i, ir_gen.module.foreign_library_paths) {
|
||||
String lib = ir_gen.module.foreign_library_paths[i];
|
||||
// gb_printf_err("Linking lib: %.*s\n", LIT(lib));
|
||||
isize len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf),
|
||||
" -l%.*s ", LIT(lib));
|
||||
#endif
|
||||
lib_str = gb_string_appendc(lib_str, lib_str_buf);
|
||||
}
|
||||
" \"%.*s\"", LIT(lib));
|
||||
lib_str = gb_string_appendc(lib_str, lib_str_buf);
|
||||
}
|
||||
|
||||
// Unlike the Win32 linker code, the output_ext includes the dot, because
|
||||
// typically executable files on *NIX systems don't have extensions.
|
||||
char *output_ext = "";
|
||||
char *link_settings = "";
|
||||
char *linker;
|
||||
if (build_context.is_dll) {
|
||||
// Shared libraries are .dylib on MacOS and .so on Linux.
|
||||
// TODO(zangent): Is that statement entirely truthful?
|
||||
#if defined(GB_SYSTEM_OSX)
|
||||
output_ext = ".dylib";
|
||||
#else
|
||||
output_ext = ".so";
|
||||
#endif
|
||||
char *output_ext = "exe";
|
||||
char *link_settings = "";
|
||||
if (build_context.is_dll) {
|
||||
output_ext = "dll";
|
||||
link_settings = "/DLL";
|
||||
} else {
|
||||
link_settings = "/ENTRY:mainCRTStartup";
|
||||
}
|
||||
|
||||
link_settings = "-shared";
|
||||
} else {
|
||||
// TODO: Do I need anything here?
|
||||
link_settings = "";
|
||||
}
|
||||
exit_code = system_exec_command_line_app("msvc-link", true,
|
||||
"link \"%.*s\".obj -OUT:\"%.*s.%s\" %s "
|
||||
"/defaultlib:libcmt "
|
||||
"/nologo /incremental:no /opt:ref /subsystem:CONSOLE "
|
||||
" %.*s "
|
||||
" %s "
|
||||
"",
|
||||
LIT(output_base), LIT(output_base), output_ext,
|
||||
lib_str, LIT(build_context.link_flags),
|
||||
link_settings
|
||||
);
|
||||
if (exit_code != 0) {
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
// timings_print_all(&timings);
|
||||
|
||||
if (run_output) {
|
||||
system_exec_command_line_app("odin run", false, "%.*s.exe", LIT(output_base));
|
||||
}
|
||||
|
||||
#if defined(GB_SYSTEM_OSX)
|
||||
linker = "ld";
|
||||
#else
|
||||
// TODO(zangent): Figure out how to make ld work on Linux.
|
||||
// It probably has to do with including the entire CRT, but
|
||||
// that's quite a complicated issue to solve while remaining distro-agnostic.
|
||||
// Clang can figure out linker flags for us, and that's good enough _for now_.
|
||||
linker = "clang -Wno-unused-command-line-argument";
|
||||
#endif
|
||||
|
||||
exit_code = system_exec_command_line_app("ld-link", true,
|
||||
"%s \"%.*s\".o -o \"%.*s%s\" %s "
|
||||
"-lc -lm "
|
||||
" %.*s "
|
||||
" %s "
|
||||
// NOTE(zangent): Linux / Unix is unfinished and not tested very well.
|
||||
|
||||
|
||||
timings_start_section(&timings, str_lit("llvm-llc"));
|
||||
// For more arguments: http://llvm.org/docs/CommandGuide/llc.html
|
||||
exit_code = system_exec_command_line_app("llc", false,
|
||||
"llc \"%.*s.bc\" -filetype=obj -relocation-model=pic -O%d "
|
||||
"%.*s "
|
||||
// "-debug-pass=Arguments "
|
||||
"",
|
||||
LIT(output_base),
|
||||
optimization_level,
|
||||
LIT(build_context.llc_flags));
|
||||
if (exit_code != 0) {
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
timings_start_section(&timings, str_lit("ld-link"));
|
||||
|
||||
gbString lib_str = gb_string_make(heap_allocator(), "");
|
||||
// defer (gb_string_free(lib_str));
|
||||
char lib_str_buf[1024] = {0};
|
||||
for_array(i, ir_gen.module.foreign_library_paths) {
|
||||
String lib = ir_gen.module.foreign_library_paths[i];
|
||||
|
||||
// NOTE(zangent): Sometimes, you have to use -framework on MacOS.
|
||||
// This allows you to specify '-f' in a #foreign_system_library,
|
||||
// without having to implement any new syntax specifically for MacOS.
|
||||
#if defined(GB_SYSTEM_OSX)
|
||||
isize len;
|
||||
if(lib.len > 2 && lib[0] == '-' && lib[1] == 'f') {
|
||||
len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf),
|
||||
" -framework %.*s ", (int)(lib.len) - 2, lib.text + 2);
|
||||
} else {
|
||||
len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf),
|
||||
" -l%.*s ", LIT(lib));
|
||||
}
|
||||
#else
|
||||
isize len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf),
|
||||
" -l%.*s ", LIT(lib));
|
||||
#endif
|
||||
lib_str = gb_string_appendc(lib_str, lib_str_buf);
|
||||
}
|
||||
|
||||
// Unlike the Win32 linker code, the output_ext includes the dot, because
|
||||
// typically executable files on *NIX systems don't have extensions.
|
||||
char *output_ext = "";
|
||||
char *link_settings = "";
|
||||
char *linker;
|
||||
if (build_context.is_dll) {
|
||||
// Shared libraries are .dylib on MacOS and .so on Linux.
|
||||
// TODO(zangent): Is that statement entirely truthful?
|
||||
#if defined(GB_SYSTEM_OSX)
|
||||
output_ext = ".dylib";
|
||||
#else
|
||||
output_ext = ".so";
|
||||
#endif
|
||||
|
||||
link_settings = "-shared";
|
||||
} else {
|
||||
// TODO: Do I need anything here?
|
||||
link_settings = "";
|
||||
}
|
||||
|
||||
#if defined(GB_SYSTEM_OSX)
|
||||
// This sets a requirement of Mountain Lion and up, but the compiler doesn't work without this limit.
|
||||
// NOTE: If you change this (although this minimum is as low as you can go with Odin working)
|
||||
// make sure to also change the `mtriple` param passed to `opt`
|
||||
" -macosx_version_min 10.8.0 "
|
||||
// This points the linker to where the entry point is
|
||||
" -e _main "
|
||||
linker = "ld";
|
||||
#else
|
||||
// TODO(zangent): Figure out how to make ld work on Linux.
|
||||
// It probably has to do with including the entire CRT, but
|
||||
// that's quite a complicated issue to solve while remaining distro-agnostic.
|
||||
// Clang can figure out linker flags for us, and that's good enough _for now_.
|
||||
linker = "clang -Wno-unused-command-line-argument";
|
||||
#endif
|
||||
, linker, LIT(output_base), LIT(output_base), output_ext,
|
||||
lib_str, LIT(build_context.link_flags),
|
||||
link_settings
|
||||
);
|
||||
if (exit_code != 0) {
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
// timings_print_all(&timings);
|
||||
exit_code = system_exec_command_line_app("ld-link", true,
|
||||
"%s \"%.*s\".o -o \"%.*s%s\" %s "
|
||||
"-lc -lm "
|
||||
" %.*s "
|
||||
" %s "
|
||||
#if defined(GB_SYSTEM_OSX)
|
||||
// This sets a requirement of Mountain Lion and up, but the compiler doesn't work without this limit.
|
||||
// NOTE: If you change this (although this minimum is as low as you can go with Odin working)
|
||||
// make sure to also change the `mtriple` param passed to `opt`
|
||||
" -macosx_version_min 10.8.0 "
|
||||
// This points the linker to where the entry point is
|
||||
" -e _main "
|
||||
#endif
|
||||
, linker, LIT(output_base), LIT(output_base), output_ext,
|
||||
lib_str, LIT(build_context.link_flags),
|
||||
link_settings
|
||||
);
|
||||
if (exit_code != 0) {
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
if (run_output) {
|
||||
system_exec_command_line_app("odin run", false, "%.*s", LIT(output_base));
|
||||
}
|
||||
// timings_print_all(&timings);
|
||||
|
||||
if (run_output) {
|
||||
system_exec_command_line_app("odin run", false, "%.*s", LIT(output_base));
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -34,6 +34,7 @@ struct AstFile {
|
||||
// NOTE(bill): Used to prevent type literals in control clauses
|
||||
isize expr_level;
|
||||
bool allow_range; // NOTE(bill): Ranges are only allowed in certain cases
|
||||
bool in_foreign_block;
|
||||
|
||||
Array<AstNode *> decls;
|
||||
bool is_global_scope;
|
||||
@@ -90,12 +91,11 @@ enum ProcTag {
|
||||
};
|
||||
|
||||
enum ProcCallingConvention {
|
||||
ProcCC_Odin = 0,
|
||||
ProcCC_C = 1,
|
||||
ProcCC_Std = 2,
|
||||
ProcCC_Fast = 3,
|
||||
|
||||
ProcCC_Invalid,
|
||||
ProcCC_Invalid = 0,
|
||||
ProcCC_Odin = 1,
|
||||
ProcCC_C = 2,
|
||||
ProcCC_Std = 3,
|
||||
ProcCC_Fast = 4,
|
||||
};
|
||||
|
||||
enum VarDeclFlag {
|
||||
@@ -861,21 +861,21 @@ AstNode *clone_ast_node(gbAllocator a, AstNode *node) {
|
||||
}
|
||||
|
||||
|
||||
void error_node(AstNode *node, char *fmt, ...) {
|
||||
void error(AstNode *node, char *fmt, ...) {
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
error_va(ast_node_token(node), fmt, va);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
void warning_node(AstNode *node, char *fmt, ...) {
|
||||
void warning(AstNode *node, char *fmt, ...) {
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
warning_va(ast_node_token(node), fmt, va);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
void syntax_error_node(AstNode *node, char *fmt, ...) {
|
||||
void syntax_error(AstNode *node, char *fmt, ...) {
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
syntax_error_va(ast_node_token(node), fmt, va);
|
||||
@@ -885,7 +885,7 @@ void syntax_error_node(AstNode *node, char *fmt, ...) {
|
||||
|
||||
bool ast_node_expect(AstNode *node, AstNodeKind kind) {
|
||||
if (node->kind != kind) {
|
||||
error_node(node, "Expected %.*s, got %.*s", LIT(ast_node_strings[node->kind]));
|
||||
error(node, "Expected %.*s, got %.*s", LIT(ast_node_strings[node->kind]));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -1980,7 +1980,7 @@ AstNode *parse_type_or_ident(AstFile *f);
|
||||
|
||||
void check_proc_add_tag(AstFile *f, AstNode *tag_expr, u64 *tags, ProcTag tag, String tag_name) {
|
||||
if (*tags & tag) {
|
||||
syntax_error_node(tag_expr, "Procedure tag already used: %.*s", LIT(tag_name));
|
||||
syntax_error(tag_expr, "Procedure tag already used: %.*s", LIT(tag_name));
|
||||
}
|
||||
*tags |= tag;
|
||||
}
|
||||
@@ -2056,7 +2056,7 @@ void parse_proc_tags(AstFile *f, u64 *tags, String *link_name, ProcCallingConven
|
||||
*link_name = f->curr_token.string;
|
||||
// TODO(bill): Check if valid string
|
||||
if (!is_foreign_name_valid(*link_name)) {
|
||||
syntax_error_node(tag_expr, "Invalid alternative link procedure name `%.*s`", LIT(*link_name));
|
||||
syntax_error(tag_expr, "Invalid alternative link procedure name `%.*s`", LIT(*link_name));
|
||||
}
|
||||
|
||||
next_token(f);
|
||||
@@ -2076,35 +2076,35 @@ void parse_proc_tags(AstFile *f, u64 *tags, String *link_name, ProcCallingConven
|
||||
if (cc == ProcCC_Invalid) {
|
||||
cc = ProcCC_Odin;
|
||||
} else {
|
||||
syntax_error_node(tag_expr, "Multiple calling conventions for procedure type");
|
||||
syntax_error(tag_expr, "Multiple calling conventions for procedure type");
|
||||
}
|
||||
} else if (tag_name == "cc_c") {
|
||||
if (cc == ProcCC_Invalid) {
|
||||
cc = ProcCC_C;
|
||||
} else {
|
||||
syntax_error_node(tag_expr, "Multiple calling conventions for procedure type");
|
||||
syntax_error(tag_expr, "Multiple calling conventions for procedure type");
|
||||
}
|
||||
} else if (tag_name == "cc_std") {
|
||||
if (cc == ProcCC_Invalid) {
|
||||
cc = ProcCC_Std;
|
||||
} else {
|
||||
syntax_error_node(tag_expr, "Multiple calling conventions for procedure type");
|
||||
syntax_error(tag_expr, "Multiple calling conventions for procedure type");
|
||||
}
|
||||
} else if (tag_name == "cc_fast") {
|
||||
if (cc == ProcCC_Invalid) {
|
||||
cc = ProcCC_Fast;
|
||||
} else {
|
||||
syntax_error_node(tag_expr, "Multiple calling conventions for procedure type");
|
||||
syntax_error(tag_expr, "Multiple calling conventions for procedure type");
|
||||
}
|
||||
} else {
|
||||
syntax_error_node(tag_expr, "Unknown procedure tag #%.*s\n", LIT(tag_name));
|
||||
syntax_error(tag_expr, "Unknown procedure tag #%.*s\n", LIT(tag_name));
|
||||
}
|
||||
|
||||
#undef ELSE_IF_ADD_TAG
|
||||
}
|
||||
|
||||
if (cc == ProcCC_Invalid) {
|
||||
if ((*tags) & ProcTag_foreign) {
|
||||
if ((*tags) & ProcTag_foreign || f->in_foreign_block) {
|
||||
cc = ProcCC_C;
|
||||
} else {
|
||||
cc = ProcCC_Odin;
|
||||
@@ -2116,7 +2116,7 @@ void parse_proc_tags(AstFile *f, u64 *tags, String *link_name, ProcCallingConven
|
||||
}
|
||||
|
||||
if ((*tags & ProcTag_foreign) && (*tags & ProcTag_export)) {
|
||||
syntax_error(f->curr_token, "You cannot apply both #foreign and #export to a procedure");
|
||||
syntax_error(f->curr_token, "A foreign procedure cannot have #export");
|
||||
}
|
||||
|
||||
if ((*tags & ProcTag_inline) && (*tags & ProcTag_no_inline)) {
|
||||
@@ -2221,7 +2221,7 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
|
||||
AstNode *expr = parse_expr(f, false);
|
||||
operand = ast_run_expr(f, token, name, expr);
|
||||
if (unparen_expr(expr)->kind != AstNode_CallExpr) {
|
||||
error_node(expr, "#run can only be applied to procedure calls");
|
||||
error(expr, "#run can only be applied to procedure calls");
|
||||
operand = ast_bad_expr(f, token, f->curr_token);
|
||||
}
|
||||
warning(token, "#run is not yet implemented");
|
||||
@@ -2943,7 +2943,7 @@ void parse_foreign_block_decl(AstFile *f, Array<AstNode *> *decls) {
|
||||
|
||||
/* fallthrough */
|
||||
default:
|
||||
error_node(decl, "Foreign blocks only allow procedure and variable declarations");
|
||||
error(decl, "Foreign blocks only allow procedure and variable declarations");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -2979,6 +2979,10 @@ AstNode *parse_decl(AstFile *f) {
|
||||
Token close = {};
|
||||
Array<AstNode *> decls = make_ast_node_array(f);
|
||||
|
||||
bool prev_in_foreign_block = f->in_foreign_block;
|
||||
defer (f->in_foreign_block = prev_in_foreign_block);
|
||||
f->in_foreign_block = true;
|
||||
|
||||
if (f->curr_token.kind != Token_OpenBrace) {
|
||||
parse_foreign_block_decl(f, &decls);
|
||||
} else {
|
||||
@@ -3161,8 +3165,7 @@ AstNode *parse_proc_type(AstFile *f, Token proc_token, String *link_name_) {
|
||||
|
||||
u64 tags = 0;
|
||||
String link_name = {};
|
||||
ProcCallingConvention cc = ProcCC_Odin;
|
||||
|
||||
ProcCallingConvention cc = ProcCC_Invalid;
|
||||
parse_proc_tags(f, &tags, &link_name, &cc);
|
||||
|
||||
if (link_name_) *link_name_ = link_name;
|
||||
@@ -3293,7 +3296,7 @@ Array<AstNode *> convert_to_ident_list(AstFile *f, Array<AstNodeAndFlags> list,
|
||||
|
||||
if (!ignore_flags) {
|
||||
if (i != 0) {
|
||||
error_node(ident, "Illegal use of prefixes in parameter list");
|
||||
error(ident, "Illegal use of prefixes in parameter list");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3302,7 +3305,7 @@ Array<AstNode *> convert_to_ident_list(AstFile *f, Array<AstNodeAndFlags> list,
|
||||
case AstNode_BadExpr:
|
||||
break;
|
||||
default:
|
||||
error_node(ident, "Expected an identifier");
|
||||
error(ident, "Expected an identifier");
|
||||
ident = ast_ident(f, blank_token);
|
||||
break;
|
||||
}
|
||||
@@ -3951,7 +3954,7 @@ AstNode *parse_for_stmt(AstFile *f) {
|
||||
index = cond->AssignStmt.lhs[1];
|
||||
break;
|
||||
default:
|
||||
error_node(cond, "Expected at 1 or 2 identifiers");
|
||||
error(cond, "Expected at 1 or 2 identifiers");
|
||||
return ast_bad_stmt(f, token, f->curr_token);
|
||||
}
|
||||
|
||||
@@ -4301,7 +4304,7 @@ Array<AstNode *> parse_stmt_list(AstFile *f) {
|
||||
if (stmt->kind == AstNode_ExprStmt &&
|
||||
stmt->ExprStmt.expr != NULL &&
|
||||
stmt->ExprStmt.expr->kind == AstNode_ProcLit) {
|
||||
syntax_error_node(stmt, "Procedure literal evaluated but not used");
|
||||
syntax_error(stmt, "Procedure literal evaluated but not used");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4466,7 +4469,7 @@ void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, Array<AstNod
|
||||
node->kind != AstNode_BadStmt &&
|
||||
node->kind != AstNode_EmptyStmt) {
|
||||
// NOTE(bill): Sanity check
|
||||
syntax_error_node(node, "Only declarations are allowed at file scope %.*s", LIT(ast_node_strings[node->kind]));
|
||||
syntax_error(node, "Only declarations are allowed at file scope %.*s", LIT(ast_node_strings[node->kind]));
|
||||
} else if (node->kind == AstNode_GenDecl) {
|
||||
ast_node(gd, GenDecl, node);
|
||||
if (gd->token.kind == Token_import ||
|
||||
@@ -4482,9 +4485,9 @@ void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, Array<AstNod
|
||||
|
||||
if (!is_import_path_valid(file_str)) {
|
||||
if (id->is_import) {
|
||||
syntax_error_node(node, "Invalid import path: `%.*s`", LIT(file_str));
|
||||
syntax_error(node, "Invalid import path: `%.*s`", LIT(file_str));
|
||||
} else {
|
||||
syntax_error_node(node, "Invalid include path: `%.*s`", LIT(file_str));
|
||||
syntax_error(node, "Invalid include path: `%.*s`", LIT(file_str));
|
||||
}
|
||||
// NOTE(bill): It's a naughty name
|
||||
decls[i] = ast_bad_decl(f, id->relpath, id->relpath);
|
||||
@@ -4513,9 +4516,9 @@ void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, Array<AstNod
|
||||
|
||||
if (!is_import_path_valid(file_str)) {
|
||||
if (fl->is_system) {
|
||||
syntax_error_node(node, "Invalid `foreign_system_library` path");
|
||||
syntax_error(node, "Invalid `foreign_system_library` path");
|
||||
} else {
|
||||
syntax_error_node(node, "Invalid `foreign_library` path");
|
||||
syntax_error(node, "Invalid `foreign_library` path");
|
||||
}
|
||||
// NOTE(bill): It's a naughty name
|
||||
gd->specs[spec_index] = ast_bad_decl(f, fl->filepath, fl->filepath);
|
||||
|
||||
Reference in New Issue
Block a user