forked from jnthn/6model
/
Dispatch.lua
73 lines (66 loc) · 2.61 KB
/
Dispatch.lua
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
function Ops.multi_dispatch_over_lexical_candidates (TC)
local CurOuter = TC.CurrentContext;
while (CurOuter ~= nil) do
local CodeObj = CurOuter.StaticCodeObject;
if (CodeObj.Dispatchees ~= nil) then
local Candidate = MultiDispatch.MultiDispatcher.FindBestCandidate(TC,
CodeObj, CurOuter.Capture);
local STable = Candidate.STable;
return STable.Invoke(STable, TC, Candidate, CurOuter.Capture);
end
CurOuter = CurOuter.Outer;
end
error("Could not find dispatchee list!");
end
Ops[35] = Ops.multi_dispatch_over_lexical_candidates;
function Ops.set_dispatchees (TC, CodeObject, Dispatchees)
CodeObject.Dispatchees = Dispatchees.Storage;
return CodeObject;
end
Ops[36] = Ops.set_dispatchees;
function Ops.create_dispatch_and_add_candidates (TC, ToInstantiate, ExtraDispatchees)
-- Make sure we got the right things.
local Source = ToInstantiate;
local AdditionalDispatchList = ExtraDispatchees;
-- Clone all but SC (since it's a new object and doesn't live in any
-- SC yet) and dispatchees (which we want to munge).
local NewDispatch = RakudoCodeRef.Instance.new(Source.STable);
NewDispatch.Body = Source.Body;
NewDispatch.CurrentContext = Source.CurrentContext;
NewDispatch.Handlers = Source.Handlers;
NewDispatch.OuterBlock = Source.OuterBlock;
NewDispatch.OuterForNextInvocation = Source.OuterForNextInvocation;
NewDispatch.Sig = Source.Sig;
NewDispatch.StaticLexPad = Source.StaticLexPad;
-- Take existing candidates and add new ones.
NewDispatch.Dispatchees = List.create(Source.Dispatchees.Count);
local i = 1;
for j = 1, Source.Dispatchees.Count do
NewDispatch.Dispatchees[i] = Source.Dispatchees[j];
i = i + 1;
end
for j = 1, AdditionalDispatchList.Storage.Count do
NewDispatch.Dispatchees[i] = AdditionalDispatchList.Storage[j];
i = i + 1;
end
return NewDispatch;
end
Ops[37] = Ops.create_dispatch_and_add_candidates;
function Ops.push_dispatchee (TC, Dispatcher, Dispatchee)
local Target = Dispatcher;
if (Target.Dispatchees == nil) then
error("push_dispatchee passed something that is not a dispatcher");
end
List.Add(Target.Dispatchees, Dispatchee);
return Target;
end
Ops[38] = Ops.push_dispatchee;
function Ops.is_dispatcher (TC, Check)
local Checkee = Check;
if (Checkee ~= nil and Checkee.Dispatchees ~= nil) then
return Ops.box_int(TC, 1, TC.DefaultBoolBoxType);
else
return Ops.box_int(TC, 0, TC.DefaultBoolBoxType);
end
end
Ops[39] = Ops.is_dispatcher;