Beispiel #1
0
        private void paramsArray(int argc1, int argc2)
        {
            int diff = argc1 - argc2;

            VAL retAddr = SS.Pop();

            VALL L1 = new VALL();

            for (int i = 0; i < argc2 - 1; i++)
            {
                L1.Insert(SS.Pop());
            }

            VALL L2 = new VALL();

            for (int i = 0; i <= diff; i++)
            {
                L2.Add(SS.Pop());
            }
            SS.Push(new VAL(L2));

            for (int i = 0; i < argc2 - 1; i++)
            {
                SS.Push(L1[i]);
            }

            SS.Push(retAddr);

            CS[retAddr.Intcon].operand.Addr += diff;
        }
Beispiel #2
0
        public static VAL Slice(VALL arr)
        {
            VAL V = arr[0];

            int start = 0;
            int stop  = -1;
            int step  = 1;

            switch (arr.Size)
            {
            case 1:
                break;

            case 2:
                start = arr[1].Intcon;
                break;

            case 3:
                start = arr[1].Intcon;
                stop  = arr[2].Intcon;
                break;

            case 4:
                start = arr[1].Intcon;
                stop  = arr[2].Intcon;
                step  = arr[3].Intcon;
                break;
            }

            return(new VAL(V.List.Slice(start, stop, step)));
        }
Beispiel #3
0
        private void UserFuncCall(VAL func, VAL instance, bool arg0)
        {
            int count1 = -CS[IP + 1].operand.Addr - 1;

            if (moduleName == func.Class)
            {
                if (arg0)
                {
                    VAL ip = SS.Pop();
                    SS.Push(instance);
                    SS.Push(ip);
                    count1++;
                }

                IP = (int)func.value;
                paramsCheck(IP, count1);
            }
            else
            {
                VALL L = SysFuncBeginParameter();
                if (arg0)
                {
                    L.Insert(instance);
                }
                VAL ret = InternalUserFuncCall(func, instance, new VAL(L));

                SysFuncEnd(ret);
            }
        }
Beispiel #4
0
        public VAL GetValData()
        {
            VALL L = new VALL();

            L.Add(new VAL(ty.FullName));
            L.Add(new VAL(this));
            return(new VAL(L));
        }
Beispiel #5
0
        //Add Association
        public VALL Add(string key, VAL val)
        {
            VALL L = new VALL();

            L.Add(new VAL(key));
            L.Add(val);
            list.Add(new VAL(L));
            return(this);
        }
Beispiel #6
0
        public VALL Slice(int start, int stop, int step)
        {
            VALL L = new VALL();

            for (int i = start; i <= Pos(stop); i += step)
            {
                L.Add(VAL.Clone(list[i]));
            }
            return(L);
        }
Beispiel #7
0
        //set union
        public static VALL operator +(VALL L1, VALL L2)
        {
            VALL L = VALL.Clone(L1);

            foreach (VAL v in L2.list)
            {
                L.list.Add(VAL.Clone(v));
            }
            return(L);
        }
Beispiel #8
0
        private void Callback(object sender, EventArgs e)
        {
            VALL L = new VALL();

            L.Add(VAL.NewHostType(sender));
            L.Add(VAL.NewHostType(e));
            VAL arguments = new VAL(L);

            ret = CPU.ExternalUserFuncCall(func, instance, arguments, context);
        }
Beispiel #9
0
        private bool SysFuncCall(object func, VAL proc, VAL instance, bool arg0)
        {
            if (proc.ty == VALTYPE.funccon)
            {
                UserFuncCall(proc, instance, arg0);
                return(true);
            }

            VALL L = SysFuncBeginParameter();

            if (arg0 && proc.temp is HostOffset)
            {
                object host = ((HostOffset)proc.temp).host;
                if (host != instance.value)
                {
                    L.Insert(instance);       //extend method
                    arg0 = false;
                }
            }
            VAL ret = HostOperation.HostTypeFunction(proc, L);

            if (ret.Defined)
            {
                return(SysFuncEnd(ret));
            }



            if (arg0)
            {
                L.Insert(instance);
            }
            try
            {
                ret = context.InvokeFunction((string)func, new VAL(L), position);
            }
            catch (FunctionNotFoundException e1)
            {
                throw e1;
            }
            catch (Exception e2)
            {
                if (e2 is RuntimeException)
                {
                    throw e2;
                }
                else
                {
                    throw new RuntimeException(position, "Error: function {0}({1}) implementation, {2}", func, L.ToString2(), e2.Message);
                }
            }

            return(SysFuncEnd(ret));
        }
Beispiel #10
0
        private static VAL WriteLine(VALL L)
        {
            StringWriter o = new StringWriter();

            for (int i = 0; i < L.Size; i++)
            {
                o.Write(L[i].ToString2());
            }

            Logger.WriteLine(o.ToString());
            return(new VAL(L));   //return void
        }
Beispiel #11
0
        private VALL SysFuncBeginParameter()
        {
            int  count = SysFuncBegin();
            VALL L     = new VALL();

            for (int i = 0; i < count; i++)
            {
                L.Add(SysFuncParam(i));
            }

            return(L);
        }
Beispiel #12
0
        internal static VAL Assemble(Memory memory)
        {
            VALL L = new VALL();

            foreach (KeyValuePair <string, VAL> pair in memory.ds)
            {
                //if (pair.Value.ty == VALTYPE.funccon || pair.Value.ty == VALTYPE.classcon)
                //    continue;

                L.Add(pair.Key, pair.Value);
            }
            return(new VAL(L));
        }
Beispiel #13
0
        public static VALL Clone(VALL l)
        {
            VALL L = new VALL();

            L.ty   = l.ty;
            L.list = new List <VAL>();
            foreach (VAL v in l.list)
            {
                L.list.Add(VAL.Clone(v));
            }

            return(L);
        }
Beispiel #14
0
        //set intersection
        public static VALL operator *(VALL L1, VALL L2)
        {
            VALL L = new VALL();

            for (int i = 0; i < L1.list.Count; i++)
            {
                if (L2.list.Contains(L1.list[i]))
                {
                    L.list.Add(L1.list[i]);
                }
            }
            return(L);
        }
