private static void ExecuteTestCase(string expression, int value, IDictionary <Variable, int> variableValues = null) { var expressionInterpreter = new ExpressionInterpreter(expression); var result = expressionInterpreter.CalculateWith(variableValues); Assert.AreEqual(value, result, $"Expected result for expression '{expression}' was {value} but got {result}"); }
public ExpressionInterpreterTest() { _statusUtil = new Mock <IStatusUtil>(MockBehavior.Strict); var interpreterStatusUtil = new InterpreterStatusUtil(_statusUtil.Object); _interpreter = new ExpressionInterpreter(interpreterStatusUtil, null, null, new Dictionary <string, VariableValue>(), null); }
public EventActionsLoader(string namespaceName, ScriptEngine engine) : base(engine) { cNamespace.Name = namespaceName; exprInter = engine.GetPlugin <ExpressionInterpreter> (); filters = engine.GetPlugin <FiltersPlugin> (); functionOperators = engine.GetPlugin <EventFunctionOperators> (); }
public LocalisationTagsLoader(string namespaceName, ScriptEngine engine) : base(engine) { loader = UnityEngine.Object.FindObjectOfType <ScriptsLoader>(); cNamespace.Name = namespaceName; exprInter = engine.GetPlugin <ExpressionInterpreter> (); filters = engine.GetPlugin <FiltersPlugin> (); functionOperators = engine.GetPlugin <EventFunctionOperators> (); }
internal static Delegate Compile(LambdaExpression lambda, ExpressionInterpreter interpreter) { if (lambda == null) { throw new ArgumentNullException("lambda"); } return(new Runner(lambda, interpreter).CreateDelegate()); }
public static object Interpret(LambdaExpression lambda, object[] arguments) { var interpreter = new ExpressionInterpreter(lambda, arguments); interpreter.Visit(lambda.Body); return(lambda.GetReturnType() != typeof(void) ? interpreter.Pop() : null); }
public RelationsMetricsLoader(string namespaceName, string typeName, Type targetFunc, ScriptEngine engine) : base(engine) { cNamespace.Name = namespaceName; exprInter = engine.GetPlugin <ExpressionInterpreter>(); functionOperators = engine.GetPlugin <EventFunctionOperators>(); codeType = new CodeTypeDeclaration(); codeType.Name = typeName; cNamespace.Types.Add(codeType); delegateMethod = targetFunc.GetMethod("Invoke"); }
public override void Interpret(Operator op, FunctionBlock block) { if (exprInterpreter == null) { exprInterpreter = Engine.GetPlugin <ExpressionInterpreter> (); ops = Engine.GetPlugin <EventFunctionOperators> (); } if (op.Args.Count == 1) { //Shouldn't declare variable IfStatement ifStatement = new IfStatement(); ifStatement.CheckExpression = exprInterpreter.InterpretExpression(op.Args [0], block).ExprString; ifStatement.TrueBlock = new FunctionBlock(block, block.Method, block.Type); block.Statements.Add(ifStatement); foreach (var entry in (op.Context as Context).Entries) { var subOp = entry as Operator; if (subOp == null) { continue; } var subInter = ops.GetInterpreter(subOp, ifStatement.TrueBlock); if (subInter == null) { Debug.LogFormat("Can't interpret operator {0} in {1}", subOp.Identifier, block.Method.Name); continue; } subInter.Interpret(subOp, ifStatement.TrueBlock); } } else if (op.Args.Count == 2) { DeclareVariableStatement declareVar = new DeclareVariableStatement(); if (op.Args [1].Operands [0] is IdWrapper) { var id = ((IdWrapper)op.Args [1].Operands [0]).ToString(); declareVar.Name = id; declareVar.Type = typeof(bool); declareVar.InitExpression = "false"; } else { Debug.Log("Wrong definition of an if operator with a variable - variable is not an identifier"); return; } block.Statements.Add(declareVar); //Should declare variable } }
private JsValue LastIndexOf(JsValue thisObj, JsValue[] arguments) { var o = ArrayOperations.For(Engine, thisObj); var len = o.GetLength(); if (len == 0) { return(-1); } var n = arguments.Length > 1 ? TypeConverter.ToInteger(arguments[1]) : len - 1; double k; if (n >= 0) { k = System.Math.Min(n, len - 1); // min } else { k = len - System.Math.Abs(n); } if (k < 0 || k > uint.MaxValue) { return(-1); } var searchElement = arguments.At(0); var i = (uint)k; for (;; i--) { JsValue value; if (o.TryGetValue(i, out value)) { var same = ExpressionInterpreter.StrictlyEqual(value, searchElement); if (same) { return(i); } } if (i == 0) { break; } } return(-1); }
private JsValue IndexOf(JsValue thisObj, JsValue[] arguments) { var o = TypeConverter.ToObject(Engine, thisObj); var lenValue = o.Get("length"); var len = TypeConverter.ToUint32(lenValue); if (len == 0) { return(-1); } var n = arguments.Length > 1 ? TypeConverter.ToInteger(arguments[1]) : 0; if (n >= len) { return(-1); } double k; if (n >= 0) { k = n; } else { k = len - System.Math.Abs(n); if (k < 0) { k = 0; } } var searchElement = arguments.At(0); for (; k < len; k++) { var kString = TypeConverter.ToString(k); var kPresent = o.HasProperty(kString); if (kPresent) { var elementK = o.Get(kString); var same = ExpressionInterpreter.StrictlyEqual(elementK, searchElement); if (same) { return(k); } } } return(-1); }
private Expression Evaluate(Expression e) { if (e.NodeType == ExpressionType.Constant) { return(e.Type.IsPrimitive || ((ConstantExpression)e).Value == null ? e : new SqlConstantPlaceholderExpression(this.index++, (ConstantExpression)e)); } if (e.NodeType == (ExpressionType)SqlExpressionType.ConstantPlaceholder) { return(e); } var value = ExpressionInterpreter.Interpret(e); return(new SqlConstantPlaceholderExpression(this.index++, Expression.Constant(value, e.Type))); }
private Expression Evaluate(Expression e) { object value; if (e.NodeType == ExpressionType.Constant) { return(e); } else if (e.NodeType == ExpressionType.Convert && ((UnaryExpression)e).Operand.NodeType == ExpressionType.Constant) { var unaryExpression = (UnaryExpression)e; var constantValue = ((ConstantExpression)(((UnaryExpression)e).Operand)).Value; if (constantValue == null) { return(Expression.Constant(null, e.Type)); } if (unaryExpression.Type.IsNullableType()) { return(Expression.Constant(Convert.ChangeType(constantValue, Nullable.GetUnderlyingType(unaryExpression.Type)), e.Type)); } else { return(Expression.Constant(Convert.ChangeType(constantValue, unaryExpression.Type), e.Type)); } } else if (e.NodeType == ExpressionType.Convert && ((UnaryExpression)e).Operand.Type.GetUnwrappedNullableType().IsEnum) { value = ExpressionInterpreter.Interpret(e); return(Expression.Constant(value, e.Type)); } else if (e.NodeType == (ExpressionType)SqlExpressionType.ConstantPlaceholder) { return(e); } else { value = ExpressionInterpreter.Interpret(e); return(new SqlConstantPlaceholderExpression(this.index++, Expression.Constant(value, e.Type))); } }
public T GetDefaultValue() { if (!this.computedDefaultValue) { if (this.defaultValueExpression == null) { this.defaultValue = default(T); } else { this.defaultValue = (T)ExpressionInterpreter.Interpret(this.defaultValueExpression); } this.computedDefaultValue = true; } return(this.defaultValue); }
public override void Interpret(Operator op, FunctionBlock block) { if (exprInter == null) { exprInter = Engine.GetPlugin <ExpressionInterpreter>(); } if (op.Args.Count == 2) { block.Method.ReturnType = new CodeTypeReference(typeof(IEnumerator)); block.Method.Attributes = MemberAttributes.Public; block.Method.Name = "ActionCoroutine"; if (!block.Method.UserData.Contains("has_transformed_action")) { var newActionMethod = new CodeMemberMethod(); newActionMethod.Name = "Action"; newActionMethod.Attributes = MemberAttributes.Public | MemberAttributes.Override; newActionMethod.Statements.Add(new CodeSnippetStatement("Coroutine = ActionCoroutine(); state = ActionState.Started;")); block.Type.Members.Add(newActionMethod); block.Method.UserData.Add("has_transformed_action", "has_transformed_action"); } var whileArg = exprInter.InterpretExpression(op.Args[0], block); var failArg = exprInter.InterpretExpression(op.Args[1], block); string operatorString = null; operatorString = string.Format("while({0}){{ if({1}) {{ this.state = EventAction.ActionState.Failed; yield break; }} yield return null; }}", whileArg.ExprString, failArg.ExprString); if (op.Context is Expression) { var timeArg = exprInter.InterpretExpression(op.Context as Expression, block); if (timeArg.Type != typeof(bool)) { operatorString = string.Format("float time{2} = UnityEngine.Time.realtimeSinceStartup; while({0}){{ if ((UnityEngine.Time.RealtimeSinceStartup - time{2} > {3}) || ({1})) {{ this.state = EventAction.ActionState.Failed; yield break; }} yield return null; }}", whileArg.ExprString, failArg.ExprString, DeclareVariableStatement.VariableId++, timeArg.ExprString); } } if (operatorString != null) { block.Statements.Add(operatorString); } } }
private JsValue LastIndexOf(JsValue thisObj, JsValue[] arguments) { var o = TypeConverter.ToObject(Engine, thisObj); var lenValue = o.Get("length"); var len = TypeConverter.ToUint32(lenValue); if (len == 0) { return(-1); } var n = arguments.Length > 1 ? TypeConverter.ToInteger(arguments[1]) : len - 1; Money k; if (n >= 0) { k = Money.Min(n, len - 1); // min } else { k = len - Money.Abs(n); } var searchElement = arguments.At(0); for (; k >= 0; k--) { var kString = TypeConverter.ToString(k); var kPresent = o.HasProperty(kString); if (kPresent) { var elementK = o.Get(kString); var same = ExpressionInterpreter.StrictlyEqual(elementK, searchElement); if (same) { return(k); } } } return(-1); }
public SkryptEngine(Options options) { GlobalEnvironment = new LexicalEnvironment(); ErrorHandler = new DefaultErrorHandler(this); ExpressionInterpreter = new ExpressionInterpreter(this); TemplateMaker = new TemplateMaker(this); FileHandler = new DefaultFileHandler(this); Visitor = new SkryptVisitor(this); Enumerable = FastAdd(new EnumerableTrait(this)); Iterator = FastAdd(new IteratorTrait(this)); AddableTrait = FastAdd(new AddableTrait(this)); SubtractableTrait = FastAdd(new SubtractableTrait(this)); DividableTrait = FastAdd(new DividableTrait(this)); MultiplicableTrait = FastAdd(new MultiplicableTrait(this)); Number = FastAdd(new NumberType(this)); String = FastAdd(new StringType(this)); Boolean = FastAdd(new BooleanType(this)); Vector = FastAdd(new VectorType(this)); Vector2 = FastAdd(new Vector2Type(this)); Vector3 = FastAdd(new Vector3Type(this)); Vector4 = FastAdd(new Vector4Type(this)); Array = FastAdd(new ArrayType(this)); Exception = FastAdd(new ExceptionType(this)); Math = FastAdd(new MathModule(this)); IO = FastAdd(new IOModule(this)); Memory = FastAdd(new MemoryModule(this)); Debug = FastAdd(new DebugModule(this)); if (options != null) { _discardGlobal = options.DiscardGlobal; _maxRecursionDepth = options.MaxRecursionDepth; MemoryLimit = options.MaxMemory; HaltMemory = options.MemoryHalt; } }
public override void Interpret(Operator op, FunctionBlock block) { if (exprInter == null) { exprInter = Engine.GetPlugin <ExpressionInterpreter>(); } if (op.Args.Count > 0 && op.Args[0].Operands[0] is ExprAtom && (op.Args[0].Operands[0] as ExprAtom).Content is Scope && ((op.Args[0].Operands[0] as ExprAtom).Content as Scope).Parts.Count == 1) { var part = ((op.Args[0].Operands[0] as ExprAtom).Content as Scope).Parts[0]; if (!(part is string)) { Debug.Log("Wrong remove_from definition"); return; } var listName = NameTranslator.CSharpNameFromScript(part as string); DeclareVariableStatement declareVar = block.FindStatement <DeclareVariableStatement>(v => v.IsContext && v.Type.GetProperty(listName) != null); //Debug.Log (declareVar.DebugString ()); if (declareVar == null) { Debug.Log("remove_from operator can't find context variable"); } else { if (op.Context is Expression) { var exprValue = exprInter.InterpretExpression(op.Context as Expression, block); //block = exprValue.NotNullBlock; block.Statements.Add(String.Format("{0}.{1}.Remove({2});", declareVar.Name, listName, exprValue.ExprString)); } } } else { Debug.Log("Wrong remove_from definition"); } }
public override void Interpret(Operator op, FunctionBlock block) { if (exprInterpreter == null) { exprInterpreter = Engine.GetPlugin <ExpressionInterpreter> (); ops = Engine.GetPlugin <EventFunctionOperators> (); } if (op.Args.Count == 1) { ForStatement stmt = new ForStatement(); stmt.RepeatBlock = new FunctionBlock(block, block.Method, block.Type); stmt.InsideExpr = String.Format("int i = 0; i < {0}; i++", exprInterpreter.InterpretExpression(op.Args [0], block).ExprString); block.Statements.Add(stmt); foreach (var entry in (op.Context as Context).Entries) { var subOp = entry as Operator; if (subOp == null) { continue; } var subInter = ops.GetInterpreter(subOp, stmt.RepeatBlock); if (subInter == null) { Debug.LogFormat("Can't interpret operator {0} in {1}", subOp.Identifier, block.Method.Name); continue; } //Debug.Log (subOp.Identifier); subInter.Interpret(subOp, stmt.RepeatBlock); } } else { Debug.Log("Error in repeat definion - more or less than one argument"); } }
public string TryGetFriendlyMessage() { foreach (var pattern in _patterns) { if (pattern.IsMatch(_assertionPart.Assertion)) { try { var visitor = new ExpressionInterpreter(_assertionPart.Assertion, pattern); visitor.Visit(_assertionPart.Assertion); if (visitor.FriendlyMessage != null) { return(visitor.FriendlyMessage); } } catch { } } } return(null); }
public void ExpressionInterpreterTest() { var actual = ExpressionInterpreter.Compute(Parser.Parse("- 2 * z / Math.Pow(2, x * PI)"), new[] { new ExpressionParameter("x", 1.0), new ExpressionParameter("z", 2.0), new ExpressionParameter("PI", Math.PI), }, (name, parameters) => { switch (name) { case "Math.Pow": { var args = parameters.Select(Convert.ToDouble).ToList(); if (args.Count != 2) { throw new InvalidOperationException("Wrong number of arguments passed to Math.Pow. Expected (double x, double y)"); } return((decimal)Math.Pow(args[0], args[1])); } default: throw new NotSupportedException(string.Format("Function is not supported: {0}", name)); } }); Assert.AreEqual(-0.4532589291870443972585070297m, actual); }
public override void Interpret(Operator op, FunctionBlock block) { interpret = false; if (exprInter == null) { switches = Engine.GetPlugin <ContextSwitchesPlugin> (); ops = Engine.GetPlugin <EventFunctionOperators> (); exprInter = Engine.GetPlugin <ExpressionInterpreter> (); } var varName = op.Identifier as string; if (ScriptEngine.AnalyzeDebug) { Debug.Log(block); } var sCtx = block.FindStatement <ContextStatement> (v => v.InterpretInContext(op, block) != null && v.ContextVar.IsContext || v.ContextVar.IsArg); var context = sCtx != null ? sCtx.ContextVar : null; if (ScriptEngine.AnalyzeDebug) { Debug.LogFormat("FOUND COUNTEXT {0} for {1}", context, op.Identifier); } if (listT == null) { if (!(op.Context is Expression)) { return; } if (ScriptEngine.AnalyzeDebug) { Debug.Log("PROPERTY " + propName); } if (context == null) { block.Statements.Add(String.Format("root.{0} = ({2})({1});", propName, exprInter.InterpretExpression(op.Context as Expression, block).ExprString, TypeName.NameOf(propType))); } else { block.Statements.Add(String.Format("{2}.{0} = ({3})({1});", propName, exprInter.InterpretExpression(op.Context as Expression, block).ExprString, context.Name, TypeName.NameOf(propType))); } } else { Debug.Log("list of" + listT); ForStatement statement = new ForStatement(); string listVarName = context == null ? "root." + propName : context.Name + "." + propName; string iterName = "i" + DeclareVariableStatement.VariableId++; statement.InsideExpr = String.Format("int {0} = 0; {1} != null && {0} < {1}.Count; {0}++", iterName, listVarName); FunctionBlock repeatBlock = new FunctionBlock(block, block.Method, block.Type); statement.RepeatBlock = repeatBlock; block.Statements.Add(statement); Operator listVarOp = new Operator(); DeclareVariableStatement listVar = new DeclareVariableStatement(); listVar.Name = "iter" + DeclareVariableStatement.VariableId++; listVar.IsContext = true; listVar.IsNew = true; listVar.Type = listT; listVar.InitExpression = String.Format("{0}[{1}]", listVarName, iterName); statement.RepeatBlock.Statements.Add(listVar); var inter = switches.GetInterByType(listT); //Debug.Log(inter); inter.Interpret(op, repeatBlock); } interpret = true; }
public override void Interpret(Operator op, FunctionBlock block) { if (ScriptEngine.AnalyzeDebug) { Debug.LogWarning("Context function " + op.Identifier); } if (exprInter == null) { exprInter = Engine.GetPlugin <ExpressionInterpreter> (); } var any = BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static; var sCtx = block.FindStatement <ContextStatement> (v => v.InterpretInContext(op, block) != null && (v.ContextVar.IsContext || v.ContextVar.IsArg)); var contextVar = sCtx != null ? sCtx.ContextVar : null; //var contextVar = block.FindStatement<DeclareVariableStatement> (v => ); StringBuilder argsBuilder = new StringBuilder(); // if (((op.Context is Expression) && op.Args.Count + 1 != argsDef.Length) || // ((op.Context is Context) && op.Args.Count != argsDef.Length)) // { // Debug.Log ("Wrong amount of arguments"); // return; // } for (int i = 0; i < op.Args.Count; i++) { if (argsDef [i].ParameterType.IsSubclassOf(typeof(Delegate))) { argsBuilder.Append(exprInter.InterpretClosure(op.Args [i], block, argsDef [i].ParameterType).ExprString).Append(","); } else if (argsDef [i].ParameterType == typeof(string)) { argsBuilder.Append('(').Append(exprInter.InterpretExpression(op.Args [i], block).ExprString).Append(')').Append(".ToString()").Append(","); } else { argsBuilder.Append('(').Append(argsDef [i].ParameterType).Append(')').Append('(').Append(exprInter.InterpretExpression(op.Args [i], block).ExprString).Append(')').Append(","); } } if (op.Context is Expression) { if (argsDef [argsDef.Length - 1].ParameterType.IsSubclassOf(typeof(Delegate))) { argsBuilder. Append('('). Append(argsDef [argsDef.Length - 1].ParameterType). Append(')'). Append('('). Append(exprInter.InterpretClosure(op.Context as Expression, block, argsDef [argsDef.Length - 1].ParameterType).ExprString). Append(')'); } else if (argsDef [argsDef.Length - 1].ParameterType == typeof(string)) { argsBuilder.Append('(').Append(exprInter.InterpretExpression(op.Context as Expression, block).ExprString).Append(')').Append(".ToString()"); } else { argsBuilder. Append('('). Append(argsDef [argsDef.Length - 1].ParameterType). Append(')'). Append('('). Append(exprInter.InterpretExpression(op.Context as Expression, block).ExprString). Append(')'); } if (contextVar == null) { block.Statements.Add(string.Format("root.{0}({1});", funcName, argsBuilder)); } else { block.Statements.Add(string.Format("{2}.{0}({1});", funcName, argsBuilder, contextVar.Name)); } } else if (ctxInter != null) { if (op.Args.Count > 0) { argsBuilder.Length -= 1; } var ctx = op.Context as Context; FunctionBlock contextBlock = new FunctionBlock(block); block.Statements.Add(contextBlock); block = contextBlock; DeclareVariableStatement ctxVar = new DeclareVariableStatement(); ctxVar.Name = "FuncCtx" + DeclareVariableStatement.VariableId++; ctxVar.InitExpression = contextVar == null?string.Format("root.{0}({1});", funcName, argsBuilder) : string.Format("{2}.{0}({1});", funcName, argsBuilder, contextVar.Name); ctxVar.Type = returnType; ctxVar.IsContext = true; ContextStatement stmt = new ContextStatement(); stmt.ContextVar = ctxVar; stmt.InterpretInContext = ctxInter.InterpretInContext; block.Statements.Add(ctxVar); block.Statements.Add(stmt); IfStatement isNotNull = new IfStatement(); isNotNull.CheckExpression = String.Format("{0} != null", ctxVar.Name); isNotNull.TrueBlock = new FunctionBlock(block); block.Statements.Add(isNotNull); block = isNotNull.TrueBlock; for (int i = 0; i < ctx.Entries.Count; i++) { ops.GetInterpreter(ctx.Entries [i] as Operator, block).Interpret(ctx.Entries [i] as Operator, block); } } else { //Func doesn't return a context, while maybe allows for either lambda as value or context addition var lastArg = argsDef.Length > 0 ? argsDef [argsDef.Length - 1] : null; if (lastArg != null) { if (typeof(Delegate).IsAssignableFrom(lastArg.ParameterType)) { Debug.Log("LAMBDA!"); //Interpret as lambda LambdaStatement lambda = new LambdaStatement(); lambda.DelegateType = lastArg.ParameterType; var method = lastArg.ParameterType.GetMethod("Invoke"); lambda.Params = method.GetParameters(); lambda.Name = "Lambda" + DeclareVariableStatement.VariableId++; block.Statements.Add(lambda); lambda.Block = new FunctionBlock(block); //DeclareVariableStatement lastVar = null; foreach (var param in lambda.Params) { var argVar = new DeclareVariableStatement(); // lastVar = argVar; argVar.Name = param.Name; argVar.IsArg = true; argVar.Type = param.ParameterType; lambda.Block.Statements.Add(argVar); } //if (lastVar != null) // lastVar.IsContext = true; var retType = lambda.DelegateType.GetMethod("Invoke").ReturnType; bool hasReturn = false; if (retType != null && retType != typeof(void)) { hasReturn = true; lambda.Block.Statements.Add(new DeclareVariableStatement() { Name = "return_value", InitExpression = string.Format("default({0})", retType), IsReturn = true, Type = retType }); } foreach (var entry in (op.Context as Context).Entries) { var subOp = entry as Operator; ops.GetInterpreter(subOp, lambda.Block).Interpret(subOp, lambda.Block); } if (hasReturn) { lambda.Block.Statements.Add("return return_value;"); } //Don't forget to call a function and add an arugment argsBuilder.Append(lambda.Name); if (contextVar == null) { block.Statements.Add(string.Format("root.{0}({1});", funcName, argsBuilder)); } else { block.Statements.Add(string.Format("{2}.{0}({1});", funcName, argsBuilder, contextVar.Name)); } } else if (addContextInter != null) { //Interpret as new value DeclareVariableStatement newVar = new DeclareVariableStatement(); newVar.Name = "NewArg" + DeclareVariableStatement.VariableId++; newVar.IsContext = true; newVar.Type = lastArg.ParameterType; if (contextVar == null) { newVar.InitExpression = String.Format("root.AddComponent<{0}>()", newVar.Type); } else { newVar.InitExpression = String.Format("{0}.AddComponent<{0}>()", contextVar.Name, newVar.Type); } FunctionBlock contextBlock = new FunctionBlock(block); contextBlock.Statements.Add(newVar); addContextInter.Interpret(op, contextBlock); argsBuilder.Append(newVar.Name); if (contextVar == null) { contextBlock.Statements.Add(string.Format("root.{0}({1});", funcName, argsBuilder)); } else { contextBlock.Statements.Add(string.Format("{2}.{0}({1});", funcName, argsBuilder, contextVar.Name)); } block.Statements.Add(contextBlock); } } } }
public ExpressionInterpreterTest() { _statusUtil = new Mock<IStatusUtil>(MockBehavior.Strict); _interpreter = new ExpressionInterpreter(_statusUtil.Object); }
public override void Init() { switches = Engine.GetPlugin <ContextSwitchesPlugin> (); exprInter = Engine.GetPlugin <ExpressionInterpreter> (); }
/// <summary> /// Creates or alters the named own property to /// have the state described by a Property /// Descriptor. The flag controls failure handling. /// </summary> /// <param name="propertyName"></param> /// <param name="desc"></param> /// <param name="throwOnError"></param> /// <returns></returns> public virtual bool DefineOwnProperty(string propertyName, PropertyDescriptor desc, bool throwOnError) { var current = GetOwnProperty(propertyName); if (current == desc) { return(true); } if (current == PropertyDescriptor.Undefined) { if (!Extensible) { if (throwOnError) { throw new JavaScriptException(Engine.TypeError); } return(false); } else { if (desc.IsGenericDescriptor() || desc.IsDataDescriptor()) { SetOwnProperty(propertyName, new PropertyDescriptor(desc) { Value = desc.Value != null ? desc.Value : JsValue.Undefined, Writable = desc.Writable.HasValue ? desc.Writable.Value : false, Enumerable = desc.Enumerable.HasValue ? desc.Enumerable.Value : false, Configurable = desc.Configurable.HasValue ? desc.Configurable.Value : false }); } else { SetOwnProperty(propertyName, new PropertyDescriptor(desc) { Get = desc.Get, Set = desc.Set, Enumerable = desc.Enumerable.HasValue ? desc.Enumerable : false, Configurable = desc.Configurable.HasValue ? desc.Configurable : false, }); } } return(true); } // Step 5 if (!current.Configurable.HasValue && !current.Enumerable.HasValue && !current.Writable.HasValue && current.Get == null && current.Set == null && current.Value == null) { return(true); } // Step 6 if ( current.Configurable == desc.Configurable && current.Writable == desc.Writable && current.Enumerable == desc.Enumerable && ((current.Get == null && desc.Get == null) || (current.Get != null && desc.Get != null && ExpressionInterpreter.SameValue(current.Get, desc.Get))) && ((current.Set == null && desc.Set == null) || (current.Set != null && desc.Set != null && ExpressionInterpreter.SameValue(current.Set, desc.Set))) && ((current.Value == null && desc.Value == null) || (current.Value != null && desc.Value != null && ExpressionInterpreter.StrictlyEqual(current.Value, desc.Value))) ) { return(true); } if (!current.Configurable.HasValue || !current.Configurable.Value) { if (desc.Configurable.HasValue && desc.Configurable.Value) { if (throwOnError) { throw new JavaScriptException(Engine.TypeError); } return(false); } if (desc.Enumerable.HasValue && (!current.Enumerable.HasValue || desc.Enumerable.Value != current.Enumerable.Value)) { if (throwOnError) { throw new JavaScriptException(Engine.TypeError); } return(false); } } if (!desc.IsGenericDescriptor()) { if (current.IsDataDescriptor() != desc.IsDataDescriptor()) { if (!current.Configurable.HasValue || !current.Configurable.Value) { if (throwOnError) { throw new JavaScriptException(Engine.TypeError); } return(false); } if (current.IsDataDescriptor()) { SetOwnProperty(propertyName, current = new PropertyDescriptor( get: Undefined.Instance, set: Undefined.Instance, enumerable: current.Enumerable, configurable: current.Configurable )); } else { SetOwnProperty(propertyName, current = new PropertyDescriptor( value: Undefined.Instance, writable: null, enumerable: current.Enumerable, configurable: current.Configurable )); } } else if (current.IsDataDescriptor() && desc.IsDataDescriptor()) { if (!current.Configurable.HasValue || current.Configurable.Value == false) { if (!current.Writable.HasValue || !current.Writable.Value && desc.Writable.HasValue && desc.Writable.Value) { if (throwOnError) { throw new JavaScriptException(Engine.TypeError); } return(false); } if (!current.Writable.Value) { if (desc.Value != null && !ExpressionInterpreter.SameValue(desc.Value, current.Value)) { if (throwOnError) { throw new JavaScriptException(Engine.TypeError); } return(false); } } } } else if (current.IsAccessorDescriptor() && desc.IsAccessorDescriptor()) { if (!current.Configurable.HasValue || !current.Configurable.Value) { if ((desc.Set != null && !ExpressionInterpreter.SameValue(desc.Set, current.Set != null ? current.Set : Undefined.Instance)) || (desc.Get != null && !ExpressionInterpreter.SameValue(desc.Get, current.Get != null ? current.Get : Undefined.Instance))) { if (throwOnError) { throw new JavaScriptException(Engine.TypeError); } return(false); } } } } if (desc.Value != null) { current.Value = desc.Value; } if (desc.Writable.HasValue) { current.Writable = desc.Writable; } if (desc.Enumerable.HasValue) { current.Enumerable = desc.Enumerable; } if (desc.Configurable.HasValue) { current.Configurable = desc.Configurable; } if (desc.Get != null) { current.Get = desc.Get; } if (desc.Set != null) { current.Set = desc.Set; } return(true); }
public ExpressionInterpreterTest() { _statusUtil = new Mock<IStatusUtil>(MockBehavior.Strict); _interpreter = new ExpressionInterpreter(_statusUtil.Object, null, null, new Dictionary<string, VariableValue>(), null); }
public ExpressionInterpreterTest() { _statusUtil = new Mock <IStatusUtil>(MockBehavior.Strict); _interpreter = new ExpressionInterpreter(_statusUtil.Object); }
private JsValue IndexOf(JsValue thisObj, JsValue[] arguments) { var o = ArrayOperations.For(Engine, thisObj); var len = o.GetLength(); if (len == 0) { return(-1); } var startIndex = arguments.Length > 1 ? TypeConverter.ToInteger(arguments[1]) : 0; if (startIndex > uint.MaxValue) { return(-1); } uint k; if (startIndex < 0) { var abs = System.Math.Abs(startIndex); long temp = len - (uint)abs; if (abs > len || temp < 0) { temp = 0; } k = (uint)temp; } else { k = (uint)startIndex; } if (k >= len) { return(-1); } uint smallestIndex = o.GetSmallestIndex(); if (smallestIndex > k) { k = smallestIndex; } var searchElement = arguments.At(0); for (; k < len; k++) { JsValue elementK; if (o.TryGetValue(k, out elementK)) { var same = ExpressionInterpreter.StrictlyEqual(elementK, searchElement); if (same) { return(k); } } } return(-1); }
public override void Interpret(InternalDSL.Operator op, FunctionBlock block) { if (ops == null) { ctxs = Engine.GetPlugin <ContextSwitchesPlugin> (); ops = Engine.GetPlugin <EventFunctionOperators> (); exprInter = Engine.GetPlugin <ExpressionInterpreter> (); } if (op.Args.Count > 0) { var varName = ((op.Args [0].Operands [0] as ExprAtom).Content as Scope).Parts [0] as string; if (op.Context is Expression) { //cache(some_name) = expression // var varDecl = block.FindStatement<DeclareVariableStatement> (v => v.Name == varName); // varDecl.IsArg = true; var exprValue = exprInter.InterpretExpression(op.Context as Expression, block); Debug.Log(exprValue.ExprString); var field = new CodeMemberField(exprValue.Type, varName); field.UserData.Add("type", exprValue.Type); block.Type.Members.Add(field); block.Statements.Add(String.Format("{0} = {1};", varName, exprValue.ExprString)); block.Statements.Add(new DeclareVariableStatement() { Name = varName, IsArg = true, Type = exprValue.Type }); //var varDecl = block.FindStatement<DeclareVariableStatement> (v => v.Name == varName); } else { //cache(some_name, scope) = { ... } var exprValue = exprInter.InterpretExpression(op.Args [1], block); var field = new CodeMemberField(exprValue.Type, varName); field.UserData.Add("type", exprValue.Type); block.Type.Members.Add(field); DeclareVariableStatement cachedVar = new DeclareVariableStatement(); cachedVar.Name = varName; cachedVar.IsContext = true; cachedVar.Type = exprValue.Type; cachedVar.IsArg = true; block.Statements.Add(cachedVar); block.Statements.Add(String.Format("{0} = {1};", varName, exprValue.ExprString)); block.Statements.Add(new DeclareVariableStatement() { Name = varName, IsArg = true, Type = exprValue.Type }); var inter = ctxs.GetInterByType(exprValue.Type); inter.Interpret(op, block); } } else { //cache = some_name var varName = (((op.Context as Expression).Operands [0] as ExprAtom).Content as Scope).Parts [0] as string; var varDecl = block.FindStatement <DeclareVariableStatement> (v => v.Name == varName); //varDecl.IsArg = true; varDecl.IsDeclaration = false; var field = new CodeMemberField(varDecl.Type, varDecl.Name); field.UserData.Add("type", varDecl.Type); block.Type.Members.Add(field); //block.Statements.Add (String.Format ("this.{0} = {0};", varName)); } //new CodeMemberField() //block.Type.Members.Add (); }
/// <summary> /// Creates or alters the named own property to /// have the state described by a Property /// Descriptor. The flag controls failure handling. /// </summary> /// <param name="propertyName"></param> /// <param name="desc"></param> /// <param name="throwOnError"></param> /// <returns></returns> public virtual bool DefineOwnProperty(string propertyName, PropertyDescriptor desc, bool throwOnError) { var current = GetOwnProperty(propertyName); if (current == PropertyDescriptor.Undefined) { if (!Extensible) { if (throwOnError) { throw new JavaScriptException(Engine.TypeError); } return(false); } else { if (desc.IsGenericDescriptor() || desc.IsDataDescriptor()) { Properties[propertyName] = new PropertyDescriptor(desc) { Value = desc.Value.HasValue ? desc.Value : JsValue.Undefined, Writable = desc.Writable.HasValue ? desc.Writable : false }; } else { Properties[propertyName] = new PropertyDescriptor(desc) { Enumerable = desc.Enumerable.HasValue ? desc.Enumerable : false, Configurable = desc.Configurable.HasValue ? desc.Configurable : false, }; } } return(true); } // Step 5 if (!current.Configurable.HasValue && !current.Enumerable.HasValue && !current.Writable.HasValue && !current.Get.HasValue && !current.Set.HasValue && !current.Value.HasValue) { return(true); } // Step 6 var configurableIsSame = current.Configurable.HasValue ? desc.Configurable.HasValue && (current.Configurable.Value == desc.Configurable.Value) : !desc.Configurable.HasValue; var enumerableIsSame = current.Enumerable.HasValue ? desc.Enumerable.HasValue && (current.Enumerable.Value == desc.Enumerable.Value) : !desc.Enumerable.HasValue; var writableIsSame = true; var valueIsSame = true; if (current.IsDataDescriptor() && desc.IsDataDescriptor()) { var currentDataDescriptor = current; var descDataDescriptor = desc; writableIsSame = currentDataDescriptor.Writable.HasValue ? descDataDescriptor.Writable.HasValue && (currentDataDescriptor.Writable.Value == descDataDescriptor.Writable.Value) : !descDataDescriptor.Writable.HasValue; var valueA = currentDataDescriptor.Value.HasValue ? currentDataDescriptor.Value.Value : Undefined.Instance; var valueB = descDataDescriptor.Value.HasValue ? descDataDescriptor.Value.Value : Undefined.Instance; valueIsSame = ExpressionInterpreter.SameValue(valueA, valueB); } else if (current.IsAccessorDescriptor() && desc.IsAccessorDescriptor()) { var currentAccessorDescriptor = current; var descAccessorDescriptor = desc; var getValueA = currentAccessorDescriptor.Get.HasValue ? currentAccessorDescriptor.Get.Value : Undefined.Instance; var getValueB = descAccessorDescriptor.Get.HasValue ? descAccessorDescriptor.Get.Value : Undefined.Instance; var setValueA = currentAccessorDescriptor.Set.HasValue ? currentAccessorDescriptor.Set.Value : Undefined.Instance; var setValueB = descAccessorDescriptor.Set.HasValue ? descAccessorDescriptor.Set.Value : Undefined.Instance; valueIsSame = ExpressionInterpreter.SameValue(getValueA, getValueB) && ExpressionInterpreter.SameValue(setValueA, setValueB); } else { valueIsSame = false; } if (configurableIsSame && enumerableIsSame && writableIsSame && valueIsSame) { return(true); } if (!current.Configurable.HasValue || !current.Configurable.Value.AsBoolean()) { if (desc.Configurable.HasValue && desc.Configurable.Value.AsBoolean()) { if (throwOnError) { throw new JavaScriptException(Engine.TypeError); } return(false); } if (desc.Enumerable.HasValue && (!current.Enumerable.HasValue || desc.Enumerable.Value != current.Enumerable.Value)) { if (throwOnError) { throw new JavaScriptException(Engine.TypeError); } return(false); } } if (!desc.IsGenericDescriptor()) { if (current.IsDataDescriptor() != desc.IsDataDescriptor()) { if (!current.Configurable.HasValue || !current.Configurable.Value.AsBoolean()) { if (throwOnError) { throw new JavaScriptException(Engine.TypeError); } return(false); } if (current.IsDataDescriptor()) { Properties[propertyName] = current = new PropertyDescriptor( get: Undefined.Instance, set: Undefined.Instance, enumerable: current.Enumerable.HasValue && current.Enumerable.Value.AsBoolean(), configurable: current.Configurable.HasValue && current.Configurable.Value.AsBoolean() ); } else { Properties[propertyName] = current = new PropertyDescriptor( value: Undefined.Instance, writable: null, enumerable: current.Enumerable.HasValue && current.Enumerable.Value.AsBoolean(), configurable: current.Configurable.HasValue && current.Configurable.Value.AsBoolean() ); } } else if (current.IsDataDescriptor() && desc.IsDataDescriptor()) { if (!current.Configurable.HasValue || current.Configurable.Value.AsBoolean() == false) { if (!current.Writable.HasValue || !current.Writable.Value.AsBoolean() && desc.Writable.HasValue && desc.Writable.Value.AsBoolean()) { if (throwOnError) { throw new JavaScriptException(Engine.TypeError); } return(false); } if (!current.Writable.Value.AsBoolean()) { if (desc.Value.HasValue && !valueIsSame) { if (throwOnError) { throw new JavaScriptException(Engine.TypeError); } return(false); } } } } else if (current.IsAccessorDescriptor() && desc.IsAccessorDescriptor()) { if (!current.Configurable.HasValue || !current.Configurable.Value.AsBoolean()) { if ((desc.Set.HasValue && !ExpressionInterpreter.SameValue(desc.Set.Value, current.Set.HasValue ? current.Set.Value : Undefined.Instance)) || (desc.Get.HasValue && !ExpressionInterpreter.SameValue(desc.Get.Value, current.Get.HasValue ? current.Get.Value : Undefined.Instance))) { if (throwOnError) { throw new JavaScriptException(Engine.TypeError); } return(false); } } } } if (desc.Value.HasValue) { current.Value = desc.Value; } if (desc.Writable.HasValue) { current.Writable = desc.Writable; } if (desc.Enumerable.HasValue) { current.Enumerable = desc.Enumerable; } if (desc.Configurable.HasValue) { current.Configurable = desc.Configurable; } if (desc.Get.HasValue) { current.Get = desc.Get; } if (desc.Set.HasValue) { current.Set = desc.Set; } return(true); }
public Engine(Action <Options> options) { _executionContexts = new Stack <ExecutionContext>(); Global = GlobalObject.CreateGlobalObject(this); Object = ObjectConstructor.CreateObjectConstructor(this); Function = FunctionConstructor.CreateFunctionConstructor(this); Array = ArrayConstructor.CreateArrayConstructor(this); String = StringConstructor.CreateStringConstructor(this); RegExp = RegExpConstructor.CreateRegExpConstructor(this); Number = NumberConstructor.CreateNumberConstructor(this); Boolean = BooleanConstructor.CreateBooleanConstructor(this); Date = DateConstructor.CreateDateConstructor(this); Math = MathInstance.CreateMathObject(this); Json = JsonInstance.CreateJsonObject(this); Error = ErrorConstructor.CreateErrorConstructor(this, "Error"); EvalError = ErrorConstructor.CreateErrorConstructor(this, "EvalError"); RangeError = ErrorConstructor.CreateErrorConstructor(this, "RangeError"); ReferenceError = ErrorConstructor.CreateErrorConstructor(this, "ReferenceError"); SyntaxError = ErrorConstructor.CreateErrorConstructor(this, "SyntaxError"); TypeError = ErrorConstructor.CreateErrorConstructor(this, "TypeError"); UriError = ErrorConstructor.CreateErrorConstructor(this, "URIError"); // Because the properties might need some of the built-in object // their configuration is delayed to a later step Global.Configure(); Object.Configure(); Object.PrototypeObject.Configure(); Function.Configure(); Function.PrototypeObject.Configure(); Array.Configure(); Array.PrototypeObject.Configure(); String.Configure(); String.PrototypeObject.Configure(); RegExp.Configure(); RegExp.PrototypeObject.Configure(); Number.Configure(); Number.PrototypeObject.Configure(); Boolean.Configure(); Boolean.PrototypeObject.Configure(); Date.Configure(); Date.PrototypeObject.Configure(); Math.Configure(); Json.Configure(); Error.Configure(); Error.PrototypeObject.Configure(); // create the global environment http://www.ecma-international.org/ecma-262/5.1/#sec-10.2.3 GlobalEnvironment = new LexicalEnvironment(); GlobalEnvironment.Setup(new ObjectEnvironmentRecord(this, Global, false), null); // create the global execution context http://www.ecma-international.org/ecma-262/5.1/#sec-10.4.1.1 EnterExecutionContext(GlobalEnvironment, GlobalEnvironment, Global); Options = new Options(); if (options != null) { options(Options); } Eval = new EvalFunctionInstance(this, new string[0], LexicalEnvironment.NewDeclarativeEnvironment(this, ExecutionContext.LexicalEnvironment), StrictModeScope.IsStrictModeCode); Global.FastAddProperty("eval", Eval, true, false, true); _statements = new StatementInterpreter(this); _expressions = new ExpressionInterpreter(this); if (Options._IsClrAllowed) { Global.FastAddProperty("System", new NamespaceReference(this, "System"), false, false, false); Global.FastAddProperty("importNamespace", new ClrFunctionInstance(this, (thisObj, arguments) => { return(new NamespaceReference(this, TypeConverter.ToString(arguments.At(0)))); }), false, false, false); } ClrTypeConverter = new DefaultTypeConverter(this); BreakPoints = new List <BreakPoint>(); DebugHandler = new DebugHandler(this); }
private Expression Evaluate(Expression e) { object value; if (e.NodeType == ExpressionType.Constant) { return(e.Type.IsPrimitive || ((ConstantExpression)e).Value == null ? e : new SqlConstantPlaceholderExpression(this.index++, (ConstantExpression)e)); } var unaryExpression = e as UnaryExpression; if (unaryExpression != null && unaryExpression.NodeType == ExpressionType.Convert) { if (unaryExpression.Operand.Type == e.Type || (unaryExpression.Type.IsAssignableFrom(unaryExpression.Operand.Type) && !(unaryExpression.Type.IsNullableType() || unaryExpression.Operand.Type.IsNullableType()))) { return(this.Visit(unaryExpression.Operand)); } if ((unaryExpression.Operand.NodeType == ExpressionType.Constant || (unaryExpression.Operand.NodeType == (ExpressionType)SqlExpressionType.ConstantPlaceholder))) { var constantValue = (unaryExpression.Operand as ConstantExpression)?.Value ?? (unaryExpression.Operand as SqlConstantPlaceholderExpression)?.ConstantExpression.Value; if (constantValue == null) { return(new SqlConstantPlaceholderExpression(this.index++, Expression.Constant(null, unaryExpression.Type))); } if (unaryExpression.Type.IsNullableType()) { return(new SqlConstantPlaceholderExpression(this.index++, Expression.Constant(Convert.ChangeType(constantValue, Nullable.GetUnderlyingType(unaryExpression.Type)), unaryExpression.Type))); } if (unaryExpression.Type.IsInstanceOfType(constantValue)) { var constantExpression = Expression.Constant(constantValue, unaryExpression.Type); return(unaryExpression.Type.IsValueType ? constantExpression : (Expression) new SqlConstantPlaceholderExpression(this.index++, constantExpression)); } if (typeof(IConvertible).IsAssignableFrom(unaryExpression.Type)) { var constantExpression = Expression.Constant(Convert.ChangeType(constantValue, unaryExpression.Type)); return(unaryExpression.Type.IsValueType ? constantExpression : (Expression) new SqlConstantPlaceholderExpression(this.index++, constantExpression)); } return(unaryExpression); } } if (e.NodeType == ExpressionType.Convert && ((UnaryExpression)e).Operand.Type.GetUnwrappedNullableType().IsEnum) { value = ExpressionInterpreter.Interpret(e); return(new SqlConstantPlaceholderExpression(this.index++, Expression.Constant(value, e.Type))); } if (e.NodeType == (ExpressionType)SqlExpressionType.ConstantPlaceholder) { return(e); } value = ExpressionInterpreter.Interpret(e); return(new SqlConstantPlaceholderExpression(this.index++, Expression.Constant(value, e.Type))); }