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());
                }
            }
        }
示例#2
0
 /// <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;
 }
示例#3
0
        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();
            }
        }
示例#7
0
 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);
 }
示例#8
0
 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);
 }
示例#9
0
        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);
        }
示例#10
0
 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);
     }
 }
示例#11
0
 /// <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);
 }
示例#12
0
 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++;
             }
         }
     }
 }
示例#13
0
        /// <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));
        }
示例#14
0
 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++;
             }
         }
     }
 }
示例#15
0
        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));
        }
示例#16
0
 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);
 }
示例#17
0
        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);
        }
示例#18
0
 public VariableField(ScriptVariable variable, FieldProperty property)
 {
     this.Variable = variable;
     this.Property = property;
 }
示例#19
0
 public ListVariable(IEnumerable <ScriptVariable> value)
     : base(ScriptVariableType.List)
 {
     _value = ScriptVariable.RemoveParamRecursion(value.ToList());
 }
示例#20
0
 public static bool EqualTo(this ScriptVariable self, ScriptVariable other)
 {
     return(self.CompareTo(other) == 0);
 }
示例#21
0
 /// <summary>
 /// 内部コンストラクタ
 /// </summary>
 /// <param name="variable">変数の値</param>
 protected RefScriptVariable(ScriptVariable value)
 {
     _value = value;
 }
示例#22
0
        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);
        }
示例#23
0
 /// <summary>
 /// 値がnullであるかを返します.
 /// </summary>
 /// <param name="param"></param>
 /// <returns></returns>
 public static bool IsNull(this ScriptVariable param)
 {
     return(param == null);
 }
示例#24
0
 public override bool GetIndexedValue(int index, out ScriptVariable value)
 {
     value = null;
     return(false);
 }
示例#25
0
 public override bool SetIndexedValue(int index, ScriptVariable value)
 {
     return(false);
 }
示例#26
0
 /// <summary>
 /// 変数にインデックスを指定して値を取得します.
 /// </summary>
 /// <param name="index">インデックス</param>
 /// <returns></returns>
 public abstract bool GetIndexedValue(int index, out ScriptVariable value);