aboutsummaryrefslogtreecommitdiff
path: root/tests/i
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-17 06:54:32 +0000
committer_ov4 <ov4@ov4.org>2026-10-17 06:54:32 +0000
commit74b6d06711afd3efbbc47436f1491900994313f3 (patch)
treeb9050214b147cd2b1b54fd27e75d669bf6146e48 /tests/i
parent39661855c0816ac248be437704c76f58359cb5f0 (diff)
feat(classes): allocate objects with NEW and rebind named class variables
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'tests/i')
-rw-r--r--tests/i/class-heap-new/case.json1
-rw-r--r--tests/i/class-heap-new/expected.txt16
-rw-r--r--tests/i/class-heap-new/notes.md5
-rw-r--r--tests/i/class-heap-new/program.cps100
4 files changed, 122 insertions, 0 deletions
diff --git a/tests/i/class-heap-new/case.json b/tests/i/class-heap-new/case.json
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/tests/i/class-heap-new/case.json
@@ -0,0 +1 @@
+{}
diff --git a/tests/i/class-heap-new/expected.txt b/tests/i/class-heap-new/expected.txt
new file mode 100644
index 0000000..37e731a
--- /dev/null
+++ b/tests/i/class-heap-new/expected.txt
@@ -0,0 +1,16 @@
+rebind:7,9
+copy:7,4,4
+byval:4,20
+caller:4
+byref:1,1
+this:1,1
+reset:1
+array:1,1
+field:1
+alias:1
+deref:1
+args:42
+declare caught
+new caught
+loop:1
+loop:1
diff --git a/tests/i/class-heap-new/notes.md b/tests/i/class-heap-new/notes.md
new file mode 100644
index 0000000..3a6435c
--- /dev/null
+++ b/tests/i/class-heap-new/notes.md
@@ -0,0 +1,5 @@
+# Heap NEW and object storage
+
+Human review: pending. Expected output was independently traced by AI.
+
+Project semantics extend guide section 10.2. Each Box constructor sets Value to 1. Rebinding A preserves the old stack object's 7 while the new object becomes 9. Ordinary A <- B copies 4 into the current heap object, leaving B and the old stack object independent. BYVAL copies 4, then independently rebinds and changes its local object to 20. BYREF NEW copies 1 into A's current object, observed through CurrentA. Replacing this likewise copies into that same object; explicit Reset calls the ordinary constructor method. Array-element, field, bare field alias and pointer-dereference NEW assignments preserve their destination addresses and copy 1. Named's argument is 42. Failing throws in both DECLARE and heap construction, reaching the surrounding catches. Loop DECLARE restores its original stack object and constructs it on every iteration, so the previous heap object's 99 is never printed.
diff --git a/tests/i/class-heap-new/program.cps b/tests/i/class-heap-new/program.cps
new file mode 100644
index 0000000..7b8363f
--- /dev/null
+++ b/tests/i/class-heap-new/program.cps
@@ -0,0 +1,100 @@
+CLASS Box
+ Value : INTEGER
+ PROCEDURE NEW()
+ Value <- 1
+ ENDPROCEDURE
+ PROCEDURE Reset()
+ this.NEW()
+ ENDPROCEDURE
+ PROCEDURE ReplaceSelf()
+ this <- NEW Box()
+ ENDPROCEDURE
+ENDCLASS
+CLASS Named
+ Value : INTEGER
+ PROCEDURE NEW(Number : INTEGER)
+ Value <- Number
+ ENDPROCEDURE
+ENDCLASS
+CLASS Holder
+ Item : Box
+ PROCEDURE ReplaceField()
+ Item <- NEW Box
+ ENDPROCEDURE
+ENDCLASS
+CLASS Failing
+ PROCEDURE NEW()
+ THROW
+ ENDPROCEDURE
+ENDCLASS
+TYPE BoxPointer = ^Box
+PROCEDURE ReplaceRef(BYREF Item : Box)
+ Item <- NEW Box
+ENDPROCEDURE
+PROCEDURE ReplaceVal(Item : Box)
+ DECLARE Old : BoxPointer
+ Old <- ^Item
+ Item <- NEW Box()
+ Item.Value <- 20
+ OUTPUT "byval:", Old^.Value, ",", Item.Value
+ENDPROCEDURE
+DECLARE A : Box
+DECLARE B : Box
+DECLARE OldA : BoxPointer
+DECLARE CurrentA : BoxPointer
+OldA <- ^A
+A.Value <- 7
+A <- NEW Box
+A.Value <- 9
+CurrentA <- ^A
+OUTPUT "rebind:", OldA^.Value, ",", A.Value
+B.Value <- 4
+A <- B
+OUTPUT "copy:", OldA^.Value, ",", CurrentA^.Value, ",", B.Value
+CALL ReplaceVal(A)
+OUTPUT "caller:", A.Value
+CALL ReplaceRef(A)
+OUTPUT "byref:", CurrentA^.Value, ",", A.Value
+A.Value <- 11
+A.ReplaceSelf()
+OUTPUT "this:", CurrentA^.Value, ",", A.Value
+A.Value <- 12
+A.Reset()
+OUTPUT "reset:", A.Value
+DECLARE Items : ARRAY[1:2] OF Box
+DECLARE Element : BoxPointer
+Element <- ^Items[1]
+Items[1].Value <- 30
+Items[1] <- NEW Box()
+OUTPUT "array:", Element^.Value, ",", Items[2].Value
+DECLARE H : Holder
+DECLARE Field : BoxPointer
+Field <- ^H.Item
+H.Item.Value <- 40
+H.Item <- NEW Box
+OUTPUT "field:", Field^.Value
+H.Item.Value <- 41
+H.ReplaceField()
+OUTPUT "alias:", Field^.Value
+CurrentA^ <- NEW Box
+OUTPUT "deref:", A.Value
+DECLARE N : Named(0)
+N <- NEW Named(42)
+OUTPUT "args:", N.Value
+TRY
+ DECLARE Broken : Failing
+CATCH
+ OUTPUT "declare caught"
+ENDTRY
+TRY
+ Broken <- NEW Failing
+CATCH
+ OUTPUT "new caught"
+ENDTRY
+DECLARE Index : INTEGER
+FOR Index <- 1 TO 2
+ DECLARE Local : Box
+ OUTPUT "loop:", Local.Value
+ Local <- NEW Box
+ Local.Value <- 99
+NEXT Index