Beispiel #15
0
        //set complmentary
        public static VALL operator -(VALL L1, VALL L2)
        {
            VALL L = VALL.Clone(L1);

            for (int i = 0; i < L1.list.Count; i++)
            {
                if (L2.list.Contains(L1.list[i]))
                {
                    L.list.Remove(L1.list[i]);
                }
            }
            return(L);
        }
Beispiel #16
0
        private static VAL LogInfo(VALL L)
        {
            StringWriter o = new StringWriter();

            o.Write(System.DateTime.Now);
            o.Write(" ");
            for (int i = 0; i < L.Size; i++)
            {
                o.Write(L[i].ToString2());
            }

            Logger.WriteLine(o.ToString());
            return(new VAL(L));   //return void
        }
Beispiel #17
0
        private Computer()
        {
            ds1 = new Memory();
            ds2 = new Memory();

            register("object", typeof(object));
            register("bool", typeof(bool));

            register("sbyte", typeof(sbyte));
            register("byte", typeof(byte));
            register("short", typeof(short));
            register("ushort", typeof(ushort));
            register("int", typeof(int));
            register("uint", typeof(uint));
            register("long", typeof(long));
            register("ulong", typeof(ulong));

            register("double", typeof(double));
            register("float", typeof(float));
            register("decimal", typeof(decimal));

            register("char", typeof(char));
            register("string", typeof(string));



            VALL L = new VALL();

            L.Add("VOID", new VAL((int)VALTYPE.voidcon));
            L.Add("NULL", new VAL((int)VALTYPE.nullcon));
            L.Add("BOOL", new VAL((int)VALTYPE.boolcon));
            L.Add("INT", new VAL((int)VALTYPE.intcon));
            L.Add("DOUBLE", new VAL((int)VALTYPE.doublecon));
            L.Add("STRING", new VAL((int)VALTYPE.stringcon));
            L.Add("LIST", new VAL((int)VALTYPE.listcon));
            L.Add("FUNCTION", new VAL((int)VALTYPE.funccon));
            L.Add("CLASS", new VAL((int)VALTYPE.classcon));
            L.Add("HOST", new VAL((int)VALTYPE.hostcon));

            ds1.Add("TYPE", new VAL(L));


            //HostType.Register(new Type[]
            //{
            //    typeof(DateTime),
            //    typeof(string),
            //    typeof(System.Reflection.Assembly),
            //    typeof(Tie.HostType)
            //}, true);
        }
Beispiel #18
0
        public static VAL HostTypeFunction(VAL proc, VALL parameters)
        {
            VAL ret = VAL.VOID;

            if (proc.ty == VALTYPE.hostcon && (proc.value is MethodInfo || proc.value is MethodInfo[]))
            {
                HostOffset temp   = (HostOffset)proc.temp;
                object     host   = temp.host;
                object     offset = temp.offset;

                if (offset is MethodInfo)
                {
                    ret = VAL.Boxing1(((MethodInfo)proc.value).Invoke(host, parameters.ObjectArray));
                }
                else
                {
                    HostFunction hFunc = new HostFunction(host, (string)offset, parameters);

                    if (proc.value is MethodInfo[])
                    {
                        ret = hFunc.RunFunction((MethodInfo[])proc.value);
                    }
                    else
                    {
                        MethodInfo method = (MethodInfo)proc.value;
                        if (method.IsGenericMethod)
                        {
                            ret = hFunc.RunFunction(new MethodInfo[] { method });
                        }
                        else
                        {
                            ret = hFunc.RunFunction();
                        }
                    }
                }
            }
            else if (proc.value is Delegate)
            {
                Delegate   d         = (Delegate)proc.value;
                MethodInfo method    = d.Method;
                object[]   arguments = parameters.ObjectArray;
                return(HostFunction.InvokeMethod(method, d.Target, arguments));
            }
            return(ret);
        }
Beispiel #19
0
        bool NewInstance(VAL V)         //new user defined class, .net object or a listcon
        {
            VALL L = SysFuncBeginParameter();

            if (V.ty == VALTYPE.funccon)
            {
                string func = V.Str;


                VAL userClass = GetVAL(func, true);
                if (userClass.ty == VALTYPE.classcon)
                {
                    //VAL instance =  NewVAL.UserType(func);
                    VAL instance = new VAL();

                    VAL ret = InternalUserFuncCall(userClass, instance, new VAL(L));
                    return(SysFuncEnd(ret));
                }
                else
                {
                    VAL args = new VAL(L);

                    VAL scope = new VAL();
                    if (!ES.IsEmpty())
                    {
                        scope = ES.Top();
                    }

                    VAL Clss = HostCoding.Decode(func, args, scope, context);
                    return(SysFuncEnd(Clss));
                }
            }
            else if (V.value is Type)       //generic class
            {
                VAL    args     = new VAL(L);
                object instance = Activator.CreateInstance((Type)V.value, HostCoding.ConstructorArguments(args));
                return(SysFuncEnd(VAL.NewHostType(instance)));
            }

            throw new RuntimeException(position, "new instance {0} failed", V);
        }
Beispiel #20
0
        private static VAL format(VALL L)
        {
            string fmt = L[0].Str;

            object[] args = new object[L.Size - 1];
            for (int i = 1; i < L.Size; i++)
            {
                if (L[i].ty != VALTYPE.listcon)
                {
                    args[i - 1] = L[i].value;  //use C# string.format string control
                }
                else
                {
                    args[i - 1] = L[i].ToString2();
                }
            }

            string s = string.Format(fmt, args);

            return(new VAL(s));
        }
Beispiel #21
0
        public static VAL OperatorOverloading(Operator opr, VAL v1, VAL v2, bool silent)
        {
            VALL L = new VALL();

            L.Add(v1);

            if ((object)v2 != null)
            {
                L.Add(v2);
            }

            HostFunction hFunc = new HostFunction(v1.value, opr.ToString(), L);

            if (silent)
            {
                return(hFunc.RunFunctionSilently(null));
            }
            else
            {
                return(hFunc.RunFunction(null));
            }
        }
