]> git.lizzy.rs Git - metalua.git/blob - src/lib/metalua/walk/bindings.mlua
f457e81cfa2a8d1374c027951b34b014a22602da
[metalua.git] / src / lib / metalua / walk / bindings.mlua
1 require 'walk'
2
3 function bindings(ast)
4    -- binders :: ast  => name => occurences
5    -- unbound :: name => occurences
6    -- scope   :: name => ast
7
8    local bound_id, unbound, cfg, scope = { }, { }, { scope={ } }, scope:new()
9
10    -- * id: identifier entering in scope
11    -- * ast: statement or expr carrying this id, on of:
12    --        Local, Localrec, Forin, Fornum, Function.
13    function cfg.binder (id, ast)
14       local id_name = id[1]
15       scope.current[id[1]] = ast
16    end
17    
18    -- identifier occurence, not as a binder: reference this occurence
19    function cfg.Id (id)
20       local id_name = id[1]
21       local binder = scope.current[id_name]
22       if binder then bound_id[id] = binder
23       else 
24          local occ = scope.current[id_name]free_id[id_name]
25          if occ then table.insert (occ, id)
26          else free_id[id_name] = { id } end
27       end
28    end
29
30    function cfg.scope.down() scope:push() end
31
32    function cfg.scope.up() scope:pop() end
33
34    walk.guess (cfg, ast)
35    return bound_id, free_id
36 end