G

G Programming Language
git clone http://git.omkov.net/G
Log | Tree | Refs | README | Download

AuthorJakob Wakeling <[email protected]>
Date2023-12-28 11:07:06
Commitb280badf2a766caf69094ea3c5b62c0463abb12f
Parent8250c82bf09c1600077ced7be4f549cf7e533c9f

Migrate to C23

Diffstat

M .gitignore | 1 -
M CMakeLists.txt | 6 +++++-
M Makefile | 5 +----
M README.md | 7 ++++---
M examples/Test.sh | 2 --
M src/analyse.c | 25 ++++++++++++-------------
M src/analyse.h | 2 --
M src/init.c | 4 +---
M src/init.h | 2 --
M src/lex.c | 17 ++++++++---------
M src/lex.h | 8 +++-----
M src/llvm.c | 25 ++++++++++++-------------
M src/llvm.h | 2 --
M src/llvm/attr.c | 2 --
M src/llvm/llvm.h | 2 --
M src/log.c | 11 ++++-------
M src/log.h | 10 +++-------
M src/main.c | 63 +++++++++++++++++++++++++++++++++------------------------------
M src/parse.c | 23 ++++++++++++-----------
M src/parse.h | 11 +++++------
M src/symbol.c | 35 ++++++++++++++---------------------
M src/symbol.h | 6 ++----
M src/type.c | 2 --
M src/type.h | 4 +---
M src/util/error.c | 7 +------
M src/util/error.h | 19 +++----------------
M src/util/fnv.c | 9 +++------
M src/util/fnv.h | 22 +++++++---------------
M src/util/optget.c | 4 +---
M src/util/optget.h | 15 ++++-----------
M src/util/util.h | 33 ++++++++-------------------------

31 files changed, 147 insertions, 237 deletions

diff --git a/.gitignore b/.gitignore
index ed26822..f5264ec 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,4 +2,3 @@
 /.vscode/
 /bin/
 /build/
-/compile_commands.json
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4f14234..fdec80c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,12 +1,16 @@
-cmake_minimum_required(VERSION 3.14)
+cmake_minimum_required(VERSION 3.21 FATAL_ERROR)
 project(G VERSION 0.2.0 LANGUAGES C)
 
+set(CMAKE_C_STANDARD 23)
+set(CMAKE_C_STANDARD_REQUIRED TRUE)
+set(CMAKE_C_EXTENSIONS FALSE)
+
 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin)
 add_compile_definitions(PROJECT_VERSION="${PROJECT_VERSION}")
 
 find_package(LLVM REQUIRED)
 
