summaryrefslogtreecommitdiff
path: root/etc/setfallback.lua
blob: 783b8667d73d5346a35a3fa861c76cdcb0b8460c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
--------------------------------------------------------------
-- Definition of "setfallback" using tag methods
-- (for compatibility with old code)
--------------------------------------------------------------


-- default fallbacks for each event:
local defaults = {
  gettable = function () error('indexed expression not a table') end,
  settable = function () error('indexed expression not a table') end,
  index = function () return nil end,
  getglobal = function () return nil end,
  arith = function () error('number expected in arithmetic operation') end,
  order = function () error('incompatible types in comparison') end,
  concat = function () error('string expected in concatenation') end,
  gc = function () return nil end,
  ['function'] = function () error('called expression not a function') end,
  error = function (s) write(_STDERR, s, '\n') end,
}


function setfallback (name, func)

  -- set the given function as the tag method for all "standard" tags
  -- (since some combinations may cause errors, use call to avoid messages)
  local fillvalids = function (n, func)
    call(settagmethod, {0, n, func}, 'x', nil)
    call(settagmethod, {tag(0), n, func}, 'x', nil)
    call(settagmethod, {tag(''), n, func}, 'x', nil)
    call(settagmethod, {tag{}, n, func}, 'x', nil)
    call(settagmethod, {tag(function () end), n, func}, 'x', nil)
    call(settagmethod, {tag(settagmethod), n, func}, 'x', nil)
    call(settagmethod, {tag(nil), n, func}, 'x', nil)
  end

  assert(type(func) == 'function')
  local oldfunc
  if name == 'error' then
    oldfunc = seterrormethod(func)
  elseif name == 'getglobal' then
    oldfunc = settagmethod(tag(nil), 'getglobal', func)
  elseif name == 'arith' then
    oldfunc = gettagmethod(tag(0), 'pow')
    foreach({"add", "sub", "mul", "div", "unm", "pow"},
            function(_, n) %fillvalids(n, %func) end)
  elseif name == 'order' then
    oldfunc = gettagmethod(tag(nil), 'lt')
    foreach({"lt", "gt", "le", "ge"},
            function(_, n) %fillvalids(n, %func) end)
  else
    oldfunc = gettagmethod(tag(nil), name)
    fillvalids(name, func)
  end
  return oldfunc or rawgettable(%defaults, name)
end