Beispiel #22
0
        public HostFunction(object host, string func, VALL parameters)
        {
            this.host = host;
            this.func = func;

            if (host is Type)
            {
                hostType = (Type)host;
            }
            else
            {
                hostType = host.GetType();
            }

            args1 = parameters.ObjectArray;
            int count = args1.Length;

            argTypes1 = new Type[count];
            for (int i = 0; i < count; i++)
            {
                argTypes1[i] = parameters[i].Type;
            }
        }
Beispiel #23
0
        internal VAL getter(VAL arr, bool created)
        {
            switch (arr.ty)
            {
            case VALTYPE.intcon:
                if (arr.Intcon >= 0)        //return row
                {
                    //subscript number > size of array, increase size of array automatically
                    if (arr.Intcon >= list.Count && created)
                    {
                        while (arr.Intcon >= list.Count)
                        {
                            list.Add(new VAL());
                        }
                    }

                    if (arr.Intcon >= list.Count)
                    {
                        return(VAL.VOID);
                    }

                    return(list[arr.Intcon]);
                }
                else
                {
                    // A={2,5,1,2,7,8}
                    // A[-1] return A's last item 8
                    // A[-2] return 7
                    int pos = Pos(arr.Intcon);
                    return(list[pos]);
                }


            case VALTYPE.stringcon:
            {
                string key = arr.Str;
                foreach (VAL v in list)
                {
                    if (v.ty != VALTYPE.listcon)
                    {
                        continue;
                    }

                    if (v.Size != 2 || v[0].ty != VALTYPE.stringcon)
                    {
                        continue;
                    }

                    string prop = v[0].Str;
                    if (key == prop)
                    {
                        return(v[1]);
                    }
                    else if (prop == Expression.BASE_INSTANCE)
                    {
                        VAL BS = v[1][key];
                        if (BS.Defined)
                        {
                            return(BS);
                        }
                    }
                }

                //not found, create new
                if (created)
                {
                    VAL val = new VAL();
                    this.Add(key, val);
                    return(val);
                }

                return(VAL.VOID);
            }

            case VALTYPE.listcon:
            {
                VALL L = this;
                for (int i = 0; ; i++)
                {
                    VAL R = L.getter(arr[i], created);
                    if (i < arr.Size - 1)
                    {
                        L = R.List;
                    }
                    else
                    {
                        return(R);
                    }
                }
            }
            }


            return(VAL.VOID);
        }
