mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 15:18:49 +00:00
Handle calling conventions correctly
This commit is contained in:
+6
-11
@@ -1,4 +1,4 @@
|
|||||||
import (
|
import {
|
||||||
"atomic.odin";
|
"atomic.odin";
|
||||||
"fmt.odin";
|
"fmt.odin";
|
||||||
"hash.odin";
|
"hash.odin";
|
||||||
@@ -8,17 +8,12 @@ import (
|
|||||||
"os.odin";
|
"os.odin";
|
||||||
"sync.odin";
|
"sync.odin";
|
||||||
"utf8.odin";
|
"utf8.odin";
|
||||||
)
|
win32 "sys/windows.odin";
|
||||||
|
}
|
||||||
|
|
||||||
proc main() {
|
proc main() {
|
||||||
var x = proc() -> int {
|
var x = ~(0 as u32);
|
||||||
proc print_here() {
|
var y = x << 32;
|
||||||
fmt.println("Here");
|
fmt.println(y);
|
||||||
}
|
|
||||||
|
|
||||||
print_here();
|
|
||||||
return 1;
|
|
||||||
};
|
|
||||||
fmt.println(x());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-8
@@ -1,10 +1,10 @@
|
|||||||
#shared_global_scope;
|
#shared_global_scope;
|
||||||
|
|
||||||
import (
|
import {
|
||||||
"os.odin";
|
"os.odin";
|
||||||
"fmt.odin";
|
"fmt.odin";
|
||||||
"mem.odin";
|
"mem.odin";
|
||||||
)
|
}
|
||||||
|
|
||||||
// IMPORTANT NOTE(bill): `type_info` & `type_info_val` cannot be used within a
|
// IMPORTANT NOTE(bill): `type_info` & `type_info_val` cannot be used within a
|
||||||
// #shared_global_scope due to the internals of the compiler.
|
// #shared_global_scope due to the internals of the compiler.
|
||||||
@@ -14,7 +14,7 @@ import (
|
|||||||
|
|
||||||
// IMPORTANT NOTE(bill): Do not change the order of any of this data
|
// IMPORTANT NOTE(bill): Do not change the order of any of this data
|
||||||
// The compiler relies upon this _exact_ order
|
// The compiler relies upon this _exact_ order
|
||||||
type (
|
type {
|
||||||
Type_Info_Member struct #ordered {
|
Type_Info_Member struct #ordered {
|
||||||
name string; // can be empty if tuple
|
name string; // can be empty if tuple
|
||||||
type_info ^Type_Info;
|
type_info ^Type_Info;
|
||||||
@@ -74,7 +74,7 @@ type (
|
|||||||
Union Type_Info_Record;
|
Union Type_Info_Record;
|
||||||
Raw_Union Type_Info_Record;
|
Raw_Union Type_Info_Record;
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
proc type_info_base(info ^Type_Info) -> ^Type_Info {
|
proc type_info_base(info ^Type_Info) -> ^Type_Info {
|
||||||
if info == nil {
|
if info == nil {
|
||||||
@@ -113,13 +113,13 @@ proc fmuladd64(a, b, c f64) -> f64 #foreign "llvm.fmuladd.f64"
|
|||||||
|
|
||||||
|
|
||||||
type Allocator_Mode u8;
|
type Allocator_Mode u8;
|
||||||
const (
|
const {
|
||||||
ALLOCATOR_ALLOC Allocator_Mode = iota;
|
ALLOCATOR_ALLOC Allocator_Mode = iota;
|
||||||
ALLOCATOR_FREE;
|
ALLOCATOR_FREE;
|
||||||
ALLOCATOR_FREE_ALL;
|
ALLOCATOR_FREE_ALL;
|
||||||
ALLOCATOR_RESIZE;
|
ALLOCATOR_RESIZE;
|
||||||
);
|
}
|
||||||
type (
|
type {
|
||||||
Allocator_Proc proc(allocator_data rawptr, mode Allocator_Mode,
|
Allocator_Proc proc(allocator_data rawptr, mode Allocator_Mode,
|
||||||
size, alignment int,
|
size, alignment int,
|
||||||
old_memory rawptr, old_size int, flags u64) -> rawptr;
|
old_memory rawptr, old_size int, flags u64) -> rawptr;
|
||||||
@@ -136,7 +136,7 @@ type (
|
|||||||
user_data rawptr;
|
user_data rawptr;
|
||||||
user_index int;
|
user_index int;
|
||||||
}
|
}
|
||||||
);
|
}
|
||||||
|
|
||||||
#thread_local var __context Context;
|
#thread_local var __context Context;
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
import (
|
import {
|
||||||
"os.odin";
|
"os.odin";
|
||||||
"mem.odin";
|
"mem.odin";
|
||||||
"utf8.odin";
|
"utf8.odin";
|
||||||
)
|
}
|
||||||
|
|
||||||
const PRINT_BUF_SIZE = 1<<12;
|
const PRINT_BUF_SIZE = 1<<12;
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -1,4 +1,4 @@
|
|||||||
const (
|
const {
|
||||||
TAU = 6.28318530717958647692528676655900576;
|
TAU = 6.28318530717958647692528676655900576;
|
||||||
PI = 3.14159265358979323846264338327950288;
|
PI = 3.14159265358979323846264338327950288;
|
||||||
ONE_OVER_TAU = 0.636619772367581343075535053490057448;
|
ONE_OVER_TAU = 0.636619772367581343075535053490057448;
|
||||||
@@ -16,9 +16,9 @@ const (
|
|||||||
|
|
||||||
τ = TAU;
|
τ = TAU;
|
||||||
π = PI;
|
π = PI;
|
||||||
)
|
}
|
||||||
|
|
||||||
type (
|
type {
|
||||||
Vec2 [vector 2]f32;
|
Vec2 [vector 2]f32;
|
||||||
Vec3 [vector 3]f32;
|
Vec3 [vector 3]f32;
|
||||||
Vec4 [vector 4]f32;
|
Vec4 [vector 4]f32;
|
||||||
@@ -26,7 +26,7 @@ type (
|
|||||||
Mat2 [2]Vec2;
|
Mat2 [2]Vec2;
|
||||||
Mat3 [3]Vec3;
|
Mat3 [3]Vec3;
|
||||||
Mat4 [4]Vec4;
|
Mat4 [4]Vec4;
|
||||||
)
|
}
|
||||||
|
|
||||||
proc sqrt32(x f32) -> f32 #foreign "llvm.sqrt.f32"
|
proc sqrt32(x f32) -> f32 #foreign "llvm.sqrt.f32"
|
||||||
proc sqrt64(x f64) -> f64 #foreign "llvm.sqrt.f64"
|
proc sqrt64(x f64) -> f64 #foreign "llvm.sqrt.f64"
|
||||||
|
|||||||
+4
-4
@@ -1,7 +1,7 @@
|
|||||||
import (
|
import {
|
||||||
"fmt.odin";
|
"fmt.odin";
|
||||||
"os.odin";
|
"os.odin";
|
||||||
)
|
}
|
||||||
|
|
||||||
proc set(data rawptr, value i32, len int) -> rawptr #link_name "__mem_set" {
|
proc set(data rawptr, value i32, len int) -> rawptr #link_name "__mem_set" {
|
||||||
proc llvm_memset_64bit(dst rawptr, val byte, len int, align i32, is_volatile bool) #foreign "llvm.memset.p0i8.i64"
|
proc llvm_memset_64bit(dst rawptr, val byte, len int, align i32, is_volatile bool) #foreign "llvm.memset.p0i8.i64"
|
||||||
@@ -116,7 +116,7 @@ proc allocation_header(data rawptr) -> ^Allocation_Header {
|
|||||||
|
|
||||||
|
|
||||||
// Custom allocators
|
// Custom allocators
|
||||||
type (
|
type {
|
||||||
Arena struct {
|
Arena struct {
|
||||||
backing Allocator;
|
backing Allocator;
|
||||||
memory []byte;
|
memory []byte;
|
||||||
@@ -127,7 +127,7 @@ type (
|
|||||||
arena ^Arena;
|
arena ^Arena;
|
||||||
original_count int;
|
original_count int;
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+50
-50
@@ -32,7 +32,7 @@ proc GetIntegerv(name i32, v ^i32) #foreign "glGetIntegerv"
|
|||||||
|
|
||||||
var _libgl = win32.LoadLibraryA(("opengl32.dll\x00" as string).data);
|
var _libgl = win32.LoadLibraryA(("opengl32.dll\x00" as string).data);
|
||||||
|
|
||||||
proc GetProcAddress(name string) -> proc() {
|
proc GetProcAddress(name string) -> proc() #cc_c {
|
||||||
assert(name[name.count-1] == 0);
|
assert(name[name.count-1] == 0);
|
||||||
var res = win32.wglGetProcAddress(name.data);
|
var res = win32.wglGetProcAddress(name.data);
|
||||||
if res == nil {
|
if res == nil {
|
||||||
@@ -41,68 +41,68 @@ proc GetProcAddress(name string) -> proc() {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var {
|
||||||
GenBuffers proc(count i32, buffers ^u32);
|
GenBuffers proc(count i32, buffers ^u32) #cc_c;
|
||||||
GenVertexArrays proc(count i32, buffers ^u32);
|
GenVertexArrays proc(count i32, buffers ^u32) #cc_c;
|
||||||
GenSamplers proc(count i32, buffers ^u32);
|
GenSamplers proc(count i32, buffers ^u32) #cc_c;
|
||||||
BindBuffer proc(target i32, buffer u32);
|
BindBuffer proc(target i32, buffer u32) #cc_c;
|
||||||
BindVertexArray proc(buffer u32);
|
BindVertexArray proc(buffer u32) #cc_c;
|
||||||
BindSampler proc(position i32, sampler u32);
|
BindSampler proc(position i32, sampler u32) #cc_c;
|
||||||
BufferData proc(target i32, size int, data rawptr, usage i32);
|
BufferData proc(target i32, size int, data rawptr, usage i32) #cc_c;
|
||||||
BufferSubData proc(target i32, offset, size int, data rawptr);
|
BufferSubData proc(target i32, offset, size int, data rawptr) #cc_c;
|
||||||
|
|
||||||
DrawArrays proc(mode, first i32, count u32);
|
DrawArrays proc(mode, first i32, count u32) #cc_c;
|
||||||
DrawElements proc(mode i32, count u32, type_ i32, indices rawptr);
|
DrawElements proc(mode i32, count u32, type_ i32, indices rawptr) #cc_c;
|
||||||
|
|
||||||
MapBuffer proc(target, access i32) -> rawptr;
|
MapBuffer proc(target, access i32) -> rawptr #cc_c;
|
||||||
UnmapBuffer proc(target i32);
|
UnmapBuffer proc(target i32) #cc_c;
|
||||||
|
|
||||||
VertexAttribPointer proc(index u32, size, type_ i32, normalized i32, stride u32, pointer rawptr);
|
VertexAttribPointer proc(index u32, size, type_ i32, normalized i32, stride u32, pointer rawptr) #cc_c;
|
||||||
EnableVertexAttribArray proc(index u32);
|
EnableVertexAttribArray proc(index u32) #cc_c;
|
||||||
|
|
||||||
CreateShader proc(shader_type i32) -> u32;
|
CreateShader proc(shader_type i32) -> u32 #cc_c;
|
||||||
ShaderSource proc(shader u32, count u32, str ^^byte, length ^i32);
|
ShaderSource proc(shader u32, count u32, str ^^byte, length ^i32) #cc_c;
|
||||||
CompileShader proc(shader u32);
|
CompileShader proc(shader u32) #cc_c;
|
||||||
CreateProgram proc() -> u32;
|
CreateProgram proc() -> u32 #cc_c;
|
||||||
AttachShader proc(program, shader u32);
|
AttachShader proc(program, shader u32) #cc_c;
|
||||||
DetachShader proc(program, shader u32);
|
DetachShader proc(program, shader u32) #cc_c;
|
||||||
DeleteShader proc(shader u32);
|
DeleteShader proc(shader u32) #cc_c;
|
||||||
LinkProgram proc(program u32);
|
LinkProgram proc(program u32) #cc_c;
|
||||||
UseProgram proc(program u32);
|
UseProgram proc(program u32) #cc_c;
|
||||||
DeleteProgram proc(program u32);
|
DeleteProgram proc(program u32) #cc_c;
|
||||||
|
|
||||||
|
|
||||||
GetShaderiv proc(shader u32, pname i32, params ^i32);
|
GetShaderiv proc(shader u32, pname i32, params ^i32) #cc_c;
|
||||||
GetProgramiv proc(program u32, pname i32, params ^i32);
|
GetProgramiv proc(program u32, pname i32, params ^i32) #cc_c;
|
||||||
GetShaderInfoLog proc(shader u32, max_length u32, length ^u32, info_long ^byte);
|
GetShaderInfoLog proc(shader u32, max_length u32, length ^u32, info_long ^byte) #cc_c;
|
||||||
GetProgramInfoLog proc(program u32, max_length u32, length ^u32, info_long ^byte);
|
GetProgramInfoLog proc(program u32, max_length u32, length ^u32, info_long ^byte) #cc_c;
|
||||||
|
|
||||||
ActiveTexture proc(texture i32);
|
ActiveTexture proc(texture i32) #cc_c;
|
||||||
GenerateMipmap proc(target i32);
|
GenerateMipmap proc(target i32) #cc_c;
|
||||||
|
|
||||||
SamplerParameteri proc(sampler u32, pname i32, param i32);
|
SamplerParameteri proc(sampler u32, pname i32, param i32) #cc_c;
|
||||||
SamplerParameterf proc(sampler u32, pname i32, param f32);
|
SamplerParameterf proc(sampler u32, pname i32, param f32) #cc_c;
|
||||||
SamplerParameteriv proc(sampler u32, pname i32, params ^i32);
|
SamplerParameteriv proc(sampler u32, pname i32, params ^i32) #cc_c;
|
||||||
SamplerParameterfv proc(sampler u32, pname i32, params ^f32);
|
SamplerParameterfv proc(sampler u32, pname i32, params ^f32) #cc_c;
|
||||||
SamplerParameterIiv proc(sampler u32, pname i32, params ^i32);
|
SamplerParameterIiv proc(sampler u32, pname i32, params ^i32) #cc_c;
|
||||||
SamplerParameterIuiv proc(sampler u32, pname i32, params ^u32);
|
SamplerParameterIuiv proc(sampler u32, pname i32, params ^u32) #cc_c;
|
||||||
|
|
||||||
|
|
||||||
Uniform1i proc(loc i32, v0 i32);
|
Uniform1i proc(loc i32, v0 i32) #cc_c;
|
||||||
Uniform2i proc(loc i32, v0, v1 i32);
|
Uniform2i proc(loc i32, v0, v1 i32) #cc_c;
|
||||||
Uniform3i proc(loc i32, v0, v1, v2 i32);
|
Uniform3i proc(loc i32, v0, v1, v2 i32) #cc_c;
|
||||||
Uniform4i proc(loc i32, v0, v1, v2, v3 i32);
|
Uniform4i proc(loc i32, v0, v1, v2, v3 i32) #cc_c;
|
||||||
Uniform1f proc(loc i32, v0 f32);
|
Uniform1f proc(loc i32, v0 f32) #cc_c;
|
||||||
Uniform2f proc(loc i32, v0, v1 f32);
|
Uniform2f proc(loc i32, v0, v1 f32) #cc_c;
|
||||||
Uniform3f proc(loc i32, v0, v1, v2 f32);
|
Uniform3f proc(loc i32, v0, v1, v2 f32) #cc_c;
|
||||||
Uniform4f proc(loc i32, v0, v1, v2, v3 f32);
|
Uniform4f proc(loc i32, v0, v1, v2, v3 f32) #cc_c;
|
||||||
UniformMatrix4fv proc(loc i32, count u32, transpose i32, value ^f32);
|
UniformMatrix4fv proc(loc i32, count u32, transpose i32, value ^f32) #cc_c;
|
||||||
|
|
||||||
GetUniformLocation proc(program u32, name ^byte) -> i32;
|
GetUniformLocation proc(program u32, name ^byte) -> i32 #cc_c;
|
||||||
);
|
}
|
||||||
|
|
||||||
proc init() {
|
proc init() {
|
||||||
proc set_proc_address(p rawptr, name string) #inline { (p as ^proc())^ = GetProcAddress(name); }
|
proc set_proc_address(p rawptr, name string) #inline { (p as ^(proc() #cc_c))^ = GetProcAddress(name); }
|
||||||
|
|
||||||
set_proc_address(^GenBuffers, "glGenBuffers\x00");
|
set_proc_address(^GenBuffers, "glGenBuffers\x00");
|
||||||
set_proc_address(^GenVertexArrays, "glGenVertexArrays\x00");
|
set_proc_address(^GenVertexArrays, "glGenVertexArrays\x00");
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
const (
|
const {
|
||||||
FALSE = 0;
|
FALSE = 0;
|
||||||
TRUE = 1;
|
TRUE = 1;
|
||||||
|
|
||||||
@@ -1382,4 +1382,4 @@ const (
|
|||||||
DEBUG_SEVERITY_HIGH_ARB = 0x9146;
|
DEBUG_SEVERITY_HIGH_ARB = 0x9146;
|
||||||
DEBUG_SEVERITY_MEDIUM_ARB = 0x9147;
|
DEBUG_SEVERITY_MEDIUM_ARB = 0x9147;
|
||||||
DEBUG_SEVERITY_LOW_ARB = 0x9148;
|
DEBUG_SEVERITY_LOW_ARB = 0x9148;
|
||||||
);
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import (
|
import {
|
||||||
win32 "sys/windows.odin";
|
win32 "sys/windows.odin";
|
||||||
"fmt.odin";
|
"fmt.odin";
|
||||||
)
|
}
|
||||||
|
|
||||||
type (
|
type {
|
||||||
File_Time u64;
|
File_Time u64;
|
||||||
|
|
||||||
File_Handle raw_union {
|
File_Handle raw_union {
|
||||||
@@ -15,7 +15,7 @@ type (
|
|||||||
handle File_Handle;
|
handle File_Handle;
|
||||||
last_write_time File_Time;
|
last_write_time File_Time;
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
proc open(name string) -> (File, bool) {
|
proc open(name string) -> (File, bool) {
|
||||||
using win32;
|
using win32;
|
||||||
@@ -87,15 +87,15 @@ proc last_write_time_by_name(name string) -> File_Time {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
const (
|
const {
|
||||||
FILE_STANDARD_INPUT = iota;
|
FILE_STANDARD_INPUT = iota;
|
||||||
FILE_STANDARD_OUTPUT;
|
FILE_STANDARD_OUTPUT;
|
||||||
FILE_STANDARD_ERROR;
|
FILE_STANDARD_ERROR;
|
||||||
|
|
||||||
FILE_STANDARD_COUNT;
|
FILE_STANDARD_COUNT;
|
||||||
)
|
}
|
||||||
// NOTE(bill): Uses startup to initialize it
|
// NOTE(bill): Uses startup to initialize it
|
||||||
var (
|
var {
|
||||||
__std_files = [FILE_STANDARD_COUNT]File{
|
__std_files = [FILE_STANDARD_COUNT]File{
|
||||||
{handle = win32.GetStdHandle(win32.STD_INPUT_HANDLE) transmute File_Handle },
|
{handle = win32.GetStdHandle(win32.STD_INPUT_HANDLE) transmute File_Handle },
|
||||||
{handle = win32.GetStdHandle(win32.STD_OUTPUT_HANDLE) transmute File_Handle },
|
{handle = win32.GetStdHandle(win32.STD_OUTPUT_HANDLE) transmute File_Handle },
|
||||||
@@ -105,7 +105,7 @@ var (
|
|||||||
stdin = ^__std_files[FILE_STANDARD_INPUT];
|
stdin = ^__std_files[FILE_STANDARD_INPUT];
|
||||||
stdout = ^__std_files[FILE_STANDARD_OUTPUT];
|
stdout = ^__std_files[FILE_STANDARD_OUTPUT];
|
||||||
stderr = ^__std_files[FILE_STANDARD_ERROR];
|
stderr = ^__std_files[FILE_STANDARD_ERROR];
|
||||||
)
|
}
|
||||||
|
|
||||||
|
|
||||||
proc read_entire_file(name string) -> ([]byte, bool) {
|
proc read_entire_file(name string) -> ([]byte, bool) {
|
||||||
|
|||||||
+4
-4
@@ -1,9 +1,9 @@
|
|||||||
import (
|
import {
|
||||||
win32 "sys/windows.odin" when ODIN_OS == "windows";
|
win32 "sys/windows.odin" when ODIN_OS == "windows";
|
||||||
"atomic.odin";
|
"atomic.odin";
|
||||||
)
|
}
|
||||||
|
|
||||||
type (
|
type {
|
||||||
Semaphore struct {
|
Semaphore struct {
|
||||||
handle win32.HANDLE;
|
handle win32.HANDLE;
|
||||||
}
|
}
|
||||||
@@ -14,7 +14,7 @@ type (
|
|||||||
owner i32;
|
owner i32;
|
||||||
recursion i32;
|
recursion i32;
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
proc current_thread_id() -> i32 {
|
proc current_thread_id() -> i32 {
|
||||||
return win32.GetCurrentThreadId() as i32;
|
return win32.GetCurrentThreadId() as i32;
|
||||||
|
|||||||
+23
-23
@@ -1,7 +1,7 @@
|
|||||||
#foreign_system_library "user32" when ODIN_OS == "windows";
|
#foreign_system_library "user32" when ODIN_OS == "windows";
|
||||||
#foreign_system_library "gdi32" when ODIN_OS == "windows";
|
#foreign_system_library "gdi32" when ODIN_OS == "windows";
|
||||||
|
|
||||||
type (
|
type {
|
||||||
HANDLE rawptr;
|
HANDLE rawptr;
|
||||||
HWND HANDLE;
|
HWND HANDLE;
|
||||||
HDC HANDLE;
|
HDC HANDLE;
|
||||||
@@ -18,9 +18,9 @@ type (
|
|||||||
ATOM i16;
|
ATOM i16;
|
||||||
BOOL i32;
|
BOOL i32;
|
||||||
WNDPROC proc(hwnd HWND, msg u32, wparam WPARAM, lparam LPARAM) -> LRESULT;
|
WNDPROC proc(hwnd HWND, msg u32, wparam WPARAM, lparam LPARAM) -> LRESULT;
|
||||||
)
|
}
|
||||||
|
|
||||||
const (
|
const {
|
||||||
INVALID_HANDLE_VALUE = (-1 as int) as HANDLE;
|
INVALID_HANDLE_VALUE = (-1 as int) as HANDLE;
|
||||||
|
|
||||||
CS_VREDRAW = 0x0001;
|
CS_VREDRAW = 0x0001;
|
||||||
@@ -52,9 +52,9 @@ const (
|
|||||||
SM_CYSCREEN = 1;
|
SM_CYSCREEN = 1;
|
||||||
|
|
||||||
SW_SHOW = 5;
|
SW_SHOW = 5;
|
||||||
)
|
}
|
||||||
|
|
||||||
type (
|
type {
|
||||||
POINT struct #ordered {
|
POINT struct #ordered {
|
||||||
x, y i32;
|
x, y i32;
|
||||||
}
|
}
|
||||||
@@ -114,11 +114,11 @@ type (
|
|||||||
}
|
}
|
||||||
|
|
||||||
GET_FILEEX_INFO_LEVELS i32;
|
GET_FILEEX_INFO_LEVELS i32;
|
||||||
)
|
}
|
||||||
const (
|
const {
|
||||||
GetFileExInfoStandard = 0 as GET_FILEEX_INFO_LEVELS;
|
GetFileExInfoStandard = 0 as GET_FILEEX_INFO_LEVELS;
|
||||||
GetFileExMaxInfoLevel = 1 as GET_FILEEX_INFO_LEVELS;
|
GetFileExMaxInfoLevel = 1 as GET_FILEEX_INFO_LEVELS;
|
||||||
)
|
}
|
||||||
|
|
||||||
proc GetLastError () -> i32 #foreign #dll_import
|
proc GetLastError () -> i32 #foreign #dll_import
|
||||||
proc ExitProcess (exit_code u32) #foreign #dll_import
|
proc ExitProcess (exit_code u32) #foreign #dll_import
|
||||||
@@ -183,7 +183,7 @@ proc GetFileSizeEx (file_handle HANDLE, file_size ^i64) -> BOOL #for
|
|||||||
proc GetFileAttributesExA (filename ^u8, info_level_id GET_FILEEX_INFO_LEVELS, file_info rawptr) -> BOOL #foreign #dll_import
|
proc GetFileAttributesExA (filename ^u8, info_level_id GET_FILEEX_INFO_LEVELS, file_info rawptr) -> BOOL #foreign #dll_import
|
||||||
proc GetFileInformationByHandle(file_handle HANDLE, file_info ^BY_HANDLE_FILE_INFORMATION) -> BOOL #foreign #dll_import
|
proc GetFileInformationByHandle(file_handle HANDLE, file_info ^BY_HANDLE_FILE_INFORMATION) -> BOOL #foreign #dll_import
|
||||||
|
|
||||||
const (
|
const {
|
||||||
FILE_SHARE_READ = 0x00000001;
|
FILE_SHARE_READ = 0x00000001;
|
||||||
FILE_SHARE_WRITE = 0x00000002;
|
FILE_SHARE_WRITE = 0x00000002;
|
||||||
FILE_SHARE_DELETE = 0x00000004;
|
FILE_SHARE_DELETE = 0x00000004;
|
||||||
@@ -201,7 +201,7 @@ const (
|
|||||||
OPEN_EXISTING = 3;
|
OPEN_EXISTING = 3;
|
||||||
OPEN_ALWAYS = 4;
|
OPEN_ALWAYS = 4;
|
||||||
TRUNCATE_EXISTING = 5;
|
TRUNCATE_EXISTING = 5;
|
||||||
)
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -248,7 +248,7 @@ proc ReadBarrier () #foreign
|
|||||||
|
|
||||||
|
|
||||||
// GDI
|
// GDI
|
||||||
type (
|
type {
|
||||||
BITMAPINFOHEADER struct #ordered {
|
BITMAPINFOHEADER struct #ordered {
|
||||||
size u32;
|
size u32;
|
||||||
width, height i32;
|
width, height i32;
|
||||||
@@ -269,13 +269,13 @@ type (
|
|||||||
RGBQUAD struct #ordered {
|
RGBQUAD struct #ordered {
|
||||||
blue, green, red, reserved byte;
|
blue, green, red, reserved byte;
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
const (
|
const {
|
||||||
BI_RGB = 0;
|
BI_RGB = 0;
|
||||||
DIB_RGB_COLORS = 0x00;
|
DIB_RGB_COLORS = 0x00;
|
||||||
SRCCOPY = 0x00cc0020 as u32;
|
SRCCOPY = 0x00cc0020 as u32;
|
||||||
)
|
}
|
||||||
|
|
||||||
proc StretchDIBits(hdc HDC,
|
proc StretchDIBits(hdc HDC,
|
||||||
x_dst, y_dst, width_dst, height_dst i32,
|
x_dst, y_dst, width_dst, height_dst i32,
|
||||||
@@ -295,7 +295,7 @@ proc GetClientRect(hwnd HWND, rect ^RECT) -> BOOL #foreign
|
|||||||
|
|
||||||
|
|
||||||
// Windows OpenGL
|
// Windows OpenGL
|
||||||
const (
|
const {
|
||||||
PFD_TYPE_RGBA = 0;
|
PFD_TYPE_RGBA = 0;
|
||||||
PFD_TYPE_COLORINDEX = 1;
|
PFD_TYPE_COLORINDEX = 1;
|
||||||
PFD_MAIN_PLANE = 0;
|
PFD_MAIN_PLANE = 0;
|
||||||
@@ -317,11 +317,11 @@ const (
|
|||||||
PFD_DEPTH_DONTCARE = 0x20000000;
|
PFD_DEPTH_DONTCARE = 0x20000000;
|
||||||
PFD_DOUBLEBUFFER_DONTCARE = 0x40000000;
|
PFD_DOUBLEBUFFER_DONTCARE = 0x40000000;
|
||||||
PFD_STEREO_DONTCARE = 0x80000000;
|
PFD_STEREO_DONTCARE = 0x80000000;
|
||||||
)
|
}
|
||||||
|
|
||||||
type (
|
type {
|
||||||
HGLRC HANDLE;
|
HGLRC HANDLE;
|
||||||
PROC proc();
|
PROC proc() #cc_c;
|
||||||
wglCreateContextAttribsARBType proc(hdc HDC, hshareContext rawptr, attribList ^i32) -> HGLRC;
|
wglCreateContextAttribsARBType proc(hdc HDC, hshareContext rawptr, attribList ^i32) -> HGLRC;
|
||||||
|
|
||||||
|
|
||||||
@@ -355,7 +355,7 @@ type (
|
|||||||
visible_mask,
|
visible_mask,
|
||||||
damage_mask u32;
|
damage_mask u32;
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
proc GetDC (h HANDLE) -> HDC #foreign
|
proc GetDC (h HANDLE) -> HDC #foreign
|
||||||
proc SetPixelFormat (hdc HDC, pixel_format i32, pfd ^PIXELFORMATDESCRIPTOR ) -> BOOL #foreign #dll_import
|
proc SetPixelFormat (hdc HDC, pixel_format i32, pfd ^PIXELFORMATDESCRIPTOR ) -> BOOL #foreign #dll_import
|
||||||
@@ -363,13 +363,13 @@ proc ChoosePixelFormat(hdc HDC, pfd ^PIXELFORMATDESCRIPTOR) -> i32 #foreign #dll
|
|||||||
proc SwapBuffers (hdc HDC) -> BOOL #foreign #dll_import
|
proc SwapBuffers (hdc HDC) -> BOOL #foreign #dll_import
|
||||||
proc ReleaseDC (wnd HWND, hdc HDC) -> i32 #foreign #dll_import
|
proc ReleaseDC (wnd HWND, hdc HDC) -> i32 #foreign #dll_import
|
||||||
|
|
||||||
const (
|
const {
|
||||||
WGL_CONTEXT_MAJOR_VERSION_ARB = 0x2091;
|
WGL_CONTEXT_MAJOR_VERSION_ARB = 0x2091;
|
||||||
WGL_CONTEXT_MINOR_VERSION_ARB = 0x2092;
|
WGL_CONTEXT_MINOR_VERSION_ARB = 0x2092;
|
||||||
WGL_CONTEXT_PROFILE_MASK_ARB = 0x9126;
|
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;
|
||||||
)
|
}
|
||||||
|
|
||||||
proc wglCreateContext (hdc HDC) -> HGLRC #foreign #dll_import
|
proc wglCreateContext (hdc HDC) -> HGLRC #foreign #dll_import
|
||||||
proc wglMakeCurrent (hdc HDC, hglrc HGLRC) -> BOOL #foreign #dll_import
|
proc wglMakeCurrent (hdc HDC, hglrc HGLRC) -> BOOL #foreign #dll_import
|
||||||
@@ -383,7 +383,7 @@ proc GetAsyncKeyState(v_key i32) -> i16 #foreign #dll_import
|
|||||||
|
|
||||||
proc is_key_down(key i32) -> bool #inline { return GetAsyncKeyState(key) < 0; }
|
proc is_key_down(key i32) -> bool #inline { return GetAsyncKeyState(key) < 0; }
|
||||||
|
|
||||||
const (
|
const {
|
||||||
KEY_LBUTTON = 0x01;
|
KEY_LBUTTON = 0x01;
|
||||||
KEY_RBUTTON = 0x02;
|
KEY_RBUTTON = 0x02;
|
||||||
KEY_CANCEL = 0x03;
|
KEY_CANCEL = 0x03;
|
||||||
@@ -535,5 +535,5 @@ const (
|
|||||||
KEY_NONAME = 0xFC;
|
KEY_NONAME = 0xFC;
|
||||||
KEY_PA1 = 0xFD;
|
KEY_PA1 = 0xFD;
|
||||||
KEY_OEM_CLEAR = 0xFE;
|
KEY_OEM_CLEAR = 0xFE;
|
||||||
)
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -1,4 +1,4 @@
|
|||||||
const (
|
const {
|
||||||
RUNE_ERROR = '\ufffd';
|
RUNE_ERROR = '\ufffd';
|
||||||
RUNE_SELF = 0x80;
|
RUNE_SELF = 0x80;
|
||||||
RUNE_BOM = 0xfeff;
|
RUNE_BOM = 0xfeff;
|
||||||
@@ -8,13 +8,13 @@ const (
|
|||||||
|
|
||||||
SURROGATE_MIN = 0xd800;
|
SURROGATE_MIN = 0xd800;
|
||||||
SURROGATE_MAX = 0xdfff;
|
SURROGATE_MAX = 0xdfff;
|
||||||
)
|
}
|
||||||
|
|
||||||
type Accept_Range struct {
|
type Accept_Range struct {
|
||||||
lo, hi u8;
|
lo, hi u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var {
|
||||||
accept_ranges = [5]Accept_Range{
|
accept_ranges = [5]Accept_Range{
|
||||||
{0x80, 0xbf},
|
{0x80, 0xbf},
|
||||||
{0xa0, 0xbf},
|
{0xa0, 0xbf},
|
||||||
@@ -42,7 +42,7 @@ var (
|
|||||||
0x13, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x23, 0x03, 0x03, // 0xe0-0xef
|
0x13, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x23, 0x03, 0x03, // 0xe0-0xef
|
||||||
0x34, 0x04, 0x04, 0x04, 0x44, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, // 0xf0-0xff
|
0x34, 0x04, 0x04, 0x04, 0x44, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, // 0xf0-0xff
|
||||||
};
|
};
|
||||||
)
|
}
|
||||||
|
|
||||||
proc encode_rune(r rune) -> ([4]byte, int) {
|
proc encode_rune(r rune) -> ([4]byte, int) {
|
||||||
var buf [4]byte;
|
var buf [4]byte;
|
||||||
@@ -99,12 +99,12 @@ proc decode_rune(s string) -> (rune, int) {
|
|||||||
return RUNE_ERROR, 1;
|
return RUNE_ERROR, 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const {
|
||||||
MASK_X = 0b00111111;
|
MASK_X = 0b00111111;
|
||||||
MASK_2 = 0b00011111;
|
MASK_2 = 0b00011111;
|
||||||
MASK_3 = 0b00001111;
|
MASK_3 = 0b00001111;
|
||||||
MASK_4 = 0b00000111;
|
MASK_4 = 0b00000111;
|
||||||
)
|
}
|
||||||
|
|
||||||
if size == 2 {
|
if size == 2 {
|
||||||
return (b0&MASK_2) as rune <<6 | (b1&MASK_X) as rune, 2;
|
return (b0&MASK_2) as rune <<6 | (b1&MASK_X) as rune, 2;
|
||||||
|
|||||||
@@ -1142,8 +1142,8 @@ void check_global_collect_entities_from_file(Checker *c, Scope *parent_scope, As
|
|||||||
for_array(iota, gd->specs) {
|
for_array(iota, gd->specs) {
|
||||||
AstNode *spec = gd->specs.e[iota];
|
AstNode *spec = gd->specs.e[iota];
|
||||||
switch (spec->kind) {
|
switch (spec->kind) {
|
||||||
case_ast_node(bd, BadDecl, decl);
|
case AstNode_BadDecl:
|
||||||
case_end;
|
break;
|
||||||
case_ast_node(is, ImportSpec, spec);
|
case_ast_node(is, ImportSpec, spec);
|
||||||
if (!parent_scope->is_file) {
|
if (!parent_scope->is_file) {
|
||||||
// NOTE(bill): _Should_ be caught by the parser
|
// NOTE(bill): _Should_ be caught by the parser
|
||||||
|
|||||||
+1
-1
@@ -308,7 +308,7 @@ bool are_signatures_similar_enough(Type *a_, Type *b_) {
|
|||||||
void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
|
void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
|
||||||
GB_ASSERT(e->type == NULL);
|
GB_ASSERT(e->type == NULL);
|
||||||
|
|
||||||
Type *proc_type = make_type_proc(c->allocator, e->scope, NULL, 0, NULL, 0, false);
|
Type *proc_type = make_type_proc(c->allocator, e->scope, NULL, 0, NULL, 0, false, ProcCC_Odin);
|
||||||
e->type = proc_type;
|
e->type = proc_type;
|
||||||
ast_node(pd, ProcDecl, d->proc_decl);
|
ast_node(pd, ProcDecl, d->proc_decl);
|
||||||
|
|
||||||
|
|||||||
+7
-7
@@ -821,13 +821,13 @@ void check_procedure_type(Checker *c, Type *type, AstNode *proc_type_node) {
|
|||||||
if (params) param_count = params ->Tuple.variable_count;
|
if (params) param_count = params ->Tuple.variable_count;
|
||||||
if (results) result_count = results->Tuple.variable_count;
|
if (results) result_count = results->Tuple.variable_count;
|
||||||
|
|
||||||
type->Proc.scope = c->context.scope;
|
type->Proc.scope = c->context.scope;
|
||||||
type->Proc.params = params;
|
type->Proc.params = params;
|
||||||
type->Proc.param_count = param_count;
|
type->Proc.param_count = param_count;
|
||||||
type->Proc.results = results;
|
type->Proc.results = results;
|
||||||
type->Proc.result_count = result_count;
|
type->Proc.result_count = result_count;
|
||||||
type->Proc.variadic = variadic;
|
type->Proc.variadic = variadic;
|
||||||
// type->Proc.implicit_context = implicit_context;
|
type->Proc.calling_convention = pt->calling_convention;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+21
-3
@@ -110,6 +110,7 @@ typedef struct TypeRecord {
|
|||||||
i32 param_count; \
|
i32 param_count; \
|
||||||
i32 result_count; \
|
i32 result_count; \
|
||||||
bool variadic; \
|
bool variadic; \
|
||||||
|
ProcCallingConvention calling_convention; \
|
||||||
})
|
})
|
||||||
|
|
||||||
typedef enum TypeKind {
|
typedef enum TypeKind {
|
||||||
@@ -382,7 +383,7 @@ Type *make_type_tuple(gbAllocator a) {
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
Type *make_type_proc(gbAllocator a, Scope *scope, Type *params, isize param_count, Type *results, isize result_count, bool variadic) {
|
Type *make_type_proc(gbAllocator a, Scope *scope, Type *params, isize param_count, Type *results, isize result_count, bool variadic, ProcCallingConvention calling_convention) {
|
||||||
Type *t = alloc_type(a, Type_Proc);
|
Type *t = alloc_type(a, Type_Proc);
|
||||||
|
|
||||||
if (variadic) {
|
if (variadic) {
|
||||||
@@ -403,6 +404,7 @@ Type *make_type_proc(gbAllocator a, Scope *scope, Type *params, isize param_coun
|
|||||||
t->Proc.results = results;
|
t->Proc.results = results;
|
||||||
t->Proc.result_count = result_count;
|
t->Proc.result_count = result_count;
|
||||||
t->Proc.variadic = variadic;
|
t->Proc.variadic = variadic;
|
||||||
|
t->Proc.calling_convention = calling_convention;
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -655,8 +657,9 @@ bool is_type_comparable(Type *t) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool are_types_identical(Type *x, Type *y) {
|
bool are_types_identical(Type *x, Type *y) {
|
||||||
if (x == y)
|
if (x == y) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if ((x == NULL && y != NULL) ||
|
if ((x == NULL && y != NULL) ||
|
||||||
(x != NULL && y == NULL)) {
|
(x != NULL && y == NULL)) {
|
||||||
@@ -747,7 +750,8 @@ bool are_types_identical(Type *x, Type *y) {
|
|||||||
|
|
||||||
case Type_Proc:
|
case Type_Proc:
|
||||||
if (y->kind == Type_Proc) {
|
if (y->kind == Type_Proc) {
|
||||||
return are_types_identical(x->Proc.params, y->Proc.params) &&
|
return x->Proc.calling_convention == y->Proc.calling_convention &&
|
||||||
|
are_types_identical(x->Proc.params, y->Proc.params) &&
|
||||||
are_types_identical(x->Proc.results, y->Proc.results);
|
are_types_identical(x->Proc.results, y->Proc.results);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1547,6 +1551,20 @@ gbString write_type_to_string(gbString str, Type *type) {
|
|||||||
str = gb_string_appendc(str, " -> ");
|
str = gb_string_appendc(str, " -> ");
|
||||||
str = write_type_to_string(str, type->Proc.results);
|
str = write_type_to_string(str, type->Proc.results);
|
||||||
}
|
}
|
||||||
|
switch (type->Proc.calling_convention) {
|
||||||
|
case ProcCC_Odin:
|
||||||
|
// str = gb_string_appendc(str, " #cc_odin");
|
||||||
|
break;
|
||||||
|
case ProcCC_C:
|
||||||
|
str = gb_string_appendc(str, " #cc_c");
|
||||||
|
break;
|
||||||
|
case ProcCC_Std:
|
||||||
|
str = gb_string_appendc(str, " #cc_std");
|
||||||
|
break;
|
||||||
|
case ProcCC_Fast:
|
||||||
|
str = gb_string_appendc(str, " #cc_fast");
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -242,7 +242,7 @@ int main(int argc, char **argv) {
|
|||||||
exit_code = win32_exec_command_line_app("msvc-link", true,
|
exit_code = win32_exec_command_line_app("msvc-link", true,
|
||||||
"link %.*s.obj -OUT:%.*s.%s %s "
|
"link %.*s.obj -OUT:%.*s.%s %s "
|
||||||
"/defaultlib:libcmt "
|
"/defaultlib:libcmt "
|
||||||
"/nologo /incremental:no /opt:ref /subsystem:CONSOLE "
|
"/nologo /incremental:no /opt:ref /subsystem:WINDOWS "
|
||||||
" %.*s "
|
" %.*s "
|
||||||
" %s "
|
" %s "
|
||||||
"",
|
"",
|
||||||
|
|||||||
+114
-53
@@ -72,12 +72,17 @@ typedef enum ProcTag {
|
|||||||
ProcTag_no_inline = GB_BIT(14),
|
ProcTag_no_inline = GB_BIT(14),
|
||||||
ProcTag_dll_import = GB_BIT(15),
|
ProcTag_dll_import = GB_BIT(15),
|
||||||
// ProcTag_dll_export = GB_BIT(16),
|
// ProcTag_dll_export = GB_BIT(16),
|
||||||
|
|
||||||
ProcTag_stdcall = GB_BIT(20),
|
|
||||||
ProcTag_fastcall = GB_BIT(21),
|
|
||||||
// ProcTag_cdecl = GB_BIT(22),
|
|
||||||
} ProcTag;
|
} ProcTag;
|
||||||
|
|
||||||
|
typedef enum ProcCallingConvention {
|
||||||
|
ProcCC_Odin = 0,
|
||||||
|
ProcCC_C,
|
||||||
|
ProcCC_Std,
|
||||||
|
ProcCC_Fast,
|
||||||
|
|
||||||
|
ProcCC_Invalid,
|
||||||
|
} ProcCallingConvention;
|
||||||
|
|
||||||
typedef enum VarDeclTag {
|
typedef enum VarDeclTag {
|
||||||
VarDeclTag_thread_local = GB_BIT(0),
|
VarDeclTag_thread_local = GB_BIT(0),
|
||||||
} VarDeclTag;
|
} VarDeclTag;
|
||||||
@@ -286,6 +291,7 @@ AST_NODE_KIND(_TypeBegin, "", i32) \
|
|||||||
AstNodeArray params; \
|
AstNodeArray params; \
|
||||||
AstNodeArray results; \
|
AstNodeArray results; \
|
||||||
u64 tags; \
|
u64 tags; \
|
||||||
|
ProcCallingConvention calling_convention; \
|
||||||
}) \
|
}) \
|
||||||
AST_NODE_KIND(PointerType, "pointer type", struct { \
|
AST_NODE_KIND(PointerType, "pointer type", struct { \
|
||||||
Token token; \
|
Token token; \
|
||||||
@@ -911,12 +917,13 @@ AstNode *make_field(AstFile *f, AstNodeArray names, AstNode *type, bool is_using
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
AstNode *make_proc_type(AstFile *f, Token token, AstNodeArray params, AstNodeArray results, u64 tags) {
|
AstNode *make_proc_type(AstFile *f, Token token, AstNodeArray params, AstNodeArray results, u64 tags, ProcCallingConvention calling_convention) {
|
||||||
AstNode *result = make_node(f, AstNode_ProcType);
|
AstNode *result = make_node(f, AstNode_ProcType);
|
||||||
result->ProcType.token = token;
|
result->ProcType.token = token;
|
||||||
result->ProcType.params = params;
|
result->ProcType.params = params;
|
||||||
result->ProcType.results = results;
|
result->ProcType.results = results;
|
||||||
result->ProcType.tags = tags;
|
result->ProcType.tags = tags;
|
||||||
|
result->ProcType.calling_convention = calling_convention;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1157,6 +1164,8 @@ void fix_advance_to_next_stmt(AstFile *f) {
|
|||||||
case Token_const:
|
case Token_const:
|
||||||
case Token_type:
|
case Token_type:
|
||||||
case Token_proc:
|
case Token_proc:
|
||||||
|
case Token_import:
|
||||||
|
case Token_include:
|
||||||
|
|
||||||
case Token_if:
|
case Token_if:
|
||||||
case Token_when:
|
case Token_when:
|
||||||
@@ -1220,7 +1229,7 @@ void expect_semicolon(AstFile *f, AstNode *s) {
|
|||||||
case AstNode_ProcDecl:
|
case AstNode_ProcDecl:
|
||||||
return;
|
return;
|
||||||
case AstNode_GenericDecl:
|
case AstNode_GenericDecl:
|
||||||
if (s->GenericDecl.close.kind == Token_CloseParen) {
|
if (s->GenericDecl.close.kind == Token_CloseBrace) {
|
||||||
return;
|
return;
|
||||||
} else if (s->GenericDecl.token.kind == Token_type) {
|
} else if (s->GenericDecl.token.kind == Token_type) {
|
||||||
if (f->prev_token.kind == Token_CloseBrace) {
|
if (f->prev_token.kind == Token_CloseBrace) {
|
||||||
@@ -1246,10 +1255,15 @@ void expect_semicolon(AstFile *f, AstNode *s) {
|
|||||||
|
|
||||||
|
|
||||||
AstNode * parse_expr(AstFile *f, bool lhs);
|
AstNode * parse_expr(AstFile *f, bool lhs);
|
||||||
AstNode * parse_proc_type(AstFile *f);
|
AstNode * parse_proc_type(AstFile *f, String *foreign_name_, String *link_name_);
|
||||||
AstNodeArray parse_stmt_list(AstFile *f);
|
AstNodeArray parse_stmt_list(AstFile *f);
|
||||||
AstNode * parse_stmt(AstFile *f);
|
AstNode * parse_stmt(AstFile *f);
|
||||||
AstNode * parse_body(AstFile *f);
|
AstNode * parse_body(AstFile *f);
|
||||||
|
AstNode * parse_proc_decl(AstFile *f);
|
||||||
|
void parse_proc_signature(AstFile *f, AstNodeArray *params, AstNodeArray *results);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AstNode *parse_identifier(AstFile *f) {
|
AstNode *parse_identifier(AstFile *f) {
|
||||||
Token token = f->curr_token;
|
Token token = f->curr_token;
|
||||||
@@ -1270,8 +1284,12 @@ AstNode *parse_tag_expr(AstFile *f, AstNode *expression) {
|
|||||||
|
|
||||||
AstNode *unparen_expr(AstNode *node) {
|
AstNode *unparen_expr(AstNode *node) {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (node->kind != AstNode_ParenExpr)
|
if (node == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (node->kind != AstNode_ParenExpr) {
|
||||||
return node;
|
return node;
|
||||||
|
}
|
||||||
node = node->ParenExpr.expr;
|
node = node->ParenExpr.expr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1380,10 +1398,13 @@ bool is_foreign_name_valid(String name) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse_proc_tags(AstFile *f, u64 *tags, String *foreign_name, String *link_name) {
|
void parse_proc_tags(AstFile *f, u64 *tags, String *foreign_name, String *link_name, ProcCallingConvention *calling_convention) {
|
||||||
// TODO(bill): Add this to procedure literals too
|
// TODO(bill): Add this to procedure literals too
|
||||||
GB_ASSERT(foreign_name != NULL);
|
GB_ASSERT(tags != NULL);
|
||||||
GB_ASSERT(link_name != NULL);
|
GB_ASSERT(link_name != NULL);
|
||||||
|
GB_ASSERT(link_name != NULL);
|
||||||
|
|
||||||
|
ProcCallingConvention cc = ProcCC_Invalid;
|
||||||
|
|
||||||
while (f->curr_token.kind == Token_Hash) {
|
while (f->curr_token.kind == Token_Hash) {
|
||||||
AstNode *tag_expr = parse_tag_expr(f, NULL);
|
AstNode *tag_expr = parse_tag_expr(f, NULL);
|
||||||
@@ -1427,16 +1448,49 @@ void parse_proc_tags(AstFile *f, u64 *tags, String *foreign_name, String *link_n
|
|||||||
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_ADD_TAG(stdcall)
|
else if (str_eq(tag_name, str_lit("cc_odin"))) {
|
||||||
ELSE_IF_ADD_TAG(fastcall)
|
if (cc == ProcCC_Invalid) {
|
||||||
// ELSE_IF_ADD_TAG(cdecl)
|
cc = ProcCC_Odin;
|
||||||
else {
|
} else {
|
||||||
|
syntax_error_node(tag_expr, "Multiple calling conventions for procedure type");
|
||||||
|
}
|
||||||
|
} else if (str_eq(tag_name, str_lit("cc_c"))) {
|
||||||
|
if (cc == ProcCC_Invalid) {
|
||||||
|
cc = ProcCC_C;
|
||||||
|
} else {
|
||||||
|
syntax_error_node(tag_expr, "Multiple calling conventions for procedure type");
|
||||||
|
}
|
||||||
|
} else if (str_eq(tag_name, str_lit("cc_std"))) {
|
||||||
|
if (cc == ProcCC_Invalid) {
|
||||||
|
cc = ProcCC_Std;
|
||||||
|
} else {
|
||||||
|
syntax_error_node(tag_expr, "Multiple calling conventions for procedure type");
|
||||||
|
}
|
||||||
|
} else if (str_eq(tag_name, str_lit("cc_fast"))) {
|
||||||
|
if (cc == ProcCC_Invalid) {
|
||||||
|
cc = ProcCC_Fast;
|
||||||
|
} else {
|
||||||
|
syntax_error_node(tag_expr, "Multiple calling conventions for procedure type");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
syntax_error_node(tag_expr, "Unknown procedure tag");
|
syntax_error_node(tag_expr, "Unknown procedure tag");
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef ELSE_IF_ADD_TAG
|
#undef ELSE_IF_ADD_TAG
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cc == ProcCC_Invalid) {
|
||||||
|
if ((*tags) & ProcTag_foreign) {
|
||||||
|
cc = ProcCC_C;
|
||||||
|
} else {
|
||||||
|
cc = ProcCC_Odin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (calling_convention) {
|
||||||
|
*calling_convention = cc;
|
||||||
|
}
|
||||||
|
|
||||||
if ((*tags & ProcTag_foreign) && (*tags & ProcTag_export)) {
|
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, "You cannot apply both #foreign and #export to a procedure");
|
||||||
}
|
}
|
||||||
@@ -1452,10 +1506,6 @@ void parse_proc_tags(AstFile *f, u64 *tags, String *foreign_name, String *link_n
|
|||||||
if (((*tags & ProcTag_bounds_check) || (*tags & ProcTag_no_bounds_check)) && (*tags & ProcTag_foreign)) {
|
if (((*tags & ProcTag_bounds_check) || (*tags & ProcTag_no_bounds_check)) && (*tags & ProcTag_foreign)) {
|
||||||
syntax_error(f->curr_token, "You cannot apply both #bounds_check or #no_bounds_check to a procedure without a body");
|
syntax_error(f->curr_token, "You cannot apply both #bounds_check or #no_bounds_check to a procedure without a body");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((*tags & ProcTag_stdcall) && (*tags & ProcTag_fastcall)) {
|
|
||||||
syntax_error(f->curr_token, "You cannot apply one calling convention to a procedure");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AstNode *parse_operand(AstFile *f, bool lhs) {
|
AstNode *parse_operand(AstFile *f, bool lhs) {
|
||||||
@@ -1545,32 +1595,28 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
|
|||||||
|
|
||||||
// Parse Procedure Type or Literal
|
// Parse Procedure Type or Literal
|
||||||
case Token_proc: {
|
case Token_proc: {
|
||||||
AstNode *curr_proc = f->curr_proc;
|
|
||||||
AstNode *type = parse_proc_type(f);
|
|
||||||
f->curr_proc = type;
|
|
||||||
|
|
||||||
u64 tags = 0;
|
|
||||||
String foreign_name = {0};
|
String foreign_name = {0};
|
||||||
String link_name = {0};
|
String link_name = {0};
|
||||||
parse_proc_tags(f, &tags, &foreign_name, &link_name);
|
AstNode *curr_proc = f->curr_proc;
|
||||||
if (tags & ProcTag_foreign) {
|
AstNode *type = parse_proc_type(f, &foreign_name, &link_name);
|
||||||
|
f->curr_proc = type;
|
||||||
|
|
||||||
|
if (type->ProcType.tags & ProcTag_foreign) {
|
||||||
syntax_error(f->curr_token, "#foreign cannot be applied to procedure literals");
|
syntax_error(f->curr_token, "#foreign cannot be applied to procedure literals");
|
||||||
}
|
}
|
||||||
if (tags & ProcTag_export) {
|
if (type->ProcType.tags & ProcTag_export) {
|
||||||
syntax_error(f->curr_token, "#export cannot be applied to procedure literals");
|
syntax_error(f->curr_token, "#export cannot be applied to procedure literals");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f->curr_token.kind == Token_OpenBrace) {
|
if (f->curr_token.kind == Token_OpenBrace) {
|
||||||
AstNode *body;
|
AstNode *body;
|
||||||
|
|
||||||
if ((tags & ProcTag_foreign) != 0) {
|
if ((type->ProcType.tags & ProcTag_foreign) != 0) {
|
||||||
syntax_error(f->curr_token, "A procedure tagged as `#foreign` cannot have a body");
|
syntax_error(f->curr_token, "A procedure tagged as `#foreign` cannot have a body");
|
||||||
}
|
}
|
||||||
|
|
||||||
body = parse_body(f);
|
body = parse_body(f);
|
||||||
type = make_proc_lit(f, type, body, tags, foreign_name, link_name);
|
type = make_proc_lit(f, type, body, type->ProcType.tags, foreign_name, link_name);
|
||||||
} else if (type != NULL && type->kind == AstNode_ProcType) {
|
|
||||||
type->ProcType.tags = tags;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
f->curr_proc = curr_proc;
|
f->curr_proc = curr_proc;
|
||||||
@@ -1920,13 +1966,13 @@ AstNode *parse_generic_decl(AstFile *f, TokenKind keyword, ParserSpecProc spec_p
|
|||||||
Token token = expect_token(f, keyword);
|
Token token = expect_token(f, keyword);
|
||||||
Token open = {0}, close = {0};
|
Token open = {0}, close = {0};
|
||||||
AstNodeArray specs = {0};
|
AstNodeArray specs = {0};
|
||||||
if (f->curr_token.kind == Token_OpenParen) {
|
if (f->curr_token.kind == Token_OpenBrace) {
|
||||||
open = expect_token(f, Token_OpenParen);
|
open = expect_token(f, Token_OpenBrace);
|
||||||
array_init(&specs, heap_allocator());
|
array_init(&specs, heap_allocator());
|
||||||
|
|
||||||
|
|
||||||
for (isize index = 0;
|
for (isize index = 0;
|
||||||
f->curr_token.kind != Token_CloseParen &&
|
f->curr_token.kind != Token_CloseBrace &&
|
||||||
f->curr_token.kind != Token_EOF;
|
f->curr_token.kind != Token_EOF;
|
||||||
index++) {
|
index++) {
|
||||||
AstNode *spec = spec_proc(f, keyword, index);
|
AstNode *spec = spec_proc(f, keyword, index);
|
||||||
@@ -1934,7 +1980,7 @@ AstNode *parse_generic_decl(AstFile *f, TokenKind keyword, ParserSpecProc spec_p
|
|||||||
expect_semicolon(f, spec);
|
expect_semicolon(f, spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
close = expect_token(f, Token_CloseParen);
|
close = expect_token(f, Token_CloseBrace);
|
||||||
} else {
|
} else {
|
||||||
array_init_reserve(&specs, heap_allocator(), 1);
|
array_init_reserve(&specs, heap_allocator(), 1);
|
||||||
array_add(&specs, spec_proc(f, keyword, 0));
|
array_add(&specs, spec_proc(f, keyword, 0));
|
||||||
@@ -2042,8 +2088,6 @@ PARSE_SPEC_PROC(parse_include_spec) {
|
|||||||
return spec;
|
return spec;
|
||||||
}
|
}
|
||||||
|
|
||||||
AstNode *parse_proc_decl(AstFile *f);
|
|
||||||
|
|
||||||
AstNode *parse_decl(AstFile *f) {
|
AstNode *parse_decl(AstFile *f) {
|
||||||
switch (f->curr_token.kind) {
|
switch (f->curr_token.kind) {
|
||||||
case Token_var:
|
case Token_var:
|
||||||
@@ -2055,6 +2099,7 @@ AstNode *parse_decl(AstFile *f) {
|
|||||||
return parse_generic_decl(f, f->curr_token.kind, parse_type_spec);
|
return parse_generic_decl(f, f->curr_token.kind, parse_type_spec);
|
||||||
|
|
||||||
case Token_proc:
|
case Token_proc:
|
||||||
|
// TODO(bill): Should I allow procedures to use the generic declaration syntax?
|
||||||
return parse_proc_decl(f);
|
return parse_proc_decl(f);
|
||||||
|
|
||||||
case Token_import:
|
case Token_import:
|
||||||
@@ -2158,20 +2203,29 @@ AstNode *convert_stmt_to_expr(AstFile *f, AstNode *statement, String kind) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void parse_proc_signature(AstFile *f, AstNodeArray *params, AstNodeArray *results);
|
|
||||||
|
|
||||||
AstNode *parse_proc_type(AstFile *f) {
|
AstNode *parse_proc_type(AstFile *f, String *foreign_name_, String *link_name_) {
|
||||||
AstNodeArray params = {0};
|
AstNodeArray params = {0};
|
||||||
AstNodeArray results = {0};
|
AstNodeArray results = {0};
|
||||||
|
|
||||||
Token proc_token = expect_token(f, Token_proc);
|
Token proc_token = expect_token(f, Token_proc);
|
||||||
parse_proc_signature(f, ¶ms, &results);
|
parse_proc_signature(f, ¶ms, &results);
|
||||||
|
|
||||||
return make_proc_type(f, proc_token, params, results, 0);
|
u64 tags = 0;
|
||||||
|
String foreign_name = {0};
|
||||||
|
String link_name = {0};
|
||||||
|
ProcCallingConvention cc = ProcCC_Odin;
|
||||||
|
|
||||||
|
parse_proc_tags(f, &tags, &foreign_name, &link_name, &cc);
|
||||||
|
|
||||||
|
if (foreign_name_) *foreign_name_ = foreign_name;
|
||||||
|
if (link_name_) *link_name_ = link_name;
|
||||||
|
|
||||||
|
return make_proc_type(f, proc_token, params, results, tags, cc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AstNodeArray parse_field_list(AstFile *f, isize *name_count_, bool allow_using, bool ellipsis_ok,
|
||||||
AstNodeArray parse_field_list(AstFile *f, isize *name_count_, bool allow_using, TokenKind separator, TokenKind follow) {
|
TokenKind separator, TokenKind follow) {
|
||||||
AstNodeArray params = make_ast_node_array(f);
|
AstNodeArray params = make_ast_node_array(f);
|
||||||
isize name_count = 0;
|
isize name_count = 0;
|
||||||
|
|
||||||
@@ -2203,7 +2257,7 @@ AstNodeArray parse_field_list(AstFile *f, isize *name_count_, bool allow_using,
|
|||||||
// expect_token_after(f, Token_Colon, "parameter list");
|
// expect_token_after(f, Token_Colon, "parameter list");
|
||||||
|
|
||||||
AstNode *type = NULL;
|
AstNode *type = NULL;
|
||||||
if (f->curr_token.kind == Token_Ellipsis) {
|
if (ellipsis_ok && f->curr_token.kind == Token_Ellipsis) {
|
||||||
Token ellipsis = f->curr_token;
|
Token ellipsis = f->curr_token;
|
||||||
next_token(f);
|
next_token(f);
|
||||||
type = parse_type_attempt(f);
|
type = parse_type_attempt(f);
|
||||||
@@ -2245,7 +2299,7 @@ AstNodeArray parse_field_list(AstFile *f, isize *name_count_, bool allow_using,
|
|||||||
|
|
||||||
|
|
||||||
AstNodeArray parse_record_fields(AstFile *f, isize *field_count_, bool allow_using, String context) {
|
AstNodeArray parse_record_fields(AstFile *f, isize *field_count_, bool allow_using, String context) {
|
||||||
return parse_field_list(f, field_count_, allow_using, Token_Semicolon, Token_CloseBrace);
|
return parse_field_list(f, field_count_, allow_using, false, Token_Semicolon, Token_CloseBrace);
|
||||||
}
|
}
|
||||||
|
|
||||||
AstNode *parse_identifier_or_type(AstFile *f) {
|
AstNode *parse_identifier_or_type(AstFile *f) {
|
||||||
@@ -2358,8 +2412,14 @@ AstNode *parse_identifier_or_type(AstFile *f) {
|
|||||||
return make_raw_union_type(f, token, decls, decl_count);
|
return make_raw_union_type(f, token, decls, decl_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
case Token_proc:
|
case Token_proc: {
|
||||||
return parse_proc_type(f);
|
Token token = f->curr_token;
|
||||||
|
AstNode *pt = parse_proc_type(f, NULL, NULL);
|
||||||
|
if (pt->ProcType.tags != 0) {
|
||||||
|
syntax_error(token, "A procedure type cannot have tags");
|
||||||
|
}
|
||||||
|
return pt;
|
||||||
|
}
|
||||||
|
|
||||||
case Token_OpenParen: {
|
case Token_OpenParen: {
|
||||||
// NOTE(bill): Skip the paren expression
|
// NOTE(bill): Skip the paren expression
|
||||||
@@ -2406,7 +2466,7 @@ void parse_proc_signature(AstFile *f,
|
|||||||
AstNodeArray *params,
|
AstNodeArray *params,
|
||||||
AstNodeArray *results) {
|
AstNodeArray *results) {
|
||||||
expect_token(f, Token_OpenParen);
|
expect_token(f, Token_OpenParen);
|
||||||
*params = parse_field_list(f, NULL, true, Token_Comma, Token_CloseParen);
|
*params = parse_field_list(f, NULL, true, true, Token_Comma, Token_CloseParen);
|
||||||
expect_token_after(f, Token_CloseParen, "parameter list");
|
expect_token_after(f, Token_CloseParen, "parameter list");
|
||||||
*results = parse_results(f);
|
*results = parse_results(f);
|
||||||
}
|
}
|
||||||
@@ -2431,21 +2491,22 @@ AstNode *parse_proc_decl(AstFile *f) {
|
|||||||
return make_expr_stmt(f, parse_expr(f, true));
|
return make_expr_stmt(f, parse_expr(f, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
Token proc_token = expect_token(f, Token_proc);
|
|
||||||
AstNode *name = parse_identifier(f);
|
|
||||||
|
|
||||||
AstNodeArray params = {0};
|
AstNodeArray params = {0};
|
||||||
AstNodeArray results = {0};
|
AstNodeArray results = {0};
|
||||||
|
|
||||||
|
Token proc_token = expect_token(f, Token_proc);
|
||||||
|
AstNode *name = parse_identifier(f);
|
||||||
parse_proc_signature(f, ¶ms, &results);
|
parse_proc_signature(f, ¶ms, &results);
|
||||||
|
|
||||||
AstNode *proc_type = make_proc_type(f, proc_token, params, results, 0);
|
|
||||||
|
|
||||||
AstNode *body = NULL;
|
|
||||||
u64 tags = 0;
|
u64 tags = 0;
|
||||||
String foreign_name = {0};
|
String foreign_name = {0};
|
||||||
String link_name = {0};
|
String link_name = {0};
|
||||||
|
ProcCallingConvention cc = ProcCC_Odin;
|
||||||
|
|
||||||
parse_proc_tags(f, &tags, &foreign_name, &link_name);
|
parse_proc_tags(f, &tags, &foreign_name, &link_name, &cc);
|
||||||
|
|
||||||
|
AstNode *proc_type = make_proc_type(f, proc_token, params, results, tags, cc);
|
||||||
|
AstNode *body = NULL;
|
||||||
|
|
||||||
if (f->curr_token.kind == Token_OpenBrace) {
|
if (f->curr_token.kind == Token_OpenBrace) {
|
||||||
if ((tags & ProcTag_foreign) != 0) {
|
if ((tags & ProcTag_foreign) != 0) {
|
||||||
|
|||||||
@@ -2607,7 +2607,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
|
|||||||
} else if (e != NULL && e->kind == Entity_Variable) {
|
} else if (e != NULL && e->kind == Entity_Variable) {
|
||||||
return ssa_addr_load(proc, ssa_build_addr(proc, expr));
|
return ssa_addr_load(proc, ssa_build_addr(proc, expr));
|
||||||
}
|
}
|
||||||
GB_PANIC("nil value for expression from identifier: %.*s", LIT(i->string));
|
GB_PANIC("NULL value for expression from identifier: %.*s", LIT(i->string));
|
||||||
return NULL;
|
return NULL;
|
||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
@@ -5025,7 +5025,7 @@ void ssa_gen_tree(ssaGen *s) {
|
|||||||
|
|
||||||
Type *proc_type = make_type_proc(a, proc_scope,
|
Type *proc_type = make_type_proc(a, proc_scope,
|
||||||
proc_params, 3,
|
proc_params, 3,
|
||||||
proc_results, 1, false);
|
proc_results, 1, false, ProcCC_Std);
|
||||||
|
|
||||||
AstNode *body = gb_alloc_item(a, AstNode);
|
AstNode *body = gb_alloc_item(a, AstNode);
|
||||||
Entity *e = make_entity_procedure(a, NULL, make_token_ident(name), proc_type, 0);
|
Entity *e = make_entity_procedure(a, NULL, make_token_ident(name), proc_type, 0);
|
||||||
@@ -5035,7 +5035,7 @@ void ssa_gen_tree(ssaGen *s) {
|
|||||||
map_ssa_value_set(&m->members, hash_string(name), p);
|
map_ssa_value_set(&m->members, hash_string(name), p);
|
||||||
|
|
||||||
ssaProcedure *proc = &p->Proc;
|
ssaProcedure *proc = &p->Proc;
|
||||||
proc->tags = ProcTag_no_inline | ProcTag_stdcall; // TODO(bill): is no_inline a good idea?
|
proc->tags = ProcTag_no_inline; // TODO(bill): is no_inline a good idea?
|
||||||
e->Procedure.link_name = name;
|
e->Procedure.link_name = name;
|
||||||
|
|
||||||
ssa_begin_procedure_body(proc);
|
ssa_begin_procedure_body(proc);
|
||||||
@@ -5084,17 +5084,19 @@ void ssa_gen_tree(ssaGen *s) {
|
|||||||
|
|
||||||
Type *proc_type = make_type_proc(a, proc_scope,
|
Type *proc_type = make_type_proc(a, proc_scope,
|
||||||
proc_params, 4,
|
proc_params, 4,
|
||||||
proc_results, 1, false);
|
proc_results, 1, false, ProcCC_Std);
|
||||||
|
|
||||||
AstNode *body = gb_alloc_item(a, AstNode);
|
AstNode *body = gb_alloc_item(a, AstNode);
|
||||||
Entity *e = make_entity_procedure(a, NULL, make_token_ident(name), proc_type, 0);
|
Entity *e = make_entity_procedure(a, NULL, make_token_ident(name), proc_type, 0);
|
||||||
ssaValue *p = ssa_make_value_procedure(a, m, e, proc_type, NULL, body, name);
|
ssaValue *p = ssa_make_value_procedure(a, m, e, proc_type, NULL, body, name);
|
||||||
|
|
||||||
|
m->entry_point_entity = e;
|
||||||
|
|
||||||
map_ssa_value_set(&m->values, hash_pointer(e), p);
|
map_ssa_value_set(&m->values, hash_pointer(e), p);
|
||||||
map_ssa_value_set(&m->members, hash_string(name), p);
|
map_ssa_value_set(&m->members, hash_string(name), p);
|
||||||
|
|
||||||
ssaProcedure *proc = &p->Proc;
|
ssaProcedure *proc = &p->Proc;
|
||||||
proc->tags = ProcTag_no_inline | ProcTag_stdcall; // TODO(bill): is no_inline a good idea?
|
proc->tags = ProcTag_no_inline; // TODO(bill): is no_inline a good idea?
|
||||||
e->Procedure.link_name = name;
|
e->Procedure.link_name = name;
|
||||||
|
|
||||||
ssa_begin_procedure_body(proc);
|
ssa_begin_procedure_body(proc);
|
||||||
@@ -5108,7 +5110,7 @@ void ssa_gen_tree(ssaGen *s) {
|
|||||||
String name = str_lit(SSA_STARTUP_RUNTIME_PROC_NAME);
|
String name = str_lit(SSA_STARTUP_RUNTIME_PROC_NAME);
|
||||||
Type *proc_type = make_type_proc(a, gb_alloc_item(a, Scope),
|
Type *proc_type = make_type_proc(a, gb_alloc_item(a, Scope),
|
||||||
NULL, 0,
|
NULL, 0,
|
||||||
NULL, 0, false);
|
NULL, 0, false, ProcCC_Odin);
|
||||||
AstNode *body = gb_alloc_item(a, AstNode);
|
AstNode *body = gb_alloc_item(a, AstNode);
|
||||||
Entity *e = make_entity_procedure(a, NULL, make_token_ident(name), proc_type, 0);
|
Entity *e = make_entity_procedure(a, NULL, make_token_ident(name), proc_type, 0);
|
||||||
ssaValue *p = ssa_make_value_procedure(a, m, e, proc_type, NULL, body, name);
|
ssaValue *p = ssa_make_value_procedure(a, m, e, proc_type, NULL, body, name);
|
||||||
|
|||||||
+17
-6
@@ -636,6 +636,16 @@ void ssa_print_value(ssaFileBuffer *f, ssaModule *m, ssaValue *value, Type *type
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ssa_print_calling_convention(ssaFileBuffer *f, ssaModule *m, ProcCallingConvention cc) {
|
||||||
|
switch (cc) {
|
||||||
|
case ProcCC_Odin: ssa_fprintf(f, ""); break;
|
||||||
|
case ProcCC_C: ssa_fprintf(f, "ccc "); break;
|
||||||
|
case ProcCC_Std: ssa_fprintf(f, "cc 64 "); break;
|
||||||
|
case ProcCC_Fast: ssa_fprintf(f, "cc 65 "); break;
|
||||||
|
default: GB_PANIC("unknown calling convention: %d", cc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) {
|
void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) {
|
||||||
GB_ASSERT(value->kind == ssaValue_Instr);
|
GB_ASSERT(value->kind == ssaValue_Instr);
|
||||||
ssaInstr *instr = &value->Instr;
|
ssaInstr *instr = &value->Instr;
|
||||||
@@ -933,6 +943,7 @@ void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) {
|
|||||||
if (gb_is_between(bo->op, Token__ComparisonBegin+1, Token__ComparisonEnd-1)) {
|
if (gb_is_between(bo->op, Token__ComparisonBegin+1, Token__ComparisonEnd-1)) {
|
||||||
if (is_type_string(elem_type)) {
|
if (is_type_string(elem_type)) {
|
||||||
ssa_fprintf(f, "call ");
|
ssa_fprintf(f, "call ");
|
||||||
|
ssa_print_calling_convention(f, m, ProcCC_Odin);
|
||||||
ssa_print_type(f, m, t_bool);
|
ssa_print_type(f, m, t_bool);
|
||||||
char *runtime_proc = "";
|
char *runtime_proc = "";
|
||||||
switch (bo->op) {
|
switch (bo->op) {
|
||||||
@@ -1033,11 +1044,14 @@ void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) {
|
|||||||
|
|
||||||
case ssaInstr_Call: {
|
case ssaInstr_Call: {
|
||||||
ssaInstrCall *call = &instr->Call;
|
ssaInstrCall *call = &instr->Call;
|
||||||
|
Type *proc_type = base_type(ssa_type(call->value));
|
||||||
|
GB_ASSERT(is_type_proc(proc_type));
|
||||||
Type *result_type = call->type;
|
Type *result_type = call->type;
|
||||||
if (result_type) {
|
if (result_type) {
|
||||||
ssa_fprintf(f, "%%%d = ", value->index);
|
ssa_fprintf(f, "%%%d = ", value->index);
|
||||||
}
|
}
|
||||||
ssa_fprintf(f, "call ");
|
ssa_fprintf(f, "call ");
|
||||||
|
ssa_print_calling_convention(f, m, proc_type->Proc.calling_convention);
|
||||||
if (result_type) {
|
if (result_type) {
|
||||||
ssa_print_type(f, m, result_type);
|
ssa_print_type(f, m, result_type);
|
||||||
} else {
|
} else {
|
||||||
@@ -1226,6 +1240,7 @@ void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ssa_print_proc(ssaFileBuffer *f, ssaModule *m, ssaProcedure *proc) {
|
void ssa_print_proc(ssaFileBuffer *f, ssaModule *m, ssaProcedure *proc) {
|
||||||
if (proc->body == NULL) {
|
if (proc->body == NULL) {
|
||||||
ssa_fprintf(f, "declare ");
|
ssa_fprintf(f, "declare ");
|
||||||
@@ -1243,14 +1258,10 @@ void ssa_print_proc(ssaFileBuffer *f, ssaModule *m, ssaProcedure *proc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proc->tags & ProcTag_stdcall) {
|
|
||||||
ssa_fprintf(f, "cc 64 ");
|
|
||||||
} else if (proc->tags & ProcTag_fastcall) {
|
|
||||||
ssa_fprintf(f, "cc 65 ");
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeProc *proc_type = &proc->type->Proc;
|
TypeProc *proc_type = &proc->type->Proc;
|
||||||
|
|
||||||
|
ssa_print_calling_convention(f, m, proc_type->calling_convention);
|
||||||
|
|
||||||
if (proc_type->result_count == 0) {
|
if (proc_type->result_count == 0) {
|
||||||
ssa_fprintf(f, "void");
|
ssa_fprintf(f, "void");
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user