@@ -42,18 +42,22 @@ import (
4242// Thus, you should never expect to see duplicate module names in the returned
4343// array.
4444func ParseSourceFiles (files []source.File , enforceTypes bool ) (ast.Circuit , * source.Maps [ast.Node ], []SyntaxError ) {
45- var circuit ast.Circuit
46- // (for now) at most one error per source file is supported.
47- var errors []SyntaxError
48- // Construct an initially empty source map
49- srcmaps := source .NewSourceMaps [ast.Node ]()
50- // Contents map holds the combined fragments of each module.
51- contents := make (map [string ]ast.Module , 0 )
52- // Names identifies the names of each unique module.
53- names := make ([]string , 0 )
45+ var (
46+ circuit ast.Circuit
47+ // (for now) at most one error per source file is supported.
48+ errors []SyntaxError
49+ // Construct an initially empty source map
50+ srcmaps = source .NewSourceMaps [ast.Node ]()
51+ // Contents map holds the combined fragments of each module.
52+ contents = make (map [string ]ast.Module , 0 )
53+ // Names identifies the names of each unique module.
54+ names = make ([]string , 0 )
55+ // Handles used for detecting duplicate constraint handles
56+ handles = make (map [string ]bool )
57+ )
5458 //
5559 for _ , file := range files {
56- c , srcmap , errs := ParseSourceFile (file , enforceTypes )
60+ c , srcmap , errs := parseSourceFile (file , enforceTypes , handles )
5761 // Handle errors
5862 if len (errs ) > 0 {
5963 // Report any errors encountered
@@ -94,10 +98,9 @@ func ParseSourceFiles(files []source.File, enforceTypes bool) (ast.Circuit, *sou
9498 return circuit , srcmaps , nil
9599}
96100
97- // ParseSourceFile parses the contents of a single lisp file into one or more
98- // modules. Observe that every lisp file starts in the "prelude" or "root"
99- // module, and may declare items for additional modules as necessary.
100- func ParseSourceFile (srcfile source.File , enforceTypes bool ) (ast.Circuit , * source.Map [ast.Node ], []SyntaxError ) {
101+ func parseSourceFile (srcfile source.File , enforceTypes bool ,
102+ handles map [string ]bool ) (ast.Circuit , * source.Map [ast.Node ], []SyntaxError ) {
103+ //
101104 //
102105 var (
103106 circuit ast.Circuit
@@ -111,7 +114,7 @@ func ParseSourceFile(srcfile source.File, enforceTypes bool) (ast.Circuit, *sour
111114 return circuit , nil , []SyntaxError {* err }
112115 }
113116 // Construct parser for corset syntax
114- p := NewParser (srcfile , srcmap , enforceTypes )
117+ p := NewParser (srcfile , srcmap , enforceTypes , handles )
115118 // Parse whatever is declared at the beginning of the file before the first
116119 // module declaration. These declarations form part of the "prelude".
117120 if circuit .Declarations , terms , errors = p .parseModuleContents (path , terms ); len (errors ) > 0 {
@@ -150,6 +153,8 @@ func ParseSourceFile(srcfile source.File, enforceTypes bool) (ast.Circuit, *sour
150153// ensuring that expressions are well-typed, etc) --- that is left up to the
151154// compiler.
152155type Parser struct {
156+ // Handles map used to detect duplicate handles
157+ handles map [string ]bool
153158 // Translator used for recursive expressions.
154159 translator * sexp.Translator [ast.Expr ]
155160 // Mapping from constructed S-Expressions to their spans in the original text.
@@ -160,12 +165,14 @@ type Parser struct {
160165
161166// NewParser constructs a new parser using a given mapping from S-Expressions to
162167// spans in the underlying source file.
163- func NewParser (srcfile source.File , srcmap * source.Map [sexp.SExp ], enforceTypes bool ) * Parser {
168+ func NewParser (srcfile source.File , srcmap * source.Map [sexp.SExp ], enforceTypes bool , handles map [string ]bool ,
169+ ) * Parser {
170+ //
164171 p := sexp .NewTranslator [ast.Expr ](& srcfile , srcmap )
165172 // Construct (initially empty) node map
166173 nodemap := source.NewSourceMap [ast.Node ](srcmap .Source ())
167174 // Construct parser
168- parser := & Parser {p , nodemap , enforceTypes }
175+ parser := & Parser {handles , p , nodemap , enforceTypes }
169176 // Configure expression translator
170177 p .AddSymbolRule (constantParserRule )
171178 p .AddSymbolRule (varAccessParserRule )
@@ -215,9 +222,8 @@ func (p *Parser) parseModuleContents(path file.Path, terms []sexp.SExp) ([]ast.D
215222 []SyntaxError ) {
216223 //
217224 var (
218- errors []SyntaxError
219- handles = make (map [string ]bool )
220- decls = make ([]ast.Declaration , 0 )
225+ errors []SyntaxError
226+ decls = make ([]ast.Declaration , 0 )
221227 )
222228 //
223229 for i , s := range terms {
@@ -228,7 +234,7 @@ func (p *Parser) parseModuleContents(path file.Path, terms []sexp.SExp) ([]ast.D
228234 errors = append (errors , * err )
229235 } else if e .MatchSymbols (2 , "module" ) {
230236 return decls , terms [i :], errors
231- } else if decl , errs := p .parseDeclaration (path , e , handles ); len (errs ) > 0 {
237+ } else if decl , errs := p .parseDeclaration (path , e ); len (errs ) > 0 {
232238 errors = append (errors , errs ... )
233239 } else {
234240 // Continue accumulating declarations for this module.
@@ -268,8 +274,7 @@ func (p *Parser) parseModuleStart(s sexp.SExp) (string, []SyntaxError) {
268274 return name , errors
269275}
270276
271- func (p * Parser ) parseDeclaration (module file.Path , s * sexp.List ,
272- handles map [string ]bool ) (ast.Declaration , []SyntaxError ) {
277+ func (p * Parser ) parseDeclaration (module file.Path , s * sexp.List ) (ast.Declaration , []SyntaxError ) {
273278 //
274279 var (
275280 decl ast.Declaration
@@ -285,7 +290,7 @@ func (p *Parser) parseDeclaration(module file.Path, s *sexp.List,
285290 } else if s .Len () > 1 && s .MatchSymbols (1 , "defconst" ) {
286291 decl , errors = p .parseDefConst (module , s .Elements )
287292 } else if s .Len () == 4 && s .MatchSymbols (2 , "defconstraint" ) {
288- decl , errors = p .parseDefConstraint (module , s .Elements , handles )
293+ decl , errors = p .parseDefConstraint (module , s .Elements )
289294 } else if s .Len () == 3 && s .MatchSymbols (1 , "defpurefun" ) {
290295 decl , errors = p .parseDefFun (module , true , s .Elements )
291296 } else if s .Len () == 3 && s .MatchSymbols (1 , "defun" ) {
@@ -295,21 +300,21 @@ func (p *Parser) parseDeclaration(module file.Path, s *sexp.List,
295300 } else if s .Len () == 3 && s .MatchSymbols (1 , "definterleaved" ) {
296301 decl , errors = p .parseDefInterleaved (module , s .Elements )
297302 } else if s .Len () == 4 && s .MatchSymbols (1 , "deflookup" ) {
298- decl , errors = p .parseDefLookup (s .Elements , handles )
303+ decl , errors = p .parseDefLookup (module , s .Elements )
299304 } else if (s .Len () == 5 || s .Len () == 6 ) && s .MatchSymbols (1 , "defclookup" ) {
300- decl , errors = p .parseDefConditionalLookup (s .Elements , handles )
305+ decl , errors = p .parseDefConditionalLookup (module , s .Elements )
301306 } else if s .Len () == 4 && s .MatchSymbols (1 , "defmlookup" ) {
302- decl , errors = p .parseDefMultiLookup (s .Elements , handles )
307+ decl , errors = p .parseDefMultiLookup (module , s .Elements )
303308 } else if s .Len () == 3 && s .MatchSymbols (2 , "defpermutation" ) {
304309 decl , errors = p .parseDefPermutation (module , s .Elements )
305310 } else if s .Len () == 4 && s .MatchSymbols (2 , "defperspective" ) {
306311 decl , errors = p .parseDefPerspective (module , s .Elements )
307312 } else if 3 <= s .Len () && s .Len () <= 4 && s .MatchSymbols (2 , "defproperty" ) {
308- decl , errors = p .parseDefProperty (s .Elements , handles )
313+ decl , errors = p .parseDefProperty (module , s .Elements )
309314 } else if s .Len () == 3 && s .MatchSymbols (2 , "defsorted" ) {
310- decl , errors = p .parseDefSorted (false , s .Elements , handles )
315+ decl , errors = p .parseDefSorted (module , false , s .Elements )
311316 } else if 3 <= s .Len () && s .Len () <= 4 && s .MatchSymbols (2 , "defstrictsorted" ) {
312- decl , errors = p .parseDefSorted (true , s .Elements , handles )
317+ decl , errors = p .parseDefSorted (module , true , s .Elements )
313318 } else if s .Len () == 3 && s .MatchSymbols (1 , "defcomputedcolumn" ) {
314319 decl , errors = p .parseDefComputedColumn (module , s .Elements )
315320 } else {
@@ -761,23 +766,21 @@ func (p *Parser) parseDefConstHead(head sexp.SExp) (*sexp.Symbol, ast.Type, bool
761766}
762767
763768// Parse a vanishing declaration
764- func (p * Parser ) parseDefConstraint (module file.Path , elements []sexp.SExp ,
765- handles map [string ]bool ) (ast.Declaration , []SyntaxError ) {
766- var (
767- errors []SyntaxError
768- handle string
769- )
769+ func (p * Parser ) parseDefConstraint (module file.Path , elements []sexp.SExp ) (ast.Declaration , []SyntaxError ) {
770+ var errors []SyntaxError
770771 // Initial sanity checks
771772 if ! isIdentifier (elements [1 ]) {
772773 return nil , p .translator .SyntaxErrors (elements [1 ], "invalid constraint handle" )
773- } else {
774- handle = elements [1 ].AsSymbol ().Value
775774 }
775+ //
776+ handle := elements [1 ].AsSymbol ().Value
777+ // Generate qualified name
778+ qualifiedHandle := fmt .Sprintf ("%s:%s" , module .String (), handle )
776779 // Check for duplicate
777- if _ , ok := handles [handle ]; ok {
780+ if _ , ok := p . handles [qualifiedHandle ]; ok {
778781 return nil , p .translator .SyntaxErrors (elements [1 ], "duplicate handle" )
779782 } else {
780- handles [handle ] = true
783+ p . handles [qualifiedHandle ] = true
781784 }
782785 // Vanishing constraints do not have global scope, hence qualified column
783786 // accesses are not permitted.
@@ -869,9 +872,9 @@ func (p *Parser) parseDefInterleavedSourceArray(source *sexp.Array) (ast.TypedSy
869872}
870873
871874// Parse a lookup declaration
872- func (p * Parser ) parseDefLookup (elements []sexp. SExp , handles map [ string ] bool ) (ast.Declaration , []SyntaxError ) {
875+ func (p * Parser ) parseDefLookup (module file. Path , elements []sexp. SExp ) (ast.Declaration , []SyntaxError ) {
873876 // Extract items
874- handle , checked , errors := p .parseLookupHandle (elements [1 ], handles )
877+ handle , checked , errors := p .parseLookupHandle (module , elements [1 ])
875878 targets , tgtErrors := p .parseDefLookupSources ("target" , elements [2 ])
876879 sources , srcErrors := p .parseDefLookupSources ("source" , elements [3 ])
877880 // Combine any and all errors
@@ -897,16 +900,15 @@ func (p *Parser) parseDefLookup(elements []sexp.SExp, handles map[string]bool) (
897900}
898901
899902// Parse a conditional lookup declaration
900- func (p * Parser ) parseDefConditionalLookup (elements []sexp.SExp ,
901- handles map [string ]bool ) (ast.Declaration , []SyntaxError ) {
903+ func (p * Parser ) parseDefConditionalLookup (module file.Path , elements []sexp.SExp ) (ast.Declaration , []SyntaxError ) {
902904 // Extract items
903905 var (
904906 targets , sources []ast.Expr
905907 targetSelector , sourceSelector ast.Expr
906908 errs1 , errs2 , errs3 , errs4 []SyntaxError
907909 )
908910 //
909- handle , checked , errors := p .parseLookupHandle (elements [1 ], handles )
911+ handle , checked , errors := p .parseLookupHandle (module , elements [1 ])
910912 //
911913 if len (elements ) == 6 {
912914 targetSelector , errs1 = p .translator .Translate (elements [2 ])
@@ -942,9 +944,9 @@ func (p *Parser) parseDefConditionalLookup(elements []sexp.SExp,
942944 [][]ast.Expr {targets }), nil
943945}
944946
945- func (p * Parser ) parseDefMultiLookup (elements []sexp. SExp , handles map [ string ] bool ) (ast.Declaration , []SyntaxError ) {
947+ func (p * Parser ) parseDefMultiLookup (module file. Path , elements []sexp. SExp ) (ast.Declaration , []SyntaxError ) {
946948 // Extract items
947- handle , checked , errors := p .parseLookupHandle (elements [1 ], handles )
949+ handle , checked , errors := p .parseLookupHandle (module , elements [1 ])
948950 m , targets , tgtErrors := p .parseDefLookupMultiSources ("target" , elements [2 ])
949951 n , sources , srcErrors := p .parseDefLookupMultiSources ("source" , elements [3 ])
950952 // Combine any and all errors
@@ -966,7 +968,7 @@ func (p *Parser) parseDefMultiLookup(elements []sexp.SExp, handles map[string]bo
966968 return ast .NewDefLookup (handle , checked , sourceSelectors , sources , targetSelectors , targets ), nil
967969}
968970
969- func (p * Parser ) parseLookupHandle (element sexp. SExp , handles map [ string ] bool ) (string , bool , []SyntaxError ) {
971+ func (p * Parser ) parseLookupHandle (module file. Path , element sexp. SExp ) (string , bool , []SyntaxError ) {
970972 var (
971973 checked = true
972974 errors []SyntaxError
@@ -981,12 +983,14 @@ func (p *Parser) parseLookupHandle(element sexp.SExp, handles map[string]bool) (
981983 } else {
982984 handle = element .AsSymbol ().Value
983985 }
986+ // Generate qualified name
987+ qualifiedHandle := fmt .Sprintf ("%s:%s" , module .String (), handle )
984988 // Check for duplicate handle
985- if _ , ok := handles [handle ]; ok {
989+ if _ , ok := p . handles [qualifiedHandle ]; ok {
986990 return "" , checked , p .translator .SyntaxErrors (element , "duplicate handle" )
987991 } else if len (errors ) == 0 {
988992 // Done
989- handles [handle ] = true
993+ p . handles [qualifiedHandle ] = true
990994 }
991995 //
992996 return handle , checked , errors
@@ -1149,8 +1153,7 @@ func (p *Parser) parseDefPermutation(module file.Path, elements []sexp.SExp) (as
11491153}
11501154
11511155// Parse a permutation declaration
1152- func (p * Parser ) parseDefSorted (strict bool , elements []sexp.SExp ,
1153- handles map [string ]bool ) (ast.Declaration , []SyntaxError ) {
1156+ func (p * Parser ) parseDefSorted (module file.Path , strict bool , elements []sexp.SExp ) (ast.Declaration , []SyntaxError ) {
11541157 //
11551158 var (
11561159 selector util.Option [ast.Expr ]
@@ -1182,12 +1185,14 @@ func (p *Parser) parseDefSorted(strict bool, elements []sexp.SExp,
11821185 } else {
11831186 handle = elements [1 ].AsSymbol ().Value
11841187 }
1188+ // Generate qualified name
1189+ qualifiedHandle := fmt .Sprintf ("%s:%s" , module .String (), handle )
11851190 // Check for duplicate handle
1186- if _ , ok := handles [handle ]; ok {
1191+ if _ , ok := p . handles [qualifiedHandle ]; ok {
11871192 return nil , p .translator .SyntaxErrors (elements [1 ], "duplicate handle" )
11881193 } else if len (errors ) == 0 {
11891194 // Record handle
1190- handles [handle ] = true
1195+ p . handles [qualifiedHandle ] = true
11911196 }
11921197 // Check source Expressions
11931198 if sexpSources == nil {
@@ -1327,7 +1332,7 @@ func (p *Parser) parseDefPerspective(module file.Path, elements []sexp.SExp) (as
13271332}
13281333
13291334// Parse a property assertion
1330- func (p * Parser ) parseDefProperty (elements []sexp. SExp , handles map [ string ] bool ) (ast.Declaration , []SyntaxError ) {
1335+ func (p * Parser ) parseDefProperty (module file. Path , elements []sexp. SExp ) (ast.Declaration , []SyntaxError ) {
13311336 var (
13321337 errors []SyntaxError
13331338 assertion int = len (elements ) - 1
@@ -1341,12 +1346,14 @@ func (p *Parser) parseDefProperty(elements []sexp.SExp, handles map[string]bool)
13411346 // Extract handle
13421347 handle = elements [1 ].AsSymbol ().Value
13431348 }
1349+ // Generate qualified name
1350+ qualifiedHandle := fmt .Sprintf ("%s:%s" , module .String (), handle )
13441351 // Check for duplicate handle
1345- if _ , ok := handles [handle ]; ok {
1352+ if _ , ok := p . handles [qualifiedHandle ]; ok {
13461353 return nil , p .translator .SyntaxErrors (elements [1 ], "duplicate handle" )
13471354 } else if len (errors ) == 0 {
13481355 // Record handle
1349- handles [handle ] = true
1356+ p . handles [qualifiedHandle ] = true
13501357 }
13511358 // Check for any attributes
13521359 if len (elements ) > 3 {
0 commit comments