BadScript 2
Loading...
Searching...
No Matches
BadExpression.cs
Go to the documentation of this file.
1using System.Runtime.ExceptionServices;
2
16
18
22public abstract class BadExpression
23{
29 protected BadExpression(bool isConstant, BadSourcePosition position)
30 {
31 IsConstant = isConstant;
32 Position = position;
33 Attributes = [];
34 }
35
36 public IEnumerable<BadExpression> Attributes { get; private set; }
37
41 public bool IsConstant { get; }
42
46 public BadSourcePosition Position { get; private set; }
47
48 public void SetAttributes(IEnumerable<BadExpression> attributes)
49 {
50 Attributes = attributes;
51 }
52
53 protected IEnumerable<BadObject> ComputeAttributes(BadExecutionContext ctx, List<BadObject> attributes)
54 {
55 foreach (BadExpression? attribute in Attributes)
56 {
58 BadExpression? attrib = null;
59 BadExpression access;
60 IEnumerable<BadExpression> args;
61
62 if (attribute is BadInvocationExpression invoc)
63 {
64 access = invoc.Left;
65 args = invoc.Arguments;
66 }
67 else if (attribute is BadMemberAccessExpression || attribute is BadVariableExpression)
68 {
69 access = attribute;
70 args = Array.Empty<BadExpression>();
71 }
72 else
73 {
74 throw BadRuntimeException.Create(ctx.Scope, "Attribute Expression not Supported.", attribute.Position);
75 }
76
77 BadClassPrototype? attribClass = null;
78
79 if (access is BadVariableExpression varExpr)
80 {
81 //Check if the variable exists and is a class.
82 if (ctx.Scope.HasVariable(varExpr.Name, ctx.Scope)) // Try to get the variable
83 {
84 BadObject? attribObj = ctx.Scope.GetVariable(varExpr.Name, ctx.Scope)
85 .Dereference(Position);
86
87 //Check if the variable is a class and inherits from IAttribute
88 if (attribObj is BadClassPrototype cls && BadNativeClassBuilder.Attribute.IsSuperClassOf(cls))
89 {
90 attribClass = cls;
91 }
92 }
93
94 //If the variable does not exist, check if the variable name + "Attribute" exists and is a class.
95 if (attribClass == null &&
96 !varExpr.Name.EndsWith("Attribute") &&
97 ctx.Scope.HasVariable(varExpr.Name + "Attribute", ctx.Scope))
98 {
99 BadObject? attribObj = ctx.Scope.GetVariable(varExpr.Name + "Attribute", ctx.Scope)
100 .Dereference(Position);
101
102 //Check if the variable is a class and inherits from IAttribute
103 if (attribObj is BadClassPrototype cls && BadNativeClassBuilder.Attribute.IsSuperClassOf(cls))
104 {
105 attribClass = cls;
106 }
107 }
108 }
109 else if (access is BadMemberAccessExpression mac)
110 {
111 //evaluate left side of the member access
112 foreach (BadObject? o in mac.Left.Execute(ctx))
113 {
114 obj = o;
115 }
116
117 BadObject? parent = obj.Dereference(Position);
118
119 //Check if parent has property
120 if (parent.HasProperty(mac.Right.Text, ctx.Scope))
121 {
122 BadObject? attribObj = parent.GetProperty(mac.Right.Text, ctx.Scope)
123 .Dereference(Position);
124
125 //Check if the property is a class and inherits from IAttribute
126 if (attribObj is BadClassPrototype cls && BadNativeClassBuilder.Attribute.IsSuperClassOf(cls))
127 {
128 attribClass = cls;
129 }
130 }
131
132 if (parent.HasProperty(mac.Right.Text + "Attribute", ctx.Scope))
133 {
134 BadObject? attribObj = parent.GetProperty(mac.Right.Text + "Attribute", ctx.Scope)
135 .Dereference(access.Position);
136
137 //Check if the property is a class and inherits from IAttribute
138 if (attribObj is BadClassPrototype cls && BadNativeClassBuilder.Attribute.IsSuperClassOf(cls))
139 {
140 attribClass = cls;
141 }
142 }
143 }
144
145 if (attribClass == null)
146 {
147 throw BadRuntimeException.Create(ctx.Scope, "Attribute must be a class", attribute.Position);
148 }
149
150 attrib =
152 attribClass
153 ),
154 args,
155 attribute.Position
156 ),
157 attribute.Position
158 );
159
160 foreach (BadObject? o in attrib.Execute(ctx))
161 {
162 yield return o;
163 obj = o;
164 }
165
166 BadObject? a = obj.Dereference(Position);
167
168 if (a is not BadClass c)
169 {
170 throw BadRuntimeException.Create(ctx.Scope, "Attribute must be a class", attrib.Position);
171 }
172
173 if (!c.InheritsFrom(BadNativeClassBuilder.Attribute))
174 {
175 throw BadRuntimeException.Create(ctx.Scope, "Attribute must inherit from IAttribute", attrib.Position);
176 }
177
178 attributes.Add(a);
179 }
180 }
181
185 public virtual void Optimize() { }
186
191 public abstract IEnumerable<BadExpression> GetDescendants();
192
197 public IEnumerable<BadExpression> GetDescendantsAndSelf()
198 {
199 yield return this;
200
201 foreach (BadExpression? descendant in GetDescendants())
202 {
203 yield return descendant;
204 }
205 }
206
212 {
213 Position = pos;
214 }
215
221 protected abstract IEnumerable<BadObject> InnerExecute(BadExecutionContext context);
222
223 private IEnumerable<BadObject> ExecuteWithCatch(BadExecutionContext context)
224 {
225 using IEnumerator<BadObject> e = InnerExecute(context)
226 .GetEnumerator();
227
228 while (true)
229 {
230 try
231 {
232 if (!e.MoveNext())
233 {
234 break;
235 }
236 }
237 catch (BadRuntimeErrorException err)
238 {
239 ExceptionDispatchInfo.Capture(err)
240 .Throw();
241 }
242 catch (Exception exception)
243 {
245 context.Scope.GetStackTrace()
246 )
247 );
248 }
249
250 yield return e.Current ?? BadObject.Null;
251 }
252 }
253
259 public IEnumerable<BadObject> Execute(BadExecutionContext context)
260 {
262 {
263 BadDebugger.Step(new BadDebuggerStep(context, Position, this));
264 }
265
266 if (BadRuntimeSettings.Instance.CatchRuntimeExceptions)
267 {
268 return ExecuteWithCatch(context);
269 }
270
271 return InnerExecute(context);
272 }
273
284 protected static IEnumerable<BadObject> ExecuteOperatorOverride(BadObject left,
285 BadObject right,
286 BadExecutionContext context,
287 string name,
288 BadSourcePosition position)
289 {
290 if (left.GetProperty(name, context.Scope)
291 .Dereference(position) is not BadFunction func)
292 {
293 throw new BadRuntimeException($"{left.GetType().Name} has no {name} property",
294 position
295 );
296 }
297
298 foreach (BadObject o in func.Invoke(new[] { right },
299 context
300 ))
301 {
302 yield return o;
303 }
304 }
305
315 protected static IEnumerable<BadObject> ExecuteOperatorOverride(BadObject left,
316 BadExecutionContext context,
317 string name,
318 BadSourcePosition position)
319 {
320 if (left.GetProperty(name, context.Scope)
321 .Dereference(position) is not BadFunction func)
322 {
323 throw new BadRuntimeException($"{left.GetType().Name} has no {name} property",
324 position
325 );
326 }
327
328 foreach (BadObject o in func.Invoke(Array.Empty<BadObject>(), context))
329 {
330 yield return o;
331 }
332 }
333}
Describes a specific position inside a source file.
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 Member Access to set or get properties from an object. LEFT.RIGHT.
Base Implementation for all Expressions used inside the Script.
IEnumerable< BadObject > InnerExecute(BadExecutionContext context)
Is used to evaluate the Expression.
static IEnumerable< BadObject > ExecuteOperatorOverride(BadObject left, BadObject right, BadExecutionContext context, string name, BadSourcePosition position)
Helper function that executes an operator override function if implemented.
IEnumerable< BadObject > ComputeAttributes(BadExecutionContext ctx, List< BadObject > attributes)
IEnumerable< BadExpression > GetDescendantsAndSelf()
Returns all Descendants of the Expression and the Expression itself.
IEnumerable< BadExpression > Attributes
virtual void Optimize()
Uses the Constant Folding Optimizer to optimize the expression.
static IEnumerable< BadObject > ExecuteOperatorOverride(BadObject left, BadExecutionContext context, string name, BadSourcePosition position)
Executes an operator override function if implemented.
BadSourcePosition Position
The source Position of the Expression.
BadExpression(bool isConstant, BadSourcePosition position)
Constructor.
IEnumerable< BadExpression > GetDescendants()
Returns all Descendants of the Expression.
void SetPosition(BadSourcePosition pos)
Sets the Source Position of the Expression.
void SetAttributes(IEnumerable< BadExpression > attributes)
IEnumerable< BadObject > Execute(BadExecutionContext context)
Evaluates the Expression within the current Execution Context.
IEnumerable< BadObject > ExecuteWithCatch(BadExecutionContext context)
bool IsConstant
Indicates if the expression stays constant at all times.
The Execution Context. Every execution of a script needs a context the script is running in....
BadScope Scope
The Root Scope of the Context.
string GetStackTrace()
Returns the Stack Trace of the Current scope.
Definition BadScope.cs:419
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.
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 a function that can be called from the script.
Implements a Type Instance in the BadScript Language.
Definition BadClass.cs:11
Implements a Class Prototype for the BadScript Language.
Helper Class that Builds a Native Class from a Prototype.
static T Instance
Returns the Instance of the Settings Provider.
Contains Shared Data Structures and Functionality.
Contains the debugging abstractions for the BadScript2 Runtime.
Definition BadDebugger.cs:7
Contains the Access Expressions for the BadScript2 Language.
Contains the Constant Expressions for the BadScript2 Language.
Contains the Function Expressions for the BadScript2 Language.
Contains the Type Expressions for the BadScript2 Language.
Contains the Variable Expressions for the BadScript2 Language.
Contains the Expressions for the BadScript2 Language.
Contains the Error Objects for the BadScript2 Language.
Contains Runtime Function Objects.
Contains the Runtime Objects.
Definition BadArray.cs:10
Contains Runtime Settings Objects.
Contains the Runtime Implementation.
Represents a Debugging Step.