public string paramReplace(ScriptVariable param, Func <ScriptVariable, string> replacer) { if (param == null) { return("null"); } string referResult = replacer(param); if (referResult != null) { return(referResult); } else { if (param.Type == ScriptVariableType.List) { StringBuilder listStr = new StringBuilder(); foreach (ScriptVariable item in param.ToList()) { if (listStr.Length != 0) { listStr.Append(", "); } listStr.Append(paramReplace(item, replacer)); } return("{ " + listStr.ToString() + " }"); } else { return(param.Serialize()); } } }
/// <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; }
public static ScriptVariable ConvertTo(this ScriptVariable self, ScriptVariableType type) { if (self.IsNull()) { return(null); } if (self.Type == type) { return(self); } switch (type) { case ScriptVariableType.Boolean: return(new BooleanVariable(self.ToBoolean())); case ScriptVariableType.List: return(new ListVariable(self.ToList())); case ScriptVariableType.Number: return(new NumberVariable(self.ToNumber())); case ScriptVariableType.String: return(new StringVariable(self.ToString())); //case ScriptVariableType.Object: //return new ObjectVariable(self.ToObject()); } return(null); }
/// <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; }
/// <summary> /// 指定された名前の変数を新しいスコープから順に探し,値を代入します. /// </summary> /// <param name="name">変数名</param> /// <param name="value">値</param> public void Set(string name, ScriptVariable value) { // スコープが空だったらとりあえずひとつ入っておく if (_variableScopes.Count == 0) { this.EnterScope(); } VariableField field; if (!this.TryLookup(name, out field)) { // ない場合にはグローバル変数に突っ込む _variableScopes[0][name] = new VariableField(value, FieldProperty.Default); return; } if (field.Property.Readonly) { // 読み取り専用だったら変更しない this.Parent.Warn(string.Format("Cannot modify readonly variable: {0}", name)); return; } // あった場合には新しいスコープから探して最初に見つかったところの値を変える foreach (var block in _variableScopes.Reverse()) { if (block.ContainsKey(name)) { field.Variable = value; block[name] = field; return; } } }
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(); } }
public override bool GetIndexedValue(int index, out ScriptVariable value) { value = null; if (index < 0 || index >= this.Value.Count) { return(false); } value = this.Value[index]; return(true); }
public override bool GetIndexedValue(int index, out ScriptVariable value) { value = null; if (index < 0 || index > this.Value.Length) { return(false); } value = new StringVariable(this.Value.Substring(index, 1)); return(true); }
public static ScriptVariable Add(this ScriptVariable self, ScriptVariable other) { if (self == null) { return(null); } other = ConvertTo(other, self.Type); switch (self.Type) { case ScriptVariableType.Boolean: if (other == null) { return(null); } return(new BooleanVariable(self.ToBoolean() || other.ToBoolean())); case ScriptVariableType.List: List <ScriptVariable> list = new List <ScriptVariable>(self.ToList()); if (other == null) { list.Add(null); } else { list.AddRange(other.ToList()); } return(new ListVariable(list)); case ScriptVariableType.Number: if (other == null) { return(self.Clone()); } try { return(new NumberVariable(self.ToNumber() + other.ToNumber())); } catch (ArithmeticException ex) { ScriptConsole.Singleton.Warn(ex.GetType().Name); return(new NumberVariable(0)); } /* * case ScriptVariableType.Object: * ScriptSub.Singleton.Warn("cannot add " + self.Type.ToString()); * return self.Clone(); */ case ScriptVariableType.String: if (other == null) { return(self.Clone()); } return(new StringVariable(self.ToString() + other.ToString())); } return(null); }
public static ScriptVariable Remainder(this ScriptVariable self, ScriptVariable other) { if (self == null || other == null) { return(null); } try { return(new NumberVariable(decimal.Remainder(self.ToNumber(), other.ToNumber()))); } catch (ArithmeticException ex) { ScriptConsole.Singleton.Warn(ex.GetType().Name); return(null); } }
/// <summary> /// 最新のスコープで変数を宣言します.そのスコープから出た時点でその変数は取り除かれます. /// </summary> /// <param name="name">変数名</param> /// <param name="variable">初期値</param> public void Declare(string name, ScriptVariable variable, FieldProperty property) { // スコープが空だったらとりあえずひとつ入っておく if (_variableScopes.Count == 0) { this.EnterScope(); } // 既に宣言されていたらコンソールに警告を表示して値は変えない if (_variableScopes[_variableScopes.Count - 1].ContainsKey(name)) { this.Parent.Warn("Cannot declare already declared variable in the block: " + name); return; } _variableScopes[_variableScopes.Count - 1][name] = new VariableField(variable, property); }
private void replaceByResultAux(ScriptVariable resultElem, VariableReplaceMap map, string resultName, ScriptVariableType targetTypes) { if (resultElem != null && (resultElem.Type & targetTypes) != 0) { map[resultElem] = resultName; if (resultElem.Type == ScriptVariableType.List) { int index = 0; foreach (ScriptVariable elem in resultElem.ToList()) { replaceByResultAux(elem, map, string.Format("{0}[{1}]", resultName, index), targetTypes); index++; } } } }
/// <summary> /// 変数の値の型に応じて名前付きスクリプト変数を作成します /// </summary> /// <param name="variable">変数の値</param> /// <param name="stringDelimiter">文字列を分割する区切り文字</param> /// <returns></returns> public static RefScriptVariable Create(ScriptVariable value, IEnumerable <char> stringDelimiter) { StringVariable str = value as StringVariable; if (str != null) { return(new RefConcatStringVariable(str, stringDelimiter)); } ListVariable list = value as ListVariable; if (list != null) { return(new RefListVariable(list, stringDelimiter)); } return(new RefScriptVariable(value)); }
private void setMap(ScriptVariable resultElem, VariableReplaceMap map, string resultName) { if (resultElem != null && (resultElem.Type == ScriptVariableType.List || resultElem.Type == ScriptVariableType.String)) { map[resultElem] = resultName; if (resultElem.Type == ScriptVariableType.List) { int index = 0; foreach (ScriptVariable elem in resultElem.ToList()) { setMap(elem, map, string.Format("{0}[{1}]", resultName, index)); index++; } } } }
public override ScriptVariable Clone() { List <ScriptVariable> ret = new List <ScriptVariable>(); foreach (var elem in ScriptVariable.RemoveParamRecursion(this.Value)) { if (elem == null) { ret.Add(null); } else { ret.Add(elem.Clone()); } } return(new ListVariable(ret)); }
public override bool SetIndexedValue(int index, ScriptVariable value) { if (index < 0) { return(false); } if (index >= _value.Count) { while (_value.Count < index) { _value.Add(null); } _value.Add(value.Clone()); } else { _value[index] = value.Clone(); } return(true); }
public static ScriptVariable Divide(this ScriptVariable self, ScriptVariable other) { if (self == null) { return(null); } other = ConvertTo(other, self.Type); switch (self.Type) { case ScriptVariableType.Boolean: if (other == null) { return(null); } return(new BooleanVariable(self.ToBoolean() || !other.ToBoolean())); case ScriptVariableType.List: case ScriptVariableType.String: //case ScriptVariableType.Object: ScriptConsole.Singleton.Warn("cannot divide " + self.Type.ToString()); return(self.Clone()); case ScriptVariableType.Number: if (other == null) { return(self.Clone()); } try { return(new NumberVariable(self.ToNumber() / other.ToNumber())); } catch (ArithmeticException ex) { ScriptConsole.Singleton.Warn(ex.GetType().Name); return(new NumberVariable(0)); } } return(null); }
public VariableField(ScriptVariable variable, FieldProperty property) { this.Variable = variable; this.Property = property; }
public ListVariable(IEnumerable <ScriptVariable> value) : base(ScriptVariableType.List) { _value = ScriptVariable.RemoveParamRecursion(value.ToList()); }
public static bool EqualTo(this ScriptVariable self, ScriptVariable other) { return(self.CompareTo(other) == 0); }
/// <summary> /// 内部コンストラクタ /// </summary> /// <param name="variable">変数の値</param> protected RefScriptVariable(ScriptVariable value) { _value = value; }
public static int?CompareTo(this ScriptVariable self, ScriptVariable other) { if (self.IsNull() && other.IsNull()) { return(0); } if (self.IsNull() || other.IsNull()) { return(null); } if (self.Type == ScriptVariableType.Number || other.Type == ScriptVariableType.Number) { if (self.Type == ScriptVariableType.String || other.Type == ScriptVariableType.String) { return(self.ToString().CompareTo(other.ToString())); } } if (self.Type != other.Type) { return(null); } switch (self.Type) { case ScriptVariableType.Boolean: return(self.ToBoolean().CompareTo(other.ToBoolean())); case ScriptVariableType.Number: return(self.ToNumber().CompareTo(other.ToNumber())); case ScriptVariableType.String: return(self.ToString().CompareTo(other.ToString())); case ScriptVariableType.List: var list1 = self.ToList(); var list2 = other.ToList(); int length = Math.Min(list1.Count, list2.Count); for (int i = 0; i < length; i++) { int?c = list1[i].CompareTo(list2[i]); if (!c.HasValue) { return(null); } if (c.Value != 0) { return(c.Value); } } return(list1.Count.CompareTo(list2.Count)); case ScriptVariableType.RegisteredFunction: RegisteredFunctionVariable regSelf = (RegisteredFunctionVariable)self; RegisteredFunctionVariable regOther = (RegisteredFunctionVariable)other; return(string.Compare(regSelf.Name, regSelf.Name)); case ScriptVariableType.Function: FunctionVariable funcSelf = (FunctionVariable)self; FunctionVariable funcOther = (FunctionVariable)other; if (funcSelf.Body == funcOther.Body) { return(0); } return(null); } return(null); }
/// <summary> /// 値がnullであるかを返します. /// </summary> /// <param name="param"></param> /// <returns></returns> public static bool IsNull(this ScriptVariable param) { return(param == null); }
public override bool GetIndexedValue(int index, out ScriptVariable value) { value = null; return(false); }
public override bool SetIndexedValue(int index, ScriptVariable value) { return(false); }
/// <summary> /// 変数にインデックスを指定して値を取得します. /// </summary> /// <param name="index">インデックス</param> /// <returns></returns> public abstract bool GetIndexedValue(int index, out ScriptVariable value);