diff --git a/docs/REFERENCE.md b/docs/REFERENCE.md
index c0c6de3..ded922a 100644
--- a/docs/REFERENCE.md
+++ b/docs/REFERENCE.md
@@ -70,7 +70,7 @@ sidebar:
## Variables & Constants {#variables}
Jam has two binding forms inside functions: `var` for mutable storage and `const` for
-single-assignment values. Every binding must be initialized at its declaration — Jam has
+single-assignment values. Every binding must be initialized at its declaration, Jam has
no `undefined` placeholder.
```jam
@@ -84,7 +84,7 @@ fn example() {
```
At module scope, `const` declarations bind a name to a compile-time value. They are
-*inlined* at every use site — referring to one costs the same as a literal. The type may
+*inlined* at every use site, referring to one costs the same as a literal. The type may
be inferred when an initializer alone determines it.
```jam
@@ -98,7 +98,7 @@ fn isZSet(f: u8) bool {
```
Module-scope `const` is also how top-level types, imports, and function pointers are
-named — Jam funnels every top-level declaration through the same form.
+named, Jam funnels every top-level declaration through the same form.
---
@@ -136,7 +136,7 @@ the standard `0x`, `0o`, `0b` prefixes.
Choosing Integer Types
- Use unsigned types (u8, u16, etc.) for values that are never negative — indices, counts, byte sizes.
+ Use unsigned types (u8, u16, etc.) for values that are never negative, indices, counts, byte sizes.
Use signed types (i8, i16, etc.) when you need to represent negative values.
@@ -234,7 +234,7 @@ const earth: str = "\u{1F30D}"; // 🌍
Jam distinguishes three reference families. Pointer types take a *required* `const` or
`mut` qualifier marking whether the pointee may be written. Slices and fixed arrays carry
-no qualifier — their element mutability follows the binding.
+no qualifier, their element mutability follows the binding.
| Type | Description |
|---------------|----------------------------------------------------------------------------------|
@@ -269,7 +269,7 @@ fn indexThroughMany() u8 {
No bare *T
- The mutability qualifier is part of the pointer type — there is no shorthand
+ The mutability qualifier is part of the pointer type, there is no shorthand
*T. Writing *const u8
vs *mut u8 documents intent at every signature.
@@ -285,7 +285,7 @@ comma-separated, fill-with-count, and empty (which produces a zero-length slice)
```jam
var a: [4]u8 = [10, 20, 30, 40]; // [a, b, c, d]
-var b: [16]u8 = [0; 16]; // [expr; N] — fill 16 slots with 0
+var b: [16]u8 = [0; 16]; // [expr; N], fill 16 slots with 0
const empty: []u8 = []; // empty slice
// Index with []. Out-of-bounds is undefined at runtime —
@@ -333,7 +333,7 @@ fn fillIndices() [16]u8 {
}
```
-The `for` loop iterates a half-open integer range — `for i in 0:N` binds `i = 0, 1, …, N-1`.
+The `for` loop iterates a half-open integer range, `for i in 0:N` binds `i = 0, 1, …, N-1`.
---
@@ -349,14 +349,14 @@ fn mixIngredients(sugar: i32, fruit: i32) i32 {
return sugar + fruit;
}
-// No return value — omit the return type.
+// No return value, omit the return type.
fn greet() {
std.fmt.println("Hello!");
}
```
Functions can be prefixed with `pub` (visible outside the defining module) and `extern`
-(declared but defined elsewhere — typically libc).
+(declared but defined elsewhere, typically libc).
```jam
pub fn add(a: i32, b: i32) i32 { return a + b; }
@@ -371,7 +371,7 @@ pub extern fn free(ptr: *mut[] u8);
Void Functions
A function with no declared return type returns nothing. Don't write
- void — just omit the return-type slot.
+ void, just omit the return-type slot.
@@ -445,19 +445,19 @@ fn observe() u32 {
var hits: u32 = 0;
var c: Counter = { value: 5, sink: &hits };
return c.value;
- // c.drop() fires automatically here — see Drop, below.
+ // c.drop() fires automatically here, see Drop, below.
}
```
A method can also be invoked by-name on the type: `Counter.drop(&c)` calls it
explicitly while `c` is still in scope (and the automatic drop will still fire at scope
-exit — calling drop manually is currently a footgun).
+exit, calling drop manually is currently a footgun).
---
## Enums {#enums}
-Enums describe a closed set of named variants. The simplest form is *payload-less* — each
+Enums describe a closed set of named variants. The simplest form is *payload-less*, each
variant is a u8 discriminant.
```jam
@@ -509,14 +509,14 @@ fn srcReg(op: Op) u8 {
}
```
-Payload-carrying enums are how `Option(T)` and `Result(T, E)` are built — see
+Payload-carrying enums are how `Option(T)` and `Result(T, E)` are built, see
[Generics](#generics).
---
## Unions {#unions}
-A `union` is *untagged* — every field shares the same storage. Use it for type punning
+A `union` is *untagged*, every field shares the same storage. Use it for type punning
(read float bits as `u32`, etc.) and for matching C-side `union { … }` types at FFI
boundaries.
@@ -533,7 +533,7 @@ fn floatBits(x: f32) u32 {
```
Unions size to their largest field; alignment is the max of all fields'. Unlike enums,
-there is no discriminant — the compiler trusts the program to know which field is live.
+there is no discriminant, the compiler trusts the program to know which field is live.
---
@@ -554,7 +554,7 @@ fn dispatch(x: u8) u8 {
}
```
-A `match` can also be used as an *expression* — each arm produces a value, and the result
+A `match` can also be used as an *expression*, each arm produces a value, and the result
is the value of the matched arm.
```jam
@@ -596,7 +596,7 @@ fn main() {
}
```
-A type alias `const Name = Generic(arg);` registers `Name` as a synonym — subsequent
+A type alias `const Name = Generic(arg);` registers `Name` as a synonym, subsequent
uses resolve to the same instantiated struct.
```jam
@@ -620,7 +620,7 @@ fn Holder(T: type) type {
}
```
-`Self` inside a struct body refers to the enclosing struct type — for a generic, that's
+`Self` inside a struct body refers to the enclosing struct type, for a generic, that's
the specific instantiation in play.
### Generic Enums
@@ -644,7 +644,7 @@ Construct variants by qualifying with the instantiated type: `Option(i32).Some(4
## Modules & Imports {#imports}
-`import("name")` returns a *module value* — a compile-time record of the symbols another
+`import("name")` returns a *module value*, a compile-time record of the symbols another
file exports. Bind it through `const` either whole or destructured.
```jam
@@ -655,7 +655,7 @@ fn show() {
std.fmt.println("Hello!");
}
-// Destructured binding — pulls specific names into the current scope.
+// Destructured binding, pulls specific names into the current scope.
const { Vec, Option } = import("collections");
const { assert } = import("test");
```
@@ -678,7 +678,7 @@ results are substituted as constants before LLVM sees the code.
```jam
fn bytesFor(n: u64) u64 {
- return n * @sizeOf(u32); // n * 4 — fully constant-folded
+ return n * @sizeOf(u32); // n * 4, fully constant-folded
}
fn pointerSize() u64 {
@@ -686,7 +686,7 @@ fn pointerSize() u64 {
}
fn sliceSize() u64 {
- return @sizeOf([]u8); // 16 — {ptr, len}
+ return @sizeOf([]u8); // 16, {ptr, len}
}
```
@@ -713,7 +713,7 @@ fn allocOne() *mut[] u32 {
```
Param types must match the C ABI. Slice arguments are passed as a `{ptr, len}` pair, and
-struct arguments larger than two words use sret-style return ABI — these match the
+struct arguments larger than two words use sret-style return ABI, these match the
platform's C compiler.
---
@@ -724,8 +724,8 @@ Jam is a *mutable value semantics* language. Every binding owns its value; passi
value to a function does not silently share storage with the caller. Functions opt into
a specific borrowing or transfer behavior via a per-parameter **mode** keyword.
-The result is the same memory safety as Rust — no use-after-free, no double-free, no
-data races, no reads of uninitialized memory — with no lifetime annotations.
+The result is the same memory safety as Rust, no use-after-free, no double-free, no
+data races, no reads of uninitialized memory, with no lifetime annotations.
The design is inspired by Hylo's parameter-mode system and Rust's drop semantics. The
compiler enforces three rules: *definite initialization* (every binding is written
@@ -745,18 +745,18 @@ the type.
| Consume ownership | `move` | read-write | becomes uninitialized |
```jam
-// Default read-only borrow — caller's value is unchanged.
+// Default read-only borrow, caller's value is unchanged.
fn distance(a: Point, b: Point) f64 {
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
-// Exclusive read-write — caller passes `&binding`.
+// Exclusive read-write, caller passes `&binding`.
fn scale(p: mut Point, factor: f64) {
p.x = p.x * factor;
p.y = p.y * factor;
}
-// Consume — caller's binding is uninitialized after the call.
+// Consume, caller's binding is uninitialized after the call.
fn storeIn(buf: move []u8, db: mut Database) {
db.append(buf);
}
@@ -766,18 +766,18 @@ At the call site, a `mut` parameter is passed with `&` to make the borrow explic
```jam
var p: Point = { x: 3.0, y: 4.0 };
-scale(&p, 2.0); // mut borrow — explicit &
-distance(p, otherPoint); // read-only — no sigil
+scale(&p, 2.0); // mut borrow, explicit &
+distance(p, otherPoint); // read-only, no sigil
```
-`move` parameters take a plain expression — the binding is dead in the caller after the
+`move` parameters take a plain expression, the binding is dead in the caller after the
call.
## Exclusivity {#mvs-exclusivity}
At any call boundary, at most one argument may be a `mut` borrow of a given binding,
and a `mut` borrow cannot coexist with any other borrow of the same binding. The
-compiler rejects programs that violate this rule — the same "law of exclusivity"
+compiler rejects programs that violate this rule, the same "law of exclusivity"
Rust's borrow checker enforces, applied locally at each call rather than across
whole-program lifetimes.
@@ -797,7 +797,7 @@ fn caller() u32 {
A struct may define a `drop` method that runs automatically when an owned instance goes
out of scope. The drop method takes `self: mut Self` and runs exactly once per owned
-value — even on early returns, in match arms, and through nested control flow. There is
+value, even on early returns, in match arms, and through nested control flow. There is
no manual `defer` ceremony.
```jam
@@ -817,4 +817,4 @@ fn readFile(path: []u8) i32 {
```
A value *moved* into another function (via the `move` mode) becomes uninitialized in
-the caller, so the drop fires at the new owner's scope exit — never twice.
+the caller, so the drop fires at the new owner's scope exit, never twice.
diff --git a/src/ast.cpp b/src/ast.cpp
index cd0cb45..1f8dae9 100644
--- a/src/ast.cpp
+++ b/src/ast.cpp
@@ -25,7 +25,7 @@ JamBasicBlockRef CurrentLoopBreak = nullptr;
// loop. SIZE_MAX means "no enclosing loop body active here".
size_t CurrentLoopBodyScopeIdx = SIZE_MAX;
-// Forward declaration so codegenCall (P9.5 auto-address path) can call
+// Forward declaration so codegenCall (auto-address path) can call
// codegenAddressOf which is defined further down in the file.
static JamValueRef codegenAddressOf(JamCodegenContext &ctx, const AstNode &n);
@@ -225,7 +225,7 @@ static JamValueRef resolveIndexedElementPtr(JamCodegenContext &ctx,
// keeps the codegen working uniformly whether the variable is
// backed by an `alloca` (locals, value-passed params) or by a
// function argument that's already a pointer to caller storage
- // (P9 mode-aware ABI for `mut` / `undefined` params).
+ // (mode-aware ABI for `mut` / `undefined` params).
JamTypeRef allocatedType = ctx.getLLVMType(varTy);
if (k.kind == TypeKind::PtrMany) {
@@ -1707,7 +1707,7 @@ static JamValueRef codegenVarDecl(JamCodegenContext &ctx, const AstNode &n) {
return Alloca;
}
-// + P9: emit a single drop call for one tracked binding. P9's
+// Emit a single drop call for one tracked binding. The
// mode-aware ABI now lowers `fn drop(self: mut T)` as a pointer-typed
// parameter, so the call site passes the binding's storage address
// directly — no load-value-then-pass-by-value workaround. The drop fn
@@ -1989,7 +1989,7 @@ static JamValueRef codegenFor(JamCodegenContext &ctx, const AstNode &n) {
//
// The Maranget decision-tree formalism degenerates to "specialize the only
// column" in (one scrutinee, one column); the cascade is the canonical
-// one-column lowering. M2+ replaces this with a multi-column tree.
+// one-column lowering. A multi-column tree will replace this later.
// Build a boolean (i1) value that is true iff the scrutinee matches the
// given pattern node. `scrut` is the already-loaded scrutinee value;
@@ -2058,7 +2058,7 @@ emitPatternTest(JamCodegenContext &ctx, NodeIdx patIdx, JamValueRef scrut,
}
uint32_t discrim = einfo->variants[idx].discriminant;
// Extract the tag if the scrutinee is a {tag, payload} struct.
- // For E1 (unit-only) enums the scrutinee is already i8.
+ // For unit-only enums the scrutinee is already i8.
JamValueRef tagVal = scrut;
JamTypeRef tagType = scrutType;
if (JamLLVMTypeIsStruct(scrutType)) {
@@ -2193,7 +2193,7 @@ static JamValueRef codegenMatch(JamCodegenContext &ctx, const AstNode &n) {
if (!scrut) return nullptr;
JamTypeRef scrutType = JamLLVMTypeOf(scrut);
// Classify the scrutinee. Enum scrutinees may be either an integer
- // (E1 unit-only enums lower to i8) or a struct (E2 payloaded enums
+ // (unit-only enums lower to i8) or a struct (payloaded enums
// lower to a named struct). For struct scrutinees we MUST verify
// the type matches a registered enum, otherwise a slice (which is
// also a struct shape `{ptr, len}`) would silently route through
@@ -2226,7 +2226,7 @@ static JamValueRef codegenMatch(JamCodegenContext &ctx, const AstNode &n) {
JamBasicBlockRef mergeBB =
JamLLVMAppendBasicBlock(func, "match.end");
- // Per-arm result for the M3 phi: pairs (basicBlock, value) where
+ // Per-arm result for the phi: pairs (basicBlock, value) where
// the arm's body ended without terminating control flow. The
// match's expression-form value is a phi over these.
std::vector> armResults;
@@ -2331,7 +2331,7 @@ static JamValueRef codegenMatch(JamCodegenContext &ctx, const AstNode &n) {
}
// Track each arm's last produced value (for match-as-expression
- // support, M3). Arms that terminate via `return` / `break` /
+ // support). Arms that terminate via `return` / `break` /
// `continue` don't fall through to merge and aren't recorded.
JamValueRef lastValue = nullptr;
ctx.pushDropScope();
diff --git a/src/ast_flat.h b/src/ast_flat.h
index cf4ecba..1ef947d 100644
--- a/src/ast_flat.h
+++ b/src/ast_flat.h
@@ -116,7 +116,7 @@ enum class AstTag : uint8_t {
// d.lhs = u32 (index into ModuleAST::AnonEnums)
EnumExpr,
- // Pattern match (M1: integer literals, ranges, or-patterns, wildcard).
+ // Pattern match (integer literals, ranges, or-patterns, wildcard).
// The catch-all is the wildcard pattern `_`; there is no `else` arm.
// d.lhs = NodeIdx (scrutinee expression)
// d.rhs = ExtraIdx → [armCount,
@@ -156,8 +156,8 @@ enum class AstTag : uint8_t {
// d.lhs = lo32 of value, d.rhs = hi32 of value, flags bit 0 = isNeg.
PatLit,
- // d.lhs = lo32 of low bound, d.rhs = lo32 of high bound (M1 limits to
- // values that fit in u32; M2+ may extend via ExtraIdx for u64).
+ // d.lhs = lo32 of low bound, d.rhs = lo32 of high bound (limited to
+ // values that fit in u32; may later extend via ExtraIdx for u64).
PatRange,
// No payload.
PatWildcard,
@@ -408,7 +408,7 @@ constexpr TypeIdx U64 = 9;
constexpr TypeIdx I64 = 10;
constexpr TypeIdx F32 = 11;
constexpr TypeIdx F64 = 12;
-constexpr TypeIdx Type = 13; // generics G1: the meta-type
+constexpr TypeIdx Type = 13; // the meta-type
constexpr TypeIdx U1 = Bool; // alias
} // namespace BuiltinType
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 874eb4b..5f2db63 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -160,7 +160,7 @@ JamTypeRef JamCodegenContext::getLLVMType(TypeIdx ty) const {
} else if (const auto *uinfo = getUnion(name)) {
result = uinfo->type;
} else if (const auto *einfo = getEnum(name)) {
- // (unit-only): lowers to i8. E2 (with payloads): lowers
+ // Unit-only enums lower to i8. Payloaded enums lower
// to {i8, [N x i8]} via the named struct type set during
// declaration.
result = einfo->hasPayloadVariant ? einfo->type : getInt8Type();
@@ -598,7 +598,7 @@ uint64_t JamCodegenContext::typeSize(TypeIdx ty) const {
return alignUp(maxSize, maxAlign);
}
case TypeKind::Enum:
- return 1; // M2 E1 enums lower to u8
+ return 1; // Unit-only enums lower to u8
case TypeKind::Type:
// Meta-type has no runtime size.
return 0;
diff --git a/src/init_analysis.cpp b/src/init_analysis.cpp
index b9d1105..5251e33 100644
--- a/src/init_analysis.cpp
+++ b/src/init_analysis.cpp
@@ -167,7 +167,7 @@ std::vector Analyzer::run(const FunctionAST &fn) {
r = analyze(stmt, std::move(r.state));
}
- // + P8.2: if control reaches the end of the body without an
+ // If control reaches the end of the body without an
// explicit return, every drop-bearing local must have been
// initialized. (Functions that always return on every path produce
// r.terminated == true and skip this check; the per-return checks
@@ -359,8 +359,8 @@ Result Analyzer::analyzeAssign(NodeIdx idx, NameMap state) {
// trigger a read check. Sub-expressions like array indices *are* reads.
//
// In any write to a sub-path (`arr[i] = x`, `s.field = x`) marks the
-// whole base binding as Init. This is intentionally imprecise: P2 does
-// not track field-level init. A later phase can refine this to only mark
+// whole base binding as Init. This is intentionally imprecise: field-level
+// init isn't tracked. A later phase can refine this to only mark
// the touched sub-path.
Result Analyzer::analyzeAssignTarget(NodeIdx idx, NameMap state) {
if (idx == kNoNode) return Result{std::move(state), false};
diff --git a/src/init_analysis.h b/src/init_analysis.h
index 988c8dd..8f1a941 100644
--- a/src/init_analysis.h
+++ b/src/init_analysis.h
@@ -66,7 +66,7 @@ using FunctionRegistry = std::unordered_map;
// vector on success; on failure, the vector contains every detected
// uninit-read with location info.
//
-// Scope (cumulative through P4):
+// Scope:
// - Tracks per-binding init state for locals declared with
// `var name: T = ...`.
// - Parameter entry state: every parameter starts Init (the caller is
diff --git a/src/main.cpp b/src/main.cpp
index 056b9e3..fb30bff 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -396,7 +396,7 @@ static int compileAndRun(const std::string &filename,
}
// Generic functions are still registered so call sites can
// look them up for instantiation, but no LLVM is emitted
- // until each instantiation is processed in G5.
+ // until each instantiation is processed.
if (func->isPub) {
codegenCtx.registerFunctionAST(func->Name, func.get());
}
@@ -519,7 +519,7 @@ static int compileAndRun(const std::string &filename,
}
}
- // MVS P2–P5.5 + P8 foundation/P8.1: definite-init + mode-aware
+ // Definite-init + mode-aware
// callsite analysis runs after every prototype is in scope but
// before any body is codegen'd. The drop registry is built here and
// kept alive for the whole codegen pass — codegen reads it via the
diff --git a/tests/cabi/README.md b/tests/cabi/README.md
deleted file mode 100644
index 629f296..0000000
--- a/tests/cabi/README.md
+++ /dev/null
@@ -1,119 +0,0 @@
-# Jam C ABI Tests
-
-This directory contains tests for Jam's C Application Binary Interface (ABI) compatibility, demonstrating interoperability between Jam and C code.
-
-## Overview
-
-The C ABI is crucial for:
-- Calling C libraries from Jam code
-- Exposing Jam functions to C code
-- System call interfaces
-- FFI (Foreign Function Interface) compatibility
-
-## Test Files
-
-### C Helper Code
-- **c_helpers.c** - C functions that can be called from Jam
-- **c_helpers.h** - Header file for C functions
-- **c_caller.c** - C program that calls Jam functions
-
-### Jam Test Code
-- **test_call_c.jam** - Jam code calling C functions
-- **jam_functions.jam** - Jam functions exposed to C
-
-## What We're Testing
-
-### 1. Calling Convention
-- Verify Jam functions use C calling convention
-- Check parameter passing (stack vs registers)
-- Validate return value handling
-
-### 2. Data Type Compatibility
-- Integer types (i8, i16, i32, i64)
-- Unsigned types (u8, u16, u32, u64)
-- Pointers and pointer arithmetic
-- Struct layout and alignment
-
-### 3. ABI Details
-- Pointer size (32-bit vs 64-bit)
-- Struct padding and alignment
-- Calling convention specifics (System V AMD64 ABI on Unix, Win64 ABI on Windows)
-
-### 4. Function Signatures
-- Simple functions (primitives)
-- Functions with pointers
-- Functions with structs
-- Variadic functions (future)
-
-## Running the Tests
-
-The previous `run_cabi_tests.sh` was removed — it masked failures with a final `exit 0`, so it provided no real signal. The `.jam` and `.c` fixtures in this directory are kept for a future, honest C-interop test harness.
-
-## Current Status
-
-✅ **Working:**
-- Target information detection
-- C calling convention setup
-- LLVM IR generation with correct ABI
-- Basic type compatibility
-
-🚧 **In Progress:**
-- Extern function declarations in Jam syntax
-- Direct linking with C object files
-- Struct ABI compatibility
-
-📋 **Planned:**
-- `extern "C"` keyword support in Jam
-- Full FFI with type marshalling
-- Callback support (C calling Jam)
-- Complex struct handling
-
-## Example: Future Jam Syntax
-
-```jam
-// Future syntax for calling C functions
-extern "C" fn printf(format: *const u8, ...) i32;
-extern "C" fn malloc(size: u64) *var u8;
-extern "C" fn free(ptr: *var u8);
-
-fn main() u8 {
- var msg: *const u8 = "Hello from Jam!\n";
- printf(msg);
- return 0;
-}
-```
-
-## C ABI Specifications
-
-### System V AMD64 ABI (Linux, macOS, BSD)
-- First 6 integer arguments in registers: RDI, RSI, RDX, RCX, R8, R9
-- First 8 floating-point arguments in XMM0-XMM7
-- Additional arguments on stack (right to left)
-- Return value in RAX (integers) or XMM0 (floats)
-
-### Microsoft x64 ABI (Windows)
-- First 4 arguments in registers: RCX, RDX, R8, R9
-- Additional arguments on stack (right to left)
-- Shadow space (32 bytes) required
-- Return value in RAX or XMM0
-
-### ARM64 (AArch64)
-- First 8 integer arguments in X0-X7
-- First 8 floating-point arguments in V0-V7
-- Additional arguments on stack
-- Return value in X0 or V0
-
-## Debugging
-
-Test output is saved in `output/` directory:
-- `*.log` - Test execution logs
-- `*.ll` - LLVM IR files
-- `*.o` - Object files
-- `*.a` - Static libraries
-
-## References
-
-- [System V AMD64 ABI](https://refspecs.linuxbase.org/elf/x86_64-abi-0.99.pdf)
-- [Microsoft x64 Calling Convention](https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention)
-- [ARM64 ABI](https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst)
-- [LLVM Calling Conventions](https://llvm.org/docs/LangRef.html#calling-conventions)
diff --git a/tests/comprehensive_test.jam b/tests/comprehensive_test.jam
deleted file mode 100644
index ef4708d..0000000
--- a/tests/comprehensive_test.jam
+++ /dev/null
@@ -1,46 +0,0 @@
-// Comprehensive test demonstrating u8, u16, u32, and u64 functionality
-fn test_all_types() u64 {
- // Test u8 (8-bit: 0-255)
- const small_a: u8 = 100;
- const small_b: u8 = 155;
- const small_sum: u8 = small_a + small_b; // 255
-
- // Test u16 (16-bit: 0-65535)
- const medium_a: u16 = 30000;
- const medium_b: u16 = 35535;
- const medium_sum: u16 = medium_a + medium_b; // 65535
-
- // Test u32 (32-bit: 0-4294967295)
- const large_a: u32 = 2000000000;
- const large_b: u32 = 2294967295;
- const large_sum: u32 = large_a + large_b; // 4294967295
-
- // Test u64 (64-bit: 0-18446744073709551615)
- const huge_a: u64 = 9000000000000000000;
- const huge_b: u64 = 1000000000000000000;
- const huge_sum: u64 = huge_a + huge_b; // 10000000000000000000
-
- return huge_sum;
-}
-
-fn test_boundary_values() u64 {
- // Test minimum values
- const u8_min: u8 = 0;
- const u16_min: u16 = 0;
- const u32_min: u32 = 0;
- const u64_min: u64 = 0;
-
- // Test maximum values
- const u8_max: u8 = 255;
- const u16_max: u16 = 65535;
- const u32_max: u32 = 4294967295;
- const u64_max: u64 = 18446744073709551615;
-
- return u64_max;
-}
-
-fn test_type_promotion(small: u8, medium: u16, large: u32) u32 {
- // All parameters are properly typed
- // Return the largest value
- return large;
-}
\ No newline at end of file
diff --git a/tests/cpp/CMakeLists.txt b/tests/cpp/CMakeLists.txt
index 42e49cd..d9ef200 100644
--- a/tests/cpp/CMakeLists.txt
+++ b/tests/cpp/CMakeLists.txt
@@ -1,18 +1,15 @@
cmake_minimum_required(VERSION 3.10)
project(JamTests)
-# Set C++ standard
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
-# Add test executable (no LLVM dependencies needed for external tests)
add_executable(jam_tests
external_tests.cpp
test_print_functions.cpp
test_loops.cpp
)
-# Add separate executable for jam files IR tests
add_executable(jam_files_ir_tests
test_jam_files_ir.cpp
)
\ No newline at end of file
diff --git a/tests/cpp/build_and_run.sh b/tests/cpp/build_and_run.sh
index 21fdf4e..692f465 100755
--- a/tests/cpp/build_and_run.sh
+++ b/tests/cpp/build_and_run.sh
@@ -1,24 +1,12 @@
#!/bin/bash
-# Build and run C++ tests for Jam compiler
-
-echo "Building C++ Tests..."
-
-# Create build directory
mkdir -p build
cd build
-
-# Configure with CMake
cmake .. -DCMAKE_BUILD_TYPE=Debug
-
-# Build
cmake --build .
if [ $? -eq 0 ]; then
- echo ""
- echo "Running C++ Tests..."
./jam_tests
else
- echo "Build failed!"
exit 1
fi
\ No newline at end of file
diff --git a/tests/cpp/external_tests.cpp b/tests/cpp/external_tests.cpp
index 243cb4c..e0b2ac1 100644
--- a/tests/cpp/external_tests.cpp
+++ b/tests/cpp/external_tests.cpp
@@ -3,7 +3,6 @@
#include
#include
-// Forward declaration
class PrintFunctionTests {
public:
static void registerAllTests(TestFramework &framework);
@@ -308,12 +307,10 @@ class CompilerExternalTests {
int main() {
TestFramework framework;
- // Register all tests
CompilerExternalTests::registerAllTests(framework);
PrintFunctionTests::registerAllTests(framework);
LoopTests::registerAllTests(framework);
- // Run all tests
framework.runAll();
return framework.allPassed() ? 0 : 1;