/
RakudoCodeRef.cs
172 lines (147 loc) · 6.23 KB
/
RakudoCodeRef.cs
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Rakudo.Runtime;
using Rakudo.Runtime.Exceptions;
namespace Rakudo.Metamodel.Representations
{
/// <summary>
/// A representation for a low-level code object (something that actually
/// references a piece of code that we'll run). This is used for things
/// that serve the role of an only sub (that has a body) and a dispatcher
/// (which has a body as well as a list of candidates that it operates
/// on).
/// </summary>
public sealed class RakudoCodeRef : Representation
{
/// <summary>
/// Instance that uses the RakudoCodeRef representation.
/// </summary>
public sealed class Instance : RakudoObject
{
/// <summary>
/// The code body - the thing that actually runs instructions.
/// </summary>
public Func<ThreadContext, RakudoObject, RakudoObject, RakudoObject> Body;
/// <summary>
/// The static lexpad.
/// </summary>
public Lexpad StaticLexPad;
/// <summary>
/// Our static outer block.
/// </summary>
public Instance OuterBlock;
/// <summary>
/// Signature object.
/// </summary>
public Signature Sig;
/// <summary>
/// Exception handlers this block has, if any.
/// </summary>
public Handler[] Handlers;
/// <summary>
/// If this is a dispatcher, this is the list of dispatchees that
/// it will operate over.
/// </summary>
public RakudoObject[] Dispatchees;
/// <summary>
/// The context currently using this sub.
/// </summary>
public Context CurrentContext;
/// <summary>
/// The outer context to use for the next invocation, if any.
/// </summary>
public Context OuterForNextInvocation;
/// <summary>
/// Creates a new instance with the given S-Table.
/// </summary>
/// <param name="STable"></param>
public Instance(SharedTable STable)
{
this.STable = STable;
}
}
/// <summary>
/// Create a new type object.
/// </summary>
/// <param name="MetaPackage"></param>
/// <returns></returns>
public override RakudoObject type_object_for(ThreadContext TC, RakudoObject MetaPackage)
{
// Do the usual bits of setup for the type-object.
var STable = new SharedTable();
STable.HOW = MetaPackage;
STable.REPR = this;
STable.WHAT = new Instance(STable);
// Also twiddle the S-Table's Invoke to invoke the contained
// function.
STable.Invoke = (TCi, Obj, Cap) =>
((RakudoCodeRef.Instance)Obj).Body(TCi, Obj, Cap);
return STable.WHAT;
}
/// <summary>
/// Creates an instance of the type with the given type object.
/// </summary>
/// <param name="WHAT"></param>
/// <returns></returns>
public override RakudoObject instance_of(ThreadContext TC, RakudoObject WHAT)
{
var Object = new Instance(WHAT.STable);
return Object;
}
/// <summary>
/// Determines if the representation is defined or not.
/// </summary>
/// <param name="Obj"></param>
/// <returns></returns>
public override bool defined(ThreadContext TC, RakudoObject Obj)
{
return ((Instance)Obj).Body != null;
}
public override RakudoObject get_attribute(ThreadContext TC, RakudoObject Object, RakudoObject ClassHandle, string Name)
{
throw new InvalidOperationException("RakudoCodeRef objects cannot store additional attributes.");
}
public override RakudoObject get_attribute_with_hint(ThreadContext TC, RakudoObject Object, RakudoObject ClassHandle, string Name, int Hint)
{
throw new InvalidOperationException("RakudoCodeRef objects cannot store additional attributes.");
}
public override void bind_attribute(ThreadContext TC, RakudoObject Object, RakudoObject ClassHandle, string Name, RakudoObject Value)
{
throw new InvalidOperationException("RakudoCodeRef objects cannot store additional attributes.");
}
public override void bind_attribute_with_hint(ThreadContext TC, RakudoObject Object, RakudoObject ClassHandle, string Name, int Hint, RakudoObject Value)
{
throw new InvalidOperationException("RakudoCodeRef objects cannot store additional attributes.");
}
public override int hint_for(ThreadContext TC, RakudoObject ClassHandle, string Name)
{
return Hints.NO_HINT;
}
public override void set_int(ThreadContext TC, RakudoObject Object, int Value)
{
throw new InvalidOperationException("This type of representation cannot box a native int");
}
public override int get_int(ThreadContext TC, RakudoObject Object)
{
throw new InvalidOperationException("This type of representation cannot unbox to a native int");
}
public override void set_num(ThreadContext TC, RakudoObject Object, double Value)
{
throw new InvalidOperationException("This type of representation cannot box a native num");
}
public override double get_num(ThreadContext TC, RakudoObject Object)
{
throw new InvalidOperationException("This type of representation cannot unbox to a native num");
}
public override void set_str(ThreadContext TC, RakudoObject Object, string Value)
{
throw new InvalidOperationException("This type of representation cannot box a native string");
}
public override string get_str(ThreadContext TC, RakudoObject Object)
{
throw new InvalidOperationException("This type of representation cannot unbox to a native string");
}
}
}