Skip to content

Commit

Permalink
Add additional array tests
Browse files Browse the repository at this point in the history
This adds a number of additional tests for arrays, and fixes a few bugs
uncovered by them.
  • Loading branch information
DavePearce committed Dec 16, 2024
1 parent 44631ad commit 8e0ff3d
Show file tree
Hide file tree
Showing 15 changed files with 380 additions and 7 deletions.
18 changes: 11 additions & 7 deletions pkg/corset/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -558,14 +558,18 @@ func (r *resolver) finaliseArrayAccessInModule(scope LocalScope, expr *ArrayAcce
//
if !expr.IsResolved() && !scope.Bind(expr) {
return nil, r.srcmap.SyntaxErrors(expr, "unknown array column")
} else if binding, ok := expr.Binding().(*ColumnBinding); ok {
// Found column, now check it is an array.
if arr_t, ok := binding.dataType.(*ArrayType); ok {
return arr_t.element, nil
}
} else if binding, ok := expr.Binding().(*ColumnBinding); !ok {
return nil, r.srcmap.SyntaxErrors(expr, "unknown array column")
} else if arr_t, ok := binding.dataType.(*ArrayType); !ok {
return nil, r.srcmap.SyntaxErrors(expr, "expected array column")
} else if c := expr.arg.AsConstant(); c == nil {
return nil, r.srcmap.SyntaxErrors(expr, "expected constant array index")
} else if i := uint(c.Uint64()); i == 0 || i > arr_t.Width() {
return nil, r.srcmap.SyntaxErrors(expr, "array access out-of-bounds")
} else {
// All good
return arr_t.element, nil
}
// Default
return nil, r.srcmap.SyntaxErrors(expr, "not an array column")
}

// Resolve an if condition contained within some expression which, in turn, is
Expand Down
3 changes: 3 additions & 0 deletions pkg/corset/translator.go
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,9 @@ func (t *translator) translateArrayAccessInModule(expr *ArrayAccess, shift int)
// Did we find it?
if !ok {
errors = append(errors, *t.srcmap.SyntaxError(expr.arg, "invalid array index encountered during translation"))
}
// Error check
if len(errors) > 0 {
return nil, errors
}
// Lookup underlying column info
Expand Down
23 changes: 23 additions & 0 deletions pkg/test/invalid_corset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,29 @@ func Test_Invalid_For_03(t *testing.T) {
CheckInvalid(t, "for_invalid_03")
}

// ===================================================================
// Arrays
// ===================================================================
func Test_Invalid_Array_01(t *testing.T) {
CheckInvalid(t, "array_invalid_01")
}

func Test_Invalid_Array_02(t *testing.T) {
CheckInvalid(t, "array_invalid_02")
}

func Test_Invalid_Array_03(t *testing.T) {
CheckInvalid(t, "array_invalid_03")
}

func Test_Invalid_Array_04(t *testing.T) {
CheckInvalid(t, "array_invalid_04")
}

func Test_Invalid_Array_05(t *testing.T) {
CheckInvalid(t, "array_invalid_05")
}

// ===================================================================
// Test Helpers
// ===================================================================
Expand Down
9 changes: 9 additions & 0 deletions pkg/test/valid_corset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,15 @@ func Test_Array_01(t *testing.T) {
Check(t, false, "array_01")
}

/* func Test_Array_02(t *testing.T) {
Check(t, false, "array_02")
}
*/

func Test_Array_03(t *testing.T) {
Check(t, false, "array_03")
}