Beispiel #24
0
        public static VAL Function(string func, VAL parameters, Memory DS, Position position)
        {
            VALL L = (VALL)parameters.value;
            VAL  R0;

            int size = L.Size;
            VAL L0   = size > 0 ? L[0] : null;
            VAL L1   = size > 1 ? L[1] : null;

            switch (func)
            {
            /*
             *  register(Type type)
             *  register(Assembly assemby)
             * */
            case "register":
                if (size == 1)
                {
                    if (L0.ty == VALTYPE.hostcon)
                    {
                        object host = L0.HostValue;
                        if (host is Type)
                        {
                            return(new VAL(HostType.Register((Type)host)));
                        }
                        if (host is Type[])
                        {
                            return(new VAL(HostType.Register((Type[])host)));
                        }
                        else if (host is Assembly)
                        {
                            return(new VAL(HostType.Register((Assembly)host)));
                        }
                    }
                }
                break;

            case "addreference":
                if (size == 2 && L0.ty == VALTYPE.stringcon && L1.ty == VALTYPE.hostcon)
                {
                    object host = L1.HostValue;
                    if (host is Assembly)
                    {
                        HostType.AddReference(L0.Str, (Assembly)host);
                        return(VAL.NewHostType(host));
                    }
                }
                break;

            //return VAL type
            case "type":
                if (size == 1)
                {
                    return(new VAL((int)L0.ty));
                }
                break;

            case "GetType":
                if (size == 1)
                {
                    if (L0.value == null)
                    {
                        return(new VAL());
                    }
                    else
                    {
                        return(VAL.NewHostType(L0.value.GetType()));
                    }
                }
                break;

            case "typeof":
                if (size == 2)
                {
                    if (L0.ty == VALTYPE.listcon && L1.ty == VALTYPE.stringcon)                //1.
                    {
                        L0.Class = L1.Str;
                        return(L0);
                    }
                }
                else if (size == 1)
                {
                    if (L0.value == null)
                    {
                        Type ty = HostType.GetType(L0.name);
                        if (ty != null)
                        {
                            return(VAL.NewHostType(ty));
                        }
                        else
                        {
                            return(new VAL());
                        }
                    }
                    else if (L0.ty == VALTYPE.listcon)
                    {
                        if (L0.Class == null)
                        {
                            return(VAL.VOID);
                        }
                        return(new VAL(L0.Class));
                    }
                    else if (L0.ty == VALTYPE.hostcon)
                    {
                        if (L0.value is Type)
                        {
                            return(L0);
                        }
                        else
                        {
                            return(VAL.NewHostType(L0.value.GetType()));
                        }
                    }
                    else if (L0.ty == VALTYPE.stringcon)
                    {
                        return(VAL.NewHostType(HostType.GetType(L0.Str)));       //6.
                    }
                }
                break;

            case "classof":
                if (size == 1)
                {
                    if (L0.ty == VALTYPE.hostcon)
                    {
                        return(HostValization.Host2Val(L0.value));
                    }
                }
                else if (size == 2)
                {
                    if (L0.ty == VALTYPE.hostcon && L1.ty == VALTYPE.listcon)                //1.
                    {
                        HostValization.Val2Host(L1, L0.value);
                        return(L0);
                    }
                }
                break;


            case "valize":
                if (size == 1)
                {
                    return(VAL.Script(L0.Valor));
                }
                break;

            case "isnull":
                if (size == 2)
                {
                    if (L0.ty == VALTYPE.nullcon)
                    {
                        return(L1);
                    }
                    else
                    {
                        return(L0);
                    }
                }
                break;

            case "VAL":
                if (size == 1)
                {
                    R0       = VAL.Clone(L0);
                    R0.Class = "VAL";                  //force to CAST VAL, don't do HostValue unboxing
                    return(R0);
                }
                break;

            case "HOST":                           //cast to hostcon
                if (size == 1)
                {
                    R0    = VAL.Clone(L0);
                    R0.ty = VALTYPE.hostcon;
                    return(R0);
                }
                break;


            case "ctype":
                if (size == 2)
                {
                    if (L1.value is Type)
                    {
                        return(VAL.cast(VAL.Clone(L0), (Type)L1.value));
                    }
                    else if (L[1].value is string)
                    {
                        Type ty = HostType.GetType(L1.Str);
                        if (ty != null)
                        {
                            return(VAL.cast(VAL.Clone(L0), ty));
                        }
                    }
                }
                break;



            case "DateTime":
                if (size == 6)
                {
                    return(VAL.NewHostType(new DateTime(L0.Intcon, L1.Intcon, L[2].Intcon, L[3].Intcon, L[4].Intcon, L[5].Intcon)));
                }
                else if (size == 3)
                {
                    return(VAL.NewHostType(new DateTime(L0.Intcon, L1.Intcon, L[2].Intcon)));
                }
                break;

            //STRING
            case "format":
                if (size >= 1 && L0.ty == VALTYPE.stringcon)
                {
                    return(format(L));
                }
                break;



                #region LIST function

            case "size":
                if (size == 1)
                {
                    return(new VAL(L0.Size));
                }
                break;

            case "array":               //array(2,3,4)
                int[] A = new int[size];
                for (int i = 0; i < size; i++)
                {
                    if (L[1].ty != VALTYPE.intcon)
                    {
                        return(null);
                    }

                    A[i] = L[i].Intcon;
                }
                return(VAL.Array(A));

            case "slice":
                return(Slice(L));

            case "append":
            case "push":
                if (size == 2 && L0.ty == VALTYPE.listcon)
                {
                    R0 = L1;
                    L0.List.Add(VAL.Clone(R0));
                    return(L0);
                }
                break;

            case "pop":
                if (size == 1 && L0.ty == VALTYPE.listcon)
                {
                    int index = L0.List.Size - 1;
                    R0 = L0.List[index];
                    L0.List.Remove(index);
                    return(R0);
                }
                else if (size == 2 && L0.ty == VALTYPE.listcon && L1.ty == VALTYPE.intcon)
                {
                    int index = L1.Intcon;
                    R0 = L0.List[index];
                    L0.List.Remove(index);
                    return(R0);
                }
                break;


            case "insert":
                if (size == 3 && L0.ty == VALTYPE.listcon && L1.ty == VALTYPE.intcon)
                {
                    L0.List.Insert(L1.Intcon, VAL.Clone(L[2]));
                    return(L0);
                }
                break;

            case "remove":
                if (size == 2 && L0.ty == VALTYPE.listcon && L1.ty == VALTYPE.intcon)
                {
                    L0.List.Remove(L1.Intcon);
                    return(L0);
                }
                break;
                #endregion


            //DEBUG
            case "echo":
                return(new VAL(L));

            case "write":
                return(WriteLine(L));

            case "loginfo":
                return(LogInfo(L));



                #region internal functions used by parser

            case Constant.FUNC_CAST_TYPE_VALUE:
                if (size == 2)
                {
                    return(cast(L1, L0));
                }
                break;

            case Constant.FUNC_CAST_VALUE_TYPE:
                if (size == 2)
                {
                    return(cast(L0, L1));
                }
                break;

            case Constant.FUNC_IS_TYPE:
                if (size == 2)
                {
                    Type type = SystemFunction.GetValDefinitionType(L1);
                    if (type != null)
                    {
                        if (L0.value == null)
                        {
                            return(new VAL(false));
                        }
                        else
                        {
                            return(new VAL(type.IsAssignableFrom(L0.value.GetType())));
                        }
                    }
                    else
                    {
                        throw new RuntimeException(position, "{0} is not type or not registered.", L1.value);
                    }
                }
                break;

            case Constant.FUNC_MAKE_ARRAY_TYPE:
                if (size == 1 || size == 2)
                {
                    Type ty = SystemFunction.GetValDefinitionType(L0);
                    if (ty != null)
                    {
                        if (size == 1)
                        {
                            return(VAL.Boxing1(ty.MakeArrayType()));
                        }
                        else if (L1.value is int)
                        {
                            return(VAL.Boxing1(ty.MakeArrayType(L1.Intcon)));
                        }
                    }
                    else
                    {
                        throw new RuntimeException(position, "declare array failed, {0} is not type.", L0.value);
                    }
                }
                break;


            case Constant.FUNC_FUNCTION:
                if (L[1].ty == VALTYPE.intcon)
                {
                    return(new VAL(Operand.Func(L[1].Intcon, L[0].Str)));
                }
                else
                {
                    return(new VAL(Operand.Func(L[1].Str, L[0].Str)));
                }

            case Constant.FUNC_CLASS:
                return(new VAL(Operand.Clss(L[1].Intcon, L[0].Str)));


                #endregion


                #region propertyof, methodof, fieldof


            case "propertyof":
                if (size >= 2 && size <= 4)
                {
                    object host = L0.value;
                    if (host == null)
                    {
                        break;
                    }

                    if (L0.ty == VALTYPE.hostcon && L1.ty == VALTYPE.stringcon)
                    {
                        if (size == 2 || size == 3)
                        {
                            return(HostFunction.propertyof(size == 2, null, (string)L1.value, host, size == 2 ? null: L[2].HostValue));
                        }
                    }
                    else if (L0.ty == VALTYPE.hostcon &&
                             L1.ty == VALTYPE.hostcon && L1.value is Type &&
                             L[2].ty == VALTYPE.stringcon)
                    {
                        if (size == 3 || size == 4)
                        {
                            return(HostFunction.propertyof(size == 3, (Type)L1.value, (string)L[2].value, host, size == 3 ? null : L[3].HostValue));
                        }
                    }
                }
                break;


            case "fieldof":
                if (size == 2 || size == 3)
                {
                    object host = L0.value;
                    if (host == null)
                    {
                        break;
                    }

                    if (L0.ty == VALTYPE.hostcon && L1.ty == VALTYPE.stringcon)
                    {
                        Type      ty        = HostType.GetHostType(host);
                        FieldInfo fieldInfo = ty.GetField((string)L1.value, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);
                        if (fieldInfo == null)
                        {
                            throw new RuntimeException(position, string.Format("Invalid field name: {0}.{1}", ty.FullName, L1.value));
                        }

                        if (size == 2)
                        {
                            return(VAL.Boxing1(fieldInfo.GetValue(host)));
                        }
                        else
                        {
                            fieldInfo.SetValue(host, L[2].HostValue);
                            return(VAL.VOID);
                        }
                    }
                }
                break;



            case "methodof":
                if (size == 4)
                {
                    object host = L0.value;
                    if (host == null)
                    {
                        break;
                    }

                    VAL    L2   = L[2];
                    object args = L[3].HostValue;

                    if (L0.ty == VALTYPE.hostcon &&
                        L1.ty == VALTYPE.hostcon && L1.value is Type &&
                        L2.ty == VALTYPE.stringcon &&
                        args is Type[])
                    {
                        MethodInfo methodInfo = HostFunction.methodof(host, (Type)L1.value, (string)L2.value, (Type[])args);
                        if (methodInfo != null)
                        {
                            VAL method = VAL.Boxing1(methodInfo);
                            method.temp = new HostOffset(host, methodInfo);
                            return(method);
                        }
                        else
                        {
                            throw new RuntimeException(position, "method {0} is not existed", L2.value);
                        }
                    }
                }
                break;

                #endregion
            }

            return(null);
        }
