Ejemplo n.º 1
0
        /// <summary>
        /// 行ないし括弧の中身にドット構文があればDotBlockに置換する
        /// </summary>
        /// <param name="block"></param>
        /// <returns></returns>
        static object[] GroupToDotBlock(IEnumerable<object> block)
        {
            foreach (object t in block)
            {
                if (t is PareBlock)//引数などに存在しうるドット構文を先に処理
                {
                    var p = t as PareBlock;
                    p.tokens = GroupToDotBlock(p.tokens);
                }
                if (t is OptionBlock)
                {
                    var o = t as OptionBlock;
                    o.Tokens = GroupToDotBlock(o.Tokens);
                }
            }

            var src = new LinkedList<object>(block);
            LinkedListNode<object> current = src.First;
            while (current != null)
            {
                if (current.Value is Marks && ((Marks)current.Value) == Marks.Dot)
                {
                    var dot = new DotBlock(current.Previous.Value, current.Next.Value);
                    src.Remove(current.Previous);
                    src.Remove(current.Next);
                    src.AddAfter(current, dot);
                    current = current.Next;
                    src.Remove(current.Previous);//ドット前後3トークンを削除してDotBlockに置き換え
                }
                else
                {
                    current = current.Next;
                }
            }
            return src.ToArray();
        }
Ejemplo n.º 2
0
        Expression ProcessDotBlock(DotBlock dot)
        {
            Type leftType;
            Expression left;
            ClassReflectionInfo info;
            var id = dot.Left as string;
            if (id != null && TypeNameDictionary.ContainsKey(id))//静的メンバアクセス
            {
                left = null;
                leftType = TypeNameDictionary[id];
            }
            else
            {
                left = ProcessSingleToken(dot.Left);
                leftType = left.Type;
            }
            info = GetObjectInfo(leftType);
            string op;
            object[] args;
            if (dot.Right is string)
            {
                op = dot.Right as string;
                args = null;
            }
            else if (dot.Right is PareBlock)
            {
                var pare = dot.Right as PareBlock;
                op = pare.tokens[0] as string;
                args = pare.tokens.Skip(1).ToArray();
            }
            else
            {
                throw new ParseException("ドット演算子の右に不正なトークン:" + dot.ToString());
            }
            if (left != null)
            {
                var pf = TryGetPropertyOrField(op, left);
                if (pf != null)
                {
                    return pf;
                }

                var res = TryCallInstanceMethod(op, args, left);
                if (res != null)
                {
                    return res;
                }
            }
            else
            {
                if (info.StaticMethodDict.ContainsKey(op))
                {
                    return CallExternalMethodInner(info.StaticMethodDict[op], args, null);
                }
                else if (op == "new")
                {
                    return CallConstructor(leftType, args);
                }
                else
                {
                    var res = CallStaticNonScriptMethod(leftType, op, args);
                    if (res != null)
                    {
                        return res;
                    }
                }
            }

            throw new ParseException("ドット演算子右辺の識別子が不明:" + dot.ToString());
        }