Explorar o código

Update old demos

Ginger Bill %!s(int64=8) %!d(string=hai) anos
pai
achega
53075e2570
Modificáronse 10 ficheiros con 440 adicións e 444 borrados
  1. 1 1
      build.sh
  2. 2 1
      code/demo.odin
  3. 78 78
      code/game.odin
  4. 63 59
      code/http_test.odin
  5. 244 235
      code/punity.odin
  6. 0 5
      code/sub/test.odin
  7. 0 35
      code/test.odin
  8. 2 2
      src/integer128.cpp
  9. 1 4
      src/ir_print.cpp
  10. 49 24
      src/parser.cpp

+ 1 - 1
build.sh

@@ -2,7 +2,7 @@
 
 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++"
 other_args=""
 compiler="clang"

+ 2 - 1
code/demo.odin

@@ -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
code/game.odin

@@ -1,38 +1,37 @@
-#import win32 "sys/windows.odin" when ODIN_OS == "windows";
-#import wgl "sys/wgl.odin" when ODIN_OS == "windows";
-#import "fmt.odin";
-#import "math.odin";
-#import "os.odin";
-#import gl "opengl.odin";
+import win32 "sys/windows.odin" when ODIN_OS == "windows";
+import wgl "sys/wgl.odin" when ODIN_OS == "windows";
+import "fmt.odin";
+import "math.odin";
+import "os.odin";
+import gl "opengl.odin";
 
-TWO_HEARTS :: '💕';
+const TWO_HEARTS = '💕';
 
