BadScript 2
Loading...
Searching...
No Matches
BadFunction.cs
Go to the documentation of this file.
10
12
16public abstract class BadFunction : BadObject
17{
21 public static readonly BadClassPrototype Prototype = BadNativeClassBuilder.GetNative("Function");
22
26 private readonly Dictionary<int, BadObject> m_Cache = new Dictionary<int, BadObject>();
27
36 protected BadFunction(
37 BadWordToken? name,
38 bool isConstant,
39 bool isStatic,
40 BadClassPrototype returnType,
41 bool isSingleLine,
42 params BadFunctionParameter[] parameters)
43 {
44 Name = name;
45 IsConstant = isConstant;
46 IsStatic = isStatic;
47 Parameters = parameters;
48 ReturnType = returnType;
49 IsSingleLine = isSingleLine;
50 }
51
56
60 public bool IsStatic { get; }
61
66
70 public bool IsConstant { get; }
71
81 public bool IsSingleLine { get; }
82
86 public BadWordToken? Name { get; }
87
92
95 {
96 return Prototype;
97 }
98
105 {
106 return this;
107 }
108
115 protected static BadObject GetParameter(BadObject[] args, int i)
116 {
117 return args.Length > i ? args[i].Dereference() : Null;
118 }
119
127 protected void CheckParameters(BadObject[] args, BadExecutionContext caller, BadSourcePosition? position = null)
128 {
129 for (int i = 0; i < Parameters.Length; i++)
130 {
131 BadFunctionParameter parameter = Parameters[i];
132
133 if (parameter.IsRestArgs)
134 {
135 //Do Nothing
136 }
137 else if (args.Length <= i)
138 {
139 if (!parameter.IsOptional)
140 {
141 throw BadRuntimeException.Create(caller.Scope, $"Wrong number of parameters for '{this}'. Expected Argument for '{parameter}'", position);
142 }
143 }
144 else
145 {
146 if (parameter.IsNullChecked && args[i] == Null)
147 {
148 throw BadRuntimeException.Create(caller.Scope, $"Null value not allowed for '{this}' parameter '{parameter}'", position);
149 }
150 }
151 }
152 }
153
163 public static void ApplyParameters(
164 string funcStr,
165 BadFunctionParameter[] parameters,
166 BadExecutionContext context,
167 BadObject[] args,
168 BadSourcePosition? position = null)
169 {
170 for (int i = 0; i < parameters.Length; i++)
171 {
172 BadFunctionParameter parameter = parameters[i];
173
174 if (parameter.IsRestArgs)
175 {
176 context.Scope.DefineVariable(
177 parameter.Name,
178 new BadArray(args.Skip(i).ToList()),
179 null,
181 );
182 }
183 else if (args.Length <= i)
184 {
185 if (parameter.IsOptional)
186 {
187 context.Scope.DefineVariable(parameter.Name, Null, null, new BadPropertyInfo(parameter.Type ?? BadAnyPrototype.Instance));
188 }
189 else
190 {
191 throw BadRuntimeException.Create(context.Scope, $"Wrong number of parameters for '{funcStr}'. Expected Argument for '{parameter}'", position);
192 }
193 }
194 else
195 {
196 if (parameter.IsNullChecked && args[i] == Null)
197 {
198 throw BadRuntimeException.Create(context.Scope, $"Null value not allowed for '{funcStr}' parameter '{parameter}'", position);
199 }
200
201 context.Scope.DefineVariable(parameter.Name, args[i], null, new BadPropertyInfo(parameter.Type ?? BadAnyPrototype.Instance));
202 }
203 }
204 }
205
213 public void ApplyParameters(BadExecutionContext context, BadObject[] args, BadSourcePosition? position = null)
214 {
215 ApplyParameters(ToString(), Parameters, context, args, position);
216 }
217
223 private static int? GetHash(IEnumerable<BadObject> args)
224 {
225 int hash = 0;
226
227 //Generate Hash from arguments
228 foreach (BadObject o in args)
229 {
230 if (o is not IBadNative native)
231 {
232 return null;
233 }
234
235 hash = hash == 0 ? native.Value.GetHashCode() : BadHashCode.Combine(hash, native.Value);
236 }
237
238 return hash;
239 }
240
247 public IEnumerable<BadObject> Invoke(BadObject[] args, BadExecutionContext caller)
248 {
249 if (IsConstant && BadNativeOptimizationSettings.Instance.UseConstantFunctionCaching)
250 {
251 int? hash = GetHash(args);
252
253 if (hash != null && m_Cache.TryGetValue(hash.Value, out BadObject? v))
254 {
255 BadLogger.Warn($"Found Cached value with Hash {hash}", "Runtime");
256
257 yield return v;
258
259 yield break;
260 }
261 }
262
263 BadObject? ret = null;
264
265 foreach (BadObject o in InvokeBlock(args, caller))
266 {
267 ret = o;
268
269 yield return o;
270 }
271
272
273 if (ret != null && !ReturnType.IsAssignableFrom(ret))
274 {
275 throw new BadRuntimeException(
276 $"Invalid return type for function '{GetHeader()}'. Expected '{ReturnType.Name}' got '{ret.GetPrototype().Name}'"
277 );
278 }
279
280 if (!IsConstant ||
281 ret == null ||
282 !BadNativeOptimizationSettings.Instance.UseConstantFunctionCaching)
283 {
284 yield break;
285 }
286
287 {
288 int? hash = GetHash(args);
289
290 if (hash != null)
291 {
292 //BadLogger.Warn($"Caching Result {ret.ToSafeString()} for function '{GetHeader()}'", "Runtime");
293 m_Cache[hash.Value] = ret;
294 }
295 }
296 }
297
304 protected abstract IEnumerable<BadObject> InvokeBlock(BadObject[] args, BadExecutionContext caller);
305
306
311 public string GetHeader()
312 {
313 return GetHeader(Name?.ToString() ?? "<anonymous>", ReturnType, Parameters);
314 }
315
323 public static string GetHeader(string name, BadClassPrototype returnType, IEnumerable<BadFunctionParameter> parameters)
324 {
325 return $"{BadStaticKeys.FUNCTION_KEY} {returnType.Name} {name}({string.Join(", ", parameters.Cast<object>())})";
326 }
327
329 public override string ToSafeString(List<BadObject> done)
330 {
331 return GetHeader();
332 }
333}
Describes a specific position inside a source file.
Public facing interface for a logger.
Definition BadLogger.cs:7
static void Warn(string message)
Writes a Warning to the Message Handler.
Definition BadLogger.cs:56
Implements a Meta Data container for an expression.
static readonly BadMetaData Empty
An empty Meta Data object.
The Execution Context. Every execution of a script needs a context the script is running in....
BadScope Scope
The Root Scope of the Context.
Implements the Scope for the Script Engine.
Definition BadScope.cs:238
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:929
static BadRuntimeException Create(BadScope? scope, string message)
Creates a new BadScriptException.
Implements a Dynamic List/Array for the BadScript Language.
Definition BadArray.cs:17
The Base Class for all BadScript Objects.
Definition BadObject.cs:14
override string ToString()
Returns a String Representation of this Object.
Definition BadObject.cs:210
static readonly BadObject Null
The Null Value for the BadScript Language.
Definition BadObject.cs:28
Stores Meta Information about a Property.
Implements a function that can be called from the script.
readonly Dictionary< int, BadObject > m_Cache
The Result Cache.
BadFunctionParameter[] Parameters
The Function Parameters.
virtual BadFunction BindParentScope(BadScope scope)
Returns an instance that is bound to the given scope.
bool IsSingleLine
Indicates if the function is a single line function(without block) Is used to determine the behaviour...
BadWordToken? Name
(optional) Name of the Function
IEnumerable< BadObject > InvokeBlock(BadObject[] args, BadExecutionContext caller)
Invokes the function with the specified arguments.
BadFunction(BadWordToken? name, bool isConstant, bool isStatic, BadClassPrototype returnType, bool isSingleLine, params BadFunctionParameter[] parameters)
Creates a new Function.
static readonly BadClassPrototype Prototype
The Prototype for the Function Object.
override string ToSafeString(List< BadObject > done)
static ? int GetHash(IEnumerable< BadObject > args)
Returns the Hash of the function arguments.
static void ApplyParameters(string funcStr, BadFunctionParameter[] parameters, BadExecutionContext context, BadObject[] args, BadSourcePosition? position=null)
Applies the function arguments to the context of the function.
IEnumerable< BadObject > Invoke(BadObject[] args, BadExecutionContext caller)
Invokes the function with the specified arguments.
static BadObject GetParameter(BadObject[] args, int i)
Returns the Function Parameter at the given index.
void ApplyParameters(BadExecutionContext context, BadObject[] args, BadSourcePosition? position=null)
Applies the function arguments to the context of the function.
string GetHeader()
Returns the Header of the function.
static string GetHeader(string name, BadClassPrototype returnType, IEnumerable< BadFunctionParameter > parameters)
Returns the Header of the function.
override BadClassPrototype GetPrototype()
void CheckParameters(BadObject[] args, BadExecutionContext caller, BadSourcePosition? position=null)
Checks Parameters for the given function call.
bool IsConstant
Indicates if the function has no side effects and the result can be cached.
bool IsStatic
Indicates if the Function is static.
virtual BadMetaData MetaData
The Metadata of the Function.
BadClassPrototype ReturnType
The Return Type of the Function.
bool IsOptional
Indicates if this parameter is optional.
BadClassPrototype? Type
The Class Prototype of the Parameter.
bool IsRestArgs
Indicates if this parameter is the rest parameter of the function.
bool IsNullChecked
Indicates if this parameter is null checked by the runtime.
The Any Prototype, Base type for all types.
static readonly BadAnyPrototype Instance
The Instance of the BadAnyPrototype.
Implements a Class Prototype for the BadScript Language.
virtual bool IsAssignableFrom(BadObject obj)
Returns true if the provided object is an instance of this class or a subclass of this class.
Helper Class that Builds a Native Class from a Prototype.
static BadClassPrototype GetNative(string name)
Returns a Native Class Prototype for the given Native Type.
static T Instance
Returns the Instance of the Settings Provider.
Implements Combination of HashCode Functions Taken from decompiled source of System....
Defines properties for Native Types.
Definition IBadNative.cs:7
Contains Logging system for the BadScript Runtime.
Definition BadLog.cs:6
Contains Shared Data Structures and Functionality.
Contains the Parser for the BadScript2 Language.
Contains the Reader Tokens for the BadScript2 Language.
Contains the Error Objects for the BadScript2 Language.
Contains Runtime Function Objects.
Contains the Native Runtime Objects.
Definition BadBoolean.cs:6
Contains Runtime Settings Objects.
Contains Utility Functions and Classes.
Definition BadEnum.cs:5