]> git.lizzy.rs Git - metalua.git/commitdiff
simpler bindings analysis: works on simple cases
authorFabien Fleutot <metalua@gmail.com>
Thu, 19 Feb 2009 17:38:19 +0000 (18:38 +0100)
committerFabien Fleutot <metalua@gmail.com>
Thu, 19 Feb 2009 17:38:19 +0000 (18:38 +0100)
src/lib/metalua/walk/bindings.mlua

index f457e81cfa2a8d1374c027951b34b014a22602da..32b41a77905cf4e9160aa92519d50cd1e1ea47a4 100644 (file)
@@ -1,36 +1,41 @@
-require 'walk'
+require 'metalua.walk'
+require 'metalua.walk.scope'
 
 function bindings(ast)
    -- binders :: ast  => name => occurences
    -- unbound :: name => occurences
    -- scope   :: name => ast
 
-   local bound_id, unbound, cfg, scope = { }, { }, { scope={ } }, scope:new()
+   local binders, unbound, cfg, scope = { }, { }, { scope={ } }, scope:new()
 
    -- * id: identifier entering in scope
    -- * ast: statement or expr carrying this id, on of:
    --        Local, Localrec, Forin, Fornum, Function.
    function cfg.binder (id, ast)
       local id_name = id[1]
-      scope.current[id[1]] = ast
+      -- Reference in scope, so that the binding statement can be retrieved:
+      scope.current[id_name] = ast
+      -- Init the occurences list for this identifier:
+      if binders[ast] then binders[ast][id_name] = { }
+      else binders[ast] = { [id_name] = { } } end
    end
    
    -- identifier occurence, not as a binder: reference this occurence
    function cfg.Id (id)
       local id_name = id[1]
-      local binder = scope.current[id_name]
-      if binder then bound_id[id] = binder
-      else 
-         local occ = scope.current[id_name]free_id[id_name]
-         if occ then table.insert (occ, id)
-         else free_id[id_name] = { id } end
-      end
+      -- ast which binds this id, might be nil:
+      local binder_ast = scope.current [id_name] 
+      -- dict id_name => occurences, might be the list of unbound occurences:
+      local occur_dict = binder_ast and binders[binder_ast] or unbound
+      -- add an occurence of `id' in the occurences list:
+      local occurences = occur_dict [id_name]
+      if occurences then table.insert (occurences, id) 
+      else occur_dict [id_name] = { id } end
    end
 
    function cfg.scope.down() scope:push() end
-
-   function cfg.scope.up() scope:pop() end
+   function cfg.scope.up()   scope:pop()  end
 
    walk.guess (cfg, ast)
-   return bound_id, free_id
+   return binders, unbound
 end
\ No newline at end of file