-win32_perf_count_freq := win32.GetQueryPerformanceFrequency();
-time_now :: proc() -> f64 {
+var win32_perf_count_freq = win32.get_query_performance_frequency();
+proc time_now() -> f64 {
 	assert(win32_perf_count_freq != 0);
 
-	counter: i64;
-	win32.QueryPerformanceCounter(^counter);
-	result := cast(f64)counter / cast(f64)win32_perf_count_freq;
-	return result;
+	var counter: i64;
+	win32.query_performance_counter(&counter);
+	return f64(counter) / f64(win32_perf_count_freq);
 }
-win32_print_last_error :: proc() {
-	err_code := cast(int)win32.GetLastError();
+proc win32_print_last_error() {
+	var err_code = win32.get_last_error();
 	if err_code != 0 {
-		fmt.println("GetLastError: %", err_code);
+		fmt.println("get_last_error: ", err_code);
 	}
 }
 
 // Yuk!
-to_c_string :: proc(s: string) -> []u8 {
-	c_str := make([]u8, len(s)+1);
-	copy(c_str, cast([]byte)s);
+proc to_c_string(s: string) -> []u8 {
+	var c_str = make([]u8, len(s)+1);
+	copy(c_str, []u8(s));
 	c_str[len(s)] = 0;
 	return c_str;
 }
 
 
-Window :: struct {
+type Window struct {
 	width, height:      int,
 	wc:                 win32.WndClassExA,
 	dc:                 win32.Hdc,
@@ -41,52 +40,52 @@ Window :: struct {
 	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;
 
-	w: Window;
+	var w: Window;
 	w.width, w.height = msg, height;
 
-	class_name := "Win32-Odin-Window\x00";
-	c_class_name := ^class_name[0];
+	var class_name = "Win32-Odin-Window\x00";
+	var c_class_name = &class_name[0];
 	if title[len(title)-1] != 0 {
 		w.c_title = to_c_string(title);
 	} 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{
 		size       = size_of(WndClassExA),
 		style      = CS_VREDRAW | CS_HREDRAW,
-		instance   = cast(Hinstance)instance,
+		instance   = Hinstance(instance),
 		class_name = c_class_name,
 		wnd_proc   = window_proc,
 	};
 
-	if RegisterClassExA(^w.wc) == 0 {
+	if register_class_ex_a(&w.wc) == 0 {
 		win32_print_last_error();
 		return w, false;
 	}
 
-	w.hwnd = CreateWindowExA(0,
-	                         c_class_name, ^w.c_title[0],
-	                         WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
-	                         CW_USEDEFAULT, CW_USEDEFAULT,
-	                         cast(i32)w.width, cast(i32)w.height,
-	                         nil, nil, instance, nil);
+	w.hwnd = create_window_ex_a(0,
+	                            c_class_name, &w.c_title[0],
+	                            WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
+	                            CW_USEDEFAULT, CW_USEDEFAULT,
+	                            i32(w.width), i32(w.height),
+	                            nil, nil, instance, nil);
 
 	if w.hwnd == nil {
 		win32_print_last_error();
 		return w, false;
 	}
 
-	w.dc = GetDC(w.hwnd);
+	w.dc = get_dc(w.hwnd);
 
 	{
-		pfd := PIXELFORMATDESCRIPTOR{
-			size         = size_of(PIXELFORMATDESCRIPTOR),
+		var pfd = PixelFormatDescriptor{
+			size         = size_of(PixelFormatDescriptor),
 			version      = 1,
 			flags        = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
 			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,
 		};
 
-		SetPixelFormat(w.dc, ChoosePixelFormat(w.dc, ^pfd), nil);
-		w.opengl_context = wgl.CreateContext(w.dc);
-		wgl.MakeCurrent(w.dc, w.opengl_context);
+		set_pixel_format(w.dc, choose_pixel_format(w.dc, &pfd), nil);
+		w.opengl_context = wgl.create_context(w.dc);
+		wgl.make_current(w.dc, w.opengl_context);
 
-		attribs := [8]i32{
+		var attribs = [8]i32{
 			wgl.CONTEXT_MAJOR_VERSION_ARB, 2,
 			wgl.CONTEXT_MINOR_VERSION_ARB, 1,
 			wgl.CONTEXT_PROFILE_MASK_ARB, wgl.CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
 			0, // NOTE(bill): tells the proc that this is the end of attribs
 		};
 
-		wgl_str := "wglCreateContextAttribsARB\x00";
-		wglCreateContextAttribsARB := cast(wgl.Create_Context_Attribs_ARB_Type)wgl.GetProcAddress(^wgl_str[0]);
-		w.rc = wglCreateContextAttribsARB(w.dc, nil, ^attribs[0]);
-		wgl.MakeCurrent(w.dc, w.rc);
-		SwapBuffers(w.dc);
+		var wgl_str = "wglCreateContextAttribsARB\x00";
+		var wglCreateContextAttribsARB = wgl.CreateContextAttribsARBType(wgl.get_proc_address(&wgl_str[0]));
+		w.rc = wglCreateContextAttribsARB(w.dc, nil, &attribs[0]);
+		wgl.make_current(w.dc, w.rc);
+		swap_buffers(w.dc);
 	}
 
 	return w, true;
 }
 
-destroy_window :: proc(w: ^Window) {
+proc destroy_window(w: ^Window) {
 	free(w.c_title);
 }
 
-display_window :: proc(w: ^Window) {
-	win32.SwapBuffers(w.dc);
+proc display_window(w: ^Window) {
+	win32.swap_buffers(w.dc);
 }
 
 
-run :: proc() {
-	using win32;
+proc run() {
 	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 {
 			os.exit(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 {
 		return;
 	}
-	defer destroy_window(^window);
+	defer destroy_window(&window);
 
 	gl.init();
 
+	using win32;
 
-	prev_time := time_now();
-	running := true;
+	var prev_time = time_now();
+	var running = true;
 
-	pos := Vec2{100, 100};
+	var pos = Vec2{100, 100};
 
 	for running {
-		curr_time := time_now();
-		dt := cast(f32)(curr_time - prev_time);
+		var curr_time = time_now();
+		var dt = f32(curr_time - prev_time);
 		prev_time = curr_time;
 
-		msg: Msg;
-		for PeekMessageA(^msg, nil, 0, 0, PM_REMOVE) > 0 {
+		var msg: Msg;
+		for peek_message_a(&msg, nil, 0, 0, PM_REMOVE) > 0 {
 			if msg.message == WM_QUIT {
 				running = false;
 			}
-			TranslateMessage(^msg);
-			DispatchMessageA(^msg);
+			translate_message(&msg);
+			dispatch_message_a(&msg);
 		}
 
-		if is_key_down(Key_Code.ESCAPE) {
+		if is_key_down(KeyCode.Escape) {
 			running = false;
 		}
 
 		{
-			SPEED :: 500;
-			v: Vec2;
+			const SPEED = 500;
+			var v: Vec2;
 
-			if is_key_down(Key_Code.RIGHT) { v[0] += 1; }
-			if is_key_down(Key_Code.LEFT)  { v[0] -= 1; }
-			if is_key_down(Key_Code.UP)    { v[1] += 1; }
-			if is_key_down(Key_Code.DOWN)  { v[1] -= 1; }
+			if is_key_down(KeyCode.Right) { v[0] += 1; }
+			if is_key_down(KeyCode.Left)  { v[0] -= 1; }
+			if is_key_down(KeyCode.Up)    { v[1] += 1; }
+			if is_key_down(KeyCode.Down)  { v[1] -= 1; }
 
 			v = norm(v);
 
@@ -190,10 +190,10 @@ run :: proc() {
 		gl.Clear(gl.COLOR_BUFFER_BIT);
 
 		gl.LoadIdentity();
-		gl.Ortho(0, cast(f64)window.width,
-		         0, cast(f64)window.height, 0, 1);
+		gl.Ortho(0, f64(window.width),
+		         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);
 			defer gl.End();
 
@@ -208,15 +208,15 @@ run :: proc() {
 
 		draw_rect(pos.x, pos.y, 50, 50);
 
-		display_window(^window);
-		ms_to_sleep := cast(i32)(16 - 1000*dt);
+		display_window(&window);
+		var ms_to_sleep = i32(16 - 1000*dt);
 		if ms_to_sleep > 0 {
-			win32.Sleep(ms_to_sleep);
+			win32.sleep(ms_to_sleep);
 		}
 	}
 }
 
 
-main :: proc() {
+proc main() {
 	run();
 }

+ 63 - 59
code/http_test.odin

@@ -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;
-INVALID_SOCKET :: ~(cast(SOCKET)0);
+type SOCKET uint;
+const INVALID_SOCKET = ~SOCKET(0);
 
-AF :: enum i32 {
+type AF enum i32 {
 	UNSPEC    = 0,       // unspecified
 	UNIX      = 1,       // local to host (pipes, portals)
 	INET      = 2,       // internetwork: UDP, TCP, etc.
@@ -37,19 +37,22 @@ AF :: enum i32 {
 	MAX       = 26,
 };
 
-SOCK_STREAM  :: 1;
-SOCKET_ERROR :: -1;
-IPPROTO_TCP  :: 6;
-AI_PASSIVE   :: 0x0020;
-SOMAXCONN    :: 128;
-
-SD_RECEIVE :: 0;
-SD_SEND    :: 1;
-SD_BOTH    :: 2;
-
-WSADESCRIPTION_LEN :: 256;
-WSASYS_STATUS_LEN  :: 128;
-WSADATA :: struct #ordered {
+const (
+	SOCK_STREAM  = 1;
+	SOCKET_ERROR = -1;
+	IPPROTO_TCP  = 6;
+	AI_PASSIVE   = 0x0020;
+	SOMAXCONN    = 128;
+)
+const (
+	SD_RECEIVE = 0;
+	SD_SEND    = 1;
+	SD_BOTH    = 2;
+)
+
+const WSADESCRIPTION_LEN = 256;
+const WSASYS_STATUS_LEN  = 128;
+type WSADATA struct #ordered {
 	version:       i16,
 	high_version:  i16,
 
@@ -57,12 +60,12 @@ WSADATA :: struct #ordered {
 // NOTE(bill): This is x64 ordering
 	max_sockets:   u16,
 	max_udp_dg:    u16,
-	vendor_info:   ^byte,
-	description:   [WSADESCRIPTION_LEN+1]byte,
-	system_status: [WSASYS_STATUS_LEN+1]byte,
+	vendor_info:   ^u8,
+	description:   [WSADESCRIPTION_LEN+1]u8,
+	system_status: [WSASYS_STATUS_LEN+1]u8,
 }
 
-addrinfo :: struct #ordered {
+type addrinfo struct #ordered {
 	flags:     i32,
 	family:    i32,
 	socktype:  i32,
@@ -73,52 +76,53 @@ addrinfo :: struct #ordered {
 	next:      ^addrinfo,
 }
 
-sockaddr :: struct #ordered {
+type sockaddr struct #ordered {
 	family: u16,
-	data:   [14]byte,
+	data:   [14]u8,
 }
 
-
-WSAStartup      :: proc(version_requested: i16, data: ^WSADATA) -> i32                             #foreign ws2;
-WSACleanup      :: proc() -> i32                                                                   #foreign ws2;
-getaddrinfo     :: proc(node_name, service_name: ^u8, hints: ^addrinfo, result: ^^addrinfo) -> i32 #foreign ws2;
-freeaddrinfo    :: proc(ai: ^addrinfo)                                                             #foreign ws2;
-socket          :: proc(af, type_, protocol: i32) -> SOCKET                                        #foreign ws2;
-closesocket     :: proc(s: SOCKET) -> i32                                                          #foreign ws2;
-bind            :: proc(s: SOCKET, name: ^sockaddr, name_len: i32) -> i32                          #foreign ws2;
-listen          :: proc(s: SOCKET, back_log: i32) -> i32                                           #foreign ws2;
-accept          :: proc(s: SOCKET, addr: ^sockaddr, addr_len: i32) -> SOCKET                       #foreign ws2;
-recv            :: proc(s: SOCKET, buf: ^byte, len: i32, flags: i32) -> i32                        #foreign ws2;
-send            :: proc(s: SOCKET, buf: ^byte, len: i32, flags: i32) -> i32                        #foreign ws2;
-shutdown        :: proc(s: SOCKET, how: i32) -> i32                                                #foreign ws2;
-WSAGetLastError :: proc() -> i32                                                                   #foreign ws2;
-
-to_c_string :: proc(s: string) -> ^byte {
-	c_str := new_slice(byte, s.count+1);
-	assert(c_str.data != nil);
-	copy(c_str, cast([]byte)s);
-	c_str[s.count] = 0;
-	return c_str.data;
+foreign ws2 {
+	proc WSAStartup     (version_requested: i16, data: ^WSADATA) -> i32;
+	proc WSACleanup     () -> i32;
+	proc getaddrinfo    (node_name, service_name: ^u8, hints: ^addrinfo, result: ^^addrinfo) -> i32;
+	proc freeaddrinfo   (ai: ^addrinfo);
+	proc socket         (af, type_, protocol: i32) -> SOCKET;
+	proc closesocket    (s: SOCKET) -> i32;
+	proc bind           (s: SOCKET, name: ^sockaddr, name_len: i32) -> i32;
+	proc listen         (s: SOCKET, back_log: i32) -> i32;
+	proc accept         (s: SOCKET, addr: ^sockaddr, addr_len: i32) -> SOCKET;
+	proc recv           (s: SOCKET, buf: ^u8, len: i32, flags: i32) -> i32;
+	proc send           (s: SOCKET, buf: ^u8, len: i32, flags: i32) -> i32;
+	proc shutdown       (s: SOCKET, how: i32) -> i32;
+	proc WSAGetLastError() -> i32;
+}
+proc to_c_string(s: string) -> ^u8 {
+	var c_str = make([]u8, len(s)+1);
+	copy(c_str, []u8(s));
+	c_str[len(s)] = 0;
+	return &c_str[0];
 }
 
-run :: proc() {
-	wsa: WSADATA;
-	res:  ^addrinfo = nil;
-	hints: addrinfo;
-	s, client: SOCKET;
+proc run() {
+	var (
+		wsa: WSADATA;
+		res:  ^addrinfo = nil;
+		hints: addrinfo;
+		s, client: SOCKET;
+	)
 
-	if WSAStartup(2 | (2 << 8), ^wsa) != 0 {
+	if WSAStartup(2 | (2 << 8), &wsa) != 0 {
 		fmt.println("WSAStartup failed: ", WSAGetLastError());
 		return;
 	}
 	defer WSACleanup();
 
-	hints.family   = cast(i32)AF.INET;
+	hints.family   = i32(AF.INET);
 	hints.socktype = SOCK_STREAM;
 	hints.protocol = IPPROTO_TCP;
 	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());
 		return;
 	}
@@ -131,7 +135,7 @@ run :: proc() {
 	}
 	defer closesocket(s);
 
-	bind(s, res.addr, cast(i32)res.addrlen);
+	bind(s, res.addr, i32(res.addrlen));
 	listen(s, SOMAXCONN);
 
 	client = accept(s, nil, 0);
@@ -141,7 +145,7 @@ run :: proc() {
 	}
 	defer closesocket(client);
 
-	html :=
+	var html =
 `HTTP/1.1 200 OK
 Connection: close
 Content-type: text/html
@@ -156,12 +160,12 @@ Content-type: text/html
 </html>
 `;
 
-	buf: [1024]byte;
+	var buf: [1024]u8;
 	for {
-		bytes := recv(client, ^buf[0], cast(i32)buf.count, 0);
+		var bytes = recv(client, &buf[0], i32(len(buf)), 0);
 		if bytes > 0 {
-			// fmt.println(buf[:bytes] as string)
-			bytes_sent := send(client, html.data, cast(i32)(html.count-1), 0);
+			// fmt.println(string(buf[0..<bytes]))
+			var bytes_sent = send(client, &html[0], i32(len(html)-1), 0);
 			if bytes_sent == SOCKET_ERROR {
 				fmt.println("send failed: ", WSAGetLastError());
 				return;

+ 244 - 235
code/punity.odin

@@ -1,35 +1,42 @@
-#import win32 "sys/windows.odin";
-#import "fmt.odin";
-#import "os.odin";
-#import "mem.odin";
-
-CANVAS_WIDTH  :: 128;
-CANVAS_HEIGHT :: 128;
-CANVAS_SCALE  :: 3;
-FRAME_TIME    :: 1.0/30.0;
-WINDOW_TITLE  :: "Punity\x00";
-
-_ := compile_assert(CANVAS_WIDTH % 16 == 0);
-
-WINDOW_WIDTH  :: CANVAS_WIDTH  * CANVAS_SCALE;
-WINDOW_HEIGHT :: CANVAS_HEIGHT * CANVAS_SCALE;
-
-
-STACK_CAPACITY   :: 1<<20;
-STORAGE_CAPACITY :: 1<<20;
-
-DRAW_LIST_RESERVE :: 128;
-
-MAX_KEYS :: 256;
-
-Core :: struct {
+import (
+	win32 "sys/windows.odin";
+	"fmt.odin";
+	"os.odin";
+	"mem.odin";
+)
+
+const (
+	CANVAS_WIDTH  = 128;
+	CANVAS_HEIGHT = 128;
+	CANVAS_SCALE  = 3;
+	FRAME_TIME    = 1.0/30.0;
+	WINDOW_TITLE  = "Punity\x00";
+)
+
+const _ = compile_assert(CANVAS_WIDTH % 16 == 0);
+
+const (
+	WINDOW_WIDTH  = CANVAS_WIDTH  * CANVAS_SCALE;
+	WINDOW_HEIGHT = CANVAS_HEIGHT * CANVAS_SCALE;
+)
+
+const (
+	STACK_CAPACITY   = 1<<20;
+	STORAGE_CAPACITY = 1<<20;
+
+	DRAW_LIST_RESERVE = 128;
+
+	MAX_KEYS = 256;
+)
+
+type Core struct {
 	stack:   ^Bank,
 	storage: ^Bank,
 
 	running:       bool,
 	key_modifiers: u32,
-	key_states:    [MAX_KEYS]byte,
-	key_deltas:    [MAX_KEYS]byte,
+	key_states:    [MAX_KEYS]u8,
+	key_deltas:    [MAX_KEYS]u8,
 
 	perf_frame,
 	perf_frame_inner,
@@ -45,52 +52,52 @@ Core :: struct {
 	draw_list: ^Draw_List,
 }
 
-Perf_Span :: struct {
+type Perf_Span struct {
 	stamp: f64,
 	delta: f32,
 }
 
-Bank :: struct {
-	memory: []byte,
+type Bank struct {
+	memory: []u8,
 	cursor: int,
 }
 
-Bank_State :: struct {
+type Bank_State struct {
 	state: Bank,
 	bank: ^Bank,
 }
 
 
-Color :: raw_union {
-	using channels: struct{a, b, g, r: byte},
+type Color raw_union {
+	using channels: struct{a, b, g, r: u8},
 	rgba: u32,
 }
 
-Palette :: struct {
+type Palette struct {
 	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 pos: struct {left, top, right, bottom: int},
 	e: [4]int,
 }
 
-Bitmap :: struct {
-	pixels: []byte,
+type Bitmap struct {
+	pixels: []u8,
 	width:  int,
 	height: int,
 }
 
-Font :: struct {
+type Font struct {
 	using bitmap: Bitmap,
 	char_width:   int,
 	char_height:  int,
 }
 
-Canvas :: struct {
+type Canvas struct {
 	using bitmap: ^Bitmap,
 	palette:      Palette,
 	translate_x:  int,
@@ -99,89 +106,92 @@ Canvas :: struct {
 	font:         ^Font,
 }
 
-DrawFlag :: enum {
+type DrawFlag enum {
 	NONE   = 0,
 	FLIP_H = 1<<0,
 	FLIP_V = 1<<1,
 	MASK   = 1<<2,
 }
 
-Draw_Item :: struct {}
-Draw_List :: struct {
+type Draw_Item struct {}
+type Draw_List struct {
 	items: []Draw_Item,
 }
 
-Key :: enum {
-	MOD_SHIFT   = 0x0001,
-	MOD_CONTROL = 0x0002,
-	MOD_ALT     = 0x0004,
-	MOD_SUPER   = 0x0008,
-
-	UNKNOWN            =-1,
-	INVALID            =-2,
-
-	LBUTTON            = 1,
-	RBUTTON            = 2,
-	CANCEL             = 3,
-	MBUTTON            = 4,
-
-	BACK               = 8,
-	TAB                = 9,
-	CLEAR              = 12,
-	RETURN             = 13,
-	SHIFT              = 16,
-	CONTROL            = 17,
-	MENU               = 18,
-	PAUSE              = 19,
-	CAPITAL            = 20,
-	KANA               = 0x15,
-	HANGEUL            = 0x15,
-	HANGUL             = 0x15,
-	JUNJA              = 0x17,
-	FINAL              = 0x18,
-	HANJA              = 0x19,
-	KANJI              = 0x19,
-	ESCAPE             = 0x1B,
-	CONVERT            = 0x1C,
-	NONCONVERT         = 0x1D,
-	ACCEPT             = 0x1E,
-	MODECHANGE         = 0x1F,
-	SPACE              = 32,
-	PRIOR              = 33,
-	NEXT               = 34,
-	END                = 35,
-	HOME               = 36,
-	LEFT               = 37,
-	UP                 = 38,
-	RIGHT              = 39,
-	DOWN               = 40,
-	SELECT             = 41,
-	PRINT              = 42,
-	EXEC               = 43,
-	SNAPSHOT           = 44,
-	INSERT             = 45,
-	DELETE             = 46,
-	HELP               = 47,
-	LWIN               = 0x5B,
-	RWIN               = 0x5C,
-	APPS               = 0x5D,
-	SLEEP              = 0x5F,
-	NUMPAD0            = 0x60,
-	NUMPAD1            = 0x61,
-	NUMPAD2            = 0x62,
-	NUMPAD3            = 0x63,
-	NUMPAD4            = 0x64,
-	NUMPAD5            = 0x65,
-	NUMPAD6            = 0x66,
-	NUMPAD7            = 0x67,
-	NUMPAD8            = 0x68,
-	NUMPAD9            = 0x69,
-	MULTIPLY           = 0x6A,
-	ADD                = 0x6B,
-	SEPARATOR          = 0x6C,
-	SUBTRACT           = 0x6D,
-	DECIMAL            = 0x6E,
-	DIVIDE             = 0x6F,
+type Key enum {
+	ModShift   = 0x0001,
+	ModControl = 0x0002,
+	ModAlt     = 0x0004,
+	ModSuper   = 0x0008,
+
+
+	Unknown            =-1,
+	Invalid            =-2,
+
+
+	Lbutton            = 1,
+	Rbutton            = 2,
+	Cancel             = 3,
+	Mbutton            = 4,
+
+
+	Back               = 8,
+	Tab                = 9,
+	Clear              = 12,
+	Return             = 13,
+	Shift              = 16,
+	Control            = 17,
+	Menu               = 18,
+	Pause              = 19,
+	Capital            = 20,
+	Kana               = 0x15,
+	Hangeul            = 0x15,
+	Hangul             = 0x15,
+	Junja              = 0x17,
+	Final              = 0x18,
+	Hanja              = 0x19,
+	Kanji              = 0x19,
+	Escape             = 0x1B,
+	Convert            = 0x1C,
+	NonConvert         = 0x1D,
+	Accept             = 0x1E,
+	ModeChange         = 0x1F,
+	Space              = 32,
+	Prior              = 33,
+	Next               = 34,
+	End                = 35,
+	Home               = 36,
+	Left               = 37,
+	Up                 = 38,
+	Right              = 39,
+	Down               = 40,
+	Select             = 41,
+	Print              = 42,
+	Exec               = 43,
+	Snapshot           = 44,
+	Insert             = 45,
+	Delete             = 46,
+	Help               = 47,
+	Lwin               = 0x5B,
+	Rwin               = 0x5C,
+	Apps               = 0x5D,
+	Sleep              = 0x5F,
+	Numpad0            = 0x60,
+	Numpad1            = 0x61,
+	Numpad2            = 0x62,
+	Numpad3            = 0x63,
+	Numpad4            = 0x64,
+	Numpad5            = 0x65,
+	Numpad6            = 0x66,
+	Numpad7            = 0x67,
+	Numpad8            = 0x68,
+	Numpad9            = 0x69,
+	Multiply           = 0x6A,
+	Add                = 0x6B,
+	Separator          = 0x6C,
+	Subtract           = 0x6D,
+	Decimal            = 0x6E,
+	Divide             = 0x6F,
 	F1                 = 0x70,
 	F2                 = 0x71,
 	F3                 = 0x72,
@@ -206,32 +216,33 @@ Key :: enum {
 	F22                = 0x85,
 	F23                = 0x86,
 	F24                = 0x87,
-	NUMLOCK            = 0x90,
-	SCROLL             = 0x91,
-	LSHIFT             = 0xA0,
-	RSHIFT             = 0xA1,
-	LCONTROL           = 0xA2,
-	RCONTROL           = 0xA3,
-	LMENU              = 0xA4,
-	RMENU              = 0xA5,
-
-	APOSTROPHE         = 39,  /* ' */
-	COMMA              = 44,  /* , */
-	MINUS              = 45,  /* - */
-	PERIOD             = 46,  /* . */
-	SLASH              = 47,  /* / */
-	NUM0               = 48,
-	NUM1               = 49,
-	NUM2               = 50,
-	NUM3               = 51,
-	NUM4               = 52,
-	NUM5               = 53,
-	NUM6               = 54,
-	NUM7               = 55,
-	NUM8               = 56,
-	NUM9               = 57,
-	SEMICOLON          = 59,  /* ; */
-	EQUAL              = 61,  /* = */
+	Numlock            = 0x90,
+	Scroll             = 0x91,
+	Lshift             = 0xA0,
+	Rshift             = 0xA1,
+	Lcontrol           = 0xA2,
+	Rcontrol           = 0xA3,
+	Lmenu              = 0xA4,
+	Rmenu              = 0xA5,
+
+
+	Apostrophe         = 39,  /* ' */
+	Comma              = 44,  /* , */
+	Minus              = 45,  /* - */
+	Period             = 46,  /* . */
+	Slash              = 47,  /* / */
+	Num0               = 48,
+	Num1               = 49,
+	Num2               = 50,
+	Num3               = 51,
+	Num4               = 52,
+	Num5               = 53,
+	Num6               = 54,
+	Num7               = 55,
+	Num8               = 56,
+	Num9               = 57,
+	Semicolon          = 59,  /* ; */
+	Equal              = 61,  /* = */
 	A                  = 65,
 	B                  = 66,
 	C                  = 67,
@@ -258,56 +269,55 @@ Key :: enum {
 	X                  = 88,
 	Y                  = 89,
 	Z                  = 90,
-	LEFT_BRACKET       = 91,  /* [ */
-	BACKSLASH          = 92,  /* \ */
-	RIGHT_BRACKET      = 93,  /* ] */
-	GRAVE_ACCENT       = 96,  /* ` */
+	LeftBracket        = 91,  /* [ */
+	Backslash          = 92,  /* \ */
+	RightBracket       = 93,  /* ] */
+	GraveAccent        = 96,  /* ` */
 };
 
 
-key_down :: proc(k: Key) -> bool {
+proc key_down(k: Key) -> bool {
 	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);
 }
 
 
 
 
-win32_perf_count_freq := win32.GetQueryPerformanceFrequency();
-time_now :: proc() -> f64 {
+let win32_perf_count_freq = win32.get_query_performance_frequency();
+proc time_now() -> f64 {
 	assert(win32_perf_count_freq != 0);
 
-	counter: i64;
-	win32.QueryPerformanceCounter(^counter);
-	result := cast(f64)counter / cast(f64)win32_perf_count_freq;
-	return result;
+	var counter: i64;
+	win32.query_performance_counter(&counter);
+	return f64(counter) / f64(win32_perf_count_freq);
 }
 
-_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;
 
 	_core.running = true;
 
-	win32_proc :: proc(hwnd: win32.HWND, msg: u32, wparam: win32.WPARAM, lparam: win32.LPARAM) -> win32.LRESULT #no_inline #cc_c {
-		win32_app_key_mods :: proc() -> u32 {
-			mods: u32 = 0;
+	proc win32_proc(hwnd: win32.Hwnd, msg: u32, wparam: win32.Wparam, lparam: win32.Lparam) -> win32.Lresult #no_inline #cc_c {
+		proc win32_app_key_mods() -> u32 {
+			var mods: u32 = 0;
 
-			if is_key_down(Key_Code.SHIFT) {
-				mods |= cast(u32)Key.MOD_SHIFT;
+			if is_key_down(KeyCode.Shift) {
+				mods |= u32(Key.ModShift);
 			}
-			if is_key_down(Key_Code.CONTROL) {
-				mods |= cast(u32)Key.MOD_CONTROL;
+			if is_key_down(KeyCode.Control) {
+				mods |= u32(Key.ModControl);
 			}
-			if is_key_down(Key_Code.MENU) {
-				mods |= cast(u32)Key.MOD_ALT;
+			if is_key_down(KeyCode.Menu) {
+				mods |= u32(Key.ModAlt);
 			}
-			if is_key_down(Key_Code.LWIN) || is_key_down(Key_Code.RWIN) {
-				mods |= cast(u32)Key.MOD_SUPER;
+			if is_key_down(KeyCode.Lwin) || is_key_down(KeyCode.Rwin) {
+				mods |= u32(Key.ModSuper);
 			}
 
 			return mods;
@@ -331,61 +341,62 @@ run :: proc(user_init, user_step: proc(c: ^Core)) {
 			return 0;
 
 		case WM_CLOSE:
-			PostQuitMessage(0);
+			post_quit_message(0);
 			_core.running = false;
 			return 0;
 		}
 
-		return DefWindowProcA(hwnd, msg, wparam, lparam);
+		return def_window_proc_a(hwnd, msg, wparam, lparam);
 	}
 
 
-	window_class := WNDCLASSEXA{
-		class_name = (cast(string)"Punity\x00").data, // C-style string
-		size       = size_of(WNDCLASSEXA),
+	var class_name = "Punity\x00";
+	var window_class = WndClassExA{
+		class_name = &class_name[0],
+		size       = size_of(WndClassExA),
 		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   = DefWindowProcA,
-		background = cast(HBRUSH)GetStockObject(BLACK_BRUSH),
+		background = Hbrush(get_stock_object(BLACK_BRUSH)),
 	};
 
-	if RegisterClassExA(^window_class) == 0 {
-		fmt.fprintln(os.stderr, "RegisterClassExA failed");
+	if register_class_ex_a(&window_class) == 0 {
+		fmt.fprintln(os.stderr, "register_class_ex_a failed");
 		return;
 	}
 
-	screen_width  := GetSystemMetrics(SM_CXSCREEN);
-	screen_height := GetSystemMetrics(SM_CYSCREEN);
+	var screen_width  = get_system_metrics(SM_CXSCREEN);
+	var screen_height = get_system_metrics(SM_CYSCREEN);
 
-	rc: RECT;
+	var rc: Rect;
 	rc.left   = (screen_width - WINDOW_WIDTH)   / 2;
 	rc.top    = (screen_height - WINDOW_HEIGHT) / 2;
 	rc.right  = rc.left + WINDOW_WIDTH;
 	rc.bottom = rc.top + WINDOW_HEIGHT;
 
-	style: u32 = WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
-	assert(AdjustWindowRect(^rc, style, 0) != 0);
+	var style: u32 = WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
+	assert(adjust_window_rect(&rc, style, 0) != 0);
 
-	wt := WINDOW_TITLE;
+	var wt = WINDOW_TITLE;
 
-	win32_window := CreateWindowExA(0,
-	                                window_class.class_name,
-	                                wt.data,
-	                                style,
-	                                rc.left, rc.top,
-	                                rc.right-rc.left, rc.bottom-rc.top,
-	                                nil, nil, window_class.instance,
-	                                nil);
+	var win32_window = create_window_ex_a(0,
+	                                      window_class.class_name,
+	                                      &wt[0],
+	                                      style,
+	                                      rc.left, rc.top,
+	                                      rc.right-rc.left, rc.bottom-rc.top,
+	                                      nil, nil, window_class.instance,
+	                                      nil);
 
 	if win32_window == nil {
-		fmt.fprintln(os.stderr, "CreateWindowExA failed");
+		fmt.fprintln(os.stderr, "create_window_ex_a failed");
 		return;
 	}
 
 
-	window_bmi: BITMAPINFO;
-	window_bmi.size        = size_of(BITMAPINFOHEADER);
+	var window_bmi: BitmapInfo;
+	window_bmi.size        = size_of(BitmapInfoHeader);
 	window_bmi.width       = CANVAS_WIDTH;
 	window_bmi.height      = CANVAS_HEIGHT;
 	window_bmi.planes      = 1;
@@ -393,27 +404,27 @@ run :: proc(user_init, user_step: proc(c: ^Core)) {
 	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);
 
-
-	for i := 0; i < window_buffer.count; i += 1 {
+	for _, i in window_buffer {
 		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;
-	prev_time := time_now();
-	curr_time := time_now();
-	total_time : f64 = 0;
-	offset_x := 0;
-	offset_y := 0;
-
-	message: MSG;
+	var message: Msg;
 	for _core.running {
 		curr_time = time_now();
 		dt = curr_time - prev_time;
@@ -424,64 +435,62 @@ run :: proc(user_init, user_step: proc(c: ^Core)) {
 		offset_y += 2;
 
 		{
-			data: [128]byte;
-			buf: fmt.Buffer;
-			buf.data = data[:];
-			fmt.bprintf(^buf, "Punity: %.4f ms\x00", dt*1000);
-			win32.SetWindowTextA(win32_window, ^buf[0]);
+			var buf: [128]u8;
+			var s = fmt.bprintf(buf[..], "Punity: %.4f ms\x00", dt*1000);
+			win32.set_window_text_a(win32_window, &s[0]);
 		}
 
 
-		for y := 0; y < CANVAS_HEIGHT; y += 1 {
-			for x := 0; x < CANVAS_WIDTH; x += 1 {
-				g := (x % 32) * 8;
-				b := (y % 32) * 8;
-				window_buffer[x + y*CANVAS_WIDTH] = cast(u32)(g << 8 | b);
+		for var y = 0; y < CANVAS_HEIGHT; y++ {
+			for var x = 0; x < CANVAS_WIDTH; x++ {
+				var g = (x % 32) * 8;
+				var b = (y % 32) * 8;
+				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 {
 				_core.running = false;
 			}
-			TranslateMessage(^message);
-			DispatchMessageA(^message);
+			translate_message(&message);
+			dispatch_message_a(&message);
 		}
 
-		user_step(^_core);
+		user_step(&_core);
 
-		dc := GetDC(win32_window);
-		StretchDIBits(dc,
-		              0, 0, CANVAS_WIDTH * CANVAS_SCALE, CANVAS_HEIGHT * CANVAS_SCALE,
-		              0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
-		              window_buffer.data,
-		              ^window_bmi,
-		              DIB_RGB_COLORS,
-		              SRCCOPY);
-		ReleaseDC(win32_window, dc);
+		var dc = get_dc(win32_window);
+		stretch_dibits(dc,
+		               0, 0, CANVAS_WIDTH * CANVAS_SCALE, CANVAS_HEIGHT * CANVAS_SCALE,
+		               0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
+		               &window_buffer[0],
+		               &window_bmi,
+		               DIB_RGB_COLORS,
+		               SRCCOPY);
+		release_dc(win32_window, dc);
 
 
 		{
-			delta := time_now() - prev_time;
-			ms := cast(i32)((FRAME_TIME - delta) * 1000);
+			var delta = time_now() - prev_time;
+			var ms = i32((FRAME_TIME - delta) * 1000);
 			if ms > 0 {
-				win32.Sleep(ms);
+				win32.sleep(ms);
 			}
 		}
 
-		_core.frame += 1;
+		_core.frame++;
 	}
 }
 
 
-main :: proc() {
-	user_init :: proc(c: ^Core) {
+proc main() {
+	proc user_init(c: ^Core) {
 
 	}
 
-	user_step :: proc(c: ^Core) {
+	proc user_step(c: ^Core) {
 
 	}
 

+ 0 - 5
code/sub/test.odin

@@ -1,5 +0,0 @@
-#import "fmt.odin" as fmt
-
-thing :: proc() {
-	fmt.println("Sub Hello!")
-}

+ 0 - 35
code/test.odin

@@ -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
src/integer128.cpp

@@ -681,8 +681,8 @@ void i128_divide(i128 a, i128 b, i128 *quo, i128 *rem) {
 	i128 ni = *cast(i128 *)&n;
 	i128 ri = *cast(i128 *)&r;
 
-	if (quo) *quo = i128_sub(i128_xor(ri, s), s);
-	if (rem) *rem = i128_sub(i128_xor(ni, s), s);
+	if (quo) *quo = i128_sub(i128_xor(ni, s), s);
+	if (rem) *rem = i128_sub(i128_xor(ri, s), s);
 #else
 	if (i128_eq(b, I128_ZERO)) {
 		if (quo) *quo = i128_from_u64(a.lo/b.lo);

+ 1 - 4
src/ir_print.cpp

@@ -1665,10 +1665,6 @@ void print_llvm_ir(irGen *ir) {
 	ir_fprintf(f, " = type {float, float} ; Basic_complex64\n");
 	ir_print_encoded_local(f, str_lit("..complex128"));
 	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"));
@@ -1679,6 +1675,7 @@ void print_llvm_ir(irGen *ir) {
 	ir_fprintf(f, "} ; Basic_any\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) {

+ 49 - 24
src/parser.cpp

@@ -339,14 +339,14 @@ AST_NODE_KIND(_DeclBegin,      "", i32) \
 		Array<AstNode *> names;  \
 		AstNode *        type;   \
 		Array<AstNode *> values; \
-		CommentGroup docs;  \
-		CommentGroup comment;        \
+		CommentGroup docs;       \
+		CommentGroup comment;    \
 	}) \
 	AST_NODE_KIND(TypeSpec, "type specification", struct { \
 		AstNode *name;          \
 		AstNode *type;          \
-		CommentGroup docs; \
-		CommentGroup comment;       \
+		CommentGroup docs;      \
+		CommentGroup comment;   \
 	}) \
 	AST_NODE_KIND(ImportSpec, "import specification", struct { \
 		bool     is_import;     \
@@ -354,8 +354,8 @@ AST_NODE_KIND(_DeclBegin,      "", i32) \
 		String   fullpath;      \
 		Token    import_name;   \
 		AstNode *cond;          \
-		CommentGroup docs; \
-		CommentGroup comment;       \
+		CommentGroup docs;      \
+		CommentGroup comment;   \
 	}) \
 	AST_NODE_KIND(ForeignLibrarySpec, "foreign library specification", struct { \
 		Token    filepath;      \
@@ -363,8 +363,8 @@ AST_NODE_KIND(_DeclBegin,      "", i32) \
 		String   base_dir;      \
 		AstNode *cond;          \
 		bool     is_system;     \
-		CommentGroup docs; \
-		CommentGroup comment;       \
+		CommentGroup docs;      \
+		CommentGroup comment;   \
 	}) \
 AST_NODE_KIND(_DeclEnd,   "", i32) \
 	AST_NODE_KIND(Field, "field", struct { \
@@ -425,28 +425,28 @@ AST_NODE_KIND(_TypeBegin, "", i32) \
 		AstNode *align; \
 	}) \
 	AST_NODE_KIND(UnionType, "union type", struct { \
-		Token        token; \
-		Array<AstNode *> fields; \
-		isize        field_count; \
-		Array<AstNode *> variants; \
+		Token            token;       \
+		Array<AstNode *> fields;      \
+		isize            field_count; \
+		Array<AstNode *> variants;    \
 	}) \
 	AST_NODE_KIND(RawUnionType, "raw union type", struct { \
-		Token token; \
+		Token            token; \
 		Array<AstNode *> fields; \
-		isize field_count; \
+		isize            field_count; \
 	}) \
 	AST_NODE_KIND(EnumType, "enum type", struct { \
-		Token token; \
-		AstNode *base_type; \
+		Token            token; \
+		AstNode *        base_type; \
 		Array<AstNode *> fields; /* FieldValue */ \
 	}) \
 	AST_NODE_KIND(BitFieldType, "bit field type", struct { \
-		Token token; \
+		Token            token; \
 		Array<AstNode *> fields; /* FieldValue with : */ \
-		AstNode *align; \
+		AstNode *        align; \
 	}) \
 	AST_NODE_KIND(MapType, "map type", struct { \
-		Token token; \
+		Token    token; \
 		AstNode *count; \
 		AstNode *key; \
 		AstNode *value; \
@@ -793,13 +793,34 @@ AstNode *clone_ast_node(gbAllocator a, AstNode *node) {
 		break;
 
 	case AstNode_BadDecl: break;
-	case AstNode_ForeignLibrarySpec:
-		n->ForeignLibrarySpec.cond = clone_ast_node(a, n->ForeignLibrarySpec.cond);
+	case AstNode_ProcDecl:
+		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;
 	case AstNode_Label:
 		n->Label.name = clone_ast_node(a, n->Label.name);
 		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:
 		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:
 		break;
 	case AstNode_ProcType:
+		n->ProcType.params  = clone_ast_node(a, n->ProcType.params);
+		n->ProcType.results = clone_ast_node(a, n->ProcType.results);
 		break;
 	case AstNode_PointerType:
 		n->PointerType.type = clone_ast_node(a, n->PointerType.type);
@@ -836,6 +859,7 @@ AstNode *clone_ast_node(gbAllocator a, AstNode *node) {
 		break;
 	case AstNode_StructType:
 		n->StructType.fields = clone_ast_node_array(a, n->StructType.fields);
+		n->StructType.align  = clone_ast_node(a, n->StructType.align);
 		break;
 	case AstNode_UnionType:
 		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");
 		}
 
+		parse_expect_field_separator(f, type);
 		AstNode *param = ast_field(f, names, type, default_value, set_flags, docs, f->line_comment);
 		array_add(&params, param);
 
-		parse_expect_field_separator(f, type);
 
 		while (f->curr_token.kind != follow &&
 		       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");
 			}
 
+			bool ok = parse_expect_field_separator(f, param);
 			AstNode *param = ast_field(f, names, type, default_value, set_flags, docs, f->line_comment);
 			array_add(&params, param);
 
-			if (!parse_expect_field_separator(f, param)) {
+			if (!ok) {
 				break;
 			}
 		}