aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/i/class-heap-new/expected.txt9
-rw-r--r--tests/i/class-heap-new/notes.md4
-rw-r--r--tests/i/class-heap-new/program.cps65
-rw-r--r--tests/iii/class-constructor-array-args-error/case.json8
-rw-r--r--tests/iii/class-constructor-array-args-error/program.cps5
-rw-r--r--tests/iii/class-constructor-duplicate-error/case.json8
-rw-r--r--tests/iii/class-constructor-duplicate-error/program.cps6
-rw-r--r--tests/iii/class-constructor-expression-error/case.json8
-rw-r--r--tests/iii/class-constructor-expression-error/program.cps4
-rw-r--r--tests/iii/class-constructor-function-error/case.json8
-rw-r--r--tests/iii/class-constructor-function-error/program.cps5
-rw-r--r--tests/iii/class-constructor-global-error/case.json8
-rw-r--r--tests/iii/class-constructor-global-error/program.cps2
-rw-r--r--tests/iii/class-constructor-nested-new-error/case.json8
-rw-r--r--tests/iii/class-constructor-nested-new-error/program.cps5
-rw-r--r--tests/iii/class-new-errors/case.json12
-rw-r--r--tests/iii/class-new-errors/program.cps5
17 files changed, 170 insertions, 0 deletions
diff --git a/tests/i/class-heap-new/expected.txt b/tests/i/class-heap-new/expected.txt
index 37e731a..27bf128 100644
--- a/tests/i/class-heap-new/expected.txt
+++ b/tests/i/class-heap-new/expected.txt
@@ -14,3 +14,12 @@ declare caught
new caught
loop:1
loop:1
+failed rebind:71,71
+nested heap:80,1
+first
+second
+outer
+first
+second
+outer
+method only:99
diff --git a/tests/i/class-heap-new/notes.md b/tests/i/class-heap-new/notes.md
index 3a6435c..a395599 100644
--- a/tests/i/class-heap-new/notes.md
+++ b/tests/i/class-heap-new/notes.md
@@ -3,3 +3,7 @@
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.
+
+Fragile's failed constructor leaves Stable bound to its original object, whose Value remains 71 through both names. Heap construction of Holder constructs its Box field as 1 while the old Holder's field remains 80 through Field. Ordered prints first, second, outer for stack and heap construction, proving field declaration order before the enclosing constructor. PrivateFactory's unused Build method checks that same-class access permits private automatic and explicit construction.
+
+A method-only Marker class has no fields, but heap NEW must still provide a non-null object address so a pointer receiver can call Get and print 99.
diff --git a/tests/i/class-heap-new/program.cps b/tests/i/class-heap-new/program.cps
index 7b8363f..aff248a 100644
--- a/tests/i/class-heap-new/program.cps
+++ b/tests/i/class-heap-new/program.cps
@@ -98,3 +98,68 @@ FOR Index <- 1 TO 2
Local <- NEW Box
Local.Value <- 99
NEXT Index
+CLASS Fragile
+ Value : INTEGER
+ PROCEDURE NEW(Fail : BOOLEAN)
+ Value <- 70
+ IF Fail THEN
+ THROW
+ ENDIF
+ ENDPROCEDURE
+ENDCLASS
+TYPE FragilePointer = ^Fragile
+DECLARE Stable : Fragile(FALSE)
+DECLARE Original : FragilePointer
+Original <- ^Stable
+Stable.Value <- 71
+TRY
+ Stable <- NEW Fragile(TRUE)
+CATCH
+ OUTPUT "failed rebind:", Stable.Value, ",", Original^.Value
+ENDTRY
+H.Item.Value <- 80
+H <- NEW Holder()
+OUTPUT "nested heap:", Field^.Value, ",", H.Item.Value
+CLASS OrderedFirst
+ PROCEDURE NEW()
+ OUTPUT "first"
+ ENDPROCEDURE
+ENDCLASS
+CLASS OrderedSecond
+ PROCEDURE NEW()
+ OUTPUT "second"
+ ENDPROCEDURE
+ENDCLASS
+CLASS Ordered
+ First : OrderedFirst
+ Second : OrderedSecond
+ PROCEDURE NEW()
+ OUTPUT "outer"
+ ENDPROCEDURE
+ENDCLASS
+DECLARE Order : Ordered
+Order <- NEW Ordered
+CLASS PrivateFactory
+ Value : INTEGER
+ PRIVATE PROCEDURE NEW()
+ Value <- 1
+ ENDPROCEDURE
+ PROCEDURE Build()
+ DECLARE Local : PrivateFactory
+ Local <- NEW PrivateFactory
+ Local.NEW()
+ ENDPROCEDURE
+ENDCLASS
+CLASS Marker
+ PROCEDURE NEW()
+ ENDPROCEDURE
+ FUNCTION Get() RETURNS INTEGER
+ RETURN 99
+ ENDFUNCTION
+ENDCLASS
+TYPE MarkerPointer = ^Marker
+DECLARE M : Marker
+DECLARE MarkerAddress : MarkerPointer
+M <- NEW Marker
+MarkerAddress <- ^M
+OUTPUT "method only:", MarkerAddress^.Get()
diff --git a/tests/iii/class-constructor-array-args-error/case.json b/tests/iii/class-constructor-array-args-error/case.json
new file mode 100644
index 0000000..6677de3
--- /dev/null
+++ b/tests/iii/class-constructor-array-args-error/case.json
@@ -0,0 +1,8 @@
+{
+ "errors": [
+ {
+ "reason": "Unexpected token",
+ "line": 5
+ }
+ ]
+}
diff --git a/tests/iii/class-constructor-array-args-error/program.cps b/tests/iii/class-constructor-array-args-error/program.cps
new file mode 100644
index 0000000..d3c7369
--- /dev/null
+++ b/tests/iii/class-constructor-array-args-error/program.cps
@@ -0,0 +1,5 @@
+CLASS Box
+ PROCEDURE NEW(Number : INTEGER)
+ ENDPROCEDURE
+ENDCLASS
+DECLARE Items : ARRAY[1:2] OF Box(1)
diff --git a/tests/iii/class-constructor-duplicate-error/case.json b/tests/iii/class-constructor-duplicate-error/case.json
new file mode 100644
index 0000000..f26c170
--- /dev/null
+++ b/tests/iii/class-constructor-duplicate-error/case.json
@@ -0,0 +1,8 @@
+{
+ "errors": [
+ {
+ "reason": "Duplicate member new in class Box",
+ "line": 4
+ }
+ ]
+}
diff --git a/tests/iii/class-constructor-duplicate-error/program.cps b/tests/iii/class-constructor-duplicate-error/program.cps
new file mode 100644
index 0000000..0782c5e
--- /dev/null
+++ b/tests/iii/class-constructor-duplicate-error/program.cps
@@ -0,0 +1,6 @@
+CLASS Box
+ PROCEDURE NEW()
+ ENDPROCEDURE
+ PROCEDURE new(Number : INTEGER)
+ ENDPROCEDURE
+ENDCLASS
diff --git a/tests/iii/class-constructor-expression-error/case.json b/tests/iii/class-constructor-expression-error/case.json
new file mode 100644
index 0000000..3055433
--- /dev/null
+++ b/tests/iii/class-constructor-expression-error/case.json
@@ -0,0 +1,8 @@
+{
+ "errors": [
+ {
+ "reason": "NEW is only allowed on the right of an assignment",
+ "line": 4
+ }
+ ]
+}
diff --git a/tests/iii/class-constructor-expression-error/program.cps b/tests/iii/class-constructor-expression-error/program.cps
new file mode 100644
index 0000000..67addd5
--- /dev/null
+++ b/tests/iii/class-constructor-expression-error/program.cps
@@ -0,0 +1,4 @@
+CLASS Box
+ Value : INTEGER
+ENDCLASS
+OUTPUT NEW Box()
diff --git a/tests/iii/class-constructor-function-error/case.json b/tests/iii/class-constructor-function-error/case.json
new file mode 100644
index 0000000..f654a51
--- /dev/null
+++ b/tests/iii/class-constructor-function-error/case.json
@@ -0,0 +1,8 @@
+{
+ "errors": [
+ {
+ "reason": "constructor NEW must be a PROCEDURE",
+ "line": 2
+ }
+ ]
+}
diff --git a/tests/iii/class-constructor-function-error/program.cps b/tests/iii/class-constructor-function-error/program.cps
new file mode 100644
index 0000000..1daa9fe
--- /dev/null
+++ b/tests/iii/class-constructor-function-error/program.cps
@@ -0,0 +1,5 @@
+CLASS Box
+ FUNCTION NEW() RETURNS INTEGER
+ RETURN 1
+ ENDFUNCTION
+ENDCLASS
diff --git a/tests/iii/class-constructor-global-error/case.json b/tests/iii/class-constructor-global-error/case.json
new file mode 100644
index 0000000..818dfca
--- /dev/null
+++ b/tests/iii/class-constructor-global-error/case.json
@@ -0,0 +1,8 @@
+{
+ "errors": [
+ {
+ "reason": "constructor NEW is only allowed in a CLASS",
+ "line": 1
+ }
+ ]
+}
diff --git a/tests/iii/class-constructor-global-error/program.cps b/tests/iii/class-constructor-global-error/program.cps
new file mode 100644
index 0000000..4ba097a
--- /dev/null
+++ b/tests/iii/class-constructor-global-error/program.cps
@@ -0,0 +1,2 @@
+PROCEDURE NEW()
+ENDPROCEDURE
diff --git a/tests/iii/class-constructor-nested-new-error/case.json b/tests/iii/class-constructor-nested-new-error/case.json
new file mode 100644
index 0000000..414816c
--- /dev/null
+++ b/tests/iii/class-constructor-nested-new-error/case.json
@@ -0,0 +1,8 @@
+{
+ "errors": [
+ {
+ "reason": "NEW is only allowed on the right of an assignment",
+ "line": 5
+ }
+ ]
+}
diff --git a/tests/iii/class-constructor-nested-new-error/program.cps b/tests/iii/class-constructor-nested-new-error/program.cps
new file mode 100644
index 0000000..b0bd349
--- /dev/null
+++ b/tests/iii/class-constructor-nested-new-error/program.cps
@@ -0,0 +1,5 @@
+CLASS Box
+ PROCEDURE NEW(Other : Box)
+ ENDPROCEDURE
+ENDCLASS
+DECLARE Item : Box(NEW Box)
diff --git a/tests/iii/class-new-errors/case.json b/tests/iii/class-new-errors/case.json
index 8ce52ed..7f33ffd 100644
--- a/tests/iii/class-new-errors/case.json
+++ b/tests/iii/class-new-errors/case.json
@@ -27,6 +27,18 @@
{
"reason": "NEW target must have type Hidden",
"line": 26
+ },
+ {
+ "reason": "Cannot access private method NEW of type Hidden",
+ "line": 28
+ },
+ {
+ "reason": "has no constructor NEW",
+ "line": 30
+ },
+ {
+ "reason": "Cannot coerce value of LLVM type to target type INTEGER",
+ "line": 31
}
]
}
diff --git a/tests/iii/class-new-errors/program.cps b/tests/iii/class-new-errors/program.cps
index 3a9e9c2..78db102 100644
--- a/tests/iii/class-new-errors/program.cps
+++ b/tests/iii/class-new-errors/program.cps
@@ -24,3 +24,8 @@ B <- NEW Box(1)
R <- NEW Required
R <- NEW Required()
B <- NEW Hidden
+PROCEDURE Forbidden(Target : Hidden)
+ Target <- NEW Hidden()
+ENDPROCEDURE
+B <- NEW Box("bad")
+R <- NEW Required("bad")