BadScript 2
Loading...
Searching...
No Matches
BadRuntimeVirtualMachine.cs
Go to the documentation of this file.
20
22
27{
31 private readonly Stack<BadObject> m_ArgumentStack = new Stack<BadObject>();
32
36 private readonly Stack<BadRuntimeVirtualStackFrame> m_ContextStack = new Stack<BadRuntimeVirtualStackFrame>();
37
42
46 private readonly BadInstruction[] m_Instructions;
47
51 private readonly bool m_UseOverrides;
52
57
64 BadInstruction[] instructions,
65 bool useOverrides = true)
66 {
67 m_Function = function;
68 m_Instructions = instructions;
69 m_UseOverrides = useOverrides;
70 }
71
72 private IEnumerable<BadObject> ExecuteStep(BadExecutionContext ctx)
73 {
75
77 {
78 BadDebugger.Step(new BadDebuggerStep(ctx, instr.Position, instr));
79 }
80
82
83 switch (instr.OpCode)
84 {
85 case BadOpCode.Nop:
86
87 break;
88 case BadOpCode.Dup:
90
91 break;
92 case BadOpCode.Pop:
93 m_ArgumentStack.Pop();
94
95 break;
96 case BadOpCode.AquireLock:
97 {
98 BadObject lockObj = m_ArgumentStack.Pop()
99 .Dereference(instr.Position);
100
101 if (lockObj is not BadArray && lockObj is not BadTable && lockObj is BadClass)
102 {
103 throw new BadRuntimeException("Lock object must be of type Array, Object or Class",
104 instr.Position
105 );
106 }
107
108 while (!BadLockList.Instance.TryAquire(lockObj))
109 {
110 yield return BadObject.Null;
111 }
112
113 break;
114 }
115 case BadOpCode.ArrayInit:
116 {
117 int length = (int)instr.Arguments[0];
118 List<BadObject> arr = new List<BadObject>();
119
120 for (int i = 0; i < length; i++)
121 {
122 arr.Insert(0,
123 m_ArgumentStack.Pop()
124 .Dereference(instr.Position)
125 );
126 }
127
128 m_ArgumentStack.Push(new BadArray(arr));
129
130 break;
131 }
132 case BadOpCode.TableInit:
133 {
134 int length = (int)instr.Arguments[0];
135 Dictionary<string, BadObject> arr = new Dictionary<string, BadObject>();
136
137 for (int i = 0; i < length; i++)
138 {
139 BadObject val = m_ArgumentStack.Pop()
140 .Dereference(instr.Position);
141
142 BadObject key = m_ArgumentStack.Pop()
143 .Dereference(instr.Position);
144
145 if (key is not IBadString s)
146 {
147 throw BadRuntimeException.Create(ctx.Scope, "Invalid Property Key", instr.Position);
148 }
149
150 arr.Add(s.Value, val);
151 }
152
153 m_ArgumentStack.Push(new BadTable(arr));
154
155 break;
156 }
157 case BadOpCode.HasProperty:
158 {
159 BadObject key = m_ArgumentStack.Pop()
160 .Dereference(instr.Position);
161
162 BadObject obj = m_ArgumentStack.Pop()
163 .Dereference(instr.Position);
164 BadObject? result = BadObject.Null;
165
166 if (m_UseOverrides)
167 {
168 foreach (BadObject o in BadInExpression.InWithOverride(ctx, key, obj, instr.Position))
169 {
170 result = o;
171 }
172 }
173 else
174 {
175 result = BadInExpression.In(ctx, key, obj);
176 }
177
178 m_ArgumentStack.Push(result);
179
180 break;
181 }
182 case BadOpCode.Invoke:
183 {
184 BadObject func = m_ArgumentStack.Pop()
185 .Dereference(instr.Position);
186 int argCount = (int)instr.Arguments[0];
187 BadObject[] args = new BadObject[argCount];
188
189 for (int i = argCount - 1; i >= 0; i--)
190 {
191 args[i] = m_ArgumentStack.Pop()
192 .Dereference(instr.Position);
193 }
194
196
197 if (m_Function == func) //Invoke Self
198 {
200 {
201 ReturnPointer = m_InstructionPointer,
202 }
203 );
205
206 break;
207 }
208
209 foreach (BadObject o in BadInvocationExpression.Invoke(func, args, instr.Position, ctx))
210 {
211 r = o;
212
213 yield return o;
214 }
215
216 m_ArgumentStack.Push(r);
217
218 break;
219 }
220 case BadOpCode.New:
221 {
222 BadObject func = m_ArgumentStack.Pop()
223 .Dereference(instr.Position);
224
225 if (func is not BadClassPrototype ptype)
226 {
227 throw new BadRuntimeException("Cannot create object from non-class type", instr.Position);
228 }
229
230 int argCount = (int)instr.Arguments[0];
231 BadObject[] args = new BadObject[argCount];
232
233 for (int i = argCount - 1; i >= 0; i--)
234 {
235 args[i] = m_ArgumentStack.Pop()
236 .Dereference(instr.Position);
237 }
238
240
241 foreach (BadObject o in BadNewExpression.CreateObject(ptype, ctx, args, instr.Position))
242 {
243 r = o;
244
245 yield return o;
246 }
247
248 m_ArgumentStack.Push(r);
249
250 break;
251 }
252 case BadOpCode.Range:
253 {
254 BadObject start = m_ArgumentStack.Pop()
255 .Dereference(instr.Position);
256
257 BadObject end = m_ArgumentStack.Pop()
258 .Dereference(instr.Position);
259
260 if (start is not IBadNumber sn || end is not IBadNumber en)
261 {
262 throw new BadRuntimeException("Range start and end must be numbers", instr.Position);
263 }
264
266 .GetEnumerator()
267 )
268 );
269
270 break;
271 }
272 case BadOpCode.ReleaseLock:
273 {
274 BadObject lockObj = m_ArgumentStack.Pop()
275 .Dereference(instr.Position);
276
277 if (lockObj is not BadArray && lockObj is not BadTable && lockObj is BadClass)
278 {
279 throw new BadRuntimeException("Lock object must be of type Array, Object or Class",
280 instr.Position
281 );
282 }
283
285
286 break;
287 }
288 case BadOpCode.DefVar:
289 {
290 string name = (string)instr.Arguments[0];
291 bool isReadOnly = (bool)instr.Arguments[1];
292
293 ctx.Scope.DefineVariable(name,
295 ctx.Scope,
297 );
298 m_ArgumentStack.Push(ctx.Scope.GetVariable(name));
299
300 break;
301 }
302 case BadOpCode.DefVarTyped:
303
304 {
305 string name = (string)instr.Arguments[0];
306 bool isReadOnly = (bool)instr.Arguments[1];
307
308 ctx.Scope.DefineVariable(name,
310 ctx.Scope,
312 .Dereference(instr.Position),
313 isReadOnly
314 )
315 );
316 m_ArgumentStack.Push(ctx.Scope.GetVariable(name));
317
318 break;
319 }
320 case BadOpCode.LoadVar:
321 {
322 if (instr.Arguments.Length > 1 && instr.Arguments[1] is int genericArgCount && genericArgCount != 0)
323 {
324 BadObject item = ctx.Scope.GetVariable((string)instr.Arguments[0])
325 .Dereference(instr.Position);
326
327 if (item is not IBadGenericObject genItem)
328 {
329 throw BadRuntimeException.Create(ctx.Scope, "Variable is not a generic object", instr.Position);
330 }
331
332 BadObject[] genericArgs = new BadObject[genericArgCount];
333
334 for (int i = genericArgCount - 1; i >= 0; i--)
335 {
336 genericArgs[i] = m_ArgumentStack.Pop()
337 .Dereference(instr.Position);
338 }
339
340 m_ArgumentStack.Push(genItem.CreateGeneric(genericArgs));
341 }
342 else
343 {
344 m_ArgumentStack.Push(ctx.Scope.GetVariable((string)instr.Arguments[0]));
345 }
346
347 break;
348 }
349 case BadOpCode.LoadMember:
350 {
351 if (instr.Arguments.Length > 1 && instr.Arguments[1] is int genericArgCount && genericArgCount != 0)
352 {
353 BadObject left =
354 m_ArgumentStack.Pop()
355 .Dereference(instr.Position)
356 .GetProperty((string)instr.Arguments[0], ctx.Scope)
357 .Dereference(instr.Position);
358
359 if (left is not IBadGenericObject genItem)
360 {
361 throw BadRuntimeException.Create(ctx.Scope, "Variable is not a generic object", instr.Position);
362 }
363
364 BadObject[] genericArgs = new BadObject[genericArgCount];
365
366 for (int i = genericArgCount - 1; i >= 0; i--)
367 {
368 genericArgs[i] = m_ArgumentStack.Pop()
369 .Dereference(instr.Position);
370 }
371
372 m_ArgumentStack.Push(genItem.CreateGeneric(genericArgs));
373 }
374 else
375 {
377 .Dereference(instr.Position)
378 .GetProperty((string)instr.Arguments[0], ctx.Scope)
379 );
380 }
381
382 break;
383 }
384 case BadOpCode.LoadMemberNullChecked:
385 {
386 BadObject obj = m_ArgumentStack.Pop()
387 .Dereference(instr.Position);
388 string name = (string)instr.Arguments[0];
389
390 if (obj.HasProperty(name, ctx.Scope))
391 {
392 if (instr.Arguments.Length > 1 && instr.Arguments[1] is int genericArgCount && genericArgCount != 0)
393 {
394 BadObject left = obj
395 .GetProperty((string)instr.Arguments[0], ctx.Scope)
396 .Dereference(instr.Position);
397
398 if (left is not IBadGenericObject genItem)
399 {
401 "Variable is not a generic object",
402 instr.Position
403 );
404 }
405
406 BadObject[] genericArgs = new BadObject[genericArgCount];
407
408 for (int i = genericArgCount - 1; i >= 0; i--)
409 {
410 genericArgs[i] = m_ArgumentStack.Pop()
411 .Dereference(instr.Position);
412 }
413
414 m_ArgumentStack.Push(genItem.CreateGeneric(genericArgs));
415 }
416 else
417 {
418 m_ArgumentStack.Push(obj.GetProperty(name, ctx.Scope));
419 }
420 }
421 else
422 {
424 }
425
426 break;
427 }
428 case BadOpCode.LoadArrayAccess:
429 {
430 BadObject obj = m_ArgumentStack.Pop()
431 .Dereference(instr.Position);
432 int argCount = (int)instr.Arguments[0];
433
434 BadObject[] args = new BadObject[argCount];
435
436 for (int i = argCount - 1; i >= 0; i--)
437 {
438 args[i] = m_ArgumentStack.Pop();
439 }
440
442
443 foreach (BadObject o in BadArrayAccessExpression.Access(ctx, obj, args, instr.Position))
444 {
445 r = o;
446
447 yield return o;
448 }
449
450 m_ArgumentStack.Push(r);
451
452 break;
453 }
454 case BadOpCode.LoadArrayAccessNullChecked:
455 {
456 BadObject obj = m_ArgumentStack.Pop()
457 .Dereference(instr.Position);
458 int argCount = (int)instr.Arguments[0];
459
460 if (obj == BadObject.Null)
461 {
462 for (int i = 0; i < argCount; i++)
463 {
464 m_ArgumentStack.Pop();
465 }
466
468
469 break;
470 }
471
472 BadObject[] args = new BadObject[argCount];
473
474 for (int i = argCount - 1; i >= 0; i--)
475 {
476 args[i] = m_ArgumentStack.Pop();
477 }
478
480
481 foreach (BadObject o in BadArrayAccessExpression.Access(ctx, obj, args, instr.Position))
482 {
483 r = o;
484
485 yield return o;
486 }
487
488 m_ArgumentStack.Push(r);
489
490 break;
491 }
492 case BadOpCode.LoadArrayAccessReverse:
493 {
494 BadObject obj = m_ArgumentStack.Pop()
495 .Dereference(instr.Position);
496 int argCount = (int)instr.Arguments[0];
497
498 BadObject[] args = new BadObject[argCount];
499
500 for (int i = argCount - 1; i >= 0; i--)
501 {
502 args[i] = m_ArgumentStack.Pop();
503 }
504
506
507 foreach (BadObject o in BadArrayAccessReverseExpression.Access(ctx, obj, args, instr.Position))
508 {
509 r = o;
510
511 yield return o;
512 }
513
514 m_ArgumentStack.Push(r);
515
516 break;
517 }
518 case BadOpCode.LoadArrayAccessReverseNullChecked:
519 {
520 BadObject obj = m_ArgumentStack.Pop()
521 .Dereference(instr.Position);
522
523 if (obj == BadObject.Null)
524 {
526
527 break;
528 }
529
530 int argCount = (int)instr.Arguments[0];
531
532 BadObject[] args = new BadObject[argCount];
533
534 for (int i = argCount - 1; i >= 0; i--)
535 {
536 args[i] = m_ArgumentStack.Pop();
537 }
538
540
541 foreach (BadObject o in BadArrayAccessReverseExpression.Access(ctx, obj, args, instr.Position))
542 {
543 r = o;
544
545 yield return o;
546 }
547
548 m_ArgumentStack.Push(r);
549
550 break;
551 }
552 case BadOpCode.Swap:
553 {
554 BadObject a = m_ArgumentStack.Pop();
555 BadObject b = m_ArgumentStack.Pop();
556
557 m_ArgumentStack.Push(a);
558 m_ArgumentStack.Push(b);
559
560 break;
561 }
562 case BadOpCode.Assign:
563 {
564 BadObject val = m_ArgumentStack.Pop()
565 .Dereference(instr.Position);
567 left.Set(val, instr.Position);
568
569 break;
570 }
571 case BadOpCode.Push:
572 m_ArgumentStack.Push((BadObject)instr.Arguments[0]);
573
574 break;
575 case BadOpCode.FormatString:
576 {
577 string format = (string)instr.Arguments[0];
578 int argCount = (int)instr.Arguments[1];
579 BadObject[] args = new BadObject[argCount];
580
581 for (int i = argCount - 1; i >= 0; i--)
582 {
583 args[i] = m_ArgumentStack.Pop()
584 .Dereference(instr.Position);
585 }
586
587 m_ArgumentStack.Push(string.Format(format,
588 args.Cast<object?>()
589 .ToArray()
590 )
591 );
592
593 break;
594 }
595 case BadOpCode.And:
596 {
597 BadObject right = m_ArgumentStack.Pop()
598 .Dereference(instr.Position);
599
600 BadObject left = m_ArgumentStack.Pop()
601 .Dereference(instr.Position);
602 m_ArgumentStack.Push(BadLogicAndExpression.And(left, right, instr.Position));
603
604 break;
605 }
606 case BadOpCode.Not:
607 {
608 BadObject left = m_ArgumentStack.Pop()
609 .Dereference(instr.Position);
611
612 if (m_UseOverrides)
613 {
614 foreach (BadObject? o in BadLogicNotExpression.NotWithOverride(ctx, left, instr.Position))
615 {
616 obj = o;
617
618 yield return o;
619 }
620 }
621 else
622 {
623 obj = BadLogicNotExpression.Not(left, instr.Position);
624 }
625
626 m_ArgumentStack.Push(obj);
627
628 break;
629 }
630 case BadOpCode.XOr:
631 {
632 BadObject right = m_ArgumentStack.Pop()
633 .Dereference(instr.Position);
634
635 BadObject left = m_ArgumentStack.Pop()
636 .Dereference(instr.Position);
637 m_ArgumentStack.Push(BadLogicXOrExpression.XOr(left, right, instr.Position));
638
639 break;
640 }
641 case BadOpCode.AndAssign:
642 {
643 BadObject right = m_ArgumentStack.Pop()
644 .Dereference(instr.Position);
646 left.Set(BadLogicAndExpression.And(left.Dereference(instr.Position), right, instr.Position), instr.Position);
647
648 break;
649 }
650 case BadOpCode.XOrAssign:
651 {
652 BadObject right = m_ArgumentStack.Pop()
653 .Dereference(instr.Position);
655 left.Set(BadLogicXOrExpression.XOr(left.Dereference(instr.Position), right, instr.Position), instr.Position);
656
657 break;
658 }
659 case BadOpCode.Add:
660 {
661 BadObject right = m_ArgumentStack.Pop()
662 .Dereference(instr.Position);
663
664 BadObject left = m_ArgumentStack.Pop()
665 .Dereference(instr.Position);
667
668 if (m_UseOverrides)
669 {
670 foreach (BadObject o in BadAddExpression.AddWithOverride(ctx, left, right, instr.Position))
671 {
672 obj = o;
673 }
674 }
675 else
676 {
677 obj = BadAddExpression.Add(left, right, instr.Position);
678 }
679
680 m_ArgumentStack.Push(obj);
681
682 break;
683 }
684 case BadOpCode.Sub:
685 {
686 BadObject right = m_ArgumentStack.Pop()
687 .Dereference(instr.Position);
688
689 BadObject left = m_ArgumentStack.Pop()
690 .Dereference(instr.Position);
692
693 if (m_UseOverrides)
694 {
695 foreach (BadObject o in BadSubtractExpression.SubWithOverride(ctx, left, right, instr.Position))
696 {
697 obj = o;
698 }
699 }
700 else
701 {
702 obj = BadSubtractExpression.Sub(left, right, instr.Position);
703 }
704
705 m_ArgumentStack.Push(obj);
706
707 break;
708 }
709 case BadOpCode.Mul:
710 {
711 BadObject right = m_ArgumentStack.Pop()
712 .Dereference(instr.Position);
713
714 BadObject left = m_ArgumentStack.Pop()
715 .Dereference(instr.Position);
717
718 if (m_UseOverrides)
719 {
720 foreach (BadObject o in BadMultiplyExpression.MulWithOverride(ctx, left, right, instr.Position))
721 {
722 obj = o;
723 }
724 }
725 else
726 {
727 obj = BadMultiplyExpression.Mul(left, right, instr.Position);
728 }
729
730 m_ArgumentStack.Push(obj);
731
732 break;
733 }
734 case BadOpCode.Exp:
735 {
736 BadObject right = m_ArgumentStack.Pop()
737 .Dereference(instr.Position);
738
739 BadObject left = m_ArgumentStack.Pop()
740 .Dereference(instr.Position);
742
743 if (m_UseOverrides)
744 {
746 left,
747 right,
748 instr.Position
749 ))
750 {
751 obj = o;
752 }
753 }
754 else
755 {
756 obj = BadExponentiationExpression.Exp(left, right, instr.Position);
757 }
758
759 m_ArgumentStack.Push(obj);
760
761 break;
762 }
763 case BadOpCode.Div:
764 {
765 BadObject right = m_ArgumentStack.Pop()
766 .Dereference(instr.Position);
767
768 BadObject left = m_ArgumentStack.Pop()
769 .Dereference(instr.Position);
771
772 if (m_UseOverrides)
773 {
774 foreach (BadObject o in BadDivideExpression.DivWithOverride(ctx, left, right, instr.Position))
775 {
776 obj = o;
777 }
778 }
779 else
780 {
781 obj = BadDivideExpression.Div(left, right, instr.Position);
782 }
783
784 m_ArgumentStack.Push(obj);
785
786 break;
787 }
788 case BadOpCode.Mod:
789 {
790 BadObject right = m_ArgumentStack.Pop()
791 .Dereference(instr.Position);
792
793 BadObject left = m_ArgumentStack.Pop()
794 .Dereference(instr.Position);
796
797 if (m_UseOverrides)
798 {
799 foreach (BadObject o in BadModulusExpression.ModWithOverride(ctx, left, right, instr.Position))
800 {
801 obj = o;
802 }
803 }
804 else
805 {
806 obj = BadModulusExpression.Mod(left, right, instr.Position);
807 }
808
809 m_ArgumentStack.Push(obj);
810
811 break;
812 }
813 case BadOpCode.Neg:
814 {
815 BadObject left = m_ArgumentStack.Pop()
816 .Dereference(instr.Position);
817
819
820 if (m_UseOverrides)
821 {
822 foreach (BadObject o in BadNegationExpression.NegateWithOverride(ctx, left, instr.Position))
823 {
824 yield return o;
825
826 obj = o;
827 }
828 }
829 else
830 {
831 obj = BadNegationExpression.Negate(left, instr.Position);
832 }
833
834 m_ArgumentStack.Push(obj);
835
836 break;
837 }
838 case BadOpCode.JumpRelative:
839 m_InstructionPointer += (int)instr.Arguments[0];
840
841 break;
842 case BadOpCode.JumpRelativeIfFalse:
843 {
845 .Dereference(instr.Position);
846
847 if (!val.Value)
848 {
849 m_InstructionPointer += (int)instr.Arguments[0];
850 }
851
852 break;
853 }
854 case BadOpCode.JumpRelativeIfNull:
855 {
856 BadObject val = m_ArgumentStack.Pop()
857 .Dereference(instr.Position);
858
859 if (val == BadObject.Null)
860 {
861 m_InstructionPointer += (int)instr.Arguments[0];
862 }
863
864 break;
865 }
866 case BadOpCode.JumpRelativeIfNotNull:
867 {
868 BadObject val = m_ArgumentStack.Pop()
869 .Dereference(instr.Position);
870
871 if (val != BadObject.Null)
872 {
873 m_InstructionPointer += (int)instr.Arguments[0];
874 }
875
876 break;
877 }
878 case BadOpCode.JumpRelativeIfTrue:
879 {
881 .Dereference(instr.Position);
882
883 if (val.Value)
884 {
885 m_InstructionPointer += (int)instr.Arguments[0];
886 }
887
888 break;
889 }
890 case BadOpCode.CreateScope:
891 {
892 //0: name
893 //1: useVisibility
894 //3: flags
895 //4: relative jump to break
896 //5: relative jump to continue
897 //6: relative jump to return
898 //7: relative jump to throw
899 string name = (string)instr.Arguments[0];
900 bool? useVisibility = null;
901
902 if (instr.Arguments[1] != BadObject.Null)
903 {
904 useVisibility = (bool)instr.Arguments[1];
905 }
906
907 BadScopeFlags flags = BadScopeFlags.AllowThrow;
908
909 if (instr.Arguments.Length > 2)
910 {
911 flags = (BadScopeFlags)instr.Arguments[2];
912 }
913
916 ctx.Scope,
917 useVisibility,
918 flags
919 )
920 )
921 ) { CreatePointer = m_InstructionPointer };
922 m_ContextStack.Push(sf);
923
924 break;
925 }
926 case BadOpCode.DestroyScope:
927 {
929 frame.Context.Dispose();
930
931 break;
932 }
933 case BadOpCode.AddDisposeFinalizer:
934 {
935 //Load Variable with that name and call dispose on it
937 (string)instr.Arguments[0],
938 instr.Position
939 )
940 );
941
942 break;
943 }
944 case BadOpCode.ClearStack:
945 m_ArgumentStack.Clear();
946
947 break;
948 case BadOpCode.TypeOf:
949 {
951 .Dereference(instr.Position)
952 .GetPrototype()
953 );
954
955 break;
956 }
957 case BadOpCode.InstanceOf:
958 {
959 BadObject right = m_ArgumentStack.Pop()
960 .Dereference(instr.Position);
961
962 BadObject left = m_ArgumentStack.Pop()
963 .Dereference(instr.Position);
964
965 if (right is not BadClassPrototype type)
966 {
968 "Cannot check if an object is an instance of a non-class object.",
969 instr.Position
970 );
971 }
972
973 m_ArgumentStack.Push(type.IsSuperClassOf(left.GetPrototype()));
974
975 break;
976 }
977 case BadOpCode.Export:
978 {
979 if (instr.Arguments.Length == 0)
980 {
981 BadObject? obj = m_ArgumentStack.Pop()
982 .Dereference(instr.Position);
983 ctx.Scope.SetExports(ctx, obj);
984 }
985 else
986 {
987 string name = (string)instr.Arguments[0];
988
989 BadObject obj = ctx.Scope.GetVariable(name)
990 .Dereference(instr.Position);
991 ctx.Scope.AddExport(name, obj);
992 }
993
994 break;
995 }
996 case BadOpCode.Import:
997 {
998 string name = (string)instr.Arguments[0];
999 string path = (string)instr.Arguments[1];
1000 foreach (var o in BadImportExpression.Import(ctx, name, path, instr.Position))
1001 {
1002 }
1003
1004 break;
1005 }
1006 case BadOpCode.Delete:
1007 {
1008 BadObject? obj = m_ArgumentStack.Pop();
1009
1010 if (obj is not BadObjectReference r)
1011 {
1013 "Cannot delete a non-reference object.",
1014 instr.Position
1015 );
1016 }
1017
1018 r.Delete(instr.Position);
1019
1020 break;
1021 }
1022 case BadOpCode.Equals:
1023 {
1024 BadObject right = m_ArgumentStack.Pop()
1025 .Dereference(instr.Position);
1026
1027 BadObject left = m_ArgumentStack.Pop()
1028 .Dereference(instr.Position);
1029 BadObject obj = BadObject.Null;
1030
1031 if (m_UseOverrides)
1032 {
1034 left,
1035 right,
1036 instr.Position
1037 ))
1038 {
1039 obj = o;
1040
1041 yield return o;
1042 }
1043 }
1044 else
1045 {
1046 obj = BadEqualityExpression.Equal(left, right);
1047 }
1048
1049 m_ArgumentStack.Push(obj.Dereference(instr.Position));
1050
1051 break;
1052 }
1053 case BadOpCode.NotEquals:
1054 {
1055 BadObject right = m_ArgumentStack.Pop()
1056 .Dereference(instr.Position);
1057
1058 BadObject left = m_ArgumentStack.Pop()
1059 .Dereference(instr.Position);
1060 BadObject obj = BadObject.Null;
1061
1062 if (m_UseOverrides)
1063 {
1065 left,
1066 right,
1067 instr.Position
1068 ))
1069 {
1070 obj = o;
1071
1072 yield return o;
1073 }
1074 }
1075 else
1076 {
1077 obj = BadInequalityExpression.NotEqual(left, right);
1078 }
1079
1080 m_ArgumentStack.Push(obj.Dereference(instr.Position));
1081
1082 break;
1083 }
1084 case BadOpCode.Greater:
1085 {
1086 BadObject right = m_ArgumentStack.Pop()
1087 .Dereference(instr.Position);
1088
1089 BadObject left = m_ArgumentStack.Pop()
1090 .Dereference(instr.Position);
1091 BadObject obj = BadObject.Null;
1092
1093 if (m_UseOverrides)
1094 {
1096 left,
1097 right,
1098 instr.Position
1099 ))
1100 {
1101 obj = o;
1102
1103 yield return o;
1104 }
1105 }
1106 else
1107 {
1108 obj = BadGreaterThanExpression.GreaterThan(left, right, instr.Position);
1109 }
1110
1111 m_ArgumentStack.Push(obj.Dereference(instr.Position));
1112
1113 break;
1114 }
1115 case BadOpCode.GreaterEquals:
1116 {
1117 BadObject right = m_ArgumentStack.Pop()
1118 .Dereference(instr.Position);
1119
1120 BadObject left = m_ArgumentStack.Pop()
1121 .Dereference(instr.Position);
1122 BadObject obj = BadObject.Null;
1123
1124 if (m_UseOverrides)
1125 {
1127 left,
1128 right,
1129 instr.Position
1130 ))
1131 {
1132 obj = o;
1133
1134 yield return o;
1135 }
1136 }
1137 else
1138 {
1139 obj = BadGreaterOrEqualExpression.GreaterOrEqual(left, right, instr.Position);
1140 }
1141
1142 m_ArgumentStack.Push(obj.Dereference(instr.Position));
1143
1144 break;
1145 }
1146 case BadOpCode.Less:
1147 {
1148 BadObject right = m_ArgumentStack.Pop()
1149 .Dereference(instr.Position);
1150
1151 BadObject left = m_ArgumentStack.Pop()
1152 .Dereference(instr.Position);
1153 BadObject obj = BadObject.Null;
1154
1155 if (m_UseOverrides)
1156 {
1158 left,
1159 right,
1160 instr.Position
1161 ))
1162 {
1163 obj = o;
1164
1165 yield return o;
1166 }
1167 }
1168 else
1169 {
1170 obj = BadLessThanExpression.LessThan(left, right, instr.Position);
1171 }
1172
1173 m_ArgumentStack.Push(obj.Dereference(instr.Position));
1174
1175 break;
1176 }
1177 case BadOpCode.LessEquals:
1178 {
1179 BadObject right = m_ArgumentStack.Pop()
1180 .Dereference(instr.Position);
1181
1182 BadObject left = m_ArgumentStack.Pop()
1183 .Dereference(instr.Position);
1184 BadObject obj = BadObject.Null;
1185
1186 if (m_UseOverrides)
1187 {
1189 left,
1190 right,
1191 instr.Position
1192 ))
1193 {
1194 obj = o;
1195
1196 yield return o;
1197 }
1198 }
1199 else
1200 {
1201 obj = BadLessOrEqualExpression.LessOrEqual(left, right, instr.Position);
1202 }
1203
1204 m_ArgumentStack.Push(obj.Dereference(instr.Position));
1205
1206 break;
1207 }
1208 case BadOpCode.AddAssign:
1209 {
1210 BadObject right = m_ArgumentStack.Pop()
1211 .Dereference(instr.Position);
1213 BadObject obj = BadObject.Null;
1214
1215 if (m_UseOverrides)
1216 {
1218 left,
1219 right,
1220 instr.Position,
1221 "+="
1222 ))
1223 {
1224 obj = o;
1225
1226 yield return o;
1227 }
1228 }
1229 else
1230 {
1231 obj = BadAddAssignExpression.Add(left, left.Dereference(instr.Position), right, instr.Position, "+=");
1232 }
1233
1234 m_ArgumentStack.Push(obj.Dereference(instr.Position));
1235
1236 break;
1237 }
1238 case BadOpCode.SubAssign:
1239 {
1240 BadObject right = m_ArgumentStack.Pop()
1241 .Dereference(instr.Position);
1243 BadObject obj = BadObject.Null;
1244
1245 if (m_UseOverrides)
1246 {
1248 left,
1249 right,
1250 instr.Position,
1251 "-="
1252 ))
1253 {
1254 obj = o;
1255
1256 yield return o;
1257 }
1258 }
1259 else
1260 {
1262 left.Dereference(instr.Position),
1263 right,
1264 instr.Position,
1265 "-="
1266 );
1267 }
1268
1269 m_ArgumentStack.Push(obj.Dereference(instr.Position));
1270
1271 break;
1272 }
1273 case BadOpCode.MulAssign:
1274 {
1275 BadObject right = m_ArgumentStack.Pop()
1276 .Dereference(instr.Position);
1278 BadObject obj = BadObject.Null;
1279
1280 if (m_UseOverrides)
1281 {
1283 left,
1284 right,
1285 instr.Position,
1286 "*="
1287 ))
1288 {
1289 obj = o;
1290
1291 yield return o;
1292 }
1293 }
1294 else
1295 {
1297 left.Dereference(instr.Position),
1298 right,
1299 instr.Position,
1300 "*="
1301 );
1302 }
1303
1304 m_ArgumentStack.Push(obj.Dereference(instr.Position));
1305
1306 break;
1307 }
1308 case BadOpCode.DivAssign:
1309 {
1310 BadObject right = m_ArgumentStack.Pop()
1311 .Dereference(instr.Position);
1313 BadObject obj = BadObject.Null;
1314
1315 if (m_UseOverrides)
1316 {
1318 left,
1319 right,
1320 instr.Position,
1321 "/="
1322 ))
1323 {
1324 obj = o;
1325
1326 yield return o;
1327 }
1328 }
1329 else
1330 {
1331 obj = BadDivideAssignExpression.Divide(left, left.Dereference(instr.Position), right, instr.Position, "/=");
1332 }
1333
1334 m_ArgumentStack.Push(obj.Dereference(instr.Position));
1335
1336 break;
1337 }
1338 case BadOpCode.ModAssign:
1339 {
1340 BadObject right = m_ArgumentStack.Pop()
1341 .Dereference(instr.Position);
1343 BadObject obj = BadObject.Null;
1344
1345 if (m_UseOverrides)
1346 {
1348 left,
1349 right,
1350 instr.Position,
1351 "%="
1352 ))
1353 {
1354 obj = o;
1355
1356 yield return o;
1357 }
1358 }
1359 else
1360 {
1361 obj = BadModulusAssignExpression.Modulus(left, left.Dereference(instr.Position), right, instr.Position, "%=");
1362 }
1363
1364 m_ArgumentStack.Push(obj.Dereference(instr.Position));
1365
1366 break;
1367 }
1368 case BadOpCode.ExpAssign:
1369 {
1370 BadObject right = m_ArgumentStack.Pop()
1371 .Dereference(instr.Position);
1373 BadObject obj = BadObject.Null;
1374
1375 if (m_UseOverrides)
1376 {
1378 left,
1379 right,
1380 instr.Position,
1381 "**="
1382 ))
1383 {
1384 obj = o;
1385
1386 yield return o;
1387 }
1388 }
1389 else
1390 {
1392 left.Dereference(instr.Position),
1393 right,
1394 instr.Position,
1395 "**="
1396 );
1397 }
1398
1399 m_ArgumentStack.Push(obj.Dereference(instr.Position));
1400
1401 break;
1402 }
1403 case BadOpCode.PostInc:
1404 {
1406 BadObject? result = BadObject.Null;
1407
1408 if (m_UseOverrides)
1409 {
1411 obj,
1412 instr.Position
1413 ))
1414 {
1415 result = o;
1416 }
1417 }
1418 else
1419 {
1420 result = BadPostIncrementExpression.Increment(obj, instr.Position);
1421 }
1422
1423 m_ArgumentStack.Push(result);
1424
1425 break;
1426 }
1427 case BadOpCode.PostDec:
1428 {
1430 BadObject? result = BadObject.Null;
1431
1432 if (m_UseOverrides)
1433 {
1435 obj,
1436 instr.Position
1437 ))
1438 {
1439 result = o;
1440 }
1441 }
1442 else
1443 {
1444 result = BadPostDecrementExpression.Decrement(obj, instr.Position);
1445 }
1446
1447 m_ArgumentStack.Push(result);
1448
1449 break;
1450 }
1451 case BadOpCode.PreInc:
1452 {
1454 BadObject? result = BadObject.Null;
1455
1456 if (m_UseOverrides)
1457 {
1459 obj,
1460 instr.Position
1461 ))
1462 {
1463 result = o;
1464 }
1465 }
1466 else
1467 {
1468 result = BadPreIncrementExpression.Increment(obj, instr.Position);
1469 }
1470
1471 m_ArgumentStack.Push(result);
1472
1473 break;
1474 }
1475 case BadOpCode.PreDec:
1476 {
1478 BadObject? result = BadObject.Null;
1479
1480 if (m_UseOverrides)
1481 {
1483 obj,
1484 instr.Position
1485 ))
1486 {
1487 result = o;
1488 }
1489 }
1490 else
1491 {
1492 result = BadPreDecrementExpression.Decrement(obj, instr.Position);
1493 }
1494
1495 m_ArgumentStack.Push(result);
1496
1497 break;
1498 }
1499 case BadOpCode.Return:
1500 {
1501 BadObject ret = BadObject.Null;
1502
1503 if (instr.Arguments.Length != 0)
1504 {
1505 ret = m_ArgumentStack.Pop();
1506 bool isRefReturn = (bool)instr.Arguments[0];
1507
1508 if (!isRefReturn)
1509 {
1510 ret = ret.Dereference(instr.Position);
1511 }
1512 }
1513
1514 if (ctx.Scope.FunctionObject != null &&
1516 {
1517 if (!ctx.Scope.FunctionObject.IsSingleLine)
1518 {
1520 "Cannot return a value from a void function",
1521 instr.Position
1522 );
1523 }
1524
1526 }
1527 else
1528 {
1529 ctx.Scope.SetReturnValue(ret);
1530 }
1531
1532 break;
1533 }
1534 case BadOpCode.Break:
1535 ctx.Scope.SetBreak();
1536
1537 break;
1538 case BadOpCode.Continue:
1539 ctx.Scope.SetContinue();
1540
1541 break;
1542 case BadOpCode.Throw:
1543 throw new BadRuntimeErrorException(new BadRuntimeError(null,
1544 m_ArgumentStack.Pop(),
1545 ctx.Scope.GetStackTrace()
1546 )
1547 );
1548
1549 case BadOpCode.SetBreakPointer:
1550 m_ContextStack.Peek()
1551 .BreakPointer = (int)instr.Arguments[0];
1552
1553 break;
1554 case BadOpCode.SetContinuePointer:
1555 m_ContextStack.Peek()
1556 .ContinuePointer = (int)instr.Arguments[0];
1557
1558 break;
1559 case BadOpCode.SetThrowPointer:
1560 m_ContextStack.Peek()
1561 .ThrowPointer = (int)instr.Arguments[0];
1562
1563 break;
1564 case BadOpCode.BinaryUnpack:
1565 {
1566 BadObject right = m_ArgumentStack.Pop()
1567 .Dereference(instr.Position);
1568
1569 BadObject left = m_ArgumentStack.Pop()
1570 .Dereference(instr.Position);
1571 m_ArgumentStack.Push(BadBinaryUnpackExpression.Unpack(left, right, instr.Position));
1572
1573 break;
1574 }
1575 case BadOpCode.UnaryUnpack:
1576 {
1577 BadObject right = m_ArgumentStack.Pop()
1578 .Dereference(instr.Position);
1579 BadTable table = ctx.Scope.GetTable();
1580 BadUnaryUnpackExpression.Unpack(table, right, instr.Position);
1581 m_ArgumentStack.Push(table);
1582
1583 break;
1584 }
1585 case BadOpCode.Eval:
1586 {
1587 BadExpression expr = (BadExpression)instr.Arguments[0];
1588 BadObject ret = BadObject.Null;
1589
1590 foreach (BadObject o in ctx.Execute(expr))
1591 {
1592 ret = o;
1593
1594 yield return o;
1595 }
1596
1597 m_ArgumentStack.Push(ret);
1598
1599 break;
1600 }
1601 default:
1602 throw new ArgumentOutOfRangeException();
1603 }
1604 }
1605
1612 private IEnumerable<BadObject> Execute()
1613 {
1614 while (m_InstructionPointer <= m_Instructions.Length)
1615 {
1617 .Context;
1618
1619 if (ctx.Scope.ReturnValue != null)
1620 {
1621 //Pop scopes until we find a scope that captures return
1622 while ((ctx.Scope.Flags & BadScopeFlags.CaptureReturn) == 0)
1623 {
1624 m_ContextStack.Pop();
1625
1626 if (m_ContextStack.Count == 0)
1627 {
1628 yield break; //We exited the virtual machine. Quit the Execute method.
1629 }
1630
1632 ctx = sf.Context;
1633
1634 //Set Return Pointer to the next instruction
1636 }
1637
1639
1640 if (m_ContextStack.Count == 0)
1641 {
1642 yield break; //We exited the virtual machine. Quit the Execute method.
1643 }
1644
1645 //We found a scope that captures return, we push the return value to the stack and continue execution
1648
1649 continue;
1650 }
1651
1652 if (ctx.Scope.IsBreak)
1653 {
1654 //Pop scopes until we find a scope that captures break
1655 while ((ctx.Scope.Flags & BadScopeFlags.CaptureBreak) == 0)
1656 {
1657 m_ContextStack.Pop();
1658
1659 if (m_ContextStack.Count == 0)
1660 {
1661 throw BadRuntimeException.Create(ctx.Scope, "VIRTUAL MACHINE BREAK ERROR");
1662 }
1663
1664 ctx = m_ContextStack.Peek()
1665 .Context;
1666 }
1667
1669
1670 //Set Return Pointer to the next instruction
1671 m_InstructionPointer = sf.CreatePointer + sf.BreakPointer;
1672
1673 continue;
1674 }
1675
1676 if (ctx.Scope.IsContinue)
1677 {
1678 //Pop scopes until we find a scope that captures continue
1679 while ((ctx.Scope.Flags & BadScopeFlags.CaptureContinue) == 0)
1680 {
1681 m_ContextStack.Pop();
1682
1683 if (m_ContextStack.Count == 0)
1684 {
1685 throw BadRuntimeException.Create(ctx.Scope, "VIRTUAL MACHINE CONTINUE ERROR");
1686 }
1687
1689 ctx = sf.Context;
1690
1691 //Set Return Pointer to the next instruction
1692 m_InstructionPointer = sf.CreatePointer + sf.ContinuePointer;
1693 }
1694
1695 m_ContextStack.Pop();
1696
1697 continue;
1698 }
1699
1701 {
1702 break;
1703 }
1704
1705 using IEnumerator<BadObject> enumerator = ExecuteStep(ctx)
1706 .GetEnumerator();
1707
1708 while (true)
1709 {
1710 try
1711 {
1712 if (!enumerator.MoveNext())
1713 {
1714 break;
1715 }
1716 }
1717 catch (Exception e)
1718 {
1719 BadRuntimeError error;
1720
1721 if (e is BadRuntimeErrorException err)
1722 {
1723 error = err.Error;
1724 }
1725 else
1726 {
1728 }
1729
1730 m_ArgumentStack.Push(error);
1731
1732 //Pop scopes until we find a scope that captures throw
1733 while ((ctx.Scope.Flags & BadScopeFlags.CaptureThrow) == 0)
1734 {
1735 m_ContextStack.Pop();
1736
1737 if (m_ContextStack.Count == 0)
1738 {
1739 yield break; //We exited the virtual machine. Quit the Execute method.
1740 }
1741 }
1742
1744 m_InstructionPointer = sframe.CreatePointer + sframe.ThrowPointer;
1745 m_ContextStack.Pop();
1746
1747 if (m_ContextStack.Count == 0)
1748 {
1749 yield break;
1750 }
1751
1752 break;
1753 }
1754
1755 yield return enumerator.Current ?? BadObject.Null;
1756 }
1757 }
1758 }
1759
1765 public IEnumerable<BadObject> Execute(BadExecutionContext ctx)
1766 {
1767 m_ContextStack.Clear();
1768 m_ArgumentStack.Clear();
1771
1772 return Execute();
1773 }
1774}
Public Debugger Interface.
static void Step(BadDebuggerStep stepInfo)
Sends a step event to the debugger.
static bool IsAttached
True if a debugger is attached.
Implements the Array Access to set or get properties from an object. LEFT[RIGHT].
static IEnumerable< BadObject > Access(BadExecutionContext? context, BadObject left, IEnumerable< BadObject > args, BadSourcePosition position)
Executes the Array Access Expression.
Implements the Reverse Array Access to set or get properties from an object. LEFT[^RIGHT].
static IEnumerable< BadObject > Access(BadExecutionContext context, BadObject left, IEnumerable< BadObject > args, BadSourcePosition position)
Executes the Array Access Expression.
Base Implementation for all Expressions used inside the Script.
Implements the binary ... operator. This operator is used to unpack the right side into the left side...
static BadTable Unpack(BadObject left, BadObject right, BadSourcePosition position)
Executes the binary ... operator.
Implements the 'in' operator. The 'in' operator is used to check if a key is present in an instance o...
static IEnumerable< BadObject > InWithOverride(BadExecutionContext context, BadObject left, BadObject right, BadSourcePosition position)
Implements the logic of the 'in' operator but checks for an operator override first.
static BadObject In(BadExecutionContext ctx, BadObject left, BadObject right)
Implements the logic of the 'in' operator.
Implements the Range Expression START..END.
static IEnumerable< BadObject > Range(decimal from, decimal to)
Returns a range of numbers.
Implements the unary ... operator. This operator is used to unpack a table into the current execution...
static void Unpack(BadTable table, BadObject right, BadSourcePosition position)
Implements the logic of the unary ... operator.
static BadObject Equal(BadObject left, BadObject right)
Returns true if the left side is equal to the right side.
static IEnumerable< BadObject > EqualWithOverride(BadExecutionContext? caller, BadObject left, BadObject right, BadSourcePosition position)
Executes the operator override for the given operator name.
static IEnumerable< BadObject > GreaterOrEqualWithOverride(BadExecutionContext? context, BadObject left, BadObject right, BadSourcePosition position)
Executes the expression.
static BadObject GreaterOrEqual(BadObject left, BadObject right, BadSourcePosition pos)
Returns true if the left side is greater or equal to the right side.
static BadObject GreaterThan(BadObject left, BadObject right, BadSourcePosition pos)
Returns true if the left side is greater than the right side.
static IEnumerable< BadObject > GreaterThanWithOverride(BadExecutionContext? context, BadObject left, BadObject right, BadSourcePosition position)
Executes the expression.
static BadObject NotEqual(BadObject left, BadObject right)
Returns True if the two Objects are not equal.
static IEnumerable< BadObject > NotEqualWithOverride(BadExecutionContext? caller, BadObject left, BadObject right, BadSourcePosition position)
Executes the expression.
static BadObject LessOrEqual(BadObject left, BadObject right, BadSourcePosition pos)
Returns true if the left side is less or equal to the right side.
static IEnumerable< BadObject > LessOrEqualWithOverride(BadExecutionContext? context, BadObject left, BadObject right, BadSourcePosition position)
Executes the expression.
static BadObject LessThan(BadObject left, BadObject right, BadSourcePosition pos)
Returns true if the left side is less than the right side.
static IEnumerable< BadObject > LessThanWithOverride(BadExecutionContext? context, BadObject left, BadObject right, BadSourcePosition position)
Executes the expression.
static BadObject And(BadObject left, BadObject right, BadSourcePosition pos)
Returns true if left and right are true.
static IEnumerable< BadObject > NotWithOverride(BadExecutionContext? context, BadObject left, BadSourcePosition position)
Executes the expression.
static BadObject Not(BadObject left, BadSourcePosition pos)
Returns true if the Input is false Returns false if the Input is true.
static BadObject XOr(BadObject left, BadObject right, BadSourcePosition pos)
Returns true if left or right are true. False if both are true.
static IEnumerable< BadObject > AddWithOverride(BadExecutionContext? context, BadObjectReference leftRef, BadObject right, BadSourcePosition position, string symbol)
Executes the Operator with operator override.
static BadObject Add(BadObjectReference leftRef, BadObject left, BadObject right, BadSourcePosition position, string symbol)
Executes the Add Assignment Operator.
static IEnumerable< BadObject > DivideWithOverride(BadExecutionContext? context, BadObjectReference leftRef, BadObject right, BadSourcePosition position, string symbol)
Executes the Operator with operator override.
static BadObject Divide(BadObjectReference leftRef, BadObject left, BadObject right, BadSourcePosition position, string symbol)
Executes the Operator.
static BadObject Exp(BadObjectReference leftRef, BadObject left, BadObject right, BadSourcePosition position, string symbol)
Implements the logic of the Exponentiation Operator.
static IEnumerable< BadObject > ExpWithOverride(BadExecutionContext? context, BadObjectReference leftRef, BadObject right, BadSourcePosition position, string symbol)
Runs the Exponentiation Operator on the given objects.
static BadObject Modulus(BadObjectReference leftRef, BadObject left, BadObject right, BadSourcePosition position, string symbol)
Executes the Operator.
static IEnumerable< BadObject > ModulusWithOverride(BadExecutionContext? context, BadObjectReference leftRef, BadObject right, BadSourcePosition position, string symbol)
Executes the Operator with operator override.
static IEnumerable< BadObject > MultiplyWithOverride(BadExecutionContext? context, BadObjectReference leftRef, BadObject right, BadSourcePosition position, string symbol)
Executes the Operator with operator override.
static BadObject Multiply(BadObjectReference leftRef, BadObject left, BadObject right, BadSourcePosition position, string symbol)
Executes the Operator.
static BadObject Subtract(BadObjectReference leftRef, BadObject left, BadObject right, BadSourcePosition position, string symbol)
Executes the Operator.
static IEnumerable< BadObject > SubtractWithOverride(BadExecutionContext? context, BadObjectReference leftRef, BadObject right, BadSourcePosition position, string symbol)
Executes the Operator with operator override.
Implements the Post Decrement Expression.
static BadObject Decrement(BadObjectReference reference, BadSourcePosition position)
Executes the Operator.
static IEnumerable< BadObject > DecrementWithOverride(BadExecutionContext? context, BadObjectReference leftRef, BadSourcePosition position)
Executes the Operator.
Implements the Post Increment Expression.
static IEnumerable< BadObject > IncrementWithOverride(BadExecutionContext? context, BadObjectReference leftRef, BadSourcePosition position)
Executes the Operator.
static BadObject Increment(BadObjectReference reference, BadSourcePosition position)
Executes the Operator.
static BadObject Decrement(BadObjectReference reference, BadSourcePosition position)
Executes the Operator.
static IEnumerable< BadObject > DecrementWithOverride(BadExecutionContext? context, BadObjectReference leftRef, BadSourcePosition position)
Executes the Operator.
static BadObject Increment(BadObjectReference reference, BadSourcePosition position)
Executes the Operator.
static IEnumerable< BadObject > IncrementWithOverride(BadExecutionContext? context, BadObjectReference leftRef, BadSourcePosition position)
Executes the Operator.
static BadObject Add(BadObject left, BadObject right, BadSourcePosition pos)
Adds left and right together.
static IEnumerable< BadObject > AddWithOverride(BadExecutionContext? context, BadObject leftRef, BadObject right, BadSourcePosition position)
Executes the Operator with operator overrides.
static IEnumerable< BadObject > DivWithOverride(BadExecutionContext? context, BadObject left, BadObject right, BadSourcePosition position)
Executes the Operator with operator overrides.
static BadObject Div(BadObject left, BadObject right, BadSourcePosition pos)
Divides left by right.
static BadObject Exp(BadObject left, BadObject right, BadSourcePosition position)
Implements the logic of the Exponentiation Operator.
static IEnumerable< BadObject > ExpWithOverride(BadExecutionContext? context, BadObject left, BadObject right, BadSourcePosition position)
Runs the Exponentiation Operator on the given objects.
static BadObject Mod(BadObject left, BadObject right, BadSourcePosition pos)
Performs the Modulus Operation on left and right.
static IEnumerable< BadObject > ModWithOverride(BadExecutionContext? context, BadObject left, BadObject right, BadSourcePosition position)
Executes the Operator with operator overrides.
static IEnumerable< BadObject > MulWithOverride(BadExecutionContext? context, BadObject left, BadObject right, BadSourcePosition position)
Executes the Operator with operator overrides.
static BadObject Mul(BadObject left, BadObject right, BadSourcePosition pos)
Performs the Multiplication Operation on left and right.
static IEnumerable< BadObject > NegateWithOverride(BadExecutionContext? context, BadObject left, BadSourcePosition position)
Executes the Operator.
static BadObject Negate(BadObject obj, BadSourcePosition pos)
Executes the Operator.
static BadObject Sub(BadObject left, BadObject right, BadSourcePosition pos)
Performs the Subtraction Operation on left and right.
static IEnumerable< BadObject > SubWithOverride(BadExecutionContext? context, BadObject left, BadObject right, BadSourcePosition position)
Executes the Operator with operator overrides.
static void Finalize(BadExecutionContext usingContext, string name, BadSourcePosition position)
The Finalizer method of the Using Expression.
The Lock List that is used to store all locks.
static readonly BadLockList Instance
Instance of the Lock List.
bool TryAquire(BadObject lockObj)
Tries to aquire a lock on the given object.
void Release(BadObject lockObj)
Releases the lock on the given object.
static IEnumerable< BadObject > Invoke(BadObject left, IEnumerable< BadObject > args, BadSourcePosition position, BadExecutionContext context)
Invokes a function.
A Import Expression that is used to import a module from a specified path.
static IEnumerable< BadObject > Import(BadExecutionContext ctx, string name, string path, BadSourcePosition? position)
Imports a module from the specified path and assigns it to the specified name.
static IEnumerable< BadObject > CreateObject(BadClassPrototype proto, BadExecutionContext context, BadObject[] args, BadSourcePosition pos)
Creates an Instance of the Specified Class prototype.
The Execution Context. Every execution of a script needs a context the script is running in....
IEnumerable< BadObject > Execute(IEnumerable< BadExpression > expressions)
Executes an enumeration of expressions.
BadScope Scope
The Root Scope of the Context.
BadScope CreateChild(string name, BadScope? caller, bool? useVisibility, BadScopeFlags flags=BadScopeFlags.RootScope)
Creates a subscope of the current scope.
Definition BadScope.cs:597
BadScopeFlags Flags
The Scope Flags.
Definition BadScope.cs:162
bool IsContinue
Is true if the Continue Keyword was set.
Definition BadScope.cs:177
BadObjectReference GetVariable(string name, BadScope caller)
Returns the variable reference of the specified variable.
Definition BadScope.cs:878
BadTable GetTable()
Returns the Variable Table of the current scope.
Definition BadScope.cs:583
void SetContinue()
Sets the continue keyword inside this scope.
Definition BadScope.cs:503
bool IsBreak
Is true if the Break Keyword was set.
Definition BadScope.cs:172
string GetStackTrace()
Returns the Stack Trace of the Current scope.
Definition BadScope.cs:419
void SetExports(BadExecutionContext ctx, BadObject exports)
Definition BadScope.cs:527
void AddExport(string key, BadObject value)
Sets an exported key value pair in the scope.
Definition BadScope.cs:542
BadObject? ReturnValue
The Return value of the scope.
Definition BadScope.cs:182
void SetReturnValue(BadObject? value)
Sets the Return value of this scope.
Definition BadScope.cs:564
void SetBreak()
Sets the break keyword inside this scope.
Definition BadScope.cs:484
void AddFinalizer(Action finalizer)
Adds a Finalizer to the Scope.
Definition BadScope.cs:281
void DefineVariable(string name, BadObject value, BadScope? caller=null, BadPropertyInfo? info=null, BadObject[]? attributes=null)
Defines a new Variable in the current scope.
Definition BadScope.cs:784
BadFunction? FunctionObject
The Function Object of the Scope.
Definition BadScope.cs:146
Gets thrown if the runtime encounters an error.
Implements the Error Object Type.
static BadRuntimeError FromException(Exception e, string? scriptStackTrace=null)
Creates a BadRuntimeError from an Exception.
static BadRuntimeException Create(BadScope? scope, string message)
Creates a new BadScriptException.
Implements a simple wrapper for C# IEnumerators to be used in BS2.
Implements a Dynamic List/Array for the BadScript Language.
Definition BadArray.cs:17
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
BadClassPrototype GetPrototype()
Returns the Prototype of this Object.
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.
void Set(BadObject obj, BadSourcePosition? position, BadPropertyInfo? info=null, bool noChangeEvent=false)
Sets the Referenced Object to a new Value.
Stores Meta Information about a Property.
Implements a Table Structure for the BadScript Language.
Definition BadTable.cs:14
The Any Prototype, Base type for all types.
static readonly BadAnyPrototype Instance
The Instance of the BadAnyPrototype.
Implements a Type Instance in the BadScript Language.
Definition BadClass.cs:11
Implements a Class Prototype for the BadScript Language.
The Void Prototype, can be assigned to nothing, can not be inherited from, can not be instantiated....
static BadVoidPrototype Instance
The Instance of the BadVoidPrototype.
BadExecutionContext CreateExecutionContext(BadExecutionContext caller, BadObject[] args)
Implements a Virtual Machine for the BadScript Language.
readonly Stack< BadObject > m_ArgumentStack
The Argument Stack.
readonly bool m_UseOverrides
Indicates if the Virtual Machine should use Operator Overrides.
readonly BadCompiledFunction m_Function
The Function that is executed by this Virtual Machine.
readonly Stack< BadRuntimeVirtualStackFrame > m_ContextStack
The Context Stack.
IEnumerable< BadObject > ExecuteStep(BadExecutionContext ctx)
IEnumerable< BadObject > Execute()
Executes the Virtual Machine.
IEnumerable< BadObject > Execute(BadExecutionContext ctx)
Executes the virtual machine with the given context.
BadRuntimeVirtualMachine(BadCompiledFunction function, BadInstruction[] instructions, bool useOverrides=true)
Creates a new BadRuntimeVirtualMachine instance.
Stores the current execution state of the Virtual Machine.
readonly BadExecutionContext Context
The current execution context.
Implements the Interface for Native Boolean.
Definition IBadBoolean.cs:7
Implements the Interface for Native Numbers.
Definition IBadNumber.cs:7
Implements the Interface for Native Strings.
Definition IBadString.cs:7
Contains the debugging abstractions for the BadScript2 Runtime.
Definition BadDebugger.cs:7
Contains the Access Expressions for the BadScript2 Language.
Contains the Comparison Expressions for the BadScript2 Language.
Contains the Logic Expressions for the BadScript2 Language.
Contains the Self-Assigning Math Expressions for the BadScript2 Language.
Contains the Atomic Math Expressions for the BadScript2 Language.
Contains the Math Expressions for the BadScript2 Language.
Contains the Binary Expressions for the BadScript2 Language.
Contains the Locking Expressions for the BadScript2 Language.
Contains the Block Expressions for the BadScript2 Language.
Contains the Function Expressions for the BadScript2 Language.
Contains the Type Expressions for the BadScript2 Language.
Contains the Expressions for the BadScript2 Language.
Contains the Error Objects for the BadScript2 Language.
Contains the Interop Abstractions and Implementations for the BadScript2 Language.
Contains the Native Runtime Objects.
Definition BadBoolean.cs:6
Contains the Runtime Objects.
Definition BadArray.cs:10
Contains the Virtual Machine Implementation.
BadOpCode
Defines the Operations that the BadVirtualMachine can execute.
Definition BadOpCode.cs:7
BadScopeFlags
Defines Different Behaviours for the Current Scope.
Represents a Debugging Step.
Implements a single instruction for the BadVirtualMachine.
readonly object[] Arguments
The arguments of this Instruction.
readonly BadSourcePosition Position
The position of this Instruction in the source code.
readonly BadOpCode OpCode
The OpCode of this Instruction.