BadScript 2
Loading...
Searching...
No Matches
BadArrayExtension.cs
Go to the documentation of this file.
11
16
21{
23 protected override void AddExtensions(BadInteropExtensionProvider provider)
24 {
25 provider.RegisterObject<BadArray>("Add",
27 (_, o) => Add(a, o),
29 "elem"
30 )
31 );
32
33 provider.RegisterObject<BadArray>("Clear",
34 a => new BadDynamicInteropFunction("Clear",
35 _ => Clear(a),
37 )
38 );
39
40 provider.RegisterObject<BadArray>("AddRange",
41 a => new BadDynamicInteropFunction<BadObject>("AddRange",
42 (ctx, elems) =>
43 {
44 if (elems is BadArray arr)
45 {
46 a.InnerArray.AddRange(arr.InnerArray);
47 }
49 .IsSuperClassOf(elems.GetPrototype()))
50 {
51 // Get the Enumerator
52 BadObject[] enumerated = BadNativeClassHelper
53 .ExecuteEnumerate(ctx, elems)
54 .ToArray();
55 a.InnerArray.AddRange(enumerated);
56 }
57 else
58 {
59 throw BadRuntimeException.Create(ctx.Scope,
60 "Argument is not of type IEnumerable"
61 );
62 }
63
64 return BadObject.Null;
65 },
67 "elems"
68 )
69 );
70
71 provider.RegisterObject<BadArray>("Insert",
73 (_, i, o) => Insert(a, i, o),
75 new BadFunctionParameter("index", false, true, false, null, BadNativeClassBuilder.GetNative("num")),
76 new BadFunctionParameter("elem", false, true, false, null, BadAnyPrototype.Instance)
77 )
78 );
79
80 provider.RegisterObject<BadArray>("InsertRange",
82 (ctx, num, elems) =>
83 {
84 if (elems is BadArray arr)
85 {
86 a.InnerArray.InsertRange((int)num, arr.InnerArray);
87 }
89 .IsSuperClassOf(elems.GetPrototype()))
90 {
91 // Get the Enumerator
92 BadObject[] enumerated = BadNativeClassHelper
93 .ExecuteEnumerate(ctx, elems)
94 .ToArray();
95 a.InnerArray.InsertRange((int)num, enumerated);
96 }
97 else
98 {
99 throw BadRuntimeException.Create(ctx.Scope,
100 "Argument is not of type IEnumerable"
101 );
102 }
103
104 return BadObject.Null;
105 },
107 "index",
108 "elems"
109 )
110 );
111
112 provider.RegisterObject<BadArray>("Remove",
113 a => new BadDynamicInteropFunction<BadObject>("Remove",
114 (_, o) => Remove(a, o),
116 "elem"
117 )
118 );
119
120 provider.RegisterObject<BadArray>("Contains",
121 a => new BadDynamicInteropFunction<BadObject>("Contains",
122 (_, o) => Contains(a, o),
124 "elem"
125 )
126 );
127
128 provider.RegisterObject<BadArray>("RemoveAt",
129 a => new BadDynamicInteropFunction<decimal>("RemoveAt",
130 (_, o) => RemoveAt(a, o),
132 "index"
133 )
134 );
135
136 provider.RegisterObject<BadArray>("Get",
138 (_, o) => Get(a, o),
140 "index"
141 )
142 );
143
144 provider.RegisterObject<BadArray>("Set",
146 (_, i, v) => Set(a, i, v),
148 new BadFunctionParameter("index", false, true, false, null, BadNativeClassBuilder.GetNative("num")),
149 new BadFunctionParameter("elem", false, true, false, null, BadAnyPrototype.Instance)
150 )
151 );
152
153 provider.RegisterObject<BadArray>("GetEnumerator",
154 a => new BadDynamicInteropFunction("GetEnumerator",
155 _ => GetEnumerator(a),
157 )
158 );
159
162 .ARRAY_ACCESS_OPERATOR_NAME,
163 (c, i) => ArrayAccess(c, a, i),
165 "index"
166 )
167 );
168
171 .ARRAY_ACCESS_REVERSE_OPERATOR_NAME,
172 (_, i) => BadObjectReference.Make($"{a}[^{i}]",
173 (p) => Get(a, a.InnerArray.Count - i),
174 (v,_, _) => Set(a, a.InnerArray.Count - i, v)
175 ),
177 "index"
178 )
179 );
180
181 provider.RegisterObject<BadArray>("Length", a => BadObject.Wrap((decimal)a.InnerArray.Count));
182 }
183
184 private static BadObject ArrayAccess(BadExecutionContext context, BadArray array, BadObject enumerator)
185 {
186 BadSourcePosition position = BadSourcePosition.FromSource("ArrayAccess", 0, 1);
187
188 if (enumerator is IBadNumber num)
189 {
190 return BadObjectReference.Make($"{array}[{num.Value}]",
191 (p) => Get(array, num.Value),
192 (v, _, _) => Set(array, num.Value, v)
193 );
194 }
195
196 BadArray result = new BadArray();
197
198 if (enumerator.HasProperty("GetEnumerator", context.Scope) &&
199 enumerator.GetProperty("GetEnumerator", context.Scope)
200 .Dereference(null) is BadFunction getEnumerator)
201 {
202 foreach (BadObject e in getEnumerator.Invoke(Array.Empty<BadObject>(), context))
203 {
204 enumerator = e;
205 }
206
207 enumerator = enumerator.Dereference(null);
208 }
209
210 (BadFunction moveNext, BadFunction getCurrent) =
211 BadForEachExpression.FindEnumerator(enumerator, context, position);
212
213 BadObject cond = BadObject.Null;
214
215 foreach (BadObject o in moveNext.Invoke(Array.Empty<BadObject>(), context))
216 {
217 cond = o;
218 }
219
220 IBadBoolean bRet = cond.Dereference(null) as IBadBoolean ??
221 throw new BadRuntimeException("While Condition is not a boolean", position);
222
223 while (bRet.Value)
224 {
225 using BadExecutionContext loopContext = new BadExecutionContext(context.Scope.CreateChild("ForEachLoop",
226 context.Scope,
227 null,
228 BadScopeFlags.Breakable |
229 BadScopeFlags.Continuable
230 )
231 );
232
233 BadObject current = BadObject.Null;
234
235 foreach (BadObject o in getCurrent.Invoke(Array.Empty<BadObject>(), loopContext))
236 {
237 current = o;
238 }
239
240 if (current is not IBadNumber n)
241 {
242 throw BadRuntimeException.Create(context.Scope, "Enumerator Current did not return a number", position);
243 }
244
245 result.InnerArray.Add(Get(array, n.Value));
246
247 foreach (BadObject o in moveNext.Invoke(Array.Empty<BadObject>(), loopContext))
248 {
249 cond = o;
250 }
251
252 bRet = cond.Dereference(null) as IBadBoolean ??
253 throw BadRuntimeException.Create(context.Scope,
254 "Enumerator MoveNext did not return a boolean",
255 position
256 );
257 }
258
259 return result;
260 }
261
267 private static BadObject GetEnumerator(BadArray array)
268 {
269 return new BadInteropEnumerator(array.InnerArray.GetEnumerator());
270 }
271
277 private static BadObject Clear(BadArray arg)
278 {
279 arg.InnerArray.Clear();
280
281 return BadObject.Null;
282 }
283
290 private static BadObject Add(BadArray arg, BadObject obj)
291 {
292 arg.InnerArray.Add(obj);
293
294 return BadObject.Null;
295 }
296
304 private static BadObject Insert(BadArray arg, decimal index, BadObject obj)
305 {
306 arg.InnerArray.Insert((int)index, obj);
307
308 return BadObject.Null;
309 }
310
317 private static BadObject Contains(BadArray arg, BadObject obj)
318 {
319 return arg.InnerArray.Contains(obj);
320 }
321
328 private static BadObject Remove(BadArray arg, BadObject obj)
329 {
330 return arg.InnerArray.Remove(obj);
331 }
332
339 private static BadObject RemoveAt(BadArray arg, decimal obj)
340 {
341 int index = (int)obj;
342 arg.InnerArray.RemoveAt(index);
343
344 return BadObject.Null;
345 }
346
353 private static BadObject Get(BadArray arg, decimal obj)
354 {
355 int index = (int)obj;
356
357 return arg.InnerArray[index];
358 }
359
367 private static BadObject Set(BadArray arg, decimal obj, BadObject value)
368 {
369 int index = (int)obj;
370 arg.InnerArray[index] = value;
371
372 return BadObject.Null;
373 }
374}
Describes a specific position inside a source file.
static BadSourcePosition FromSource(string source, int index, int length)
Creates a new Source Position.
Contains Static Data for the BadScript Language.
const string ARRAY_ACCESS_REVERSE_OPERATOR_NAME
static BadObject ArrayAccess(BadExecutionContext context, BadArray array, BadObject enumerator)
static BadObject Get(BadArray arg, decimal obj)
Returns a value from the array.
static BadObject Remove(BadArray arg, BadObject obj)
Removes an element from the array.
static BadObject Add(BadArray arg, BadObject obj)
Adds an element to the array.
static BadObject Set(BadArray arg, decimal obj, BadObject value)
Sets a value in the array.
override void AddExtensions(BadInteropExtensionProvider provider)
static BadObject RemoveAt(BadArray arg, decimal obj)
Removes an element at the given index.
static BadObject Contains(BadArray arg, BadObject obj)
Returns True if the array contains the given element.
static BadObject GetEnumerator(BadArray array)
Returns an enumerator of the array.
static BadObject Clear(BadArray arg)
Clears the array.
static BadObject Insert(BadArray arg, decimal index, BadObject obj)
Inserts an element at the given index.
static BadFunction BadFunction getCurrent FindEnumerator(BadObject target, BadExecutionContext context, BadSourcePosition position)
The Execution Context. Every execution of a script needs a context the script is running in....
BadScope Scope
The Root Scope of the Context.
static BadRuntimeException Create(BadScope? scope, string message)
Creates a new BadScriptException.
Implements a simple wrapper for C# IEnumerators to be used in BS2.
Public Extension API for the BS2 Runtime.
void RegisterObject(Type t, string propName, BadObject obj)
Registers the specified extension for the specified type.
Implements a Dynamic List/Array for the BadScript Language.
Definition BadArray.cs:17
List< BadObject > InnerArray
The Inner Array.
Definition BadArray.cs:45
The Base Class for all BadScript Objects.
Definition BadObject.cs:14
virtual BadObjectReference GetProperty(string propName, BadScope? caller=null)
Returns a Reference to the Property with the given Name.
Definition BadObject.cs:141
virtual bool HasProperty(string propName, BadScope? caller=null)
Returns true if the object contains a given property or there exists an extension for the current Ins...
Definition BadObject.cs:130
static readonly BadObject Null
The Null Value for the BadScript Language.
Definition BadObject.cs:28
Implements the base functionality for a BadScript Reference.
static BadObjectReference Make(string refText, Func< BadSourcePosition?, BadObject > getter, Action< BadObject, BadSourcePosition?, BadPropertyInfo?>? setter=null, Action< BadSourcePosition?>? delete=null)
Creates a new Reference Object.
Implements a function that can be called from the script.
The Any Prototype, Base type for all types.
static readonly BadAnyPrototype Instance
The Instance of the BadAnyPrototype.
Helper Class that Builds a Native Class from a Prototype.
static readonly BadInterfacePrototype Enumerable
The IEnumerable Interface Prototype.
static BadClassPrototype GetNative(string name)
Returns a Native Class Prototype for the given Native Type.
static readonly BadInterfacePrototype Enumerator
The IEnumerator Interface Prototype.
Helper Class for Creating Native Class Prototypes.
static IEnumerable< BadObject > ExecuteEnumerate(BadExecutionContext ctx, BadObject enumerable)
Executes the Enumerable.
Implements the Interface for Native Boolean.
Definition IBadBoolean.cs:7
Implements the Interface for Native Numbers.
Definition IBadNumber.cs:7
Contains Shared Data Structures and Functionality.
Contains Common Interop Extensions for the BadScript2 Runtime.
Contains the Loop Expressions for the BadScript2 Language.
Contains the Error Objects for the BadScript2 Language.
Contains the Interop Function Classes for the BadScript2 Language.
Contains the Interop Abstractions and Implementations for the BadScript2 Language.
Contains Runtime Function Objects.
Contains the Native Runtime Objects.
Definition BadBoolean.cs:6
Contains the Runtime Objects.
Definition BadArray.cs:10
Contains the Runtime Implementation.
BadScopeFlags
Defines Different Behaviours for the Current Scope.