/// <summary> /// 既定のコンストラクタ /// </summary> /// <param name="history">基となる関数呼び出し履歴</param> /// <param name="stringDelimiters">文字列を分解する区切り文字</param> public RefFunctionCallHistory(FunctionCallHistory history, IEnumerable <char> stringDelimiters) { this.Function = history.Function; this.Params = history.Params.Select(p => RefScriptVariable.Create(p, stringDelimiters)).ToList(); this.Result = history.Result; this.CreatedTime = history.CreatedTime; }
/// <summary> /// 補助コンストラクタ.作成時刻は自動で設定されます /// </summary> /// <param name="function">呼び出された関数</param> /// <param name="params">呼び出された時の実引数</param> /// <param name="result">呼び出された時の戻り値</param> public FunctionCallHistory(IScriptFunction function, IList <ScriptVariable> @params, ScriptVariable result) { this.Function = function; this.Params = @params; this.Result = result; this.CreatedTime = DateTime.Now; }
public ScriptVariable Invoke(IScriptFunction function, IList <ScriptVariable> args) { if (function == null) { throw new ArgumentNullException("function", "'function' cannot be null"); } if (args == null) { args = new List <ScriptVariable>(); } bool topLevelInvoke = _executedFunctionStack.Count == 0; _executedFunctionStack.Push(function); try { ScriptVariable result = function.Call(args, this); if (topLevelInvoke) { this.PushHistory(new FunctionCallHistory(function, args, result)); } return(result); } catch { _lastSyntaxOnError = _executedSyntaxElementStack.Count > 0 ? _executedSyntaxElementStack.Peek() : null; _lastSubroutineOnError = _executedFunctionStack.Peek().Name; throw; } finally { _executedFunctionStack.Pop(); } }
/// <summary> /// 名前から呼べるよう関数をリストに追加します. /// </summary> /// <param name="subroutine"></param> public void RegisterFunction(IScriptFunction function) { try { if (function == null) { throw new ArgumentNullException("function", "'function' cannot be null"); } string name = NormalizeIdentifier(function.Name); if (string.IsNullOrEmpty(name)) { throw new ArgumentException("function.Name cannot be empty", "function"); } string usage = function.Usage; if (_functions.ContainsKey(name)) { this.WriteDebugInfo("Function overwritten: " + name); } _functions[name] = function; } catch { if (_constructed) { throw; } try { throw; } catch (NotImplementedException) { this.WriteDebugInfo(function.GetType().ToString() + " not implemented"); } catch (Exception ex) { this.WriteDebugInfo(ex.GetType().ToString() + ": " + ex.Message); } } }
/// <summary> /// アセンブリからIScriptFunctionを実装するクラスのインスタンスを作成して関数に追加します. /// </summary> /// <param name="assembly">探索対象のアセンブリ</param> public void LoadFunctions(Assembly assembly) { if (_registeredAssemblies.Contains(assembly)) { return; } _registeredAssemblies.Add(assembly); foreach (var module in assembly.GetModules()) { Type[] types; try { types = module.GetTypes(); } catch (ReflectionTypeLoadException ex) { types = ex.Types; } foreach (var type in types.Where(t => t != null)) { if (type.IsInterface || type.IsAbstract) { continue; } if (!type.GetInterfaces().Contains(typeof(IScriptFunction))) { continue; } ConstructorInfo constructor = type.GetConstructor(new Type[0]); if (constructor == null) { continue; } IScriptFunction function = (IScriptFunction)constructor.Invoke(new object[0]); this.RegisterFunction(function); } } }
/// <summary> /// Initializes a new instance of the <see cref="ScriptFunctionContext"/> class. /// </summary> /// <param name="scriptBuilder"> /// The script builder. /// </param> /// <param name="scriptFunction"> /// The script function. /// </param> public ScriptFunctionContext([NotNull] IScriptBuilder scriptBuilder, [NotNull] IScriptFunction scriptFunction) { this.ScriptBuilder = scriptBuilder; this.ScriptFunction = scriptFunction; }
public string ExecuteThread(TextReader reader) { string ret = ""; WaitForForm _waitForForm = new WaitForForm(ctrl => { // 実行処理 try { ret = this.Execute(reader); } finally { ctrl.DialogResult = System.Windows.Forms.DialogResult.OK; } }, () => { try { // どの関数にいるか string call = "Script Body"; if (_executedFunctionStack.Count > 0) { IScriptFunction subroutine = null; try { _executedFunctionStack.Peek(); } catch (InvalidOperationException) { } if (subroutine != null) { ITimeConsumingScriptFunction timeConsume = subroutine as ITimeConsumingScriptFunction; if (timeConsume != null) { return(timeConsume.GetProgress()); } call = subroutine.Name; } } // どの行にいるか string position = ""; if (_executedSyntaxElementStack.Count > 0) { SyntaxElement syntax = _executedSyntaxElementStack.Peek(); if (syntax == null) { position = ", ..."; } else { position = string.Format(", Column {0} at Line {1}", syntax.LexAtStart.Column, syntax.LexAtStart.Line); } } return(new System.ComponentModel.ProgressChangedEventArgs(0, "Process at " + call + position)); } catch (InvalidOperationException) { return(new System.ComponentModel.ProgressChangedEventArgs(0, "")); } }); _waitForForm.Icon = global::MotionDataHandler.Properties.Resources.script; try { _waitForForm.CancelEnabled = true; if (_waitForForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) { return(ret); } } finally { if (_executedFunctionStack.Count > 0) { _executedFunctionStack.Clear(); } if (_executedSyntaxElementStack.Count > 0) { _executedSyntaxElementStack.Clear(); } } return(null); }