diff options
author | Martin Peach <mrpeach@users.sourceforge.net> | 2011-03-15 20:53:57 +0000 |
---|---|---|
committer | Martin Peach <mrpeach@users.sourceforge.net> | 2011-03-15 20:53:57 +0000 |
commit | 267170167d52cab9e97f879d9127a1cf04f6bb58 (patch) | |
tree | 00260a90ce6472e34c5eff41602af57595c8830d /examples/ltabfill.pd_lua |
This is a version of Claude Heiland-Allen's lua for Pd. The objects are named pdlua and pdluax instead of lua and luax. So far it seems to work on linux.svn2git-root
svn path=/trunk/externals/pdlua/; revision=15030
Diffstat (limited to 'examples/ltabfill.pd_lua')
-rw-r--r-- | examples/ltabfill.pd_lua | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/examples/ltabfill.pd_lua b/examples/ltabfill.pd_lua new file mode 100644 index 0000000..56ef81b --- /dev/null +++ b/examples/ltabfill.pd_lua @@ -0,0 +1,156 @@ +local ltabfill = pd.Class:new():register("ltabfill") + +local function sandbox(e, f, x) -- only supports unary f() with one return + local g = getfenv(f) + setfenv(f, e) + local r = f(x) + setfenv(f, g) + return r +end + +local ltabfill_globals = { + abs = math.abs, + acos = math.acos, + asin = math.asin, + atan = math.atan, + atan2 = math.atan2, + ceil = math.ceil, + cos = math.cos, + cosh = math.cosh, + deg = math.deg, + exp = math.exp, + floor = math.floor, + fmod = math.fmod, + log = math.log, + log10 = math.log10, + max = math.max, + min = math.min, + int = function (x) i,f = math.modf(x) ; return i end, + wrap = function (x) i,f = math.modf(x) ; return f end, + pi = math.pi, + pow = math.pow, + rad = math.rad, + sin = math.sin, + sinh = math.sinh, + sqrt = math.sqrt, + tan = math.tan, + tanh = math.tanh, + val = function (s) return (pd.getvalue(s) or 0) end +} + +function ltabfill:readexpr(atoms) + local vname = { } + local context = { } + local expr + local i + local k + local v + local j = 2 + local inlets + local f + local phase = "table" + for k,v in pairs(ltabfill_globals) do + context[k] = v + end + for i,v in ipairs(atoms) do + if phase == "table" then + if type(v) == "string" then + self.tabname = v + phase = "vars" + else + self:error("ltabfill: table name must be a symbol") + return -1 + end + else if phase == "vars" then -- create variables + if v == "->" then + inlets = i - 1 + phase = "expr" + expr = "" + else + if type(v) == "string" then + vname[j] = v + context[v] = 0 + j = j + 1 + else + self:error("ltabfill: variable names must be symbols") + return -1 + end + end + else if phase == "expr" then -- build string + expr = expr .. " " .. v + else + self:error("ltabfill: internal error parsing expression") + return -1 + end end end + end + f = assert(loadstring("return function(x) return " .. expr .. " end"))() + return inlets, vname, context, f, 0 +end + +function ltabfill:initialize(sel, atoms) + self.tabname = nil + self.vname = { } + self.context = { } + self.hot = { } + self.f = function (x) return 0 end + function self:in_1_bang() + if self.tabname ~= nil then + local t = pd.Table:new():sync(self.tabname) + if t ~= nil then + local i + local l = t:length() + for i = 1,l do + local y = sandbox(self.context, self.f, (i-1)/l) + t:set(i-1, y) + end + t:redraw() + end + end + end + function self:in_1_symbol(s) + self.tabname = s + if self.hot[1] then self:in_1_bang() end + end + function self:in_1_float(f) + self:error("table name expected, got a float") + end + function self:in_n_float(i, f) + self.context[self.vname[i]] = f + if self.hot[i] then self:in_1_bang() end + end + function self:in_n_symbol(i, s) + self.context[self.vname[i]] = s + if self.hot[i] then self:in_1_bang() end + end + function self:in_n_hot(i, atoms) + if type(atoms[1]) == "number" then + self.hot[i] = atoms[1] ~= 0 + else + self:error("hot method expects a float") + end + end + function self:in_1_ltabfill(atoms) + local inlets + local vname + local context + local f + local outlets + inlets, vname, context, f, outlets = self:readexpr(atoms) + if (inlets == self.inlets) and (outlets == self.outlets) then + self.vname = vname + self.context = context + self.f = f + else + self:error("new expression has different inlet/outlet count") + end + end + self.inlets, self.vname, self.context, self.f, self.outlets = self:readexpr(atoms) + if self.inlets < 1 then + pd.post("ltabfill: error: would have no inlets") + return false + end + for i = 1,self.inlets,1 do + self.hot[i] = i == 1 + end + return true +end |