Update old demos

This commit is contained in:
Ginger Bill
2017-06-21 21:20:26 +01:00
parent 264ca00db7
commit 53075e2570
10 changed files with 428 additions and 432 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
release_mode=0 release_mode=0
warnings_to_disable="-std=c++11 -g -Wno-switch -Wno-pointer-sign -Wno-tautological-constant-out-of-range-compare -Wno-tautological-compare -Wno-macro-redefined" warnings_to_disable="-std=c++11 -g -Wno-switch -Wno-pointer-sign -Wno-tautological-constant-out-of-range-compare -Wno-tautological-compare -Wno-macro-redefined -Wno-writable-strings"
libraries="-pthread -ldl -lm -lstdc++" libraries="-pthread -ldl -lm -lstdc++"
other_args="" other_args=""
compiler="clang" compiler="clang"
+2 -1
View File
@@ -16,5 +16,6 @@ proc main() {
} }
} }
fmt.printf("The program \"%s\" calculates the value %d\n", program, accumulator); fmt.printf("The program \"%s\" calculates the value %d\n",
program, accumulator);
} }
+78 -78
View File
@@ -1,38 +1,37 @@
#import win32 "sys/windows.odin" when ODIN_OS == "windows"; import win32 "sys/windows.odin" when ODIN_OS == "windows";
#import wgl "sys/wgl.odin" when ODIN_OS == "windows"; import wgl "sys/wgl.odin" when ODIN_OS == "windows";
#import "fmt.odin"; import "fmt.odin";
#import "math.odin"; import "math.odin";
#import "os.odin"; import "os.odin";
#import gl "opengl.odin"; import gl "opengl.odin";
TWO_HEARTS :: '💕'; const TWO_HEARTS = '💕';
win32_perf_count_freq := win32.GetQueryPerformanceFrequency(); var win32_perf_count_freq = win32.get_query_performance_frequency();
time_now :: proc() -> f64 { proc time_now() -> f64 {
assert(win32_perf_count_freq != 0); assert(win32_perf_count_freq != 0);
counter: i64; var counter: i64;
win32.QueryPerformanceCounter(^counter); win32.query_performance_counter(&counter);
result := cast(f64)counter / cast(f64)win32_perf_count_freq; return f64(counter) / f64(win32_perf_count_freq);
return result;
} }
win32_print_last_error :: proc() { proc win32_print_last_error() {
err_code := cast(int)win32.GetLastError(); var err_code = win32.get_last_error();
if err_code != 0 { if err_code != 0 {
fmt.println("GetLastError: %", err_code); fmt.println("get_last_error: ", err_code);
} }
} }
// Yuk! // Yuk!
to_c_string :: proc(s: string) -> []u8 { proc to_c_string(s: string) -> []u8 {
c_str := make([]u8, len(s)+1); var c_str = make([]u8, len(s)+1);
copy(c_str, cast([]byte)s); copy(c_str, []u8(s));
c_str[len(s)] = 0; c_str[len(s)] = 0;
return c_str; return c_str;
} }
Window :: struct { type Window struct {
width, height: int, width, height: int,
wc: win32.WndClassExA, wc: win32.WndClassExA,
dc: win32.Hdc, dc: win32.Hdc,
@@ -41,52 +40,52 @@ Window :: struct {
c_title: []u8, c_title: []u8,
} }
make_window :: proc(title: string, msg, height: int, window_proc: win32.Wnd_Proc) -> (Window, bool) { proc make_window(title: string, msg, height: int, window_proc: win32.WndProc) -> (Window, bool) {
using win32; using win32;
w: Window; var w: Window;
w.width, w.height = msg, height; w.width, w.height = msg, height;
class_name := "Win32-Odin-Window\x00"; var class_name = "Win32-Odin-Window\x00";
c_class_name := ^class_name[0]; var c_class_name = &class_name[0];
if title[len(title)-1] != 0 { if title[len(title)-1] != 0 {
w.c_title = to_c_string(title); w.c_title = to_c_string(title);
} else { } else {
w.c_title = cast([]u8)title; w.c_title = []u8(title);
} }
instance := GetModuleHandleA(nil); var instance = get_module_handle_a(nil);
w.wc = WndClassExA{ w.wc = WndClassExA{
size = size_of(WndClassExA), size = size_of(WndClassExA),
style = CS_VREDRAW | CS_HREDRAW, style = CS_VREDRAW | CS_HREDRAW,
instance = cast(Hinstance)instance, instance = Hinstance(instance),
class_name = c_class_name, class_name = c_class_name,
wnd_proc = window_proc, wnd_proc = window_proc,
}; };
if RegisterClassExA(^w.wc) == 0 { if register_class_ex_a(&w.wc) == 0 {
win32_print_last_error(); win32_print_last_error();
return w, false; return w, false;
} }
w.hwnd = CreateWindowExA(0, w.hwnd = create_window_ex_a(0,
c_class_name, ^w.c_title[0], c_class_name, &w.c_title[0],
WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
cast(i32)w.width, cast(i32)w.height, i32(w.width), i32(w.height),
nil, nil, instance, nil); nil, nil, instance, nil);
if w.hwnd == nil { if w.hwnd == nil {
win32_print_last_error(); win32_print_last_error();
return w, false; return w, false;
} }
w.dc = GetDC(w.hwnd); w.dc = get_dc(w.hwnd);
{ {
pfd := PIXELFORMATDESCRIPTOR{ var pfd = PixelFormatDescriptor{
size = size_of(PIXELFORMATDESCRIPTOR), size = size_of(PixelFormatDescriptor),
version = 1, version = 1,
flags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, flags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
pixel_type = PFD_TYPE_RGBA, pixel_type = PFD_TYPE_RGBA,
@@ -97,88 +96,89 @@ make_window :: proc(title: string, msg, height: int, window_proc: win32.Wnd_Proc
layer_type = PFD_MAIN_PLANE, layer_type = PFD_MAIN_PLANE,
}; };
SetPixelFormat(w.dc, ChoosePixelFormat(w.dc, ^pfd), nil); set_pixel_format(w.dc, choose_pixel_format(w.dc, &pfd), nil);
w.opengl_context = wgl.CreateContext(w.dc); w.opengl_context = wgl.create_context(w.dc);
wgl.MakeCurrent(w.dc, w.opengl_context); wgl.make_current(w.dc, w.opengl_context);
attribs := [8]i32{ var attribs = [8]i32{
wgl.CONTEXT_MAJOR_VERSION_ARB, 2, wgl.CONTEXT_MAJOR_VERSION_ARB, 2,
wgl.CONTEXT_MINOR_VERSION_ARB, 1, wgl.CONTEXT_MINOR_VERSION_ARB, 1,
wgl.CONTEXT_PROFILE_MASK_ARB, wgl.CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, wgl.CONTEXT_PROFILE_MASK_ARB, wgl.CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
0, // NOTE(bill): tells the proc that this is the end of attribs 0, // NOTE(bill): tells the proc that this is the end of attribs
}; };
wgl_str := "wglCreateContextAttribsARB\x00"; var wgl_str = "wglCreateContextAttribsARB\x00";
wglCreateContextAttribsARB := cast(wgl.Create_Context_Attribs_ARB_Type)wgl.GetProcAddress(^wgl_str[0]); var wglCreateContextAttribsARB = wgl.CreateContextAttribsARBType(wgl.get_proc_address(&wgl_str[0]));
w.rc = wglCreateContextAttribsARB(w.dc, nil, ^attribs[0]); w.rc = wglCreateContextAttribsARB(w.dc, nil, &attribs[0]);
wgl.MakeCurrent(w.dc, w.rc); wgl.make_current(w.dc, w.rc);
SwapBuffers(w.dc); swap_buffers(w.dc);
} }
return w, true; return w, true;
} }
destroy_window :: proc(w: ^Window) { proc destroy_window(w: ^Window) {
free(w.c_title); free(w.c_title);
} }
display_window :: proc(w: ^Window) { proc display_window(w: ^Window) {
win32.SwapBuffers(w.dc); win32.swap_buffers(w.dc);
} }
run :: proc() { proc run() {
using win32;
using math; using math;
win32_proc :: proc(hwnd: win32.Hwnd, msg: u32, wparam: win32.Wparam, lparam: win32.Lparam) -> win32.Lresult #no_inline { proc win32_proc(hwnd: win32.Hwnd, msg: u32, wparam: win32.Wparam, lparam: win32.Lparam) -> win32.Lresult #no_inline {
using win32;
if msg == WM_DESTROY || msg == WM_CLOSE || msg == WM_QUIT { if msg == WM_DESTROY || msg == WM_CLOSE || msg == WM_QUIT {
os.exit(0); os.exit(0);
return 0; return 0;
} }
return DefWindowProcA(hwnd, msg, wparam, lparam); return def_window_proc_a(hwnd, msg, wparam, lparam);
} }
window, window_success := make_window("Odin Language Demo", 854, 480, cast(Wnd_Proc)win32_proc); var window, window_success = make_window("Odin Language Demo", 854, 480, win32.WndProc(win32_proc));
if !window_success { if !window_success {
return; return;
} }
defer destroy_window(^window); defer destroy_window(&window);
gl.init(); gl.init();
using win32;
prev_time := time_now(); var prev_time = time_now();
running := true; var running = true;
pos := Vec2{100, 100}; var pos = Vec2{100, 100};
for running { for running {
curr_time := time_now(); var curr_time = time_now();
dt := cast(f32)(curr_time - prev_time); var dt = f32(curr_time - prev_time);
prev_time = curr_time; prev_time = curr_time;
msg: Msg; var msg: Msg;
for PeekMessageA(^msg, nil, 0, 0, PM_REMOVE) > 0 { for peek_message_a(&msg, nil, 0, 0, PM_REMOVE) > 0 {
if msg.message == WM_QUIT { if msg.message == WM_QUIT {
running = false; running = false;
} }
TranslateMessage(^msg); translate_message(&msg);
DispatchMessageA(^msg); dispatch_message_a(&msg);
} }
if is_key_down(Key_Code.ESCAPE) { if is_key_down(KeyCode.Escape) {
running = false; running = false;
} }
{ {
SPEED :: 500; const SPEED = 500;
v: Vec2; var v: Vec2;
if is_key_down(Key_Code.RIGHT) { v[0] += 1; } if is_key_down(KeyCode.Right) { v[0] += 1; }
if is_key_down(Key_Code.LEFT) { v[0] -= 1; } if is_key_down(KeyCode.Left) { v[0] -= 1; }
if is_key_down(Key_Code.UP) { v[1] += 1; } if is_key_down(KeyCode.Up) { v[1] += 1; }
if is_key_down(Key_Code.DOWN) { v[1] -= 1; } if is_key_down(KeyCode.Down) { v[1] -= 1; }
v = norm(v); v = norm(v);
@@ -190,10 +190,10 @@ run :: proc() {
gl.Clear(gl.COLOR_BUFFER_BIT); gl.Clear(gl.COLOR_BUFFER_BIT);
gl.LoadIdentity(); gl.LoadIdentity();
gl.Ortho(0, cast(f64)window.width, gl.Ortho(0, f64(window.width),
0, cast(f64)window.height, 0, 1); 0, f64(window.height), 0, 1);
draw_rect :: proc(x, y, w, h: f32) { proc draw_rect(x, y, w, h: f32) {
gl.Begin(gl.TRIANGLES); gl.Begin(gl.TRIANGLES);
defer gl.End(); defer gl.End();
@@ -208,15 +208,15 @@ run :: proc() {
draw_rect(pos.x, pos.y, 50, 50); draw_rect(pos.x, pos.y, 50, 50);
display_window(^window); display_window(&window);
ms_to_sleep := cast(i32)(16 - 1000*dt); var ms_to_sleep = i32(16 - 1000*dt);
if ms_to_sleep > 0 { if ms_to_sleep > 0 {
win32.Sleep(ms_to_sleep); win32.sleep(ms_to_sleep);
} }
} }
} }
main :: proc() { proc main() {
run(); run();
} }
+62 -58
View File
@@ -1,12 +1,12 @@
#import "fmt.odin"; import "fmt.odin";
#foreign_system_library ws2 "Ws2_32.lib" when ODIN_OS == "windows"; foreign_system_library ws2 "Ws2_32.lib" when ODIN_OS == "windows";
SOCKET :: #type uint; type SOCKET uint;
INVALID_SOCKET :: ~(cast(SOCKET)0); const INVALID_SOCKET = ~SOCKET(0);
AF :: enum i32 { type AF enum i32 {
UNSPEC = 0, // unspecified UNSPEC = 0, // unspecified
UNIX = 1, // local to host (pipes, portals) UNIX = 1, // local to host (pipes, portals)
INET = 2, // internetwork: UDP, TCP, etc. INET = 2, // internetwork: UDP, TCP, etc.
@@ -37,19 +37,22 @@ AF :: enum i32 {
MAX = 26, MAX = 26,
}; };
SOCK_STREAM :: 1; const (
SOCKET_ERROR :: -1; SOCK_STREAM = 1;
IPPROTO_TCP :: 6; SOCKET_ERROR = -1;
AI_PASSIVE :: 0x0020; IPPROTO_TCP = 6;
SOMAXCONN :: 128; AI_PASSIVE = 0x0020;
SOMAXCONN = 128;
)
const (
SD_RECEIVE = 0;
SD_SEND = 1;
SD_BOTH = 2;
)
SD_RECEIVE :: 0; const WSADESCRIPTION_LEN = 256;
SD_SEND :: 1; const WSASYS_STATUS_LEN = 128;
SD_BOTH :: 2; type WSADATA struct #ordered {
WSADESCRIPTION_LEN :: 256;
WSASYS_STATUS_LEN :: 128;
WSADATA :: struct #ordered {
version: i16, version: i16,
high_version: i16, high_version: i16,
@@ -57,12 +60,12 @@ WSADATA :: struct #ordered {
// NOTE(bill): This is x64 ordering // NOTE(bill): This is x64 ordering
max_sockets: u16, max_sockets: u16,
max_udp_dg: u16, max_udp_dg: u16,
vendor_info: ^byte, vendor_info: ^u8,
description: [WSADESCRIPTION_LEN+1]byte, description: [WSADESCRIPTION_LEN+1]u8,
system_status: [WSASYS_STATUS_LEN+1]byte, system_status: [WSASYS_STATUS_LEN+1]u8,
} }
addrinfo :: struct #ordered { type addrinfo struct #ordered {
flags: i32, flags: i32,
family: i32, family: i32,
socktype: i32, socktype: i32,
@@ -73,52 +76,53 @@ addrinfo :: struct #ordered {
next: ^addrinfo, next: ^addrinfo,
} }
sockaddr :: struct #ordered { type sockaddr struct #ordered {
family: u16, family: u16,
data: [14]byte, data: [14]u8,
} }
foreign ws2 {
WSAStartup :: proc(version_requested: i16, data: ^WSADATA) -> i32 #foreign ws2; proc WSAStartup (version_requested: i16, data: ^WSADATA) -> i32;
WSACleanup :: proc() -> i32 #foreign ws2; proc WSACleanup () -> i32;
getaddrinfo :: proc(node_name, service_name: ^u8, hints: ^addrinfo, result: ^^addrinfo) -> i32 #foreign ws2; proc getaddrinfo (node_name, service_name: ^u8, hints: ^addrinfo, result: ^^addrinfo) -> i32;
freeaddrinfo :: proc(ai: ^addrinfo) #foreign ws2; proc freeaddrinfo (ai: ^addrinfo);
socket :: proc(af, type_, protocol: i32) -> SOCKET #foreign ws2; proc socket (af, type_, protocol: i32) -> SOCKET;
closesocket :: proc(s: SOCKET) -> i32 #foreign ws2; proc closesocket (s: SOCKET) -> i32;
bind :: proc(s: SOCKET, name: ^sockaddr, name_len: i32) -> i32 #foreign ws2; proc bind (s: SOCKET, name: ^sockaddr, name_len: i32) -> i32;
listen :: proc(s: SOCKET, back_log: i32) -> i32 #foreign ws2; proc listen (s: SOCKET, back_log: i32) -> i32;
accept :: proc(s: SOCKET, addr: ^sockaddr, addr_len: i32) -> SOCKET #foreign ws2; proc accept (s: SOCKET, addr: ^sockaddr, addr_len: i32) -> SOCKET;
recv :: proc(s: SOCKET, buf: ^byte, len: i32, flags: i32) -> i32 #foreign ws2; proc recv (s: SOCKET, buf: ^u8, len: i32, flags: i32) -> i32;
send :: proc(s: SOCKET, buf: ^byte, len: i32, flags: i32) -> i32 #foreign ws2; proc send (s: SOCKET, buf: ^u8, len: i32, flags: i32) -> i32;
shutdown :: proc(s: SOCKET, how: i32) -> i32 #foreign ws2; proc shutdown (s: SOCKET, how: i32) -> i32;
WSAGetLastError :: proc() -> i32 #foreign ws2; proc WSAGetLastError() -> i32;
}
to_c_string :: proc(s: string) -> ^byte { proc to_c_string(s: string) -> ^u8 {
c_str := new_slice(byte, s.count+1); var c_str = make([]u8, len(s)+1);
assert(c_str.data != nil); copy(c_str, []u8(s));
copy(c_str, cast([]byte)s); c_str[len(s)] = 0;
c_str[s.count] = 0; return &c_str[0];
return c_str.data;
} }
run :: proc() { proc run() {
wsa: WSADATA; var (
res: ^addrinfo = nil; wsa: WSADATA;
hints: addrinfo; res: ^addrinfo = nil;
s, client: SOCKET; hints: addrinfo;
s, client: SOCKET;
)
if WSAStartup(2 | (2 << 8), ^wsa) != 0 { if WSAStartup(2 | (2 << 8), &wsa) != 0 {
fmt.println("WSAStartup failed: ", WSAGetLastError()); fmt.println("WSAStartup failed: ", WSAGetLastError());
return; return;
} }
defer WSACleanup(); defer WSACleanup();
hints.family = cast(i32)AF.INET; hints.family = i32(AF.INET);
hints.socktype = SOCK_STREAM; hints.socktype = SOCK_STREAM;
hints.protocol = IPPROTO_TCP; hints.protocol = IPPROTO_TCP;
hints.flags = AI_PASSIVE; hints.flags = AI_PASSIVE;
if getaddrinfo(nil, to_c_string("8080"), ^hints, ^res) != 0 { if getaddrinfo(nil, to_c_string("8080"), &hints, &res) != 0 {
fmt.println("getaddrinfo failed: ", WSAGetLastError()); fmt.println("getaddrinfo failed: ", WSAGetLastError());
return; return;
} }
@@ -131,7 +135,7 @@ run :: proc() {
} }
defer closesocket(s); defer closesocket(s);
bind(s, res.addr, cast(i32)res.addrlen); bind(s, res.addr, i32(res.addrlen));
listen(s, SOMAXCONN); listen(s, SOMAXCONN);
client = accept(s, nil, 0); client = accept(s, nil, 0);
@@ -141,7 +145,7 @@ run :: proc() {
} }
defer closesocket(client); defer closesocket(client);
html := var html =
`HTTP/1.1 200 OK `HTTP/1.1 200 OK
Connection: close Connection: close
Content-type: text/html Content-type: text/html
@@ -156,12 +160,12 @@ Content-type: text/html
</html> </html>
`; `;
buf: [1024]byte; var buf: [1024]u8;
for { for {
bytes := recv(client, ^buf[0], cast(i32)buf.count, 0); var bytes = recv(client, &buf[0], i32(len(buf)), 0);
if bytes > 0 { if bytes > 0 {
// fmt.println(buf[:bytes] as string) // fmt.println(string(buf[0..<bytes]))
bytes_sent := send(client, html.data, cast(i32)(html.count-1), 0); var bytes_sent = send(client, &html[0], i32(len(html)-1), 0);
if bytes_sent == SOCKET_ERROR { if bytes_sent == SOCKET_ERROR {
fmt.println("send failed: ", WSAGetLastError()); fmt.println("send failed: ", WSAGetLastError());
return; return;
+233 -224
View File
@@ -1,35 +1,42 @@
#import win32 "sys/windows.odin"; import (
#import "fmt.odin"; win32 "sys/windows.odin";
#import "os.odin"; "fmt.odin";
#import "mem.odin"; "os.odin";
"mem.odin";
)
CANVAS_WIDTH :: 128; const (
CANVAS_HEIGHT :: 128; CANVAS_WIDTH = 128;
CANVAS_SCALE :: 3; CANVAS_HEIGHT = 128;
FRAME_TIME :: 1.0/30.0; CANVAS_SCALE = 3;
WINDOW_TITLE :: "Punity\x00"; FRAME_TIME = 1.0/30.0;
WINDOW_TITLE = "Punity\x00";
)
_ := compile_assert(CANVAS_WIDTH % 16 == 0); const _ = compile_assert(CANVAS_WIDTH % 16 == 0);
WINDOW_WIDTH :: CANVAS_WIDTH * CANVAS_SCALE; const (
WINDOW_HEIGHT :: CANVAS_HEIGHT * CANVAS_SCALE; WINDOW_WIDTH = CANVAS_WIDTH * CANVAS_SCALE;
WINDOW_HEIGHT = CANVAS_HEIGHT * CANVAS_SCALE;
)
const (
STACK_CAPACITY = 1<<20;
STORAGE_CAPACITY = 1<<20;
STACK_CAPACITY :: 1<<20; DRAW_LIST_RESERVE = 128;
STORAGE_CAPACITY :: 1<<20;
DRAW_LIST_RESERVE :: 128; MAX_KEYS = 256;
)
MAX_KEYS :: 256; type Core struct {
Core :: struct {
stack: ^Bank, stack: ^Bank,
storage: ^Bank, storage: ^Bank,
running: bool, running: bool,
key_modifiers: u32, key_modifiers: u32,
key_states: [MAX_KEYS]byte, key_states: [MAX_KEYS]u8,
key_deltas: [MAX_KEYS]byte, key_deltas: [MAX_KEYS]u8,
perf_frame, perf_frame,
perf_frame_inner, perf_frame_inner,
@@ -45,52 +52,52 @@ Core :: struct {
draw_list: ^Draw_List, draw_list: ^Draw_List,
} }
Perf_Span :: struct { type Perf_Span struct {
stamp: f64, stamp: f64,
delta: f32, delta: f32,
} }
Bank :: struct { type Bank struct {
memory: []byte, memory: []u8,
cursor: int, cursor: int,
} }
Bank_State :: struct { type Bank_State struct {
state: Bank, state: Bank,
bank: ^Bank, bank: ^Bank,
} }
Color :: raw_union { type Color raw_union {
using channels: struct{a, b, g, r: byte}, using channels: struct{a, b, g, r: u8},
rgba: u32, rgba: u32,
} }
Palette :: struct { type Palette struct {
colors: [256]Color, colors: [256]Color,
colors_count: byte, colors_count: u8,
} }
Rect :: raw_union { type Rect raw_union {
using minmax: struct {min_x, min_y, max_x, max_y: int}, using minmax: struct {min_x, min_y, max_x, max_y: int},
using pos: struct {left, top, right, bottom: int}, using pos: struct {left, top, right, bottom: int},
e: [4]int, e: [4]int,
} }
Bitmap :: struct { type Bitmap struct {
pixels: []byte, pixels: []u8,
width: int, width: int,
height: int, height: int,
} }
Font :: struct { type Font struct {
using bitmap: Bitmap, using bitmap: Bitmap,
char_width: int, char_width: int,
char_height: int, char_height: int,
} }
Canvas :: struct { type Canvas struct {
using bitmap: ^Bitmap, using bitmap: ^Bitmap,
palette: Palette, palette: Palette,
translate_x: int, translate_x: int,
@@ -99,89 +106,92 @@ Canvas :: struct {
font: ^Font, font: ^Font,
} }
DrawFlag :: enum { type DrawFlag enum {
NONE = 0, NONE = 0,
FLIP_H = 1<<0, FLIP_H = 1<<0,
FLIP_V = 1<<1, FLIP_V = 1<<1,
MASK = 1<<2, MASK = 1<<2,
} }
Draw_Item :: struct {} type Draw_Item struct {}
Draw_List :: struct { type Draw_List struct {
items: []Draw_Item, items: []Draw_Item,
} }
Key :: enum { type Key enum {
MOD_SHIFT = 0x0001, ModShift = 0x0001,
MOD_CONTROL = 0x0002, ModControl = 0x0002,
MOD_ALT = 0x0004, ModAlt = 0x0004,
MOD_SUPER = 0x0008, ModSuper = 0x0008,
UNKNOWN =-1,
INVALID =-2,
LBUTTON = 1, Unknown =-1,
RBUTTON = 2, Invalid =-2,
CANCEL = 3,
MBUTTON = 4,
BACK = 8,
TAB = 9, Lbutton = 1,
CLEAR = 12, Rbutton = 2,
RETURN = 13, Cancel = 3,
SHIFT = 16, Mbutton = 4,
CONTROL = 17,
MENU = 18,
PAUSE = 19, Back = 8,
CAPITAL = 20, Tab = 9,
KANA = 0x15, Clear = 12,
HANGEUL = 0x15, Return = 13,
HANGUL = 0x15, Shift = 16,
JUNJA = 0x17, Control = 17,
FINAL = 0x18, Menu = 18,
HANJA = 0x19, Pause = 19,
KANJI = 0x19, Capital = 20,
ESCAPE = 0x1B, Kana = 0x15,
CONVERT = 0x1C, Hangeul = 0x15,
NONCONVERT = 0x1D, Hangul = 0x15,
ACCEPT = 0x1E, Junja = 0x17,
MODECHANGE = 0x1F, Final = 0x18,
SPACE = 32, Hanja = 0x19,
PRIOR = 33, Kanji = 0x19,
NEXT = 34, Escape = 0x1B,
END = 35, Convert = 0x1C,
HOME = 36, NonConvert = 0x1D,
LEFT = 37, Accept = 0x1E,
UP = 38, ModeChange = 0x1F,
RIGHT = 39, Space = 32,
DOWN = 40, Prior = 33,
SELECT = 41, Next = 34,
PRINT = 42, End = 35,
EXEC = 43, Home = 36,
SNAPSHOT = 44, Left = 37,
INSERT = 45, Up = 38,
DELETE = 46, Right = 39,
HELP = 47, Down = 40,
LWIN = 0x5B, Select = 41,
RWIN = 0x5C, Print = 42,
APPS = 0x5D, Exec = 43,
SLEEP = 0x5F, Snapshot = 44,
NUMPAD0 = 0x60, Insert = 45,
NUMPAD1 = 0x61, Delete = 46,
NUMPAD2 = 0x62, Help = 47,
NUMPAD3 = 0x63, Lwin = 0x5B,
NUMPAD4 = 0x64, Rwin = 0x5C,
NUMPAD5 = 0x65, Apps = 0x5D,
NUMPAD6 = 0x66, Sleep = 0x5F,
NUMPAD7 = 0x67, Numpad0 = 0x60,
NUMPAD8 = 0x68, Numpad1 = 0x61,
NUMPAD9 = 0x69, Numpad2 = 0x62,
MULTIPLY = 0x6A, Numpad3 = 0x63,
ADD = 0x6B, Numpad4 = 0x64,
SEPARATOR = 0x6C, Numpad5 = 0x65,
SUBTRACT = 0x6D, Numpad6 = 0x66,
DECIMAL = 0x6E, Numpad7 = 0x67,
DIVIDE = 0x6F, Numpad8 = 0x68,
Numpad9 = 0x69,
Multiply = 0x6A,
Add = 0x6B,
Separator = 0x6C,
Subtract = 0x6D,
Decimal = 0x6E,
Divide = 0x6F,
F1 = 0x70, F1 = 0x70,
F2 = 0x71, F2 = 0x71,
F3 = 0x72, F3 = 0x72,
@@ -206,32 +216,33 @@ Key :: enum {
F22 = 0x85, F22 = 0x85,
F23 = 0x86, F23 = 0x86,
F24 = 0x87, F24 = 0x87,
NUMLOCK = 0x90, Numlock = 0x90,
SCROLL = 0x91, Scroll = 0x91,
LSHIFT = 0xA0, Lshift = 0xA0,
RSHIFT = 0xA1, Rshift = 0xA1,
LCONTROL = 0xA2, Lcontrol = 0xA2,
RCONTROL = 0xA3, Rcontrol = 0xA3,
LMENU = 0xA4, Lmenu = 0xA4,
RMENU = 0xA5, Rmenu = 0xA5,
APOSTROPHE = 39, /* ' */
COMMA = 44, /* , */ Apostrophe = 39, /* ' */
MINUS = 45, /* - */ Comma = 44, /* , */
PERIOD = 46, /* . */ Minus = 45, /* - */
SLASH = 47, /* / */ Period = 46, /* . */
NUM0 = 48, Slash = 47, /* / */
NUM1 = 49, Num0 = 48,
NUM2 = 50, Num1 = 49,
NUM3 = 51, Num2 = 50,
NUM4 = 52, Num3 = 51,
NUM5 = 53, Num4 = 52,
NUM6 = 54, Num5 = 53,
NUM7 = 55, Num6 = 54,
NUM8 = 56, Num7 = 55,
NUM9 = 57, Num8 = 56,
SEMICOLON = 59, /* ; */ Num9 = 57,
EQUAL = 61, /* = */ Semicolon = 59, /* ; */
Equal = 61, /* = */
A = 65, A = 65,
B = 66, B = 66,
C = 67, C = 67,
@@ -258,56 +269,55 @@ Key :: enum {
X = 88, X = 88,
Y = 89, Y = 89,
Z = 90, Z = 90,
LEFT_BRACKET = 91, /* [ */ LeftBracket = 91, /* [ */
BACKSLASH = 92, /* \ */ Backslash = 92, /* \ */
RIGHT_BRACKET = 93, /* ] */ RightBracket = 93, /* ] */
GRAVE_ACCENT = 96, /* ` */ GraveAccent = 96, /* ` */
}; };
key_down :: proc(k: Key) -> bool { proc key_down(k: Key) -> bool {
return _core.key_states[k] != 0; return _core.key_states[k] != 0;
} }
key_pressed :: proc(k: Key) -> bool { proc key_pressed(k: Key) -> bool {
return (_core.key_deltas[k] != 0) && key_down(k); return (_core.key_deltas[k] != 0) && key_down(k);
} }
win32_perf_count_freq := win32.GetQueryPerformanceFrequency(); let win32_perf_count_freq = win32.get_query_performance_frequency();
time_now :: proc() -> f64 { proc time_now() -> f64 {
assert(win32_perf_count_freq != 0); assert(win32_perf_count_freq != 0);
counter: i64; var counter: i64;
win32.QueryPerformanceCounter(^counter); win32.query_performance_counter(&counter);
result := cast(f64)counter / cast(f64)win32_perf_count_freq; return f64(counter) / f64(win32_perf_count_freq);
return result;
} }
_core: Core; var _core: Core;
run :: proc(user_init, user_step: proc(c: ^Core)) { proc run(user_init, user_step: proc(c: ^Core)) {
using win32; using win32;
_core.running = true; _core.running = true;
win32_proc :: proc(hwnd: win32.HWND, msg: u32, wparam: win32.WPARAM, lparam: win32.LPARAM) -> win32.LRESULT #no_inline #cc_c { proc win32_proc(hwnd: win32.Hwnd, msg: u32, wparam: win32.Wparam, lparam: win32.Lparam) -> win32.Lresult #no_inline #cc_c {
win32_app_key_mods :: proc() -> u32 { proc win32_app_key_mods() -> u32 {
mods: u32 = 0; var mods: u32 = 0;
if is_key_down(Key_Code.SHIFT) { if is_key_down(KeyCode.Shift) {
mods |= cast(u32)Key.MOD_SHIFT; mods |= u32(Key.ModShift);
} }
if is_key_down(Key_Code.CONTROL) { if is_key_down(KeyCode.Control) {
mods |= cast(u32)Key.MOD_CONTROL; mods |= u32(Key.ModControl);
} }
if is_key_down(Key_Code.MENU) { if is_key_down(KeyCode.Menu) {
mods |= cast(u32)Key.MOD_ALT; mods |= u32(Key.ModAlt);
} }
if is_key_down(Key_Code.LWIN) || is_key_down(Key_Code.RWIN) { if is_key_down(KeyCode.Lwin) || is_key_down(KeyCode.Rwin) {
mods |= cast(u32)Key.MOD_SUPER; mods |= u32(Key.ModSuper);
} }
return mods; return mods;
@@ -331,61 +341,62 @@ run :: proc(user_init, user_step: proc(c: ^Core)) {
return 0; return 0;
case WM_CLOSE: case WM_CLOSE:
PostQuitMessage(0); post_quit_message(0);
_core.running = false; _core.running = false;
return 0; return 0;
} }
return DefWindowProcA(hwnd, msg, wparam, lparam); return def_window_proc_a(hwnd, msg, wparam, lparam);
} }
window_class := WNDCLASSEXA{ var class_name = "Punity\x00";
class_name = (cast(string)"Punity\x00").data, // C-style string var window_class = WndClassExA{
size = size_of(WNDCLASSEXA), class_name = &class_name[0],
size = size_of(WndClassExA),
style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC, style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC,
instance = cast(HINSTANCE)GetModuleHandleA(nil), instance = Hinstance(get_module_handle_a(nil)),
wnd_proc = win32_proc, wnd_proc = win32_proc,
// wnd_proc = DefWindowProcA, // wnd_proc = DefWindowProcA,
background = cast(HBRUSH)GetStockObject(BLACK_BRUSH), background = Hbrush(get_stock_object(BLACK_BRUSH)),
}; };
if RegisterClassExA(^window_class) == 0 { if register_class_ex_a(&window_class) == 0 {
fmt.fprintln(os.stderr, "RegisterClassExA failed"); fmt.fprintln(os.stderr, "register_class_ex_a failed");
return; return;
} }
screen_width := GetSystemMetrics(SM_CXSCREEN); var screen_width = get_system_metrics(SM_CXSCREEN);
screen_height := GetSystemMetrics(SM_CYSCREEN); var screen_height = get_system_metrics(SM_CYSCREEN);
rc: RECT; var rc: Rect;
rc.left = (screen_width - WINDOW_WIDTH) / 2; rc.left = (screen_width - WINDOW_WIDTH) / 2;
rc.top = (screen_height - WINDOW_HEIGHT) / 2; rc.top = (screen_height - WINDOW_HEIGHT) / 2;
rc.right = rc.left + WINDOW_WIDTH; rc.right = rc.left + WINDOW_WIDTH;
rc.bottom = rc.top + WINDOW_HEIGHT; rc.bottom = rc.top + WINDOW_HEIGHT;
style: u32 = WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; var style: u32 = WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
assert(AdjustWindowRect(^rc, style, 0) != 0); assert(adjust_window_rect(&rc, style, 0) != 0);
wt := WINDOW_TITLE; var wt = WINDOW_TITLE;
win32_window := CreateWindowExA(0, var win32_window = create_window_ex_a(0,
window_class.class_name, window_class.class_name,
wt.data, &wt[0],
style, style,
rc.left, rc.top, rc.left, rc.top,
rc.right-rc.left, rc.bottom-rc.top, rc.right-rc.left, rc.bottom-rc.top,
nil, nil, window_class.instance, nil, nil, window_class.instance,
nil); nil);
if win32_window == nil { if win32_window == nil {
fmt.fprintln(os.stderr, "CreateWindowExA failed"); fmt.fprintln(os.stderr, "create_window_ex_a failed");
return; return;
} }
window_bmi: BITMAPINFO; var window_bmi: BitmapInfo;
window_bmi.size = size_of(BITMAPINFOHEADER); window_bmi.size = size_of(BitmapInfoHeader);
window_bmi.width = CANVAS_WIDTH; window_bmi.width = CANVAS_WIDTH;
window_bmi.height = CANVAS_HEIGHT; window_bmi.height = CANVAS_HEIGHT;
window_bmi.planes = 1; window_bmi.planes = 1;
@@ -393,27 +404,27 @@ run :: proc(user_init, user_step: proc(c: ^Core)) {
window_bmi.compression = BI_RGB; window_bmi.compression = BI_RGB;
user_init(^_core); user_init(&_core);
ShowWindow(win32_window, SW_SHOW); show_window(win32_window, SW_SHOW);
window_buffer := new_slice(u32, CANVAS_WIDTH * CANVAS_HEIGHT); var window_buffer = make([]u32, CANVAS_WIDTH * CANVAS_HEIGHT);
defer free(window_buffer); defer free(window_buffer);
for _, i in window_buffer {
for i := 0; i < window_buffer.count; i += 1 {
window_buffer[i] = 0xff00ff; window_buffer[i] = 0xff00ff;
} }
var (
dt: f64;
prev_time = time_now();
curr_time = time_now();
total_time : f64 = 0;
offset_x = 0;
offset_y = 0;
)
dt: f64; var message: Msg;
prev_time := time_now();
curr_time := time_now();
total_time : f64 = 0;
offset_x := 0;
offset_y := 0;
message: MSG;
for _core.running { for _core.running {
curr_time = time_now(); curr_time = time_now();
dt = curr_time - prev_time; dt = curr_time - prev_time;
@@ -424,64 +435,62 @@ run :: proc(user_init, user_step: proc(c: ^Core)) {
offset_y += 2; offset_y += 2;
{ {
data: [128]byte; var buf: [128]u8;
buf: fmt.Buffer; var s = fmt.bprintf(buf[..], "Punity: %.4f ms\x00", dt*1000);
buf.data = data[:]; win32.set_window_text_a(win32_window, &s[0]);
fmt.bprintf(^buf, "Punity: %.4f ms\x00", dt*1000);
win32.SetWindowTextA(win32_window, ^buf[0]);
} }
for y := 0; y < CANVAS_HEIGHT; y += 1 { for var y = 0; y < CANVAS_HEIGHT; y++ {
for x := 0; x < CANVAS_WIDTH; x += 1 { for var x = 0; x < CANVAS_WIDTH; x++ {
g := (x % 32) * 8; var g = (x % 32) * 8;
b := (y % 32) * 8; var b = (y % 32) * 8;
window_buffer[x + y*CANVAS_WIDTH] = cast(u32)(g << 8 | b); window_buffer[x + y*CANVAS_WIDTH] = u32(g << 8 | b);
} }
} }
mem.zero(^_core.key_deltas[0], size_of_val(_core.key_deltas)); mem.zero(&_core.key_deltas[0], size_of(_core.key_deltas));
for PeekMessageA(^message, nil, 0, 0, PM_REMOVE) != 0 { for peek_message_a(&message, nil, 0, 0, PM_REMOVE) != 0 {
if message.message == WM_QUIT { if message.message == WM_QUIT {
_core.running = false; _core.running = false;
} }
TranslateMessage(^message); translate_message(&message);
DispatchMessageA(^message); dispatch_message_a(&message);
} }
user_step(^_core); user_step(&_core);
dc := GetDC(win32_window); var dc = get_dc(win32_window);
StretchDIBits(dc, stretch_dibits(dc,
0, 0, CANVAS_WIDTH * CANVAS_SCALE, CANVAS_HEIGHT * CANVAS_SCALE, 0, 0, CANVAS_WIDTH * CANVAS_SCALE, CANVAS_HEIGHT * CANVAS_SCALE,
0, 0, CANVAS_WIDTH, CANVAS_HEIGHT, 0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
window_buffer.data, &window_buffer[0],
^window_bmi, &window_bmi,
DIB_RGB_COLORS, DIB_RGB_COLORS,
SRCCOPY); SRCCOPY);
ReleaseDC(win32_window, dc); release_dc(win32_window, dc);
{ {
delta := time_now() - prev_time; var delta = time_now() - prev_time;
ms := cast(i32)((FRAME_TIME - delta) * 1000); var ms = i32((FRAME_TIME - delta) * 1000);
if ms > 0 { if ms > 0 {
win32.Sleep(ms); win32.sleep(ms);
} }
} }
_core.frame += 1; _core.frame++;
} }
} }
main :: proc() { proc main() {
user_init :: proc(c: ^Core) { proc user_init(c: ^Core) {
} }
user_step :: proc(c: ^Core) { proc user_step(c: ^Core) {
} }
-5
View File
@@ -1,5 +0,0 @@
#import "fmt.odin" as fmt
thing :: proc() {
fmt.println("Sub Hello!")
}
-35
View File
@@ -1,35 +0,0 @@
/*#import "fmt.odin"
thing :: proc() {
fmt.println("Hello1!")
}*/
#import "fmt.odin";
main :: proc() {
fmt.println("hello, world!");
}
/*#import "fmt.odin" as .
thing :: proc() {
println("Hello3!")
}
*/
/*#import "fmt.odin" as _
thing :: proc() {
// println("Hello4!")
}
*/
/*
#include "fmt.odin"
thing :: proc() {
println("Hello5!")
}*/
+2 -2
View File
@@ -681,8 +681,8 @@ void i128_divide(i128 a, i128 b, i128 *quo, i128 *rem) {
i128 ni = *cast(i128 *)&n; i128 ni = *cast(i128 *)&n;
i128 ri = *cast(i128 *)&r; i128 ri = *cast(i128 *)&r;
if (quo) *quo = i128_sub(i128_xor(ri, s), s); if (quo) *quo = i128_sub(i128_xor(ni, s), s);
if (rem) *rem = i128_sub(i128_xor(ni, s), s); if (rem) *rem = i128_sub(i128_xor(ri, s), s);
#else #else
if (i128_eq(b, I128_ZERO)) { if (i128_eq(b, I128_ZERO)) {
if (quo) *quo = i128_from_u64(a.lo/b.lo); if (quo) *quo = i128_from_u64(a.lo/b.lo);
+1 -4
View File
@@ -1665,10 +1665,6 @@ void print_llvm_ir(irGen *ir) {
ir_fprintf(f, " = type {float, float} ; Basic_complex64\n"); ir_fprintf(f, " = type {float, float} ; Basic_complex64\n");
ir_print_encoded_local(f, str_lit("..complex128")); ir_print_encoded_local(f, str_lit("..complex128"));
ir_fprintf(f, " = type {double, double} ; Basic_complex128\n"); ir_fprintf(f, " = type {double, double} ; Basic_complex128\n");
ir_print_encoded_local(f, str_lit("..quaternion128"));
ir_fprintf(f, " = type {float, float, float, float} ; Basic_quaternion128\n");
ir_print_encoded_local(f, str_lit("..quaternion256"));
ir_fprintf(f, " = type {double, double, double, double} ; Basic_quaternion256\n");
ir_print_encoded_local(f, str_lit("..any")); ir_print_encoded_local(f, str_lit("..any"));
@@ -1679,6 +1675,7 @@ void print_llvm_ir(irGen *ir) {
ir_fprintf(f, "} ; Basic_any\n"); ir_fprintf(f, "} ; Basic_any\n");
ir_fprintf(f, "declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone \n"); ir_fprintf(f, "declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone \n");
ir_fprintf(f, "\n");
for_array(member_index, m->members.entries) { for_array(member_index, m->members.entries) {
+49 -24
View File
@@ -339,14 +339,14 @@ AST_NODE_KIND(_DeclBegin, "", i32) \
Array<AstNode *> names; \ Array<AstNode *> names; \
AstNode * type; \ AstNode * type; \
Array<AstNode *> values; \ Array<AstNode *> values; \
CommentGroup docs; \ CommentGroup docs; \
CommentGroup comment; \ CommentGroup comment; \
}) \ }) \
AST_NODE_KIND(TypeSpec, "type specification", struct { \ AST_NODE_KIND(TypeSpec, "type specification", struct { \
AstNode *name; \ AstNode *name; \
AstNode *type; \ AstNode *type; \
CommentGroup docs; \ CommentGroup docs; \
CommentGroup comment; \ CommentGroup comment; \
}) \ }) \
AST_NODE_KIND(ImportSpec, "import specification", struct { \ AST_NODE_KIND(ImportSpec, "import specification", struct { \
bool is_import; \ bool is_import; \
@@ -354,8 +354,8 @@ AST_NODE_KIND(_DeclBegin, "", i32) \
String fullpath; \ String fullpath; \
Token import_name; \ Token import_name; \
AstNode *cond; \ AstNode *cond; \
CommentGroup docs; \ CommentGroup docs; \
CommentGroup comment; \ CommentGroup comment; \
}) \ }) \
AST_NODE_KIND(ForeignLibrarySpec, "foreign library specification", struct { \ AST_NODE_KIND(ForeignLibrarySpec, "foreign library specification", struct { \
Token filepath; \ Token filepath; \
@@ -363,8 +363,8 @@ AST_NODE_KIND(_DeclBegin, "", i32) \
String base_dir; \ String base_dir; \
AstNode *cond; \ AstNode *cond; \
bool is_system; \ bool is_system; \
CommentGroup docs; \ CommentGroup docs; \
CommentGroup comment; \ CommentGroup comment; \
}) \ }) \
AST_NODE_KIND(_DeclEnd, "", i32) \ AST_NODE_KIND(_DeclEnd, "", i32) \
AST_NODE_KIND(Field, "field", struct { \ AST_NODE_KIND(Field, "field", struct { \
@@ -425,28 +425,28 @@ AST_NODE_KIND(_TypeBegin, "", i32) \
AstNode *align; \ AstNode *align; \
}) \ }) \
AST_NODE_KIND(UnionType, "union type", struct { \ AST_NODE_KIND(UnionType, "union type", struct { \
Token token; \ Token token; \
Array<AstNode *> fields; \ Array<AstNode *> fields; \
isize field_count; \ isize field_count; \
Array<AstNode *> variants; \ Array<AstNode *> variants; \
}) \ }) \
AST_NODE_KIND(RawUnionType, "raw union type", struct { \ AST_NODE_KIND(RawUnionType, "raw union type", struct { \
Token token; \ Token token; \
Array<AstNode *> fields; \ Array<AstNode *> fields; \
isize field_count; \ isize field_count; \
}) \ }) \
AST_NODE_KIND(EnumType, "enum type", struct { \ AST_NODE_KIND(EnumType, "enum type", struct { \
Token token; \ Token token; \
AstNode *base_type; \ AstNode * base_type; \
Array<AstNode *> fields; /* FieldValue */ \ Array<AstNode *> fields; /* FieldValue */ \
}) \ }) \
AST_NODE_KIND(BitFieldType, "bit field type", struct { \ AST_NODE_KIND(BitFieldType, "bit field type", struct { \
Token token; \ Token token; \
Array<AstNode *> fields; /* FieldValue with : */ \ Array<AstNode *> fields; /* FieldValue with : */ \
AstNode *align; \ AstNode * align; \
}) \ }) \
AST_NODE_KIND(MapType, "map type", struct { \ AST_NODE_KIND(MapType, "map type", struct { \
Token token; \ Token token; \
AstNode *count; \ AstNode *count; \
AstNode *key; \ AstNode *key; \
AstNode *value; \ AstNode *value; \
@@ -793,13 +793,34 @@ AstNode *clone_ast_node(gbAllocator a, AstNode *node) {
break; break;
case AstNode_BadDecl: break; case AstNode_BadDecl: break;
case AstNode_ForeignLibrarySpec: case AstNode_ProcDecl:
n->ForeignLibrarySpec.cond = clone_ast_node(a, n->ForeignLibrarySpec.cond); n->ProcDecl.name = clone_ast_node(a, n->ProcDecl.name);
n->ProcDecl.type = clone_ast_node(a, n->ProcDecl.type);
n->ProcDecl.body = clone_ast_node(a, n->ProcDecl.body);
// TODO(bill): Clone the comment group too?
break;
case AstNode_ForeignBlockDecl:
n->ForeignBlockDecl.foreign_library = clone_ast_node(a, n->ForeignBlockDecl.foreign_library);
n->ForeignBlockDecl.decls = clone_ast_node_array(a, n->ForeignBlockDecl.decls);
break; break;
case AstNode_Label: case AstNode_Label:
n->Label.name = clone_ast_node(a, n->Label.name); n->Label.name = clone_ast_node(a, n->Label.name);
break; break;
case AstNode_GenDecl:
n->GenDecl.specs = clone_ast_node_array(a, n->GenDecl.specs);
break;
case AstNode_ValueSpec:
n->ValueSpec.names = clone_ast_node_array(a, n->ValueSpec.names);
n->ValueSpec.type = clone_ast_node(a, n->ValueSpec.type);
n->ValueSpec.values = clone_ast_node_array(a, n->ValueSpec.values);
break;
case AstNode_TypeSpec:
n->TypeSpec.name = clone_ast_node(a, n->TypeSpec.name);
n->TypeSpec.type = clone_ast_node(a, n->TypeSpec.type);
break;
case AstNode_ForeignLibrarySpec:
n->ForeignLibrarySpec.cond = clone_ast_node(a, n->ForeignLibrarySpec.cond);
break;
case AstNode_Field: case AstNode_Field:
n->Field.names = clone_ast_node_array(a, n->Field.names); n->Field.names = clone_ast_node_array(a, n->Field.names);
@@ -816,6 +837,8 @@ AstNode *clone_ast_node(gbAllocator a, AstNode *node) {
case AstNode_HelperType: case AstNode_HelperType:
break; break;
case AstNode_ProcType: case AstNode_ProcType:
n->ProcType.params = clone_ast_node(a, n->ProcType.params);
n->ProcType.results = clone_ast_node(a, n->ProcType.results);
break; break;
case AstNode_PointerType: case AstNode_PointerType:
n->PointerType.type = clone_ast_node(a, n->PointerType.type); n->PointerType.type = clone_ast_node(a, n->PointerType.type);
@@ -836,6 +859,7 @@ AstNode *clone_ast_node(gbAllocator a, AstNode *node) {
break; break;
case AstNode_StructType: case AstNode_StructType:
n->StructType.fields = clone_ast_node_array(a, n->StructType.fields); n->StructType.fields = clone_ast_node_array(a, n->StructType.fields);
n->StructType.align = clone_ast_node(a, n->StructType.align);
break; break;
case AstNode_UnionType: case AstNode_UnionType:
n->UnionType.fields = clone_ast_node_array(a, n->UnionType.fields); n->UnionType.fields = clone_ast_node_array(a, n->UnionType.fields);
@@ -3393,10 +3417,10 @@ AstNode *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, Tok
syntax_error(f->curr_token, "Default parameters can only be applied to single values"); syntax_error(f->curr_token, "Default parameters can only be applied to single values");
} }
parse_expect_field_separator(f, type);
AstNode *param = ast_field(f, names, type, default_value, set_flags, docs, f->line_comment); AstNode *param = ast_field(f, names, type, default_value, set_flags, docs, f->line_comment);
array_add(&params, param); array_add(&params, param);
parse_expect_field_separator(f, type);
while (f->curr_token.kind != follow && while (f->curr_token.kind != follow &&
f->curr_token.kind != Token_EOF) { f->curr_token.kind != Token_EOF) {
@@ -3429,10 +3453,11 @@ AstNode *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, Tok
syntax_error(f->curr_token, "Default parameters can only be applied to single values"); syntax_error(f->curr_token, "Default parameters can only be applied to single values");
} }
bool ok = parse_expect_field_separator(f, param);
AstNode *param = ast_field(f, names, type, default_value, set_flags, docs, f->line_comment); AstNode *param = ast_field(f, names, type, default_value, set_flags, docs, f->line_comment);
array_add(&params, param); array_add(&params, param);
if (!parse_expect_field_separator(f, param)) { if (!ok) {
break; break;
} }
} }