Beispiel #25
0
        public VAL Run(int breakPoint)
        {
L1:

            Instruction I = CS[IP];
            Operand operand = I.operand;

            position.line  = I.line;
            position.col   = I.col;
            position.cur   = I.cur;
            position.block = I.block;

            if (I.line == breakPoint)
            {
                return(null);
            }

            switch (I.cmd)
            {
                //----------------------------------------------------------------------------

                #region  MOV, STO,STO1, RMT. RCP

            case INSTYPE.MOV:
                if (operand.ty == OPRTYPE.identcon)         // MOV [v]
                {
                    if (CS[IP + 1].cmd == INSTYPE.OFS)      // if this is offset of a struct, keep variable name
                    {
                        REG.Push(new VAL(operand));
                    }
                    else
                    {
                        REG.Push(GetVAL(operand.Str, false));
                    }
                }
                else if (operand.ty == OPRTYPE.addrcon)         // MOV [BP-3]
                {
                    //VAL opr = Register.BPAddr(BP, operand);

                    VAL opr = new VAL();
                    opr.ty    = VALTYPE.addrcon;
                    opr.value = BP + operand.Addr;
                    opr.name  = operand.name;

                    REG.Push(opr);
                }
                else
                {
                    VAL x = new VAL(operand);
                    if (operand.ty == OPRTYPE.funccon)
                    {
                        if (ES.SP > -1)
                        {
                            x.temp = new ContextInstance(this.context, ES.Top());
                        }
                        else
                        {
                            x.temp = new ContextInstance(this.context, new VAL());
                        }
                    }

                    REG.Push(VAL.Clone(x));     // MOV 3
                }
                break;



            //----------------------------------------------------------------------------


            case INSTYPE.STO1:
            case INSTYPE.STO:
                R0 = REG.Pop();
                R1 = REG.pop();
                if (R1.ty == VALTYPE.addrcon)
                {
                    SS[R1.Address] = R0;
                }
                else
                {
                    HostOperation.Assign(R1, R0);
                }

                if (I.cmd == INSTYPE.STO)
                {
                    REG.Push(R1);
                }
                break;

            case INSTYPE.RMT:
                if (CS[IP + 1].cmd != INSTYPE.HALT)      //used for expression decoding,keep last value
                {
                    REG.Pop();
                }
                break;

            case INSTYPE.RCP:
                REG.Push(VAL.Clone(REG.Top()));
                break;

                #endregion


                //----------------------------------------------------------------------------

                #region PUSH/POP/SP/ESI/ESO
            case INSTYPE.ESI:
                R0 = REG.Pop();
                ES.Push(R0);
                break;

            case INSTYPE.ESO:
                ES.Pop();
                break;

            case INSTYPE.PUSH:
                if (operand != null && operand.ty == OPRTYPE.regcon)
                {
                    switch (operand.SEG)
                    {
                    case SEGREG.BP: SS.Push(new VAL(BP)); break;

                    case SEGREG.SP: SS.Push(new VAL(SS.SP)); break;

                    case SEGREG.SI: SS.Push(new VAL(SI)); break;

                    case SEGREG.IP: SS.Push(new VAL(IP + 2)); break;

                    case SEGREG.EX: EX.Push((int)operand.value); break;
                    }
                }
                else
                {
                    R0 = REG.Pop();
                    SS.Push(R0);
                }
                break;

            case INSTYPE.POP:
                if (operand.ty == OPRTYPE.regcon)
                {
                    switch (operand.SEG)
                    {
                    case SEGREG.BP: BP = (SS.Pop()).Address; break;

                    case SEGREG.SI: SI = (SS.Pop()).Address; break;

                    case SEGREG.SP: SS.SP = (SS.Pop()).Address; break;

                    case SEGREG.EX: EX.Pop(); break;
                    }
                }
                else
                {
                    R0 = SS.Pop();
                    REG.Push(R0);
                }
                break;

            case INSTYPE.SP:
                SS.SP += operand.Addr;
                break;

                #endregion


                //----------------------------------------------------------------------------

                #region OFS, ARR
            //----------------------------------------------------------------------------
            // Associative List
            // Mike={{"street", "3620 Street"},{"zip", 20201},{"phone","111-222-333},{"apt",1111}}
            // Mike.street = "3620 Street";
            // Mike.zip = 40802;
            case INSTYPE.OFS:
                R0 = REG.Pop();
                R1 = REG.pop();
                {
                    VAL v = new VAL();
                    switch (R1.ty)
                    {
                    case VALTYPE.hostcon:
                        v = R1.getter(R0, true, OffsetType.STRUCT);
                        goto LOFS;

                    case VALTYPE.addrcon:
                        v = SS[R1.Address];
                        if (v.Undefined || v.IsNull)
                        {
                            v.ty    = VALTYPE.listcon;
                            v.value = new VALL();
                        }
                        break;

                    case VALTYPE.listcon:
                        v = R1;
                        break;

                    default:           // if assoicative arrary is empty or not list
                        R1.ty    = VALTYPE.listcon;
                        R1.value = new VALL();
                        v        = R1;
                        break;
                    }

                    switch (v.ty)
                    {
                    case VALTYPE.listcon:
                        VALL L = v.List;
                        v = L[R0.Str];

                        // if property is not found in the associative array
                        if (!v.Defined)
                        {
                            L[R0.Str] = v;
                        }

                        break;

                    case VALTYPE.hostcon:
                        //VAL.Assign(v, VAL.HostTypeOffset(v.value, R0.value));
                        v = HostOperation.HostTypeOffset(v, R0, OffsetType.STRUCT);
                        break;
                    }

LOFS:
                    if ((object)v == null)
                    {
                        v = new VAL();
                    }

                    v.name = R1.name + "." + R0.name;
                    REG.Push(v);
                }
                break;

            case INSTYPE.ARR:
                R0 = REG.Pop();
                R1 = REG.pop();
                {
                    VAL v = new VAL();
                    switch (R1.ty)
                    {
                    case VALTYPE.addrcon:
                        v = SS[R1.Address];           //indirect addressing
                        if (v.Undefined || v.IsNull)
                        {
                            v.ty    = VALTYPE.listcon;
                            v.value = new VALL();
                            v       = v.getter(R0, true, OffsetType.ARRAY);
                        }
                        else
                        {
                            v = v.getter(R0, true, OffsetType.ARRAY);
                        }
                        break;

                    case VALTYPE.listcon:                       //push reference
                        v = R1.getter(R0, true, OffsetType.ARRAY);
                        break;

                    case VALTYPE.hostcon:
                        v = R1.getter(R0, true, OffsetType.ARRAY);
                        if (!v.Defined)
                        {
                            throw new RuntimeException(position, "{0} does not have property {1}.", R1, R0);
                        }
                        break;

                    default:
                        //refer: public VAL this[VAL arr], when R1 == null, dynamically allocate a list
                        R1.ty    = VALTYPE.listcon;
                        R1.value = new VALL();
                        v        = R1.getter(R0, true, OffsetType.ARRAY);

                        //JError.OnRuntime(0);
                        break;
                    }

                    v.name = R1.name + "[" + R0.ToString() + "]";
                    REG.Push(v);
                }
                break;

                #endregion


                //----------------------------------------------------------------------------

                #region  CALL, NEW, ENDP, RET, GNRC
            case  INSTYPE.GNRC:
                R0 = REG.Pop();         // R0 = new Type[] { string, int }
                R1 = REG.Pop();         // R1 = System.Collection.Generic
                {
                    Operand opr = I.operand;
                    VAL     R2  = R1[opr.Str];    // I.val.Str == Dictionary`2
                    if (R2.Undefined)             // Type is not registered
                    {
                        object t = HostType.GetType(R1.name + "." + opr.Str);
                        if (t != null)
                        {
                            R2 = VAL.NewHostType(t);
                        }
                        else
                        {
                            throw new RuntimeException(position, "Type {0}.{1} is not registered.", R1.name, opr.Str);
                        }
                    }

                    object A = R0.HostValue;
                    if (A is object[] && ((object[])A).Length == 0)         //case: typeof(Dictionary<,>)
                    {
                        if (R2.value is Type)
                        {
                            REG.Push(VAL.NewHostType(R2.value));
                        }
                        else
                        {
                            throw new RuntimeException(position, "{0} is not System.Type.", R1);
                        }
                    }
                    else
                    {
                        if (!(A is Type[]))
                        {
                            throw new RuntimeException(position, "<{0}> is not System.Type[].", R0.ToString2());
                        }

                        if (R2.value is Type)
                        {
                            Type t = (Type)R2.value;
                            REG.Push(VAL.NewHostType(t.MakeGenericType((Type[])A)));
                        }
                        else if (R2.value is MethodInfo)
                        {
                            MethodInfo t = (MethodInfo)R2.value;
                            VAL        m = VAL.NewHostType(t.MakeGenericMethod((Type[])A));
                            m.temp = R2.temp;
                            REG.Push(m);
                        }
                        else if (R2.value is MethodInfo[])
                        {
                            MethodInfo[] T = (MethodInfo[])R2.value;
                            for (int i = 0; i < T.Length; i++)
                            {
                                T[i] = T[i].MakeGenericMethod((Type[])A);
                            }
                            VAL m = VAL.NewHostType(T);
                            m.temp = R2.temp;
                            REG.Push(m);
                        }
                        else
                        {
                            throw new RuntimeException(position, "{0} is not System.Type.", R1);
                        }
                    }
                }

                break;

            case INSTYPE.CALL:
                if (operand.ty == OPRTYPE.intcon)
                {
                    IP = operand.Addr;
                }
                else if (operand.ty == OPRTYPE.addrcon)      // high-level programming
                {
                    SysFuncCallByAddr(SS[operand.Addr + BP]);
                }
                else if (operand.ty == OPRTYPE.regcon)
                {
                    SysFuncCallByAddr(SS[operand.Addr + SS.SP]);
                }
                else if (operand.ty == OPRTYPE.none)       //used for Generic method
                {
                    if (ES.IsEmpty())
                    {
                        R0 = REG.Pop();
                    }
                    else
                    {
                        R0 = ES.Top();
                    }

                    SysFuncCallByName(R0);
                }
                else
                {
                    SysFuncCallByName(new VAL(operand));
                }
                goto L1;

            case INSTYPE.NEW:
                if (operand.ty == OPRTYPE.funccon)
                {
                    NewInstance(new VAL(operand));         //system predifined class & user-defined class
                }
                else if (operand.ty == OPRTYPE.none)       //used for Generic class
                {
                    if (ES.IsEmpty())
                    {
                        R0 = REG.Pop();
                    }
                    else
                    {
                        R0 = ES.Top();
                    }

                    NewInstance(R0);
                }
                else if (operand.ty == OPRTYPE.intcon)
                {
                    int opr = (int)operand.value;
                    if (opr > 1)
                    {
                        R0 = REG.Pop();
                        R1 = REG.Pop();
                    }
                    else
                    {
                        R1 = REG.Pop();
                    }

                    if (R1.value is Type)
                    {
                        Type ty = (Type)R1.value;

                        if (opr == 1)
                        {
                            if (ty.IsArray)
                            {
                                R0 = VAL.Array();
                            }
                            else
                            {
                                R0 = new VAL();
                            }
                        }

                        if (R0.ty == VALTYPE.listcon)
                        {
                            if (ty.IsArray)
                            {
                                R0.List.ty = ty;
                            }
                            else
                            {
                                throw new RuntimeException(position, "new object failed. {0} is not Array Type", R1);
                            }
                        }

                        R0.Class = ty.FullName;
                        REG.Push(R0);
                    }
                    else
                    {
                        throw new RuntimeException(position, "new object failed. {0} is not System.Type", R1);
                    }

                    IP++;
                }

                goto L1;

            case INSTYPE.ENDP:
                if ((OPRTYPE)operand.Intcon == OPRTYPE.classcon)
                {
                    REG.Push(ES.Top());                 //return this;
                }
                else
                {
                    REG.Push(VAL.VOID);        //return void;
                }
                SS.SP = BP;                    //PUSH BP; POP SP;
                BP    = (SS.Pop()).Address;    //POP BP;

                R0 = SS.Top();                 //EXEC RET
                IP = R0.Address;
                goto L1;

            case INSTYPE.RET:
                if (!SS.IsEmpty())
                {
                    R0 = SS.Top();
                    IP = R0.Address;                        //goto V.i
                }
                else
                {
                    if (REG.IsEmpty())
                    {
                        return(VAL.VOID);
                    }
                    else
                    {
                        return(REG.Top());
                    }
                }

                goto L1;

                #endregion


                //----------------------------------------------------------------------------

                #region  +,-,*,/,%,>,<,!=,==,<=,>=, ++, --
            //----------------------------------------------------------------------------
            case INSTYPE.NEG:
                R0 = REG.Pop();
                if (operand.Intcon == -1)
                {
                    R0 = -R0;       //call VAL.operator -(VAL)
                }
                else
                {
                    R0 = +R0;       //call VAL.operator +(VAL)
                }
                REG.Push(R0);
                break;

            case INSTYPE.ADD: R0 = REG.Pop(); R1 = REG.Pop(); R1 += R0; REG.Push(R1); break;

            case INSTYPE.SUB: R0 = REG.Pop(); R1 = REG.Pop(); R1 -= R0; REG.Push(R1); break;

            case INSTYPE.MUL: R0 = REG.Pop(); R1 = REG.Pop(); R1 *= R0; REG.Push(R1); break;

            case INSTYPE.DIV: R0 = REG.Pop(); R1 = REG.Pop(); R1 /= R0; REG.Push(R1); break;

            case INSTYPE.MOD: R0 = REG.Pop(); R1 = REG.Pop(); R1 %= R0; REG.Push(R1); break;

            case INSTYPE.GTR: R0 = REG.Pop(); R1 = REG.Pop(); REG.Push(new VAL(R1 > R0)); break;

            case INSTYPE.LSS: R0 = REG.Pop(); R1 = REG.Pop(); REG.Push(new VAL(R1 < R0)); break;

            case INSTYPE.GEQ: R0 = REG.Pop(); R1 = REG.Pop(); REG.Push(new VAL(R1 >= R0)); break;

            case INSTYPE.LEQ: R0 = REG.Pop(); R1 = REG.Pop(); REG.Push(new VAL(R1 <= R0)); break;

            case INSTYPE.EQL: R0 = REG.Pop(); R1 = REG.Pop(); REG.Push(new VAL(R1 == R0)); break;

            case INSTYPE.NEQ: R0 = REG.Pop(); R1 = REG.Pop(); REG.Push(new VAL(R1 != R0)); break;

            case INSTYPE.INC:
                R0 = REG.pop();
                R1 = VAL.Clone(R0);
                if (R0.ty == VALTYPE.addrcon)
                {
                    SS[R0.Address] += new VAL(1);
                }
                else     //global varible
                {
                    HostOperation.Assign(R0, R0 + new VAL(1));
                }
                REG.Push(R1);
                break;

            case INSTYPE.DEC:
                R0 = REG.pop();
                R1 = VAL.Clone(R0);
                if (R0.ty == VALTYPE.addrcon)
                {
                    SS[R0.Address] -= new VAL(1);
                }
                else     //global varible
                {
                    HostOperation.Assign(R0, R0 - new VAL(1));
                }
                REG.Push(R1);
                break;

                #endregion


                //----------------------------------------------------------------------------

                #region MARK, END, EACH, CAS, DIRC

            case INSTYPE.MARK: REG.Push(Mark); break;

            case INSTYPE.END:
            {
                VAL L = new VAL(new VALL());
                while (REG.Top() != Mark)
                {
                    L.List.Insert(REG.Pop());
                }
                REG.Pop();                      // pop mark
                REG.Push(L);
            } break;

            case INSTYPE.EACH:
                R0 = REG.Pop();             //Collection
                R1 = REG.pop();             //address of element [BP+addr]
                REG.Push(ForEach(R0, SS[R1.Intcon], SS[R1.Intcon + 1]));
                break;

            case INSTYPE.CAS:
                R0 = REG.Pop(); R1 = REG.Top();
                if (R1 == R0)
                {
                    REG.Pop(); IP = operand.Addr; goto L1;
                }                                                            //goto V.i
                break;

            case INSTYPE.DIRC:          //directive command
                switch (operand.mod)
                {
                case Constant.SCOPE:
                    this.scope = (string)operand.value;
                    break;
                }
                break;

                #endregion


                //----------------------------------------------------------------------------

                #region &&, ||, ~, &, |, >>, <<
            //----------------------------------------------------------------------------
            case INSTYPE.NOTNOT:
                R0 = REG.Pop();
                if (R0.ty == VALTYPE.stringcon)
                {
                    REG.Push(Computer.Run(scope, R0.Str, CodeType.statements, context));
                }
                else
                {
                    REG.Push(new VAL(!R0));         //call VAL.operator !(VAL)
                }
                break;

            case INSTYPE.ANDAND: R0 = REG.pop(); R1 = REG.Pop();
                REG.Push(new VAL(R0.ty == VALTYPE.boolcon && R1.ty == VALTYPE.boolcon? R0.Boolcon && R1.Boolcon: false));
                break;

            case INSTYPE.OROR: R0 = REG.pop(); R1 = REG.Pop();
                REG.Push(new VAL(R0.ty == VALTYPE.boolcon && R1.ty == VALTYPE.boolcon ? R0.Boolcon || R1.Boolcon : false));
                break;


            //----------------------------------------------------------------------------
            case INSTYPE.NOT: R0 = REG.Pop();
                REG.Push(~R0);      //call VAL.operator ~(VAL)
                break;

            case INSTYPE.AND: R0 = REG.pop(); R1 = REG.Pop();
                REG.Push(R1 & R0);
                break;

            case INSTYPE.OR: R0 = REG.pop(); R1 = REG.Pop();
                REG.Push(R1 | R0);
                break;

            case INSTYPE.XOR: R0 = REG.pop(); R1 = REG.Pop();
                REG.Push(R1 ^ R0);
                break;

            //----------------------------------------------------------------------------
            case INSTYPE.SHL: R0 = REG.pop(); R1 = REG.Pop();
                if (!(R0.value is int))
                {
                    throw new RuntimeException(position, "the 2nd operand {0} in << operation must be integer", R0);
                }
                REG.Push(R1 << (int)R0.value);
                break;

            case INSTYPE.SHR: R0 = REG.pop(); R1 = REG.Pop();
                if (!(R0.value is int))
                {
                    throw new RuntimeException(position, "the 2nd operand {0} in >> operation must be integer", R0);
                }
                REG.Push(R1 >> (int)R0.value);
                break;
                #endregion


                //----------------------------------------------------------------------------

                #region JUMP, ADR, VLU

            case INSTYPE.JMP: IP = operand.Addr; goto L1;

            case INSTYPE.LJMP: IP += operand.Addr; goto L1;

            case INSTYPE.JNZ:
                if (REG.Pop() == new VAL(true))
                {
                    IP = operand.Addr; goto L1;
                }
                else
                {
                    break;
                }

            case INSTYPE.JZ:
                if (REG.Pop() != new VAL(true))
                {
                    IP = operand.Addr; goto L1;
                }
                else
                {
                    break;
                }

            case INSTYPE.LJZ:
                if (REG.Pop() != new VAL(true))
                {
                    IP += operand.Addr; goto L1;
                }
                else
                {
                    break;
                }

            case INSTYPE.ADR:
                R0 = REG.Pop();
                REG.Push(new VAL(R0.name));
                break;

            case INSTYPE.VLU:
                R0 = REG.Pop();
                if (R0.ty == VALTYPE.stringcon)
                {
                    REG.Push(Computer.Run(scope, R0.Str, CodeType.expression, context));
                }
                else
                {
                    throw new RuntimeException(position, "Invalid address type:" + R0.ToString());
                }
                break;

                #endregion


                //----------------------------------------------------------------------------


                #region  THIS,BASE
            case INSTYPE.THIS:                                           //this.x
                if (ES.SP > -1)
                {
                    if (this.scope != "")
                    {
                        VAL NS = GetScopeVAL(this.scope);
                        if (NS != ES.Top())
                        {
                            REG.Push(NS);
                        }
                    }
                    else
                    {
                        REG.Push(ES.Top());
                    }
                }
                else if (this.scope != "")
                {
                    if (operand.ty == OPRTYPE.intcon)                         //this.x=100;
                    {
                        REG.Push(GetScopeVAL(this.scope));
                    }
                    else
                    {
                        REG.Push(new VAL(this.scope));             //p=&this.x;
                    }
                }
                else
                {
                    if (CS[IP + 2].cmd == INSTYPE.OFS)
                    {
                        CS[IP + 2].cmd = INSTYPE.NOP;
                    }
                    else
                    {
                        throw new RuntimeException(position, "Operator[this] is invalid since namespace is empty.");
                    }
                }
                break;

            case INSTYPE.BASE:           //base.x
                //if (ES.SP > -1)
                //{
                //    VAL BS = ES.Top()[JExpression.BASE_INSTANCE];
                //    if((object)BS!=null)
                //        REG.Push(BS);
                //    else
                //        throw new RuntimeException(string.Format("Operator[base] is invalid since class {0} does not have base class.",ES.Top()));
                //}
                if (this.scope != "")
                {
                    string bv = "";
                    int    n  = 1;
                    if (operand.ty == OPRTYPE.intcon)          //base.base.x=10;
                    {
                        n = operand.Intcon;

                        bv = GetBaseScope(this.scope, n);

                        if (bv != "")
                        {
                            REG.Push(GetScopeVAL(bv));
                        }
                        else
                        {
                            if (CS[IP + 2].cmd == INSTYPE.OFS)
                            {
                                CS[IP + 2].cmd = INSTYPE.NOP;
                            }
                        }
                    }
                    else
                    {
                        n  = operand.Addr;                 // p = &base.base.x;
                        bv = GetBaseScope(this.scope, n);
                        REG.Push(new VAL(bv));
                    }
                }
                else
                {
                    throw new RuntimeException(position, "Operator[base] is invalid since scope is root.");
                }
                break;

                #endregion


                //----------------------------------------------------------------------------

                #region THRW, DDT, HALT

            case INSTYPE.THRW:
                R0 = REG.Top();
                if (!(R0.HostValue is Exception))
                {
                    throw new RuntimeException(position, "{0} is not type of System.Exception.", R0.HostValue);
                }

                if (EX.IsEmpty())
                {
                    throw (Exception)R0.HostValue;
                }
                IP = EX.Pop();

                if (IP == -1)
                {
                    throw (Exception)R0.HostValue;
                }
                break;

            case INSTYPE.DDT:
                Logger.WriteLine(DebugInfo());
                break;

            case INSTYPE.HALT:
                if (REG.IsEmpty())
                {
                    return(VAL.VOID);
                }
                else
                {
                    return(REG.Top());
                }

                #endregion
            }

            IP++;
            goto L1;
        }