diff --git a/pkg/corset/compiler/translator.go b/pkg/corset/compiler/translator.go index f0a7a447e..e98b2ccdb 100644 --- a/pkg/corset/compiler/translator.go +++ b/pkg/corset/compiler/translator.go @@ -389,7 +389,10 @@ func (t *translator) translateDefLookup(decl *ast.DefLookup) []SyntaxError { func (t *translator) translateDefLookupSources(selector ast.Expr, sources []ast.Expr) (lookup.Vector[mir.Term], ast.Context, []SyntaxError) { // Determine context of ith set of targets - context, j := ast.ContextOfExpressions(sources...) + var ( + context, j = ast.ContextOfExpressions(sources...) + vector lookup.Vector[mir.Term] + ) // Include selector (when present) if selector != nil { context = context.Join(selector.Context()) @@ -408,10 +411,51 @@ func (t *translator) translateDefLookupSources(selector ast.Expr, s, errs := t.translateExpression(selector, module, 0) errors = append(errors, errs...) - return lookup.FilteredVector(module.Id(), s, terms...), context, errors + vector = lookup.FilteredVector(module.Id(), s, terms...) + } else { + vector = lookup.UnfilteredVector(module.Id(), terms...) } + // Sanity check vector + errors = append(errors, t.checkLookupVector(vector, selector, sources)...) + // + return vector, context, errors +} + +func (t *translator) checkLookupVector(vector lookup.Vector[mir.Term], selector ast.Expr, + terms []ast.Expr) []SyntaxError { // - return lookup.UnfilteredVector(module.Id(), terms...), context, errors + var ( + modmap = t.schema.Module(vector.Module) + errors []SyntaxError + ) + // Look for any negative terms + for i, ith := range vector.Terms { + // Determine value range of ith term + valrange := ith.ValueRange(modmap) + // Determine bitwidth for that range + _, signed := valrange.BitWidth() + // Sanity check signed lookups + if signed { + errors = append(errors, *t.srcmap.SyntaxError(terms[i], "signed term encountered")) + } + } + // Check selector is binary + if vector.HasSelector() { + // Determine value range of ith term + valrange := vector.Selector.Unwrap().ValueRange(modmap) + // Determine bitwidth for that range + bitwidth, signed := valrange.BitWidth() + // Check for signed selector + if signed { + errors = append(errors, *t.srcmap.SyntaxError(selector, "signed selector encountered")) + } + // Check for non-binary selector + if bitwidth > 1 { + errors = append(errors, *t.srcmap.SyntaxError(selector, "non-binary selector encountered")) + } + } + // Done + return errors } // Translate a "definrange" declaration. diff --git a/pkg/test/invalid_corset_test.go b/pkg/test/invalid_corset_test.go index 1c1112ed0..29fb6e9fd 100644 --- a/pkg/test/invalid_corset_test.go +++ b/pkg/test/invalid_corset_test.go @@ -480,6 +480,19 @@ func Test_Invalid_Lookup_10(t *testing.T) { CheckInvalid(t, "invalid/lookup_invalid_10") } +func Test_Invalid_Lookup_11(t *testing.T) { + CheckInvalid(t, "invalid/lookup_invalid_11") +} +func Test_Invalid_Lookup_12(t *testing.T) { + CheckInvalid(t, "invalid/lookup_invalid_12") +} +func Test_Invalid_Lookup_13(t *testing.T) { + CheckInvalid(t, "invalid/lookup_invalid_13") +} +func Test_Invalid_Lookup_14(t *testing.T) { + CheckInvalid(t, "invalid/lookup_invalid_14") +} + // =================================================================== // Interleavings // =================================================================== diff --git a/testdata/invalid/lookup_invalid_11.lisp b/testdata/invalid/lookup_invalid_11.lisp new file mode 100644 index 000000000..6876eff2e --- /dev/null +++ b/testdata/invalid/lookup_invalid_11.lisp @@ -0,0 +1,3 @@ +;;error:3:16-23:signed term encountered +(defcolumns (X :u16) (Y :u16)) +(deflookup l1 ((- 1 X)) (Y)) diff --git a/testdata/invalid/lookup_invalid_12.lisp b/testdata/invalid/lookup_invalid_12.lisp new file mode 100644 index 000000000..e88e1dce0 --- /dev/null +++ b/testdata/invalid/lookup_invalid_12.lisp @@ -0,0 +1,3 @@ +;;error:3:20-27:signed term encountered +(defcolumns (X :u16) (Y :u16)) +(deflookup l1 (X) ((- 1 Y))) diff --git a/testdata/invalid/lookup_invalid_13.lisp b/testdata/invalid/lookup_invalid_13.lisp new file mode 100644 index 000000000..180e2190f --- /dev/null +++ b/testdata/invalid/lookup_invalid_13.lisp @@ -0,0 +1,3 @@ +;;error:3:20-27:signed selector encountered +(defcolumns (P :u1) (X :u16) (Y :u16)) +(defclookup l1 (X) (- 0 P) (Y)) diff --git a/testdata/invalid/lookup_invalid_14.lisp b/testdata/invalid/lookup_invalid_14.lisp new file mode 100644 index 000000000..49ae13430 --- /dev/null +++ b/testdata/invalid/lookup_invalid_14.lisp @@ -0,0 +1,3 @@ +;;error:3:20-21:non-binary selector encountered +(defcolumns (P :u2) (X :u16) (Y :u16)) +(defclookup l1 (X) P (Y))