-file(GLOB SRC CONFIGURE_DEPENDS ${PROJECT_SOURCE_DIR}/src/*.c ${PROJECT_SOURCE_DIR}/src/**/*.c)
+file(GLOB_RECURSE SRC CONFIGURE_DEPENDS ${PROJECT_SOURCE_DIR}/src/*.c)
 
 add_executable(g ${SRC})
 target_link_libraries(g LLVM)
diff --git a/Makefile b/Makefile
index 2932c0c..e994e06 100644
--- a/Makefile
+++ b/Makefile
@@ -4,11 +4,8 @@ all: help
 build: ## Build the project
 	@cmake -S . -B ./build -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_EXPORT_COMPILE_COMMANDS=1
 	@cmake --build ./build
-	@mv -f ./build/compile_commands.json ./compile_commands.json
 
-test: ## Run unit tests
-	@cmake -S . -B ./build -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=1
-	@cmake --build ./build
+test: build ## Run unit tests
 	@(cd ./build && ctest)
 
 help: ## Display help information
diff --git a/README.md b/README.md
index 5f8b5f8..28d43b1 100644
--- a/README.md
+++ b/README.md
@@ -25,13 +25,14 @@ main :: proc() -> u8 {
 
 ### Dependencies
 
-- CMake >= 3.14, to build
+- A C23 capable compiler, to build
+- CMake >= 3.21, to build
 - LLVM, to build
-- Clang, for `_start()` and linking
+- Clang, for `_start()` and linking (optional)
 
 ### Building
 
-To build the **G** compiler on UNIX, run `BuildUNIX.sh`.
+To build the **G** compiler, from the project root, run `make build`.
 
 ### Running
 
diff --git a/examples/Test.sh b/examples/Test.sh
index bf47ccb..9702b26 100755
--- a/examples/Test.sh
+++ b/examples/Test.sh
@@ -1,6 +1,4 @@
 #!/bin/sh
-# Shell script to compile all example programs and report on failure
-
 DIR="$(dirname "$(realpath "$0")")"; cd "$DIR"
 
 for f in *.g; do
diff --git a/src/analyse.c b/src/analyse.c
index 21647a8..bb4c50d 100644
--- a/src/analyse.c
+++ b/src/analyse.c
@@ -1,5 +1,3 @@
-// analyse.c
-// Semantic analyser source file for G
 // Copyright (C) 2022, Jakob Wakeling
 // All rights reserved.
 
@@ -31,7 +29,7 @@ static void analyse_expr_hash(ast *a, syt *st);
 
 /* Analyse a program. */
 void analyse(ast *a) {
-	for (UINT i = 0; i < CL; i += 1) { analyse_stmt_decl(C[i], &A.st); }
+	for (uptr i = 0; i < CL; i += 1) { analyse_stmt_decl(C[i], &A.st); }
 }
 
 /* Analyse a statement. */
@@ -50,7 +48,7 @@ static void analyse_stmt(ast *a, syt *st) {
 static inline void analyse_stmt_comp(ast *a, syt *st) {
 	assert(A.k == AK_COMP);
 
-	for (UINT i = 0; i < CL; i += 1) { analyse_stmt(C[i], &A.st); }
+	for (uptr i = 0; i < CL; i += 1) { analyse_stmt(C[i], &A.st); }
 }
 
 /* Analyse a declaration statement. */
@@ -150,7 +148,7 @@ static void analyse_stmt_for(ast *a, syt *st) {
 	assert(A.k == AK_FOR);
 	assert(CL == 2 || CL == 4);
 
-	for (UINT i = 0; i < CL; i += 1) { analyse_stmt(C[i], &A.st); }
+	for (uptr i = 0; i < CL; i += 1) { analyse_stmt(C[i], &A.st); }
 }
 
 /* Analyse an expression. */
@@ -180,11 +178,11 @@ static void analyse_expr(ast *a, syt *st) {
 		}
 		else if (sym->k == AK_PROC) { A.k = AK_BUILTIN; A.t = sym->t; }
 
-		for (UINT i = 1; i < CL; i += 1) { analyse_expr(C[i], st); }
+		for (uptr i = 1; i < CL; i += 1) { analyse_expr(C[i], st); }
 
 		if (is_proc(t)) {
-			register ast **av = sym->c.a[0]->c.a; register UINT ac = sym->c.a[0]->c.al;
-			for (UINT i = 0; i < ac - 1; i += 1) {
+			register ast **av = sym->c.a[0]->c.a; register uptr ac = sym->c.a[0]->c.al;
+			for (uptr i = 0; i < ac - 1; i += 1) {
 				if (is_equal(C[i + 1]->t, av[i]->t)) { /* Ignored */ }
 				else if (is_com(C[i + 1]->t, av[i]->t)) {
 					if (C[i + 1]->t->l <= av[i]->t->l) {
@@ -223,15 +221,15 @@ static void analyse_expr(ast *a, syt *st) {
 	case AK_ADO: { analyse_expr(C[0], st); A.t = type_ptr(ast_type(C[0], st), 1); } break;
 	case AK_DRF: { analyse_expr(C[0], st); A.t = ast_type(C[0], st)->base;        } break;
 	case AK_ASSIGN: case AK_AS_ADD: case AK_AS_SUB: case AK_AS_MUL: case AK_AS_DIV: case AK_AS_MOD: {
-		for (UINT i = 0; i < CL; i += 1) { analyse_expr(C[i], st); } A.t = ast_type(C[0], st);
+		for (uptr i = 0; i < CL; i += 1) { analyse_expr(C[i], st); } A.t = ast_type(C[0], st);
 	} break;
 	case AK_ADD: case AK_SUB: case AK_MUL: case AK_DIV: case AK_MOD: {
-		for (UINT i = 0; i < CL; i += 1) { analyse_expr(C[i], st); } A.t = ast_type(C[0], st);
+		for (uptr i = 0; i < CL; i += 1) { analyse_expr(C[i], st); } A.t = ast_type(C[0], st);
 	} break;
 	case AK_EQ: case AK_NE: case AK_LT: case AK_LE: case AK_GT: case AK_GE: {
-		for (UINT i = 0; i < CL; i += 1) { analyse_expr(C[i], st); } A.t = &TYPE(TY_BOOL);
+		for (uptr i = 0; i < CL; i += 1) { analyse_expr(C[i], st); } A.t = &TYPE(TY_BOOL);
 	} break;
-	default: { for (UINT i = 0; i < CL; i += 1) { analyse_expr(C[i], st); }} break;
+	default: { for (uptr i = 0; i < CL; i += 1) { analyse_expr(C[i], st); }} break;
 	}
 }
 
@@ -240,7 +238,7 @@ static void analyse_expr_proc(ast *a, syt *st) {
 	assert(A.k == AK_PROC);
 
 	/* Analyse the procedure arguments */
-	for (UINT i = 0; i < CL - 1; i += 1) {
+	for (uptr i = 0; i < CL - 1; i += 1) {
 		/* TODO */
 	}
 
@@ -255,5 +253,5 @@ static void analyse_expr_hash(ast *a, syt *st) {
 	if (strcmp(A.s, "syscall") == 0) { A.k = AK_HASH_SYSCALL; A.t = &TYPE(TY_SINT); }
 	else { note("TODO", A.ln, A.cl, 0, "Unrecognised hash expression \"%s\"", A.s); }
 
-	for (UINT i = 0; i < CL; i += 1) { analyse_expr(C[i], st); }
+	for (uptr i = 0; i < CL; i += 1) { analyse_expr(C[i], st); }
 }
diff --git a/src/analyse.h b/src/analyse.h
index f58a8e2..95d9006 100644
--- a/src/analyse.h
+++ b/src/analyse.h
@@ -1,5 +1,3 @@
-// analyse.h
-// Semantic analyser header file for G
 // Copyright (C) 2022, Jakob Wakeling
 // All rights reserved.
 
diff --git a/src/init.c b/src/init.c
index f6832d7..359848f 100644
--- a/src/init.c
+++ b/src/init.c
@@ -1,5 +1,3 @@
-// init.c
-// Initialiser source file for G
 // Copyright (C) 2021, Jakob Wakeling
 // All rights reserved.
 
@@ -55,7 +53,7 @@ static ast kwds[] = {
 
 void initialise(void) {
 	/* Populate the keyword symbol table */
-	for (UINT i = 0; kwds[i].s != NULL; i += 1) {
+	for (uptr i = 0; kwds[i].s != NULL; i += 1) {
 		kwds[i].h = syt_hash(kwds[i].s, strlen(kwds[i].s));
 		syt_insert_h(&kwt, kwds[i].h, kwds[i].s, &kwds[i]);
 	}
diff --git a/src/init.h b/src/init.h
index 47a3b61..21e0c67 100644
--- a/src/init.h
+++ b/src/init.h
@@ -1,5 +1,3 @@
-// init.h
-// Initialiser header file for G
 // Copyright (C) 2021, Jakob Wakeling
 // All rights reserved.
 
diff --git a/src/lex.c b/src/lex.c
index 6254c20..fc0196f 100644
--- a/src/lex.c
+++ b/src/lex.c
@@ -1,5 +1,3 @@
-// lex.c
-// Lexer source file for G
 // Copyright (C) 2021, Jakob Wakeling
 // All rights reserved.
 
@@ -41,7 +39,7 @@ char *tok_ks[] = {
 #define is_digit_hex(c) ((c >= '0' && c <= '9') || (c >= 'A' || c == 'F'))
 
 /* Initialise a lexer. */
-lex lex_init(const char *file, char *src, UINT len) {
+lex lex_init(const char *file, char *src, uptr len) {
 	lex l = { file, src, src, src + len, 0, 0, 0, 0 };
 	lex_next(&l); return l;
 }
@@ -75,7 +73,7 @@ tok lex_next(lex *l) {
 	if (C == '/') switch (P[1]) {
 		case '/': { for (P += 2; P != Q && C != '\n'; P += 1); } goto skip;
 		case '*': {
-			UINT d = 1; for (P += 2, CL += 2; P != Q && d; P += 1) {
+			uptr d = 1; for (P += 2, CL += 2; P != Q && d; P += 1) {
 				if (C == '/' && P[1] == '*') { P += 2; CL += 2; d += 1; continue; }
 				if (C == '*' && P[1] == '/') { P += d == 1 ? 1 : 2; CL += 2; d -= 1; continue; }
 				if (C == '\n') { LN += 1; CL = 0; } else { CL += 1; }
@@ -87,7 +85,7 @@ tok lex_next(lex *l) {
 
 	/* Handle identifiers and keywords */
 	if (is_alpha(C) || C == '_') {
-		char *s = P; UINT sl;
+		char *s = P; uptr sl;
 
 		for (P += 1; is_alpha(C) || is_digit_dec(C) || C == '_'; P += 1);
 		sl = P - s; CL += sl; T.h = syt_hash(s, sl);
@@ -115,13 +113,13 @@ tok lex_next(lex *l) {
 			if (C == 'e' || C == 'E') { T.k = TK_FLT; P += P[1] == '+' || P[1] == '-'; }
 		}
 
-		UINT sl = P - start; CL += sl;
+		uptr sl = P - start; CL += sl;
 		if (!(T.s = strndup(start, sl))) { panic(SERR); }
 
 		switch (T.k) {
 		case TK_INT: {
 			char *s = T.s; register u64 v = 0; u64 c;
-			register UINT b = 10; char *b_s;
+			register uptr b = 10; char *b_s;
 
 			if (s[0] == '0') switch (s[1]) {
 			case 'b': { s += 2; b = 2;  b_s = "binary";      } break;
@@ -267,7 +265,7 @@ tok lex_next(lex *l) {
 				}
 			}
 
-			UINT sl = head - s; CL += sl;
+			uptr sl = head - s; CL += sl;
 			if (C != quote) { note(l->n, T.ln, T.cl, 0, "Missing closing quote"); }
 			else if (P != Q) { P += 1; CL += 1; }
 
@@ -275,7 +273,7 @@ tok lex_next(lex *l) {
 				T.k = TK_INT; if (!(T.s = strndup(s, sl))) { panic(SERR); }
 
 				/* Numerical value of character literals is calculated and stored in T.v_int */
-				for (UINT i = 0; i < sl; i += 1) {
+				for (uptr i = 0; i < sl; i += 1) {
 					if (T.v_int > (U32_MAX - s[i]) / 256) {
 						note(l->n, T.ln, T.cl, 0, "Character literal cannot be represented"); break;
 					}
diff --git a/src/lex.h b/src/lex.h
index a0e4474..6ca9044 100644
--- a/src/lex.h
+++ b/src/lex.h
@@ -1,5 +1,3 @@
-// lex.h
-// Lexer header file for G
 // Copyright (C) 2021, Jakob Wakeling
 // All rights reserved.
 
@@ -32,17 +30,17 @@ typedef enum {
 	k : Kind, ln : Line, cl : Column, h : Hash, s : String,
 	v_int : Int Value, v_flt : Flt Value
 */
-typedef struct { tok_k k; UINT ln, cl; u64 h; char *s; union { u64 v_int; f128 v_flt; }; } tok;
+typedef struct { tok_k k; uptr ln, cl; u64 h; char *s; union { u64 v_int; f128 v_flt; }; } tok;
 
 /*
 	n : File Name, s : Start of File, p : Current Character, q : End of File,
 	ln : Line Index, cl : Column Index, t : Current Token
 */
-typedef struct { const char *n; char *s, *p, *q; UINT ln, cl; tok t; } lex;
+typedef struct { const char *n; char *s, *p, *q; uptr ln, cl; tok t; } lex;
 
 extern char *tok_ks[];
 
-extern lex lex_init(const char *file, char *src, UINT len);
+extern lex lex_init(const char *file, char *src, uptr len);
 extern tok lex_peek(lex *l);
 extern tok lex_next(lex *l);
 extern tok lex_kind(lex *l, tok_k k);
diff --git a/src/llvm.c b/src/llvm.c
index 0d61033..6f9f1c8 100644
--- a/src/llvm.c
+++ b/src/llvm.c
@@ -1,5 +1,3 @@
-// llvm.c
-// LLVM source file for G
 // Copyright (C) 2021, Jakob Wakeling
 // All rights reserved.
 
@@ -59,7 +57,7 @@ void llvm(ast *a, char *file, llvm_action action) {
 	llvm_builder = LLVMCreateBuilder();
 
 	/* Generate IR for all child nodes */
-	for (UINT i = 0; i < a->c.al; i += 1) { llvm_stmt_decl(a->c.a[i], &a->st); }
+	for (uptr i = 0; i < a->c.al; i += 1) { llvm_stmt_decl(a->c.a[i], &a->st); }
 
 	char *err = NULL; bool failed = false;
 
@@ -133,7 +131,7 @@ static LLVMValueRef llvm_stmt(ast *a, syt *st) {
 
 /* Generate IR for a compound statement. */
 static LLVMValueRef llvm_stmt_compound(ast *a, syt *st) {
-	for (UINT i = 0; i < A.c.al; i += 1) { llvm_stmt(C[i], &A.st); }
+	for (uptr i = 0; i < A.c.al; i += 1) { llvm_stmt(C[i], &A.st); }
 	return NULL;
 }
 
@@ -143,7 +141,7 @@ static LLVMValueRef llvm_stmt_decl(ast *a, syt *st) {
 
 	if (CL && C[0]->k == AK_PROC) /* AK_PROC has a scope */ {
 		LLVMTypeRef art[C[0]->c.al - 1];
-		for (UINT i = 0; i < C[0]->c.al - 1; i += 1) { art[i] = llvm_type(ast_type(C[0]->c.a[i], &A.st)); }
+		for (uptr i = 0; i < C[0]->c.al - 1; i += 1) { art[i] = llvm_type(ast_type(C[0]->c.a[i], &A.st)); }
 
 		LLVMTypeRef ft = LLVMFunctionType(llvm_type(C[0]->t), art, C[0]->c.al - 1, 0);
 		LLVMValueRef f = LLVMAddFunction(llvm_module, A.s, ft);
@@ -152,8 +150,8 @@ static LLVMValueRef llvm_stmt_decl(ast *a, syt *st) {
 		LLVMPositionBuilderAtEnd(llvm_builder, bb);
 
 		/* Allocate scoped procedure arguments */
-		for (UINT i = 0; i < C[0]->c.al - 1; i += 1) { C[0]->c.a[i]->llvm_v = LLVMBuildAlloca(llvm_builder, art[i], ""); }
-		for (UINT i = 0; i < C[0]->c.al - 1; i += 1) { LLVMBuildStore(llvm_builder, LLVMGetParam(f, i), C[0]->c.a[i]->llvm_v); }
+		for (uptr i = 0; i < C[0]->c.al - 1; i += 1) { C[0]->c.a[i]->llvm_v = LLVMBuildAlloca(llvm_builder, art[i], ""); }
+		for (uptr i = 0; i < C[0]->c.al - 1; i += 1) { LLVMBuildStore(llvm_builder, LLVMGetParam(f, i), C[0]->c.a[i]->llvm_v); }
 
 		A.llvm_t = ft; A.llvm_v = f;
 		llvm_expr_proc(C[0], &A.st);
@@ -263,7 +261,7 @@ static LLVMValueRef llvm_expr(ast *a, syt *st, bool load) {
 		if (sym == NULL) { note(file_name, A.ln, A.cl, -1, "Undefined procedure \"%s\" (llvm:llvm_expr)", C[0]->s); }
 		if (!sym->llvm_v) { note(file_name, A.ln, A.cl, -1, "Procedure \"%s\" follows (llvm:llvm_expr)", C[0]->s); }
 
-		LLVMValueRef args[CL - 1]; for (UINT i = 1; i < CL; i += 1) { args[i - 1] = llvm_expr(C[i], st, true); }
+		LLVMValueRef args[CL - 1]; for (uptr i = 1; i < CL; i += 1) { args[i - 1] = llvm_expr(C[i], st, true); }
 		return LLVMBuildCall2(llvm_builder, sym->llvm_t, sym->llvm_v, args, CL - 1, "");
 	} break;
 	case AK_BUILTIN: { return llvm_expr_builtin(a, st); } break;
@@ -508,7 +506,7 @@ static LLVMValueRef llvm_expr_hash(ast *a, syt *st) {
 	assert(A.k == AK_HASH_SYSCALL);
 
 	LLVMValueRef args[CL]; LLVMTypeRef argt[CL];
-	for (UINT i = 0; i < CL; i += 1) {
+	for (uptr i = 0; i < CL; i += 1) {
 		args[i] = llvm_expr(C[i], st, true);
 		argt[i] = llvm_type(ast_type(C[i], st));
 	}
@@ -523,7 +521,7 @@ static LLVMValueRef llvm_expr_hash(ast *a, syt *st) {
 		char constraints[128] = "={rax}";
 
 		char const *registers[] = { "rax", "rdi", "rsi", "rdx", "r10", "r8", "r9" };
-		for (UINT i = 0; i < CL; i += 1) {
+		for (uptr i = 0; i < CL; i += 1) {
 			strcat(constraints, ",{");
 			strcat(constraints, registers[i]);
 			strcat(constraints, "}");
@@ -565,7 +563,7 @@ static LLVMValueRef llvm_arr(ast *a, syt *st) {
 
 	LLVMValueRef *va = calloc(CL, sizeof (LLVMValueRef));
 
-	for (UINT i = 0; i < CL; i += 1) { va[i] = llvm_expr(C[i], st, true); }
+	for (uptr i = 0; i < CL; i += 1) { va[i] = llvm_expr(C[i], st, true); }
 
 	return LLVMConstArray(llvm_type(C[0]->t), va, CL);
 }
@@ -610,7 +608,7 @@ static LLVMValueRef llvm_ival(type *t) {
 	case TY_PTR:  { return LLVMConstNull(llvm_type(t->base)); } break;
 	case TY_ARR:  {
 		LLVMValueRef va[t->l], bv = llvm_ival(t->base);
-		for (UINT i = 0; i < t->l; i += 1) { va[i] = bv; }
+		for (uptr i = 0; i < t->l; i += 1) { va[i] = bv; }
 		return LLVMConstArray(llvm_type(t->base), va, t->l);
 	} break;
 	case TY_BOOL: { return LLVMConstInt(LLVMIntType(1),   0, false); } break;
diff --git a/src/llvm.h b/src/llvm.h
index 83b4f67..312aa6d 100644
--- a/src/llvm.h
+++ b/src/llvm.h
@@ -1,5 +1,3 @@
-// llvm.h
-// LLVM header file for G
 // Copyright (C) 2021, Jakob Wakeling
 // All rights reserved.
 
diff --git a/src/llvm/attr.c b/src/llvm/attr.c
index 4aab1c2..4b775e9 100644
--- a/src/llvm/attr.c
+++ b/src/llvm/attr.c
@@ -1,5 +1,3 @@
-// attr.c
-// LLVM attributes source file for G
 // Copyright (C) 2023, Jakob Wakeling
 // All rights reserved.
 
diff --git a/src/llvm/llvm.h b/src/llvm/llvm.h
index fa43176..245bf35 100644
--- a/src/llvm/llvm.h
+++ b/src/llvm/llvm.h
@@ -1,5 +1,3 @@
-// llvm/llvm.h
-// LLVM header file for G
 // Copyright (C) 2023, Jakob Wakeling
 // All rights reserved.
 
diff --git a/src/log.c b/src/log.c
index 58b469c..2ed9c85 100644
--- a/src/log.c
+++ b/src/log.c
@@ -1,5 +1,3 @@
-// log.c
-// Log source file for G
 // Copyright (C) 2022, Jakob Wakeling
 // All rights reserved.
 
@@ -10,15 +8,14 @@
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <stdnoreturn.h>
 
 bool log_waerr = false;
-sint log_level = 4, log_limit = 8;
+sptr log_level = 4, log_limit = 8;
 
-static sint log_count = 0;
+static sptr log_count = 0;
 
 /* Log a compiler fatal (-1), error (0), warning (1-3), or note (4). */
-void note(const char *file, UINT ln, UINT cl, sint level, const char *format, ...) {
+void note(const char *file, uptr ln, uptr cl, sptr level, const char *format, ...) {
 	if (file) { fprintf(stderr, "%s:%lu:%lu: ", file, ln + 1, cl + 1); }
 
 	if (level <= -1) { fprintf(stderr, "fatal: "); }
@@ -37,7 +34,7 @@ void note(const char *file, UINT ln, UINT cl, sint level, const char *format, ..
 bool has_error(void) { return log_count > 0; }
 
 /* Print a panic message and exit. */
-noreturn void __panic(const char *file, UINT ln, const char *format, ...) {
+[[noreturn]] void __panic(const char *file, uptr ln, const char *format, ...) {
 	fflush(stderr); fprintf(stderr, file != NULL ? "panic: %s:%lu: " : "panic: ", file, ln);
 	va_list ap; va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap); fputc('\n', stderr); exit(-1);
 }
diff --git a/src/log.h b/src/log.h
index 6f56c89..f71e9dd 100644
--- a/src/log.h
+++ b/src/log.h
@@ -1,22 +1,18 @@
-// log.h
-// Log header file for G
 // Copyright (C) 2022, Jakob Wakeling
 // All rights reserved.
 
 #ifndef G_LOG_H_1RPM5P9E
 #define G_LOG_H_1RPM5P9E
 
-#include <stdnoreturn.h>
-
 #include "util/util.h"
 
 extern bool log_waerr;
-extern sint log_level, log_limit;
+extern sptr log_level, log_limit;
 
-extern void note(const char *file, UINT ln, UINT cl, sint level, const char *format, ...);
+extern void note(const char *file, uptr ln, uptr cl, sptr level, const char *format, ...);
 extern bool has_error(void);
 
-extern noreturn void __panic(const char *file, UINT ln, const char *format, ...);
+[[noreturn]] extern void __panic(const char *file, uptr ln, const char *format, ...);
 
 #ifdef NDEBUG
 #define dprint(file, ln, cl, format, ...) ((void)0)
diff --git a/src/main.c b/src/main.c
index cfa2372..b4e32dc 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,5 +1,3 @@
-// main.c
-// Main source file for G
 // Copyright (C) 2021, Jakob Wakeling
 // All rights reserved.
 
@@ -16,20 +14,14 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-static struct lop lops[] = {
-	{ "help",          ARG_NUL, 256 },
-	{ "version",       ARG_NUL, 257 },
-	{ NULL, 0, 0 }
-};
-
-static bool bflag = false, Bflag = false, cflag = false;
-static bool Eflag = false, pflag = false, Pflag = false;
-static bool qflag = false, Sflag = false;
+static struct {
+	bool bflag, Bflag, cflag, Eflag, pflag, Pflag, qflag, Sflag;
+} args = {};
 
 static char *output = NULL;
 static int verbosity = 0;
 
-static void compile(const char *file, char *src, UINT len);
+static void compile(const char *file, char *src, uptr len);
 static void compile_file(const char *file);
 
 static void opt_f(const char *arg);
@@ -40,21 +32,28 @@ static void hlp(void);
 static void ver(void);
 
 int main(int ac, char *av[]) { A0 = av[0];
-	struct opt opt = OPTGET_INIT; opt.str = "bBcEf:O:pPqSvW:"; opt.lops = lops;
+	struct opt opt = OPTGET_INIT;
+	opt.str = "bBcEf:O:pPqSvW:";
+	opt.lops = (struct lop[]){
+		{ "help",    ARG_NUL, 256 },
+		{ "version", ARG_NUL, 257 },
+		{ NULL, 0, 0 }
+	};
+	
 	for (int o; (o = optget(&opt, av, 1)) != -1;) switch (o) {
-	case 'b': { bflag = true;     } break; /* Output LLVM IR files */
-	case 'B': { Bflag = true;     } break; /* Output LLVM bitcode files */
-	case 'c': { cflag = true;     } break; /* Output object files */
-	case 'E': { Eflag = true;     } break; /* Output lexer tokens */
-	case 'f': { opt_f(opt.arg);   } break; /* Configure formatting */
-	case 'o': { output = opt.arg; } break; /* Specify output file */
-	case 'O': { opt_O(opt.arg);   } break; /* Configure optimisation */
-	case 'p': { pflag = true;     } break; /* Output parser AST */
-	case 'P': { Pflag = true;     } break; /* Output analyser AST */
-	case 'q': { qflag = true;     } break; /* Silence certain outputs (for benchmarking) */
-	case 'S': { Sflag = true;     } break; /* Output assembly files */
-	case 'v': { verbosity += 1;   } break; /* Increase verbosity */
-	case 'W': { opt_W(opt.arg);   } break; /* Configure warnings and errors */
+	case 'b': { args.bflag = true; } break; /* Output LLVM IR files */
+	case 'B': { args.Bflag = true; } break; /* Output LLVM bitcode files */
+	case 'c': { args.cflag = true; } break; /* Output object files */
+	case 'E': { args.Eflag = true; } break; /* Output lexer tokens */
+	case 'f': { opt_f(opt.arg);    } break; /* Configure formatting */
+	case 'o': { output = opt.arg;  } break; /* Specify output file */
+	case 'O': { opt_O(opt.arg);    } break; /* Configure optimisation */
+	case 'p': { args.pflag = true; } break; /* Output parser AST */
+	case 'P': { args.Pflag = true; } break; /* Output analyser AST */
+	case 'q': { args.qflag = true; } break; /* Silence certain outputs (for benchmarking) */
+	case 'S': { args.Sflag = true; } break; /* Output assembly files */
+	case 'v': { verbosity += 1;    } break; /* Increase verbosity */
+	case 'W': { opt_W(opt.arg);    } break; /* Configure warnings and errors */
 	case 256: { hlp(); } return 0;
 	case 257: { ver(); } return 0;
 	default: {} return 1;
@@ -66,23 +65,23 @@ int main(int ac, char *av[]) { A0 = av[0];
 	return 0;
 }
 
-static void compile(const char * file, char *src, UINT len) {
+static void compile(const char * file, char *src, uptr len) {
 	initialise();
 
 	lex l = lex_init(file, src, len);
-	if (Eflag) { lex_debug(&l); goto end; }
+	if (args.Eflag) { lex_debug(&l); goto end; }
 
 	ast *a = parse(&l);
-	if (pflag) { if (!qflag) { ast_print(a, 0); } goto end; }
+	if (args.pflag) { if (!args.qflag) { ast_print(a, 0); } goto end; }
 	if (has_error()) { exit(1); }
 
 	assert(a->k == AK_PROG); analyse(a);
-	if (Pflag) { if (!qflag) { ast_print(a, 0); } goto end; }
+	if (args.Pflag) { if (!args.qflag) { ast_print(a, 0); } goto end; }
 	if (has_error()) { exit(1); }
 
-	if (bflag) { llvm(a, strdup(file), llvm_ir); }
-	else if (Bflag) { llvm(a, strdup(file), llvm_bc); }
-	else if (Sflag) { llvm(a, strdup(file), llvm_asm); }
+	if (args.bflag) { llvm(a, strdup(file), llvm_ir); }
+	else if (args.Bflag) { llvm(a, strdup(file), llvm_bc); }
+	else if (args.Sflag) { llvm(a, strdup(file), llvm_asm); }
 	else { llvm(a, strdup(file), llvm_obj); }
 	if (has_error()) { exit(1); }
 
@@ -92,7 +91,7 @@ static void compile(const char * file, char *src, UINT len) {
 static void compile_file(const char *file) {
 	FILE *fi; char *fb; size_t fl;
 
-	if (!(fi = fopen(file, "r"))) { error(1, "%s: %s", file, serr()); }
+	if (!(fi = fopen(file, "r"))) { error(1, "%s: %s", file, SERR); }
 	fseek(fi, 0, SEEK_END); fl = ftell(fi); rewind(fi);
 
 	fb = malloc((fl + 1) * sizeof (*fb));
diff --git a/src/parse.c b/src/parse.c
index cd94f54..1f3a76d 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -1,5 +1,3 @@
-// parse.c
-// Parser source file for G
 // Copyright (C) 2021, Jakob Wakeling
 // All rights reserved.
 
@@ -64,7 +62,7 @@ static s32 ast_precedence(ast_k ak);
 static inline char *strdup_or_fail(const char *s);
 
 /* Initialise an AST node. */
-inline ast *ast_init(ast_k kind, UINT ln, UINT cl) {
+inline ast *ast_init(ast_k kind, uptr ln, uptr cl) {
 	ast *a = calloc(1, sizeof (*a)); if (a == NULL) { panic(SERR); }
 	a->k = kind; a->ln = ln; a->cl = cl; return a;
 }
@@ -90,15 +88,15 @@ void ast_push(ast *a, ast *c) {
 
 /* Displace a child AST node from a parent AST node. */
 void ast_displace(ast *a, ast *c) {
-	ast **oa = a->c.a; UINT ol = a->c.al; bool found = false;
+	ast **oa = a->c.a; uptr ol = a->c.al; bool found = false;
 
-	for (UINT i = 0; i < ol; i += 1) { if (oa[i] == c) { found = true; break; }}
+	for (uptr i = 0; i < ol; i += 1) { if (oa[i] == c) { found = true; break; }}
 	if (!found) { return; }
 
 	ast **ca = calloc((a->c.al -= 1), sizeof (ast *));
 	if (!ca) { panic(SERR); } else { a->c.a = ca; ca = NULL; }
 
-	for (UINT i = 0, j = 0; i < ol && j < a->c.al; i += 1) {
+	for (uptr i = 0, j = 0; i < ol && j < a->c.al; i += 1) {
 		if (oa[i] == c) { continue; } a->c.a[j] = oa[i]; j += 1;
 	}
 
@@ -108,9 +106,9 @@ void ast_displace(ast *a, ast *c) {
 /* Insert a wrapper AST node between a child and its parent. */
 void ast_wrap(ast *const a, ast *const c, ast *const w) {
 	assert(a != NULL); assert(c != NULL); assert(w != NULL);
-	ast **oa = a->c.a; UINT ol = a->c.al, ifound; bool found = false;
+	ast **oa = a->c.a; uptr ol = a->c.al, ifound; bool found = false;
 
-	for (UINT i = 0; i < ol; i += 1) { if (oa[i] == c) { found = true; ifound = i; break; }}
+	for (uptr i = 0; i < ol; i += 1) { if (oa[i] == c) { found = true; ifound = i; break; }}
 	if (!found) { panic("ast_wrap called with an unrelated parent and child"); }
 
 	w->p = a; a->c.a[ifound] = w; c->p = NULL; ast_push(w, c);
@@ -567,8 +565,8 @@ static inline char *strdup_or_fail(const char *s) {
 }
 
 /* Recursively print an AST. */
-void ast_print(ast *a, UINT indent) {
-	for (UINT i = 0; i < indent; ++i) { printf("    "); }
+void ast_print(ast *a, uptr indent) {
+	for (uptr i = 0; i < indent; ++i) { printf("    "); }
 
 	/* Print basic AST information (line:column: kind "string") */
 	printf("%zu:%zu: %s \"%s\"", a->ln + 1, a->cl + 1, ast_ks[a->k], a->s);
@@ -602,7 +600,7 @@ void ast_print(ast *a, UINT indent) {
 	fputc('\n', stdout);
 
 	/* Print AST children */
-	for (UINT i = 0; i < a->c.al; i += 1) { ast_print(a->c.a[i], indent + 1); }
+	for (uptr i = 0; i < a->c.al; i += 1) { ast_print(a->c.a[i], indent + 1); }
 
 	if (a->st.a != NULL) {
 		printf("--- SYT for %s \"%s\"%s ---\n", ast_ks[a->k], a->s, a->st.pt == NULL ? " NO PARENT" : "");
diff --git a/src/parse.h b/src/parse.h
index 0e4716c..bc043a7 100644
--- a/src/parse.h
+++ b/src/parse.h
@@ -1,5 +1,3 @@
-// parse.h
-// Parser header file for G
 // Copyright (C) 2021, Jakob Wakeling
 // All rights reserved.
 
@@ -42,18 +40,18 @@ typedef enum {
 	v_bool : Boolean Value, v_int : Integer Value, v_flt : Float Value
 */
 typedef struct ast_s {
-	ast_k k; UINT ln, cl; u64 h; char *s; type *t; syt st;
-	struct ast_s *p; struct { struct ast_s **a; UINT al; } c;
+	ast_k k; uptr ln, cl; u64 h; char *s; type *t; syt st;
+	struct ast_s *p; struct { struct ast_s **a; uptr al; } c;
 	union { bool v_bool; u64 v_int; f128 v_flt; };
 
 	LLVMTypeRef llvm_t; LLVMValueRef llvm_v;
 } ast;
 
-typedef struct { ast **a; UINT al; } ast_a;
+typedef struct { ast **a; uptr al; } ast_a;
 
 extern char *ast_ks[];
 
-extern ast *ast_init(ast_k kind, UINT ln, UINT cl);
+extern ast *ast_init(ast_k kind, uptr ln, uptr cl);
 extern void ast_free(ast **a);
 
 extern void ast_push(ast *a, ast *c);
@@ -66,7 +64,7 @@ extern ast *ast_a_pop(ast_a *aa);
 
 extern ast *parse(lex *l);
 
-extern void ast_print(ast *a, UINT i);
+extern void ast_print(ast *a, uptr i);
 extern ast *find_proc(ast *a);
 
 #endif // G_PARSE_H_VB50JOSX
diff --git a/src/symbol.c b/src/symbol.c
index 769d931..a1ecde9 100644
--- a/src/symbol.c
+++ b/src/symbol.c
@@ -1,15 +1,6 @@
-// symbol.c
-// Symbol source file for G
 // Copyright (C) 2021, Jakob Wakeling
 // All rights reserved.
 
-/*
-	This file uses the currently non-standard 'typeof' operator. Its use is
-	considered acceptable because it is supported by both GCC and Clang, and
-	POSIX extensions are used here anyway. Additionally, it is expected that the
-	'typeof' operator will become standard in C23.
-*/
-
 #include "parse.h"
 #include "symbol.h"
 #include "util/util.h"
@@ -35,7 +26,7 @@ syt *syt_aloc(void) { return calloc(1, sizeof (syt)); }
 void syt_free(syt *st) {
 	if (st == NULL || st->a == NULL) { return; }
 
-	for (UINT i = 0; i < st->ac; i += 1) {
+	for (uptr i = 0; i < st->ac; i += 1) {
 		if (st->a[i].h == 0) { continue; }
 		free(st->a[i].k); /*free(s->a[i].v)*/
 	}
@@ -44,7 +35,7 @@ void syt_free(syt *st) {
 }
 
 /* Compute the hash of some data. Will not return 0. */
-u64 syt_hash(const char *s, UINT l) {
+u64 syt_hash(const char *s, uptr l) {
 	register u64 fnv = 0xCBF29CE484222325;
 	for (; l; l -= 1, s += 1) { fnv ^= *s; fnv *= 0x00000100000001B3; }
 	fnv |= fnv == 0; return fnv;
@@ -76,9 +67,9 @@ ast *syt_search(syt *st, char *k) {
 /* Insert a key-value pair into a map using a precalculated hash. */
 void syt_insert_h(syt *st, u64 h, char *k, ast *v) {
 	if (st->ac == 0 || st->al >= ((f64)st->ac * LOAD_FACTOR)) { syt_resize(st); }
-	UINT i = h % st->ac; k = strdup(k);
+	uptr i = h % st->ac; k = strdup(k);
 
-	for (UINT dist = 0;; i = (i + 1) % st->ac, dist += 1) {
+	for (uptr dist = 0;; i = (i + 1) % st->ac, dist += 1) {
 		if (st->a[i].h == 0) {
 			/* If an empty bucket is found, insert here */
 			st->a[i] = (typeof (*st->a)){ h, k, v };
@@ -86,7 +77,7 @@ void syt_insert_h(syt *st, u64 h, char *k, ast *v) {
 		}
 
 		/* Calculate tsid, the DIB of the item at the current index */
-		UINT tsid = (i + st->ac - (st->a[i].h % st->ac)) % st->ac;
+		uptr tsid = (i + st->ac - (st->a[i].h % st->ac)) % st->ac;
 
 		if (dist > tsid) {
 			SWAP(st->a[i].h, h);
@@ -102,9 +93,9 @@ void syt_insert_h(syt *st, u64 h, char *k, ast *v) {
 ast *syt_lookup_h(syt *st, u64 h, char *k) {
 	if (st->a == NULL) { return NULL; }
 
-	UINT i = h % st->ac;
+	uptr i = h % st->ac;
 
-	for (UINT dist = 0;; i = (i + 1) % st->ac, dist += 1) {
+	for (uptr dist = 0;; i = (i + 1) % st->ac, dist += 1) {
 		if (st->a[i].h == 0) { return NULL; }
 
 		if (dist > DIB(i)) { return NULL; /* ? */ }
@@ -118,9 +109,9 @@ ast *syt_lookup_h(syt *st, u64 h, char *k) {
 void syt_remove_h(syt *st, u64 h, char *k) {
 	if (st->a == NULL) { return; }
 
-	UINT i = h % st->ac;
+	uptr i = h % st->ac;
 
-	for (UINT dist = 0;; i = (i + 1) % st->ac, dist += 1) {
+	for (uptr dist = 0;; i = (i + 1) % st->ac, dist += 1) {
 		if (st->a[i].h == 0) { return; }
 
 		if (dist > DIB(i)) { return; }
@@ -130,7 +121,7 @@ void syt_remove_h(syt *st, u64 h, char *k) {
 			st->a[i] = (typeof (*st->a)){ 0, NULL, NULL }; st->al -= 1;
 
 			/*  */
-			for (UINT j = (i + 1) % st->ac;; i = j, j = (j + 1) % st->ac) {
+			for (uptr j = (i + 1) % st->ac;; i = j, j = (j + 1) % st->ac) {
 				if (st->a[j].h == 0 || DIB(j) == 0) { break; }
 
 				SWAP(st->a[i].h, st->a[j].h);
@@ -158,12 +149,12 @@ ast *syt_search_h(syt *st, u64 h, char *k) {
 
 /* Print a basic representation of a map to stdout. */
 void syt_print(syt *st) {
-	for (UINT i = 0; i < st->ac; i += 1) if (st->a[i].h != 0) {
+	for (uptr i = 0; i < st->ac; i += 1) if (st->a[i].h != 0) {
 		printf("%s %s", ast_ks[st->a[i].v->k], st->a[i].k);
 
 		if (st->a[i].v->k == AK_DECL && st->a[i].v->c.al > 0 && st->a[i].v->c.a[0]->k == AK_PROC) {
 			fputc('(', stdout);
-			for (UINT j = 0; j < st->a[i].v->c.al - 1; j += 1) {
+			for (uptr j = 0; j < st->a[i].v->c.al - 1; j += 1) {
 				/* TODO */
 			}
 			fputc(')', stdout);
@@ -182,7 +173,7 @@ void syt_print(syt *st) {
 
 /* Print a debug representation of a map to stdout. */
 void syt_debug(syt *st) {
-	for (UINT i = 0; i < st->ac; i += 1) {
+	for (uptr i = 0; i < st->ac; i += 1) {
 		if (st->a[i].h == 0) { printf("[%zu] %lu\n", i, st->a[i].h); }
 		else printf(
 			"[%zu] %lu, %s -> %s, DIB: %zu\n",
@@ -203,7 +194,7 @@ static void syt_resize(syt *st) {
 	syt old = *st; st->ac *= 2; st->al = 0;
 	st->a = calloc(st->ac, sizeof (*st->a));
 
-	for (UINT i = 0; i < old.ac; i += 1) {
+	for (uptr i = 0; i < old.ac; i += 1) {
 		if (old.a[i].h == 0) { continue; }
 
 		syt_insert(st, old.a[i].k, old.a[i].v);
diff --git a/src/symbol.h b/src/symbol.h
index d759cce..004fcf0 100644
--- a/src/symbol.h
+++ b/src/symbol.h
@@ -1,5 +1,3 @@
-// symbol.h
-// Symbol header file for G
 // Copyright (C) 2021, Jakob Wakeling
 // All rights reserved.
 
@@ -16,7 +14,7 @@ typedef struct ast_s ast;
 */
 typedef struct syt_s {
 	struct { u64 h; char *k; ast *v; } *a;
-	UINT al, ac; struct syt_s *pt;
+	uptr al, ac; struct syt_s *pt;
 } syt;
 
 extern syt kwt;
@@ -24,7 +22,7 @@ extern syt kwt;
 // extern syt *syt_aloc(void);
 // extern void syt_init(syt *st);
 extern void syt_free(syt *st);
-extern u64  syt_hash(const char *s, UINT l);
+extern u64  syt_hash(const char *s, uptr l);
 
 extern void syt_insert(syt *st, char *k, ast *v);
 extern ast *syt_lookup(syt *st, char *k);
diff --git a/src/type.c b/src/type.c
index 3d44c1a..7a55077 100644
--- a/src/type.c
+++ b/src/type.c
@@ -1,5 +1,3 @@
-// type.c
-// Type source file for G
 // Copyright (C) 2021, Jakob Wakeling
 // All rights reserved.
 
diff --git a/src/type.h b/src/type.h
index 93eeb5f..67472a0 100644
--- a/src/type.h
+++ b/src/type.h
@@ -1,5 +1,3 @@
-// type.h
-// Type header file for G
 // Copyright (C) 2021, Jakob Wakeling
 // All rights reserved.
 
@@ -54,7 +52,7 @@ typedef enum {
 
 /* k : Kind, f : Flags, l : Length, s : String */
 typedef struct type_s { type_k k; type_f f; s64 l; char *s; struct type_s *base; } type;
-typedef struct { type *a; UINT al, ac; } type_a;
+typedef struct { type *a; uptr al, ac; } type_a;
 
 extern type types[];
 
diff --git a/src/util/error.c b/src/util/error.c
index b043b01..3d80eed 100644
--- a/src/util/error.c
+++ b/src/util/error.c
@@ -1,5 +1,3 @@
-// util/error.h, version 1.1.2
-// Error source file from libutil
 // Copyright (C) 2020, Jakob Wakeling
 // All rights reserved.
 
@@ -7,17 +5,15 @@
 
 #include <errno.h>
 #include <stdarg.h>
-#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <stdnoreturn.h>
 #include <string.h>
 
 char *A0 = NULL;
 bool warned = false;
 
 /* Print an error message and exit. */
-noreturn void error(int status, const char *format, ...) {
+[[noreturn]] void error(int status, const char *format, ...) {
 	fflush(stdout); if (A0) { fputs(A0, stderr); fputs(": ", stderr); }
 	va_list ap; va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap);
 	fputc('\n', stderr); exit(status);
diff --git a/src/util/error.h b/src/util/error.h
index 8532283..44650a7 100644
--- a/src/util/error.h
+++ b/src/util/error.h
@@ -1,18 +1,10 @@
-// util/error.h, version 1.1.2
-// Error header file from libutil
 // Copyright (C) 2020, Jakob Wakeling
 // All rights reserved.
 
-#ifndef UTIL_ERROR_H_38W06M3W
-#define UTIL_ERROR_H_38W06M3W
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+#ifndef G_UTIL_ERROR_H_38W06M3W
+#define G_UTIL_ERROR_H_38W06M3W
 
 #include <errno.h>
-#include <stdbool.h>
-#include <stdnoreturn.h>
 #include <string.h>
 
 /* Warn and then return status */
@@ -52,17 +44,10 @@ extern char *A0;
 extern bool warned;
 
 /* Print an error message and exit. */
-extern noreturn void error(int status, const char *format, ...);
+[[noreturn]] extern void error(int status, const char *format, ...);
 /* Print a warning message and set the warned flag. */
 extern void warn(const char *format, ...);
 /* Print a warning message but do not set the warned flag. */
 extern void alert(const char *format, ...);
 
-/* Shorthand for strerror(errno). DEPRECIATED, use the SERR macro. */
-extern char *serr(void);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif // UTIL_ERROR_H_38W06M3W
+#endif // G_UTIL_ERROR_H_38W06M3W
diff --git a/src/util/fnv.c b/src/util/fnv.c
index b74a7ed..08c422f 100644
--- a/src/util/fnv.c
+++ b/src/util/fnv.c
@@ -1,5 +1,3 @@
-// util/fnv.c, version 1.0.2
-// FNV hash source file from libutil
 // Copyright (C) 2021, Jakob Wakeling
 // All rights reserved.
 
@@ -12,25 +10,25 @@ static const u64 FNV_PRIME_64 = 0x00000100000001B3;
 static const u64 FNV_BASIS_64 = 0xCBF29CE484222325;
 
 /* Compute the FNV1a-32 hash of some data. */
-u32 fnv1a32(const char *dat, UINT len) {
+u32 fnv1a32(const char *dat, uptr len) {
 	register u32 fnv = FNV_BASIS_32;
 	for (; len; len -= 1, dat += 1) { fnv ^= *dat; fnv *= FNV_PRIME_32; }
 	return fnv;
 }
 
 /* Compute the FNV1a-64 hash of some data. */
-u64 fnv1a64(const char *dat, UINT len) {
+u64 fnv1a64(const char *dat, uptr len) {
 	register u64 fnv = FNV_BASIS_64;
 	for (; len; len -= 1, dat += 1) { fnv ^= *dat; fnv *= FNV_PRIME_64; }
 	return fnv;
 }
 
 void fnv1a32_init(u32 *ctx) { *ctx = FNV_BASIS_32; }
-void fnv1a32_hash(u32 *ctx, char *dat, UINT len) {
+void fnv1a32_hash(u32 *ctx, char *dat, uptr len) {
 	for (; len; len -= 1, dat += 1) { *ctx ^= *dat; *ctx *= FNV_PRIME_32; }
 }
 
 void fnv1a64_init(u64 *ctx) { *ctx = FNV_BASIS_64; }
-void fnv1a64_hash(u64 *ctx, char *dat, UINT len) {
+void fnv1a64_hash(u64 *ctx, char *dat, uptr len) {
 	for (; len; len -= 1, dat += 1) { *ctx ^= *dat; *ctx *= FNV_PRIME_64; }
 }
diff --git a/src/util/fnv.h b/src/util/fnv.h
index fb769a7..967983e 100644
--- a/src/util/fnv.h
+++ b/src/util/fnv.h
@@ -1,28 +1,18 @@
-// util/fnv.h, version 1.0.2
-// FNV hash header file from libutil
 // Copyright (C) 2021, Jakob Wakeling
 // All rights reserved.
 
-#ifndef UTIL_FNV_H_O4TYU6Q1
-#define UTIL_FNV_H_O4TYU6Q1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+#ifndef G_UTIL_FNV_H_O4TYU6Q1
+#define G_UTIL_FNV_H_O4TYU6Q1
 
 #include "util.h"
 
-extern u32 fnv1a32(const char *dat, UINT len);
-extern u64 fnv1a64(const char *dat, UINT len);
+extern u32 fnv1a32(const char *dat, uptr len);
+extern u64 fnv1a64(const char *dat, uptr len);
 
 extern void fnv1a32_init(u32 *ctx);
-extern void fnv1a32_hash(u32 *ctx, char *dat, UINT len);
+extern void fnv1a32_hash(u32 *ctx, char *dat, uptr len);
 
 extern void fnv1a64_init(u64 *ctx);
-extern void fnv1a64_hash(u64 *ctx, char *dat, UINT len);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
+extern void fnv1a64_hash(u64 *ctx, char *dat, uptr len);
 
-#endif // UTIL_FNV_H_O4TYU6Q1
+#endif // G_UTIL_FNV_H_O4TYU6Q1
diff --git a/src/util/optget.c b/src/util/optget.c
index b088fe0..630a556 100644
--- a/src/util/optget.c
+++ b/src/util/optget.c
@@ -1,6 +1,4 @@
-// util/optget.h, version 1.6.2
-// optget source file from libutil
-// Copyright (C) 2020, Jakob Wakeling
+// Copyright (C) 2021, Jakob Wakeling
 // All rights reserved.
 
 #include "error.h"
diff --git a/src/util/optget.h b/src/util/optget.h
index 3faf2e0..caa1967 100644
--- a/src/util/optget.h
+++ b/src/util/optget.h
@@ -1,14 +1,8 @@
-// util/optget.h, version 1.6.2
-// optget header file from libutil
-// Copyright (C) 2020, Jakob Wakeling
+// Copyright (C) 2021, Jakob Wakeling
 // All rights reserved.
 
-#ifndef UTIL_OPTGET_H_W3LIZK1S
-#define UTIL_OPTGET_H_W3LIZK1S
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+#ifndef G_UTIL_OPTGET_H_W3LIZK1S
+#define G_UTIL_OPTGET_H_W3LIZK1S
 
 #define ARG_NUL 0
 #define ARG_REQ 1
@@ -29,8 +23,4 @@ extern const struct opt OPTGET_INIT;
 
 extern int optget(struct opt *opt, char *av[], int flags);
 
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif // UTIL_OPTGET_H_W3LIZK1S
+#endif // G_UTIL_OPTGET_H_W3LIZK1S
diff --git a/src/util/util.h b/src/util/util.h
index a00cf31..bf29f59 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -1,18 +1,11 @@
-// util/util.h, version 1.0.1
-// Utility header file from libutil
 // Copyright (C) 2021, Jakob Wakeling
 // All rights reserved.
 
-#ifndef UTIL_UTIL_H_KP8NS9DC
-#define UTIL_UTIL_H_KP8NS9DC
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+#ifndef G_UTIL_UTIL_H_KP8NS9DC
+#define G_UTIL_UTIL_H_KP8NS9DC
 
 #include <assert.h>
 #include <float.h>
-#include <stdbool.h>
 #include <stddef.h>
 #include <stdint.h>
 
@@ -21,21 +14,18 @@ typedef uint8_t   u8;
 typedef uint16_t  u16;
 typedef uint32_t  u32;
 typedef uint64_t  u64;
-typedef uintptr_t UINT;
+typedef uintptr_t uptr;
 
 typedef int8_t   s8;
 typedef int16_t  s16;
 typedef int32_t  s32;
 typedef int64_t  s64;
-typedef intptr_t sint;
+typedef intptr_t sptr;
 
 typedef float       f32;
 typedef double      f64;
 typedef long double f128;
 
-typedef __uint128_t u128;
-typedef __int128_t s128;
-
 /* Type Limits */
 #define U8_MIN   UINT8_MIN
 #define U8_MAX   UINT8_MAX
@@ -45,8 +35,8 @@ typedef __int128_t s128;
 #define U32_MAX  UINT32_MAX
 #define U64_MIN  UINT64_MIN
 #define U64_MAX  UINT64_MAX
-#define UINT_MIN UINTPTR_MIN
-#define UINT_MAX UINTPTR_MAX
+#define UPTR_MIN UINTPTR_MIN
+#define UPTR_MAX UINTPTR_MAX
 
 #define S8_MIN   INT8_MIN
 #define S8_MAX   INT8_MAX
@@ -56,8 +46,8 @@ typedef __int128_t s128;
 #define S32_MAX  INT32_MAX
 #define S64_MIN  INT64_MIN
 #define S64_MAX  INT64_MAX
-#define SINT_MIN INTPTR_MIN
-#define SINT_MAX INTPTR_MAX
+#define SPTR_MIN INTPTR_MIN
+#define SPTR_MAX INTPTR_MAX
 
 #define F32_MIN  FLT_MIN
 #define F32_MAX  FLT_MAX
@@ -66,16 +56,7 @@ typedef __int128_t s128;
 #define F128_MIN LDBL_MIN
 #define F128_MAX LDBL_MAX
 
-#define S128_MAX (__int128)(((unsigned __int128) 1 << ((sizeof(__int128) * __CHAR_BIT__) - 1)) - 1)
-#define S128_MIN (-S128_MAX - 1)
-#define U128_MAX ((2 * (unsigned __int128) S128_MAX) + 1)
-#define U128_MIN 0
-
 /* Miscellaneous */
 #define BIT(x) (1 << (x))
 
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif // UTIL_UTIL_H_KP8NS9DC
+#endif // G_UTIL_UTIL_H_KP8NS9DC