@@ -227,15 +227,23 @@ attribute node_symbol = node => symbol = (source-text node), source_n
227227}
228228
229229(program)@prog {
230- ; propagate lexical scope
231- edge @prog.lexical_scope -> ROOT_NODE
232-
233230 ; expose definitions
234231 edge @prog.lexical_scope -> @prog.defs
232+
233+ ; import builtins
234+ node builtins_ref__ns
235+ attr (builtins_ref__ns) symbol_reference = "%Proj"
236+ edge builtins_ref__ns -> ROOT_NODE
237+ ;
238+ node builtins_ref
239+ attr (builtins_ref) symbol_reference = "<builtins>"
240+ edge builtins_ref -> builtins_ref__ns
241+ ;
242+ edge @prog.lexical_scope -> builtins_ref
235243}
236244
237245;; Project and module definitions
238- (program)@prog {
246+ (program [(import_statement) (export_statement)]* @imexs )@prog {
239247 var proj_scope = ROOT_NODE
240248 if (not (eq PROJECT_NAME "")) {
241249 ; project definition
@@ -250,35 +258,39 @@ attribute node_symbol = node => symbol = (source-text node), source_n
250258 set proj_scope = proj_def
251259 }
252260
253- ; module definition
254- let mod_name = (path-filestem FILE_PATH)
255- let mod_path = (path-normalize (path-join (path-dir FILE_PATH) mod_name))
256- ;
257- node mod_def__ns
258- attr (mod_def__ns) pop_symbol = "%M"
259- edge proj_scope -> mod_def__ns
260- ;
261- var mod_scope = mod_def__ns
262- scan mod_path {
263- "index$" {
264- ; skip last component for index files
265- }
266- "([^/]+)/?" {
267- node mod_def
268- attr (mod_def) pop_symbol = $1
269- edge mod_scope -> mod_def
270- ;
271- set mod_scope = mod_def
261+ var mod_scope = proj_scope
262+ if (not (is-empty @imexs)) {
263+ ; module definition
264+ let mod_name = (path-filestem FILE_PATH)
265+ let mod_path = (path-normalize (path-join (path-dir FILE_PATH) mod_name))
266+ ;
267+ node mod_def__ns
268+ attr (mod_def__ns) pop_symbol = "%M"
269+ edge mod_scope -> mod_def__ns
270+ set mod_scope = mod_def__ns
271+ ;
272+ scan mod_path {
273+ "index$" {
274+ ; skip last component for index files
275+ }
276+ "([^/]+)/?" {
277+ node mod_def
278+ attr (mod_def) pop_symbol = $1
279+ edge mod_scope -> mod_def
280+ set mod_scope = mod_def
281+ }
272282 }
283+ ; make the last one a definition
284+ attr (mod_scope) is_definition, source_node = @prog, empty_source_span
285+ ; expose exports via module definition
286+ edge mod_scope -> @prog.exports
287+ } else {
288+ edge mod_scope -> @prog.defs
273289 }
274- ; make the last one a definition
275- attr (mod_scope) is_definition, source_node = @prog, empty_source_span
276- ; expose exports via module definition
277- edge mod_scope -> @prog.exports
278290}
279291
280292;; Project and module reference
281- (program)@prog {
293+ (program [(import_statement) (export_statement)]* @imexs )@prog {
282294 var proj_scope = ROOT_NODE
283295 if (not (eq PROJECT_NAME "")) {
284296 ; project reference
@@ -291,44 +303,47 @@ attribute node_symbol = node => symbol = (source-text node), source_n
291303 edge proj_ref -> proj_ref__ns
292304 ;
293305 set proj_scope = proj_ref
294- ; compose all project files by adding edge to the project reference
295- edge @prog.lexical_scope -> proj_scope
296306 }
297307
298- ; module reference
299- ;
300- node mod_ref__ns
301- attr (mod_ref__ns) push_symbol = "%M"
302- edge mod_ref__ns -> proj_scope
303- ;
304- let mod_dir = (path-normalize (path-dir FILE_PATH))
305- var mod_scope = mod_ref__ns
306- scan mod_dir {
307- "([^/]+)/?" {
308- node mod_ref
309- attr (mod_ref) push_symbol = $1
310- edge mod_ref -> mod_scope
311-
312- node mod_node
313- edge mod_node -> mod_ref
308+ ; compose all project files by adding edge to the project reference
309+ edge @prog.lexical_scope -> proj_scope
314310
315- node parent_def
316- attr (parent_def) pop_symbol = ".."
317- edge parent_def -> mod_scope
318- edge mod_node -> parent_def
319- attr (mod_node -> parent_def) precedence = 1 ; consume dots eagerly
320-
321- set mod_scope = mod_node
311+ var mod_scope = proj_scope
312+ if (not (is-empty @imexs)) {
313+ ; module reference
314+ node mod_ref__ns
315+ attr (mod_ref__ns) push_symbol = "%M"
316+ edge mod_ref__ns -> mod_scope
317+ set mod_scope = mod_ref__ns
318+ ;
319+ let mod_dir = (path-normalize (path-dir FILE_PATH))
320+ scan mod_dir {
321+ "([^/]+)/?" {
322+ node mod_ref
323+ attr (mod_ref) push_symbol = $1
324+ edge mod_ref -> mod_scope
325+
326+ node mod_node
327+ edge mod_node -> mod_ref
328+
329+ node parent_def
330+ attr (parent_def) pop_symbol = ".."
331+ edge parent_def -> mod_scope
332+ edge mod_node -> parent_def
333+ attr (mod_node -> parent_def) precedence = 1 ; consume dots eagerly
334+
335+ set mod_scope = mod_node
336+ }
322337 }
323- }
324338
325- ; relative import definition
326- node rel_def
327- attr (rel_def) pop_symbol = "%RelM"
328- edge rel_def -> mod_scope
339+ ; relative import definition
340+ node rel_def
341+ attr (rel_def) pop_symbol = "%RelM"
342+ edge rel_def -> mod_scope
329343
330- ; expose reference in lexical scope
331- edge @prog.lexical_scope -> rel_def
344+ ; expose reference in lexical scope
345+ edge @prog.lexical_scope -> rel_def
346+ }
332347}
333348
334349(program
@@ -345,13 +360,6 @@ attribute node_symbol = node => symbol = (source-text node), source_n
345360 edge @prog.exports -> @stmt.exports
346361}
347362
348- (program [(import_statement) (export_statement)]* @imexs)@prog {
349- if (is-empty @imexs) {
350- ; expose global definitions in ROOT_NODE
351- edge ROOT_NODE -> @prog.defs
352- }
353- }
354-
355363
356364;; hashbang
357365
@@ -6129,5 +6137,5 @@ if none @is_acc {
61296137 edge @async.async_type__promise_ref -> @async.async_type__promise_ref__ns
61306138 ;
61316139 attr (@async.async_type__promise_ref__ns) push_symbol = "%T"
6132- edge @async.async_type__promise_ref__ns -> ROOT_NODE
6140+ edge @async.async_type__promise_ref__ns -> @async.lexical_scope
61336141}
0 commit comments