diff --git a/pkg/corset/resolver.go b/pkg/corset/resolver.go index 98c255c..56de1d6 100644 --- a/pkg/corset/resolver.go +++ b/pkg/corset/resolver.go @@ -23,14 +23,16 @@ func ResolveCircuit(srcmap *sexp.SourceMaps[Node], circuit *Circuit) (*GlobalSco } // Construct resolver r := resolver{srcmap} - // Allocate declared input columns - errs := r.resolveDeclarations(scope, circuit) + // Initialise all columns + errs1 := r.initialiseDeclarations(scope, circuit) + // Finalise all columns / declarations + errs2 := r.resolveDeclarations(scope, circuit) // - if len(errs) > 0 { - return nil, errs + if len(errs1)+len(errs2) > 0 { + return nil, append(errs1, errs2...) } // Done - return scope, errs + return scope, nil } // Resolver packages up information necessary for resolving a circuit and @@ -42,6 +44,22 @@ type resolver struct { srcmap *sexp.SourceMaps[Node] } +// Initialise all columns from their declaring constructs. +func (r *resolver) initialiseDeclarations(scope *GlobalScope, circuit *Circuit) []SyntaxError { + // Input columns must be allocated before assignemts, since the hir.Schema + // separates these out. + errs := r.initialiseDeclarationsInModule(scope.Module(""), circuit.Declarations) + // + for _, m := range circuit.Modules { + // Process all declarations in the module + merrs := r.initialiseDeclarationsInModule(scope.Module(m.Name), m.Declarations) + // Package up all errors + errs = append(errs, merrs...) + } + // + return errs +} + // Process all assignment column declarations. These are more complex than for // input columns, since there can be dependencies between them. Thus, we cannot // simply resolve them in one linear scan. @@ -65,10 +83,6 @@ func (r *resolver) resolveDeclarations(scope *GlobalScope, circuit *Circuit) []S // to process all columns before we can sure that they are all declared // correctly. func (r *resolver) resolveDeclarationsInModule(scope *ModuleScope, decls []Declaration) []SyntaxError { - // Columns & Assignments - if errors := r.initialiseDeclarationsInModule(scope, decls); len(errors) > 0 { - return errors - } // Aliases if errors := r.initialiseAliasesInModule(scope, decls); len(errors) > 0 { return errors diff --git a/pkg/test/valid_corset_test.go b/pkg/test/valid_corset_test.go index 73e6f3e..fa84f49 100644 --- a/pkg/test/valid_corset_test.go +++ b/pkg/test/valid_corset_test.go @@ -588,6 +588,10 @@ func Test_Lookup_08(t *testing.T) { Check(t, false, "lookup_08") } +func Test_Lookup_09(t *testing.T) { + Check(t, false, "lookup_09") +} + // =================================================================== // Interleaving // =================================================================== diff --git a/testdata/constant_invalid_10.lisp b/testdata/constant_invalid_10.lisp index 480027e..e131979 100644 --- a/testdata/constant_invalid_10.lisp +++ b/testdata/constant_invalid_10.lisp @@ -1,4 +1,7 @@ -;;error:9:13-14:symbol X already declared +;;error:12:13-14:symbol X already declared +;;error:13:22-37:expected loobean constraint (found 𝔽) +;;error:14:22-45:expected loobean constraint (found 𝔽) +;;error:15:22-46:expected loobean constraint (found 𝔽) (defconst X 1 ONE X diff --git a/testdata/lookup_09.accepts b/testdata/lookup_09.accepts new file mode 100644 index 0000000..1e5d955 --- /dev/null +++ b/testdata/lookup_09.accepts @@ -0,0 +1,175 @@ +;; { "X": [], "m1.A": [] } +;; { "X": [0], "m1.A": [0] } +;; Check initial padding row! +{ "X": [0], "m1.A": [1] } +;; +{ "X": [0,0], "m1.A": [0,0] } +{ "X": [0,0], "m1.A": [0,1] } +{ "X": [0,0], "m1.A": [1,0] } +{ "X": [1,0], "m1.A": [0,1] } +{ "X": [1,0], "m1.A": [1,0] } +{ "X": [1,0], "m1.A": [1,1] } +{ "X": [0,1], "m1.A": [0,1] } +{ "X": [0,1], "m1.A": [1,0] } +{ "X": [0,1], "m1.A": [1,1] } +{ "X": [1,1], "m1.A": [0,1] } +{ "X": [1,1], "m1.A": [1,0] } +{ "X": [1,1], "m1.A": [1,1] } +{ "X": [1,1], "m1.A": [1,2] } +{ "X": [2,2], "m1.A": [2,2] } +{ "X": [2,2], "m1.A": [2,1] } +{ "X": [2,2], "m1.A": [1,2] } +{ "X": [1,2], "m1.A": [2,1] } +{ "X": [1,2], "m1.A": [1,2] } +{ "X": [2,1], "m1.A": [2,1] } +{ "X": [2,1], "m1.A": [1,2] } +{ "X": [1,1], "m1.A": [2,1] } +{ "X": [1,1], "m1.A": [1,2] } +{ "X": [1,1], "m1.A": [1,1] } +;; +{ "X": [0,0,0], "m1.A": [2,0,1] } +{ "X": [1,0,0], "m1.A": [2,0,1] } +{ "X": [0,1,0], "m1.A": [2,0,1] } +{ "X": [0,0,1], "m1.A": [2,0,1] } +{ "X": [1,0,1], "m1.A": [2,0,1] } +{ "X": [0,1,1], "m1.A": [2,0,1] } +{ "X": [1,1,0], "m1.A": [2,0,1] } +{ "X": [1,1,1], "m1.A": [2,0,1] } +{ "X": [0,0,0], "m1.A": [0,2,1] } +{ "X": [1,0,0], "m1.A": [0,2,1] } +{ "X": [0,1,0], "m1.A": [0,2,1] } +{ "X": [0,0,1], "m1.A": [0,2,1] } +{ "X": [1,0,1], "m1.A": [0,2,1] } +{ "X": [0,1,1], "m1.A": [0,2,1] } +{ "X": [1,1,0], "m1.A": [0,2,1] } +{ "X": [1,1,1], "m1.A": [0,2,1] } +{ "X": [0,0,0], "m1.A": [0,1,2] } +{ "X": [1,0,0], "m1.A": [0,1,2] } +{ "X": [0,1,0], "m1.A": [0,1,2] } +{ "X": [0,0,1], "m1.A": [0,1,2] } +{ "X": [1,0,1], "m1.A": [0,1,2] } +{ "X": [0,1,1], "m1.A": [0,1,2] } +{ "X": [1,1,0], "m1.A": [0,1,2] } +{ "X": [1,1,1], "m1.A": [0,1,2] } +{ "X": [0,0,0], "m1.A": [2,1,0] } +{ "X": [1,0,0], "m1.A": [2,1,0] } +{ "X": [0,1,0], "m1.A": [2,1,0] } +{ "X": [0,0,1], "m1.A": [2,1,0] } +{ "X": [1,0,1], "m1.A": [2,1,0] } +{ "X": [0,1,1], "m1.A": [2,1,0] } +{ "X": [1,1,0], "m1.A": [2,1,0] } +{ "X": [1,1,1], "m1.A": [2,1,0] } +{ "X": [0,0,0], "m1.A": [1,2,0] } +{ "X": [1,0,0], "m1.A": [1,2,0] } +{ "X": [0,1,0], "m1.A": [1,2,0] } +{ "X": [0,0,1], "m1.A": [1,2,0] } +{ "X": [1,0,1], "m1.A": [1,2,0] } +{ "X": [0,1,1], "m1.A": [1,2,0] } +{ "X": [1,1,0], "m1.A": [1,2,0] } +{ "X": [1,1,1], "m1.A": [1,2,0] } +{ "X": [0,0,0], "m1.A": [1,0,2] } +{ "X": [1,0,0], "m1.A": [1,0,2] } +{ "X": [0,1,0], "m1.A": [1,0,2] } +{ "X": [0,0,1], "m1.A": [1,0,2] } +{ "X": [1,0,1], "m1.A": [1,0,2] } +{ "X": [0,1,1], "m1.A": [1,0,2] } +{ "X": [1,1,0], "m1.A": [1,0,2] } +{ "X": [1,1,1], "m1.A": [1,0,2] } +{ "X": [0,0,0], "m1.A": [2,1,1] } +{ "X": [1,0,0], "m1.A": [2,1,1] } +{ "X": [0,1,0], "m1.A": [2,1,1] } +{ "X": [0,0,1], "m1.A": [2,1,1] } +{ "X": [1,0,1], "m1.A": [2,1,1] } +{ "X": [0,1,1], "m1.A": [2,1,1] } +{ "X": [1,1,0], "m1.A": [2,1,1] } +{ "X": [1,1,1], "m1.A": [2,1,1] } +{ "X": [0,0,0], "m1.A": [1,2,1] } +{ "X": [1,0,0], "m1.A": [1,2,1] } +{ "X": [0,1,0], "m1.A": [1,2,1] } +{ "X": [0,0,1], "m1.A": [1,2,1] } +{ "X": [1,0,1], "m1.A": [1,2,1] } +{ "X": [0,1,1], "m1.A": [1,2,1] } +{ "X": [1,1,0], "m1.A": [1,2,1] } +{ "X": [1,1,1], "m1.A": [1,2,1] } +{ "X": [0,0,0], "m1.A": [1,1,2] } +{ "X": [1,0,0], "m1.A": [1,1,2] } +{ "X": [0,1,0], "m1.A": [1,1,2] } +{ "X": [0,0,1], "m1.A": [1,1,2] } +{ "X": [1,0,1], "m1.A": [1,1,2] } +{ "X": [0,1,1], "m1.A": [1,1,2] } +{ "X": [1,1,0], "m1.A": [1,1,2] } +{ "X": [1,1,1], "m1.A": [1,1,2] } +;; +{ "X": [3,3,3], "m1.A": [2,3,1] } +{ "X": [1,3,3], "m1.A": [2,3,1] } +{ "X": [3,1,3], "m1.A": [2,3,1] } +{ "X": [3,3,1], "m1.A": [2,3,1] } +{ "X": [1,3,1], "m1.A": [2,3,1] } +{ "X": [3,1,1], "m1.A": [2,3,1] } +{ "X": [1,1,3], "m1.A": [2,3,1] } +{ "X": [1,1,1], "m1.A": [2,3,1] } +{ "X": [3,3,3], "m1.A": [3,2,1] } +{ "X": [1,3,3], "m1.A": [3,2,1] } +{ "X": [3,1,3], "m1.A": [3,2,1] } +{ "X": [3,3,1], "m1.A": [3,2,1] } +{ "X": [1,3,1], "m1.A": [3,2,1] } +{ "X": [3,1,1], "m1.A": [3,2,1] } +{ "X": [1,1,3], "m1.A": [3,2,1] } +{ "X": [1,1,1], "m1.A": [3,2,1] } +{ "X": [3,3,3], "m1.A": [3,1,2] } +{ "X": [1,3,3], "m1.A": [3,1,2] } +{ "X": [3,1,3], "m1.A": [3,1,2] } +{ "X": [3,3,1], "m1.A": [3,1,2] } +{ "X": [1,3,1], "m1.A": [3,1,2] } +{ "X": [3,1,1], "m1.A": [3,1,2] } +{ "X": [1,1,3], "m1.A": [3,1,2] } +{ "X": [1,1,1], "m1.A": [3,1,2] } +{ "X": [3,3,3], "m1.A": [2,1,3] } +{ "X": [1,3,3], "m1.A": [2,1,3] } +{ "X": [3,1,3], "m1.A": [2,1,3] } +{ "X": [3,3,1], "m1.A": [2,1,3] } +{ "X": [1,3,1], "m1.A": [2,1,3] } +{ "X": [3,1,1], "m1.A": [2,1,3] } +{ "X": [1,1,3], "m1.A": [2,1,3] } +{ "X": [1,1,1], "m1.A": [2,1,3] } +{ "X": [3,3,3], "m1.A": [1,2,3] } +{ "X": [1,3,3], "m1.A": [1,2,3] } +{ "X": [3,1,3], "m1.A": [1,2,3] } +{ "X": [3,3,1], "m1.A": [1,2,3] } +{ "X": [1,3,1], "m1.A": [1,2,3] } +{ "X": [3,1,1], "m1.A": [1,2,3] } +{ "X": [1,1,3], "m1.A": [1,2,3] } +{ "X": [1,1,1], "m1.A": [1,2,3] } +{ "X": [3,3,3], "m1.A": [1,3,2] } +{ "X": [1,3,3], "m1.A": [1,3,2] } +{ "X": [3,1,3], "m1.A": [1,3,2] } +{ "X": [3,3,1], "m1.A": [1,3,2] } +{ "X": [1,3,1], "m1.A": [1,3,2] } +{ "X": [3,1,1], "m1.A": [1,3,2] } +{ "X": [1,1,3], "m1.A": [1,3,2] } +{ "X": [1,1,1], "m1.A": [1,3,2] } +;; +{ "X": [3,3,3], "m1.A": [1,2,3] } +{ "X": [1,3,3], "m1.A": [1,2,3] } +{ "X": [3,1,3], "m1.A": [1,2,3] } +{ "X": [3,3,1], "m1.A": [1,2,3] } +{ "X": [1,3,1], "m1.A": [1,2,3] } +{ "X": [3,1,1], "m1.A": [1,2,3] } +{ "X": [1,1,3], "m1.A": [1,2,3] } +{ "X": [1,1,1], "m1.A": [1,2,3] } +{ "X": [3,3,3], "m1.A": [2,1,3] } +{ "X": [1,3,3], "m1.A": [2,1,3] } +{ "X": [3,1,3], "m1.A": [2,1,3] } +{ "X": [3,3,1], "m1.A": [2,1,3] } +{ "X": [1,3,1], "m1.A": [2,1,3] } +{ "X": [3,1,1], "m1.A": [2,1,3] } +{ "X": [1,1,3], "m1.A": [2,1,3] } +{ "X": [1,1,1], "m1.A": [2,1,3] } +{ "X": [3,3,3], "m1.A": [1,3,2] } +{ "X": [1,3,3], "m1.A": [1,3,2] } +{ "X": [3,1,3], "m1.A": [1,3,2] } +{ "X": [3,3,1], "m1.A": [1,3,2] } +{ "X": [1,3,1], "m1.A": [1,3,2] } +{ "X": [3,1,1], "m1.A": [1,3,2] } +{ "X": [1,1,3], "m1.A": [1,3,2] } +{ "X": [1,1,1], "m1.A": [1,3,2] } diff --git a/testdata/lookup_09.lisp b/testdata/lookup_09.lisp new file mode 100644 index 0000000..39c8244 --- /dev/null +++ b/testdata/lookup_09.lisp @@ -0,0 +1,5 @@ +(defcolumns X) +(deflookup test (m1.A) (X)) + +(module m1) +(defcolumns A) diff --git a/testdata/lookup_09.rejects b/testdata/lookup_09.rejects new file mode 100644 index 0000000..0e9574f --- /dev/null +++ b/testdata/lookup_09.rejects @@ -0,0 +1,37 @@ +{ "X": [1], "m1.A": [2] } +;; +{ "X": [1,2], "m1.A": [1,1] } +{ "X": [2,1], "m1.A": [1,1] } +{ "X": [2,2], "m1.A": [1,1] } +;; +{ "X": [1,2], "m1.A": [1,3] } +{ "X": [1,2], "m1.A": [3,1] } +{ "X": [1,2], "m1.A": [1,1] } +{ "X": [2,1], "m1.A": [1,1] } +{ "X": [2,1], "m1.A": [1,3] } +{ "X": [2,1], "m1.A": [3,1] } +{ "X": [2,2], "m1.A": [1,3] } +{ "X": [2,2], "m1.A": [3,1] } +;; +{ "X": [3,3,3], "m1.A": [1,2,1] } +{ "X": [1,3,3], "m1.A": [1,2,1] } +{ "X": [3,1,3], "m1.A": [1,2,1] } +{ "X": [3,3,1], "m1.A": [1,2,1] } +{ "X": [1,3,1], "m1.A": [1,2,1] } +{ "X": [3,1,1], "m1.A": [1,2,1] } +{ "X": [1,1,3], "m1.A": [1,2,1] } +{ "X": [1,1,1], "m1.A": [2,2,2] } +{ "X": [1,1,1], "m1.A": [2,2,3] } +{ "X": [1,1,1], "m1.A": [3,2,2] } +{ "X": [1,1,1], "m1.A": [2,3,2] } +{ "X": [3,3,3], "m1.A": [1,1,2] } +{ "X": [1,3,3], "m1.A": [1,1,2] } +{ "X": [3,1,3], "m1.A": [1,1,2] } +{ "X": [3,3,1], "m1.A": [1,1,2] } +{ "X": [1,3,1], "m1.A": [1,1,2] } +{ "X": [3,1,1], "m1.A": [1,1,2] } +{ "X": [1,1,3], "m1.A": [1,1,2] } +{ "X": [1,1,1], "m1.A": [2,2,2] } +{ "X": [1,1,1], "m1.A": [3,2,2] } +{ "X": [1,1,1], "m1.A": [2,3,2] } +{ "X": [1,1,1], "m1.A": [2,2,3] } diff --git a/testdata/lookup_invalid_06.lisp b/testdata/lookup_invalid_06.lisp index 33b03d9..ec2eaeb 100644 --- a/testdata/lookup_invalid_06.lisp +++ b/testdata/lookup_invalid_06.lisp @@ -1,5 +1,4 @@ -;;error:4:18-22:unknown symbol -;;error:4:23-27:unknown symbol +;;error:3:23-27:conflicting context (defcolumns X Y) (deflookup test (m1.A m2.B) (X Y)) diff --git a/testdata/lookup_invalid_07.lisp b/testdata/lookup_invalid_07.lisp index 5330cdc..6dfc8f7 100644 --- a/testdata/lookup_invalid_07.lisp +++ b/testdata/lookup_invalid_07.lisp @@ -1,5 +1,4 @@ -;;error:4:21-25:unknown symbol -;;error:4:26-30:unknown symbol +;;error:3:26-30:conflicting context (defcolumns X) (deflookup test ((+ m1.A m2.B)) (X))