aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-17 05:30:57 +0000
committer_ov4 <ov4@ov4.org>2026-10-17 05:30:57 +0000
commit4dd85fd6ecd9a67e5c2b68380873e6e114714355 (patch)
treeb9dad1d0845f4c2ae7e6efed171fbee40ccd1f31 /tests
parente782898e420c7f2abd83b97c160194d0e70598dd (diff)
feat(memory): add tracked MALLOC and FREE builtins
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/i/memory-allocation/case.json1
-rw-r--r--tests/i/memory-allocation/expected.txt14
-rw-r--r--tests/i/memory-allocation/notes.md5
-rw-r--r--tests/i/memory-allocation/program.cps63
-rw-r--r--tests/iii/memory-call-arity/case.json8
-rw-r--r--tests/iii/memory-call-arity/notes.md5
-rw-r--r--tests/iii/memory-call-arity/program.cps1
-rw-r--r--tests/iii/memory-pointer-type/case.json8
-rw-r--r--tests/iii/memory-pointer-type/notes.md5
-rw-r--r--tests/iii/memory-pointer-type/program.cps4
-rw-r--r--tests/iii/memory-size-type/case.json8
-rw-r--r--tests/iii/memory-size-type/notes.md5
-rw-r--r--tests/iii/memory-size-type/program.cps1
13 files changed, 128 insertions, 0 deletions
diff --git a/tests/i/memory-allocation/case.json b/tests/i/memory-allocation/case.json
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/tests/i/memory-allocation/case.json
@@ -0,0 +1 @@
+{}
diff --git a/tests/i/memory-allocation/expected.txt b/tests/i/memory-allocation/expected.txt
new file mode 100644
index 0000000..330c9ba
--- /dev/null
+++ b/tests/i/memory-allocation/expected.txt
@@ -0,0 +1,14 @@
+TRUE
+TRUE
+42
+11:22
+TRUE
+[Fatal] line 34: Invalid memory address (not an active allocation)
+double free caught
+[Fatal] line 40: Invalid memory address (not an active allocation)
+stack address caught
+[Fatal] line 48: Invalid memory address (not an active allocation)
+interior address caught
+[Fatal] line 54: Memory allocation failed
+allocation failure caught
+99
diff --git a/tests/i/memory-allocation/notes.md b/tests/i/memory-allocation/notes.md
new file mode 100644
index 0000000..c0d4286
--- /dev/null
+++ b/tests/i/memory-allocation/notes.md
@@ -0,0 +1,5 @@
+# Trace notes
+
+Human review: pending.
+
+Explicit memory allocation is a compiler extension. Zero size and FREE(null) return null. An INTEGER allocation stores 42; a two-INTEGER record stores 11 and 22. FREE returns the input address. Freeing the middle, head and tail nodes empties the allocation list. Repeated free, a stack address and a record field's interior address are caught before libc is called. The negative size converts to SIZE_MAX, whose allocation fails. A final allocation still stores 99. Sizes 8 and 16 cover the fixed i64 representation.
diff --git a/tests/i/memory-allocation/program.cps b/tests/i/memory-allocation/program.cps
new file mode 100644
index 0000000..85a24dc
--- /dev/null
+++ b/tests/i/memory-allocation/program.cps
@@ -0,0 +1,63 @@
+TYPE Raw = C_TYPE("void*")
+TYPE IntPointer = ^INTEGER
+TYPE Pair
+ DECLARE First : INTEGER
+ DECLARE Second : INTEGER
+ENDTYPE
+TYPE PairPointer = ^Pair
+DECLARE Empty : Raw
+DECLARE P : Raw
+DECLARE Q : Raw
+DECLARE R : Raw
+DECLARE Number : INTEGER
+DECLARE Pointer : IntPointer
+DECLARE PairAddress : PairPointer
+DECLARE Result : Raw
+OUTPUT MALLOC(0) = Empty
+OUTPUT FREE(Empty) = Empty
+P <- malloc(8)
+Pointer <- (IntPointer)P
+Pointer^ <- 42
+OUTPUT Pointer^
+Q <- MALLOC((C_INT)16)
+PairAddress <- (PairPointer)Q
+PairAddress^.First <- 11
+PairAddress^.Second <- 22
+OUTPUT PairAddress^.First, ":", PairAddress^.Second
+R <- MALLOC(1)
+// Remove a middle node, then the head, then the tail.
+Result <- FREE(Q)
+OUTPUT Result = Q
+FREE(R)
+FREE(P)
+TRY
+ FREE(P)
+CATCH
+ OUTPUT "double free caught"
+ENDTRY
+Pointer <- ^Number
+TRY
+ FREE((Raw)Pointer)
+CATCH
+ OUTPUT "stack address caught"
+ENDTRY
+Q <- MALLOC(16)
+PairAddress <- (PairPointer)Q
+Pointer <- ^PairAddress^.Second
+TRY
+ FREE((Raw)Pointer)
+CATCH
+ OUTPUT "interior address caught"
+ENDTRY
+FREE(Q)
+TRY
+ MALLOC(-1)
+CATCH
+ OUTPUT "allocation failure caught"
+ENDTRY
+// Allocation still works after all caught failures.
+P <- MALLOC(8)
+Pointer <- (IntPointer)P
+Pointer^ <- 99
+OUTPUT Pointer^
+FREE(P)
diff --git a/tests/iii/memory-call-arity/case.json b/tests/iii/memory-call-arity/case.json
new file mode 100644
index 0000000..3159635
--- /dev/null
+++ b/tests/iii/memory-call-arity/case.json
@@ -0,0 +1,8 @@
+{
+ "errors": [
+ {
+ "reason": "FREE\\ expects\\ 1\\ arg",
+ "line": 1
+ }
+ ]
+}
diff --git a/tests/iii/memory-call-arity/notes.md b/tests/iii/memory-call-arity/notes.md
new file mode 100644
index 0000000..456445e
--- /dev/null
+++ b/tests/iii/memory-call-arity/notes.md
@@ -0,0 +1,5 @@
+# Rejection notes
+
+Human review: pending.
+
+The explicit memory builtin rejects the invalid argument before emitting a runtime call.
diff --git a/tests/iii/memory-call-arity/program.cps b/tests/iii/memory-call-arity/program.cps
new file mode 100644
index 0000000..2ae44d4
--- /dev/null
+++ b/tests/iii/memory-call-arity/program.cps
@@ -0,0 +1 @@
+FREE()
diff --git a/tests/iii/memory-pointer-type/case.json b/tests/iii/memory-pointer-type/case.json
new file mode 100644
index 0000000..557c4b9
--- /dev/null
+++ b/tests/iii/memory-pointer-type/case.json
@@ -0,0 +1,8 @@
+{
+ "errors": [
+ {
+ "reason": "Cannot\\ implicitly\\ convert",
+ "line": 4
+ }
+ ]
+}
diff --git a/tests/iii/memory-pointer-type/notes.md b/tests/iii/memory-pointer-type/notes.md
new file mode 100644
index 0000000..456445e
--- /dev/null
+++ b/tests/iii/memory-pointer-type/notes.md
@@ -0,0 +1,5 @@
+# Rejection notes
+
+Human review: pending.
+
+The explicit memory builtin rejects the invalid argument before emitting a runtime call.
diff --git a/tests/iii/memory-pointer-type/program.cps b/tests/iii/memory-pointer-type/program.cps
new file mode 100644
index 0000000..2c1abeb
--- /dev/null
+++ b/tests/iii/memory-pointer-type/program.cps
@@ -0,0 +1,4 @@
+TYPE Raw = C_TYPE("void*")
+TYPE P = ^INTEGER
+DECLARE Pointer : P
+FREE(Pointer)
diff --git a/tests/iii/memory-size-type/case.json b/tests/iii/memory-size-type/case.json
new file mode 100644
index 0000000..9753757
--- /dev/null
+++ b/tests/iii/memory-size-type/case.json
@@ -0,0 +1,8 @@
+{
+ "errors": [
+ {
+ "reason": "Allocation\\ size\\ must\\ be\\ INTEGER\\ or\\ a\\ C\\ integer",
+ "line": 1
+ }
+ ]
+}
diff --git a/tests/iii/memory-size-type/notes.md b/tests/iii/memory-size-type/notes.md
new file mode 100644
index 0000000..456445e
--- /dev/null
+++ b/tests/iii/memory-size-type/notes.md
@@ -0,0 +1,5 @@
+# Rejection notes
+
+Human review: pending.
+
+The explicit memory builtin rejects the invalid argument before emitting a runtime call.
diff --git a/tests/iii/memory-size-type/program.cps b/tests/iii/memory-size-type/program.cps
new file mode 100644
index 0000000..0215fef
--- /dev/null
+++ b/tests/iii/memory-size-type/program.cps
@@ -0,0 +1 @@
+MALLOC(1.5)