aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-17 06:02:21 +0000
committer_ov4 <ov4@ov4.org>2026-10-17 06:02:21 +0000
commit3425b95cb654f8e1adc98365a4b370aa1fff8b4d (patch)
tree4d81b91d0bd807cd6f7ced037533d6e60f5c307f /tests
parent4e22f464387725a5a282f3d72e11cfb694a31a5a (diff)
feat(classes): support ordinary member methods and this references
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/i/class-methods/case.json3
-rw-r--r--tests/i/class-methods/expected.txt9
-rw-r--r--tests/i/class-methods/notes.md7
-rw-r--r--tests/i/class-methods/program.cps89
-rw-r--r--tests/iii/class-method-errors/case.json52
-rw-r--r--tests/iii/class-method-errors/notes.md3
-rw-r--r--tests/iii/class-method-errors/program.cps35
7 files changed, 198 insertions, 0 deletions
diff --git a/tests/i/class-methods/case.json b/tests/i/class-methods/case.json
new file mode 100644
index 0000000..1f18635
--- /dev/null
+++ b/tests/i/class-methods/case.json
@@ -0,0 +1,3 @@
+{
+ "exit_code": 0
+}
diff --git a/tests/i/class-methods/expected.txt b/tests/i/class-methods/expected.txt
new file mode 100644
index 0000000..c3e4c42
--- /dev/null
+++ b/tests/i/class-methods/expected.txt
@@ -0,0 +1,9 @@
+5,8
+9,8
+9,9
+10,100
+10,7
+10,10
+caught
+42
+99
diff --git a/tests/i/class-methods/notes.md b/tests/i/class-methods/notes.md
new file mode 100644
index 0000000..903166c
--- /dev/null
+++ b/tests/i/class-methods/notes.md
@@ -0,0 +1,7 @@
+# class-methods
+
+Human review: pending. Expected output was independently traced by AI, not captured from cpsc.
+
+Basis: guide section 10.1; this and existing class value semantics are project behavior.
+
+Trace: A and B start at 3 and 8; Add changes only A to 5. Copy then Set leaves A at 9 and B at 8. Clone copies 9 into B; same-class private access reads 9. Sum(4) is 10 and the global Get returns 100. The array pointer changes Items[1] from 6 to 10; the nested object stays 7. Take adds A's 9 to Number's 1 and writes 10 into Values[1]. Fail is caught. Passing this BYREF changes A to 42. A method-only class returns 99 from its independent Get method.
diff --git a/tests/i/class-methods/program.cps b/tests/i/class-methods/program.cps
new file mode 100644
index 0000000..655fb8b
--- /dev/null
+++ b/tests/i/class-methods/program.cps
@@ -0,0 +1,89 @@
+CLASS Counter
+ PRIVATE Value : INTEGER
+ PROCEDURE Set(Number : INTEGER)
+ Value <- Number
+ ENDPROCEDURE
+ FUNCTION Get() RETURNS INTEGER
+ RETURN Value
+ ENDFUNCTION
+ PROCEDURE Add(Number : INTEGER)
+ this.Set(this.Get() + Number)
+ ENDPROCEDURE
+ PROCEDURE Copy(Other : Counter)
+ this <- Other
+ ENDPROCEDURE
+ FUNCTION Clone() RETURNS Counter
+ RETURN this
+ ENDFUNCTION
+ FUNCTION ReadOther(Other : Counter) RETURNS INTEGER
+ RETURN Other.Hidden()
+ ENDFUNCTION
+ PRIVATE FUNCTION Hidden() RETURNS INTEGER
+ RETURN Value
+ ENDFUNCTION
+ FUNCTION Sum(Number : INTEGER) RETURNS INTEGER
+ IF Number = 0 THEN
+ RETURN 0
+ ENDIF
+ RETURN Number + this.Sum(Number - 1)
+ ENDFUNCTION
+ PROCEDURE Take(BYREF Number : INTEGER, BYREF Values : ARRAY OF INTEGER)
+ Number <- Number + Value
+ Values[1] <- Number
+ ENDPROCEDURE
+ PROCEDURE Fail()
+ THROW
+ ENDPROCEDURE
+ PROCEDURE PassSelf()
+ CALL Change(this)
+ ENDPROCEDURE
+ENDCLASS
+CLASS Marker
+ FUNCTION Get() RETURNS INTEGER
+ RETURN 99
+ ENDFUNCTION
+ENDCLASS
+TYPE Container
+ DECLARE Item : Counter
+ENDTYPE
+TYPE CounterPointer = ^Counter
+PROCEDURE Change(BYREF Target : Counter)
+ Target.Set(42)
+ENDPROCEDURE
+FUNCTION Get() RETURNS INTEGER
+ RETURN 100
+ENDFUNCTION
+DECLARE A : Counter
+DECLARE B : Counter
+CALL a.sET(3)
+B.Set(8)
+A.Add(2)
+OUTPUT A.Get(), ",", B.Get()
+CALL A.Copy(B)
+A.Set(9)
+OUTPUT A.Get(), ",", B.Get()
+B <- A.Clone()
+OUTPUT B.Get(), ",", A.ReadOther(B)
+OUTPUT A.Sum(4), ",", Get()
+DECLARE Items : ARRAY[1:2] OF Counter
+Items[1].Set(6)
+DECLARE Wrapped : Container
+Wrapped.Item.Set(7)
+DECLARE P : CounterPointer
+P <- ^Items[1]
+P^.Add(4)
+OUTPUT Items[1].Get(), ",", Wrapped.Item.Get()
+DECLARE Number : INTEGER
+DECLARE Values : ARRAY[1:2] OF INTEGER
+Number <- 1
+CALL A.Take(Number, Values)
+OUTPUT Number, ",", Values[1]
+TRY
+ A.Fail()
+CATCH
+ OUTPUT "caught"
+ENDTRY
+A.PassSelf()
+OUTPUT A.Get()
+DECLARE M : Marker
+OUTPUT M.Get()
diff --git a/tests/iii/class-method-errors/case.json b/tests/iii/class-method-errors/case.json
new file mode 100644
index 0000000..655296d
--- /dev/null
+++ b/tests/iii/class-method-errors/case.json
@@ -0,0 +1,52 @@
+{
+ "errors": [
+ {
+ "reason": "Cannot redeclare this inside a method",
+ "line": 11
+ },
+ {
+ "reason": "A method parameter cannot be named this",
+ "line": 13
+ },
+ {
+ "reason": "NEW constructors are not implemented",
+ "line": 15
+ },
+ {
+ "reason": "Duplicate member set in class Box",
+ "line": 17
+ },
+ {
+ "reason": "Duplicate member Value in class Box",
+ "line": 19
+ },
+ {
+ "reason": "Cannot access private field Hidden of type Box",
+ "line": 25
+ },
+ {
+ "reason": "Cannot access private method Secret of type Box",
+ "line": 26
+ },
+ {
+ "reason": "Cannot access private method Secret of type Box",
+ "line": 30
+ },
+ {
+ "reason": "Cannot access private field Hidden of type Box",
+ "line": 31
+ },
+ {
+ "reason": "Incorrect # arguments passed to Box.Set",
+ "line": 32
+ },
+ {
+ "reason": "Type Box has no method Missing",
+ "line": 33
+ },
+ {
+ "reason": "Type INTEGER has no method Set",
+ "line": 35
+ }
+ ]
+}
diff --git a/tests/iii/class-method-errors/notes.md b/tests/iii/class-method-errors/notes.md
new file mode 100644
index 0000000..f9be5b9
--- /dev/null
+++ b/tests/iii/class-method-errors/notes.md
@@ -0,0 +1,3 @@
+# class-method-errors
+
+Reject private access from outside the owning class, duplicate members, NEW constructors, redeclarations of this, incorrect arguments and invalid receivers.
diff --git a/tests/iii/class-method-errors/program.cps b/tests/iii/class-method-errors/program.cps
new file mode 100644
index 0000000..f2503e2
--- /dev/null
+++ b/tests/iii/class-method-errors/program.cps
@@ -0,0 +1,35 @@
+CLASS Box
+ PRIVATE Hidden : INTEGER
+ PUBLIC Value : INTEGER
+ PROCEDURE Set(Number : INTEGER)
+ Hidden <- Number
+ ENDPROCEDURE
+ PRIVATE FUNCTION Secret() RETURNS INTEGER
+ RETURN Hidden
+ ENDFUNCTION
+ PROCEDURE BadLocal()
+ DECLARE this : Box
+ ENDPROCEDURE
+ PROCEDURE BadParam(this : Box)
+ ENDPROCEDURE
+ PROCEDURE NEW()
+ ENDPROCEDURE
+ PROCEDURE set()
+ ENDPROCEDURE
+ FUNCTION Value() RETURNS INTEGER
+ RETURN 0
+ ENDFUNCTION
+ENDCLASS
+CLASS Stranger
+ PROCEDURE Probe(Other : Box)
+ OUTPUT Other.Hidden
+ OUTPUT Other.Secret()
+ ENDPROCEDURE
+ENDCLASS
+DECLARE B : Box
+OUTPUT B.Secret()
+OUTPUT B.Hidden
+B.Set()
+B.Missing()
+DECLARE Number : INTEGER
+Number.Set(1)