public object Invoke(Script script, Scope scope, object[] arguments) { var localScope = new Scope(scope); // Init our locals. for (int i = 0; i < Parameters.Count; i++) { localScope.Locals[Parameters[i]] = arguments[i]; } return new Code(Code, script).Evaluate(localScope, true); }
public Script(ScriptEngine engine, SecurityPolicy policy) { _engine = engine; _tokens = new List<List<List<Token>>>(); _functions = new List<Function>(); _securityPolicy = policy; _globals = new ObjectTable(); IsDirty = true; DefaultScope = new Scope(); UseEngineGlobals = true; }
/// <summary> /// Evaluates the tokens that are in the list. /// </summary> /// <param name="scope">The scope of the objects; if null, it will use the script's default scope.</param> /// <returns>An object of the execution.</returns> public object Evaluate(Scope scope = null) { if (scope == null) { scope = _script.DefaultScope; } object result = null; for (int i = 0; i < _tokens.Count; i++) { result = _tokens[i].Execute(_script, scope, i == 0 ? null : _tokens[i - 1], result); } return result; }
/// <summary> /// Evaluates the script. /// </summary> /// <param name="scope">The scope; if null, will use the scripts default scope.</param> /// <param name="returnObject">If true, the code will return the object if it's not null. If false, it will return the Return reference.</param> /// <returns></returns> public object Evaluate(Scope scope= null, bool returnObject = false) { if (scope == null) { scope = _script.DefaultScope; } for (int i = 0; i < _code.Count; i++) { // This is effectively "each statement" that the program has. var endObj = new object[_code[i].Count]; object result = null; for (int j = 0; j < _code[i].Count; j++) { object buf = null; for (int k = 0; k < _code[i][j].Count; k++) { result = _code[i][j][k].Execute(_script, scope, null, buf); if (result is Return) { return returnObject ? ((Return) result).GetResult() : result; } if (k < _code[i][j].Count - 1) { buf = result; } } endObj[j] = buf; } // And then we set the value from the RHS though to the LHS. if (_code[i].Count > 1) { for (int j = 0; j < _code[i].Count - 1; j++) { _code[i][j][_code[i][j].Count - 1].Set(_script, scope, endObj[j], result); } } } return null; }
protected object ExecuteCode(List<List<Token>> code, Scope scope, Script script) { var endObj = new object[code.Count]; object result = null; for (int i = 0; i < code.Count; i++) { object buf = null; for (int j = 0; j < code[i].Count; j++) { result = code[i][j].Execute(script, scope, null, buf); if (j < code[i].Count - 1) { buf = result; } } endObj[i] = buf; } for (int i = 0; i < code.Count - 1; i++) { code[i][code[i].Count - 1].Set(script, scope, endObj[i], result); } return result; }
protected object ExecuteCode(List<List<List<Token>>> code, Scope scope, Script script) { for (int i = 0; i < code.Count; i++) { // This is effectively "each statement" that the program has. var endObj = new object[code[i].Count]; object result = null; for (int j = 0; j < code[i].Count; j++) { object buf = null; for (int k = 0; k < code[i][j].Count; k++) { result = code[i][j][k].Execute(script, scope, null, buf); if (result is Return) { return result; } if (k < code[i][j].Count - 1) { buf = result; } } endObj[j] = buf; } // And then we set the value from the RHS though to the LHS. if (code[i].Count > 1) { for (int j = 0; j < code[i].Count - 1; j++) { code[i][j][code[i][j].Count - 1].Set(script, scope, endObj[j], result); } } } return null; }
public override void Set(Script script, Scope scope, object obj, object value) { }
public abstract void Set(Script script, Scope scope, object obj, object value);
public override object Execute(Script script, Scope scope, Token previousToken, object unknown) { return null; }
public override void Set(Script script, Scope scope, object obj, object value) { throw new Exception(String.Format("{0} cannot have a value assigned to it!", TokenName)); }
public abstract object Execute(Script script, Scope scope, Token previousToken, object unknown);
protected object Execute(Script script, Scope scope) { return ExecuteCode(_code, scope, script); }
public override void Set(Script script, Scope scope, object obj, object value) { throw new Exception("Loop tokens cannot have a value assigned to them!"); }
public object Invoke(Script script, Scope scope, string functionName, List<List<Token>> arguments) { // First, check script functions. if (_scriptFunctions.ContainsKey(functionName)) { Function f = _scriptFunctions[functionName]; if (f.Parameters.Count == arguments.Count) { // We have a match. var args = new object[arguments.Count]; for (int i = 0; i < arguments.Count; i++) { args[i] = new Chunk(arguments[i], script).Evaluate(scope); } return f.Invoke(script, scope, args); } } if (!_functions.ContainsKey(functionName)) { return null; } var results = new object[arguments.Count]; var types = new Type[arguments.Count]; for (int i = 0; i < arguments.Count; i++) { results[i] = new Chunk(arguments[i], script).Evaluate(); types[i] = results[i].GetType(); } MethodInfo calling = null; List<KeyValuePair<object, MethodInfo>> methods = _functions[functionName]; for (int i = 0; i < methods.Count; i++) { if (methods[i].Value.GetParameters().Length == results.Length) { bool canInvoke = true; ParameterInfo[] args = methods[i].Value.GetParameters(); var needsChange = new bool[args.Length]; for (int j = 0; j < args.Length; j++) { if (args[j].ParameterType == types[j] || types[j].IsSubclassOf(args[j].ParameterType)) { needsChange[j] = false; continue; } needsChange[j] = true; if (!args[j].ParameterType.IsAssignableFrom(types[j])) { if (types[j] == typeof (Number)) { try { Convert.ChangeType(results[j], args[j].ParameterType); } catch (Exception e) { canInvoke = false; } } else { canInvoke = false; } } } if (canInvoke) { for (int j = 0; j < args.Length; j++) { if (needsChange[j]) { results[j] = Convert.ChangeType(results[j], args[j].ParameterType); } } return methods[i].Value.Invoke(methods[i].Key, results); } } } return null; }
public Scope(Scope other) { Functions = new Functions(other.Functions); _locals = new ObjectTable(other._locals); }