// ===================================================================
// Complex Tests
// ===================================================================
Expand Down
18 changes: 18 additions & 0 deletions testdata/array_02.accepts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{ "ARG": [], "BIT_4": [], "BIT_3": [], "BIT_2": [], "BIT_1": [] }
;;
{ "ARG": [0], "BIT_4": [0], "BIT_3": [0], "BIT_2": [0], "BIT_1": [0] }
{ "ARG": [1], "BIT_4": [0], "BIT_3": [0], "BIT_2": [0], "BIT_1": [1] }
{ "ARG": [2], "BIT_4": [0], "BIT_3": [0], "BIT_2": [1], "BIT_1": [0] }
{ "ARG": [3], "BIT_4": [0], "BIT_3": [0], "BIT_2": [1], "BIT_1": [1] }
{ "ARG": [4], "BIT_4": [0], "BIT_3": [1], "BIT_2": [0], "BIT_1": [0] }
{ "ARG": [5], "BIT_4": [0], "BIT_3": [1], "BIT_2": [0], "BIT_1": [1] }
{ "ARG": [6], "BIT_4": [0], "BIT_3": [1], "BIT_2": [1], "BIT_1": [0] }
{ "ARG": [7], "BIT_4": [0], "BIT_3": [1], "BIT_2": [1], "BIT_1": [1] }
{ "ARG": [8], "BIT_4": [1], "BIT_3": [0], "BIT_2": [0], "BIT_1": [0] }
{ "ARG": [9], "BIT_4": [1], "BIT_3": [0], "BIT_2": [0], "BIT_1": [1] }
{ "ARG": [10], "BIT_4": [1], "BIT_3": [0], "BIT_2": [1], "BIT_1": [0] }
{ "ARG": [11], "BIT_4": [1], "BIT_3": [0], "BIT_2": [1], "BIT_1": [1] }
{ "ARG": [12], "BIT_4": [1], "BIT_3": [1], "BIT_2": [0], "BIT_1": [0] }
{ "ARG": [13], "BIT_4": [1], "BIT_3": [1], "BIT_2": [0], "BIT_1": [1] }
{ "ARG": [14], "BIT_4": [1], "BIT_3": [1], "BIT_2": [1], "BIT_1": [0] }
{ "ARG": [15], "BIT_4": [1], "BIT_3": [1], "BIT_2": [1], "BIT_1": [1] }
8 changes: 8 additions & 0 deletions testdata/array_02.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
(defcolumns
(BIT :binary@prove :array [4])
(ARG :i16@loob))

(defconstraint bits ()
(- ARG
(reduce +
(for i [0:3] (* (^ 2 i) [BIT (+ 1 i)])))))
256 changes: 256 additions & 0 deletions testdata/array_02.rejects

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions testdata/array_03.accepts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{"ARR_1": [], "ARR_2": []}
{"ARR_1": [-1], "ARR_2": [1]}
{"ARR_1": [0], "ARR_2": [0]}
{"ARR_1": [1], "ARR_2": [-1]}
{"ARR_1": [0,-1], "ARR_2": [0,1]}
{"ARR_1": [0,0], "ARR_2": [0,0]}
{"ARR_1": [0,1], "ARR_2": [0,-1]}
3 changes: 3 additions & 0 deletions testdata/array_03.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(defcolumns (ARR :@loob :array [2]))
(defconstraint c1 () (+ [ARR 1] [ARR 2]))
(defconstraint c2 () (+ [ARR 2] [ARR 2]))
6 changes: 6 additions & 0 deletions testdata/array_03.rejects
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{"ARR_1": [1], "ARR_2": [0]}
{"ARR_1": [-1], "ARR_2": [0]}
{"ARR_1": [0], "ARR_2": [1]}
{"ARR_1": [0], "ARR_2": [-1]}
{"ARR_1": [2], "ARR_2": [-1]}
{"ARR_1": [-2], "ARR_2": [1]}
4 changes: 4 additions & 0 deletions testdata/array_invalid_01.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
;;error:4:24-30:not an array column
(defcolumns (BIT :@loob))

(defconstraint bits () [BIT 1])
4 changes: 4 additions & 0 deletions testdata/array_invalid_02.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
;;error:4:24-25:expected loobean constraint (found (𝔽@loob)[4])
(defcolumns (BIT :@loob :array [4]))

(defconstraint bits () BIT)
4 changes: 4 additions & 0 deletions testdata/array_invalid_03.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
;;error:4:24-30:expected constant array index
(defcolumns X (BIT :@loob :array [4]))

(defconstraint bits () [BIT X])
12 changes: 12 additions & 0 deletions testdata/array_invalid_04.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
;;error:12:12-18:out-of-bounds array access
(defcolumns
(BIT :binary@prove :array [3])
(ARG :i16@loob))

(defconstraint bits ()
(- ARG
(+
(* 1 [BIT 1])
(* 2 [BIT 2])
(* 4 [BIT 3])
(* 8 [BIT 4]))))
12 changes: 12 additions & 0 deletions testdata/array_invalid_05.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
;;error:12:12-18:out-of-bounds array access
(defcolumns
(BIT :binary@prove :array [4])
(ARG :i16@loob))

(defconstraint bits ()
(- ARG
(+
(* 1 [BIT 0])
(* 2 [BIT 1])
(* 4 [BIT 2])
(* 8 [BIT 3]))))

0 comments on commit 8e0ff3d

Please sign in to comment.