2 require 'metalua.walk.scope'
5 -- binders :: ast => name => occurences
6 -- unbound :: name => occurences
7 -- scope :: name => ast
9 local binders, unbound, cfg, scope = { }, { }, { scope={ } }, scope:new()
11 -- * id: identifier entering in scope
12 -- * ast: statement or expr carrying this id, on of:
13 -- Local, Localrec, Forin, Fornum, Function.
14 function cfg.binder (id, ast)
16 -- Reference in scope, so that the binding statement can be retrieved:
17 scope.current[id_name] = ast
18 -- Init the occurences list for this identifier:
19 if binders[ast] then binders[ast][id_name] = { }
20 else binders[ast] = { [id_name] = { } } end
23 -- identifier occurence, not as a binder: reference this occurence
26 -- ast which binds this id, might be nil:
27 local binder_ast = scope.current [id_name]
28 -- dict id_name => occurences, might be the list of unbound occurences:
29 local occur_dict = binder_ast and binders[binder_ast] or unbound
30 -- add an occurence of `id' in the occurences list:
31 local occurences = occur_dict [id_name]
32 if occurences then table.insert (occurences, id)
33 else occur_dict [id_name] = { id } end
36 function cfg.scope.down() scope:push() end
37 function cfg.scope.up() scope:pop() end
40 return binders, unbound