-{ extension 'match' } require 'walk.id' ast = +{ block: y = type(1) function foo(x) local type = 'number' assert(x==type or not x) end foo(x) } disp = |msg,ast| printf("\n%s:\n%s", msg, table.tostring(ast, 80, 'nohash')) disp('initial term', ast) require'autotable' do -- Make globals explicit: local ast = table.deep_copy(ast) local cfg = { id = { } } function cfg.id.free(i) i <- `Index{ `Id '_G', `String{i[1]} } return 'break' end walk_id.block(cfg, ast) disp('Globals made explicit', ast) end do -- Alpha rename local vars: local ast = table.deep_copy(ast) local cfg = { id = { } } local translations = autotable() function cfg.id.bound (id, binder) local tmp = translations[id[1]] if not tmp then printf("new tmp for name %s", id[1]) tmp = { } translations[id[i]] = tmp end local new_name = tmp[binder] if not new_name then printf("new name for name %s binder %s", id[1], tostring(binder)) new_name = mlp.gensym('_local_'..id[1]) tmp[binder] = new_name end id[1] = new_name end walk_id.block(cfg, ast) disp('Local alpha-renamed', ast) end --[=[ local varlist_mt = { __index = function (self, key) local x={ }; self[key] = x; return x end } local bound_vars = setmetatable({ }, varlist_mt) local free_vars = setmetatable({ }, varlist_mt) cfg = { id = { bound = |x, binder| table.insert(bound_vars[binder], x), free = |x| table.insert(free_vars[x[1]], x) } } walk_id.block(cfg, x) -- Alpha convert bound variables for binder, occurences in pairs(bound_vars) do local new_name = "_LOCAL_"..occurences[1][1] local cfg = { binder = function (x) x[1]=new_name; return 'break' end } walk.guess(cfg, binder) for occ in ivalues(occurences) do occ[1] = new_name end end -- Alpha convert free variables for name, occurences in pairs(free_vars) do local new_name = "_GLOBAL_"..occurences[1][1] for occ in ivalues(occurences) do occ[1] = new_name end end --]=] --print "\n\n TERM AFTER PARSING:" --table.print(x,60,'nohash')