From 0029c3d1007a0e692719efde5aa4252004a75ad5 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sun, 27 May 2012 22:26:24 +0000 Subject: gates 0.2 (27may12) git-svn-id: svn://tug.org/texlive/trunk@26675 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/tex/generic/gates/gates.lua | 243 ++++++++++++++---------- Master/texmf-dist/tex/generic/gates/gates.sty | 4 +- Master/texmf-dist/tex/generic/gates/t-gates.tex | 4 +- 3 files changed, 147 insertions(+), 104 deletions(-) (limited to 'Master/texmf-dist/tex/generic/gates') diff --git a/Master/texmf-dist/tex/generic/gates/gates.lua b/Master/texmf-dist/tex/generic/gates/gates.lua index d5ea2c4ae88..826e1a13f3c 100644 --- a/Master/texmf-dist/tex/generic/gates/gates.lua +++ b/Master/texmf-dist/tex/generic/gates/gates.lua @@ -5,7 +5,7 @@ -- Author: Paul Isambert. -- E-mail: zappathustra AT free DOT fr -- Comments and suggestions are welcome. --- Date: December 2011. +-- Date: May 2012. if gates then return @@ -22,16 +22,32 @@ else end print_error = error end -local unpack = table.unpack or unpack +local unpack, maxn = table.unpack or unpack +if lua.version == "Lua 5.1" then + maxn = table.maxn +else + local pairs, type = pairs, type + function maxn (t) + local max = 0 + for i in pairs(t) do + if type(i) == "number" then + max = i > max and i or max + end + end + return max + end +end +local function unpackargs (t) + return unpack(t, 1, maxn(t)) +end local function _copy (tb) local t = {} for a, b in pairs (tb) do if type(b) == "table" then - t[a] = _copy(b) - else - t[a] = b + b = _copy(b) end + t[a] = b end return t end @@ -97,13 +113,22 @@ local function _getinfo (g) local c = tostring(g.conditional) local l = g.loop and tostring(g.loop) local u = g.loopuntil and tostring(g.loopuntil) - local a = g.autoreturn and " (autoreturn)" or "" - return s, c, l, u, a + local i = g.iterator and tostring(g.iterator) + local a + if type(g.autoreturn) == "function" then + a = " (autoreturn: " .. tostring (g.autoreturn) .. ")" + elseif g.autoreturn then + a = " (autoreturn)" + else + a = "" + end + return s, c, l, u, i, a end +local shown local function _show (gate, tab) local g = _rawgate(gate.name) - local s, c, l, u, a = _getinfo(gate) + local s, c, l, u, i, a = _getinfo(gate) local info = _format(tab .. "%s (%s-gate) (status: %s) (conditional: %s)%s", gate.name, g.list and "l" or "m", s, c, a) if l then @@ -112,15 +137,24 @@ local function _show (gate, tab) if u then info = _format(info .. " (loopuntil: %s)", u) end + if i then + info = _format(info .. " (iterator: %s)", i) + end _write(info) if g.list then - for _, G in ipairs(g.list) do - _show(G, tab .. ". ") + if shown[g.name] then + texio.write(" [subgates already shown]") + else + shown[g.name] = true + for _, G in ipairs(g.list) do + _show(G, tab .. ". ") + end end end end local function show (fam, name) + shown = {} name = _check_family(fam, name) local g = _rawgate(name) if g then @@ -163,7 +197,8 @@ local function _getmax (tb) return max end local function _restoreargs (arg, orarg, autoreturn) - if autoreturn then + -- autoreturn may be a function + if autoreturn == true then local argmax, orargmax = _getmax(arg), _getmax(orarg) for i = argmax + 1, orargmax do arg[i] = orarg[i] @@ -171,65 +206,93 @@ local function _restoreargs (arg, orarg, autoreturn) end return arg end +local function _processfunction (fct, autoreturn, ...) + if type(autoreturn) == "function" then + return {autoreturn(...)} + elseif autoreturn then + local newarg = {fct(...)} + local argmax, newargmax = _getmax(arg), _getmax(newarg) + for i = newargmax + 1, argmax do + newarg[i] = arg[i] + end + return newarg + else + return {fct(...)} + end +end -execute.__index = function (_, name) - local f = _rawgate(name) - if f then - return function (...) - local s = "" - if f.status == _open or f.status == _ajar then - if f.status == _ajar then - s = " (ajar -> close)" - f.status = _close +local function _execute (f, sub, ...) + local name, list, fct, status, conditional, loop, loopuntil, iterator, autoreturn = + f.name, f.list, sub and execute[f.name] or f.fct, f.status, f.conditional, f.loop, f.loopuntil, f.iterator, f.autoreturn + local action, report, t + if sub then + action, report, t = "Calling", _reporttab, "subgate " .. name + else + action, report, t = "Executing", _report, (list and "l" or "m") .. "-gate " .. name + end + local s = "" + local orarg, arg = {...}, {...} + if status == _open or status == _ajar then + if status == _ajar then + s = " (ajar -> close)" + f.status = _close + end + if conditional(...) then + report(name, "%s %s%s", action, t, s) + if not sub and not list and _trace_value(name) > 1 then + for i=1, maxn(arg) do + _write_nl(_white .. "#" .. i .. "<-" .. tostring(arg[i])) end - if f.conditional(...) then - _report(name, "Executing %s-gate %s", f.list and "l" or "m", name, s) - if not f.list and _trace_value(name) > 1 then - local arg = _copy({...}) - for a, b in pairs(arg) do - arg[a] = b - for i = 1, a-1 do - arg[i] = arg[i] or "nil" - end - end - for a, b in ipairs(arg) do - b = tostring(b) - -- Can't use _write(), because it calls string.format(), - -- and b might contain literal %'s. - _write_nl(_white .. "#" .. a .. "<-" .. b) - end - end - local orarg, arg = {...}, {...} - if f.loop then - while f.loop(unpack(arg)) do - arg = {f.fct(unpack(arg))} - orarg = _restoreargs(arg, orarg, f.autoreturn) - end - return unpack(arg) - elseif f.loopuntil then - repeat - arg = {f.fct(unpack(arg))} - orarg = _restoreargs(arg, orarg, f.autoreturn) - until f.loopuntil(unpack(arg)) - return unpack(arg) + end + if loop then + while loop(unpackargs(arg)) do + arg = {fct(unpackargs(arg))} + orarg = _restoreargs(arg, orarg, autoreturn) + end + elseif loopuntil then + repeat + arg = {fct(unpackargs(arg))} + orarg = _restoreargs(arg, orarg, autoreturn) + until loopuntil(unpackargs(arg)) + elseif iterator then + local iter, state, var = iterator(unpackargs(arg)) + while iter do + local args = {iter(state, var)} + if args[1] ~= nil then + arg = {fct(unpackargs(args))} + orarg = _restoreargs(arg, orarg, autoreturn) + var = args[1] else - arg = {f.fct(unpack(arg))} - orarg = _restoreargs(arg, orarg, f.autoreturn) - return unpack(arg) + break end - else - _report(name, "Ignoring %s-gate %s%s (False conditional)", f.list and "l" or "m", name, s) end else - if f.status == _skip then - s = " (skip -> open)" - f.status = _open - else - s = " (close)" - end - _report(name, "Ignoring %s-gate %s%s%s", f.list and "l" or "m", name, s, f.conditional() and "" or " (False conditional)") - return ... + arg = {fct(unpackargs(arg))} + orarg = _restoreargs(arg, orarg, autoreturn) end + if type(autoreturn) == "function" then + arg = {autoreturn(...)} + end + else + report(name, "Ignoring %s%s (False conditional)", t, s) + end + else + if status == _skip then + s = " (skip -> open)" + f.status = _open + else + s = " (close)" + end + report(name, "Ignoring %s%s%s", t, s, conditional() and "" or " (False conditional)") + end + return unpackargs(arg) +end + +execute.__index = function (_, name) + local f = _rawgate(name) + if f then + return function (...) + return _execute(f, nil, ...) end else _error_nogate(name) @@ -454,6 +517,14 @@ local function loopuntil (fam, fct, list, cond) end end +local function iterator (fam, fct, list, cond) + if type(list) == "string" then + _status(fam, fct, list, "iterator", cond) + else + _status(fam, fct, nil, "iterator", list) + end +end + local function autoreturn (fam, fct, list, cond) if type(list) == "string" then _status(fam, fct, list, "autoreturn", cond) @@ -472,50 +543,18 @@ local function _store (tab) conditional = tab.conditional or _evertrue, loop = tab.loop, loopuntil = tab.loopuntil, + iterator = tab.iterator, autoreturn = tab.autoreturn} if not fct then tb.list = {} fct = function (...) _addtab() - local orarg, arg = {...}, {...} + local arg = {...} for n, func in ipairs(tb.list) do - local s = "" - if func.status == _open or func.status == _ajar then - if func.status == _ajar then - s = " (ajar -> close)" - func.status = _close - end - if func.conditional(unpack(arg)) then - _reporttab(func.name, "Calling subgate %s%s", func.name, s) - if func.loop then - while func.loop(unpack(arg)) do - arg = {execute[func.name](unpack(arg))} - orarg = _restoreargs(arg, orarg, func.autoreturn) - end - elseif func.loopuntil then - repeat - arg = {execute[func.name](unpack(arg))} - orarg = _restoreargs(arg, orarg, func.autoreturn) - until func.loopuntil(unpack(arg)) - else - arg = {execute[func.name](unpack(arg))} - orarg = _restoreargs(arg, orarg, func.autoreturn) - end - else - _reporttab(func.name, "Ignoring subgate %s%s (False conditional)", func.name, s) - end - else - if func.status == _skip then - s = " (skip -> open)" - tb.list[n].status = _open - else - s = " (close)" - end - _reporttab(func.name, "Ignoring subgate %s%s%s", func.name, s, func.conditional() and "" or " (False conditional)") - end + arg = {_execute(func, true, unpackargs(arg))} end _untab() - return unpack(arg) + return unpackargs(arg) end end tb.fct = fct @@ -540,7 +579,7 @@ local function list (fam, tab) g[1] = _check_family(fam, g[1]) if type(g[2]) == "function" then _store({g[1], g[2]}) - elseif type(g[2]) == "table" then + elseif type(g[2]) == "table" or type(g[2]) == "string" then local a = {} for i = 2, #g do _insert(a, g[i]) @@ -562,6 +601,8 @@ local function list (fam, tab) _status(fam, g[1], tab[1], "loop", l) local L = type(g.loopuntil) == "function" and g.loopuntil _status(fam, g[1], tab[1], "loopuntil", L) + local I = type(g.iterator) == "function" and g.iterator + _status(fam, g[1], tab[1], "iterator", I) _status(fam, g[1], tab[1], "autoreturn", g.autoreturn) end end @@ -580,6 +621,7 @@ local function copy (fam, name1, name2) _status(fam, name1, nil, "conditional", base.conditional) _status(fam, name1, nil, "loop", base.loop) _status(fam, name1, nil, "loopuntil", base.loopuntil) + _status(fam, name1, nil, "iterator", base.iterator) else _error_nogate(name2) end @@ -632,6 +674,7 @@ local _mt = { conditional = conditional, loop = loop, loopuntil = loopuntil, + iterator = iterator, autoreturn = autoreturn, subgates = subgates, } diff --git a/Master/texmf-dist/tex/generic/gates/gates.sty b/Master/texmf-dist/tex/generic/gates/gates.sty index 28152eacb60..61d725b0a6a 100644 --- a/Master/texmf-dist/tex/generic/gates/gates.sty +++ b/Master/texmf-dist/tex/generic/gates/gates.sty @@ -5,10 +5,10 @@ % Author: Paul Isambert. % E-mail: zappathustra AT free DOT fr % Comments and suggestions are welcome. -% Date: December 2011. +% Date: May 2012. \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{gates}[2011/12/03 v.0.1 Modular architecture.] +\ProvidesPackage{gates}[2012/05/26 v.0.2 Modular architecture.] \chardef\formatnumber=4 \input gates.tex \endinput diff --git a/Master/texmf-dist/tex/generic/gates/t-gates.tex b/Master/texmf-dist/tex/generic/gates/t-gates.tex index 0fb80e8d01b..ff2426cd83d 100644 --- a/Master/texmf-dist/tex/generic/gates/t-gates.tex +++ b/Master/texmf-dist/tex/generic/gates/t-gates.tex @@ -5,11 +5,11 @@ % Author: Paul Isambert. % E-mail: zappathustra AT free DOT fr % Comments and suggestions are welcome. -% Date: December 2011. +% Date: May 2012. % %D \module %D [ file=t-gates, -%D version=2011.12.03, +%D version=2012.05.26, %D title=\CONTEXT\ User Module, %D subtitle=Gates, %D author=Paul Isambert, -- cgit v1.2.3