コード例 #1
0
ファイル: Class1.cs プロジェクト: TheProjecter/xvar
        public object execXVARScript(BinaryReader source, ImportedObject[] imports)
        {
            //Create an XVARFunctionContainer
            int headercount = source.ReadInt32();
            #region Generic import logic
            //Import imports from source machine
            foreach (ImportedObject e in imports)
            {
                internalobjects.Add(e.VObject.refValue, e.VObject);

            }
            //Import the global variables
            for (int i = 0; i < headercount; i++)
            {
            //Read in the reference value ON THE double (yes, pun intended :)
                double refval = source.ReadDouble();
                if (source.ReadBoolean())
                {
                    int len = source.ReadInt32();
                    byte[] data = source.ReadBytes(len);
                    VMObject obj = VMObject.Deserialize(data);
                    obj.refValue = refval;
                    internalobjects.Add(refval,obj);

                }
                else
                {
                    internalobjects.Add(refval, null);
                }

            }
            long beginningoffile = source.BaseStream.Position;
            //Read in the length of the INIT function
            long initlen = source.ReadInt64();
            byte[] mainmethod = source.ReadBytes((int)initlen);
            XVARMethod method = new XVARMethod(source.BaseStream,this);

            //TODO: Read in all of the functions (with offsets)
            while (true)
            {
                try
                {
                    //Read in function length, and download function
                    int funclen = source.ReadInt32();
                    //TODO: Correct this. There should be a better way to load functions (without loading them all into RAM first. Maybe as variables somehow???)
                    byte[] functiondata = source.ReadBytes(funclen);
                    MemoryStream mstream = new MemoryStream(functiondata);
                    BinaryReader mreader = new BinaryReader(mstream);
                    //Read in the return type (not really used for anything at THIS point)
                    mreader.ReadDouble();
                    //Read in associated object
                    VMObject assocObj = internalobjects[mreader.ReadDouble()];
                    assocObj.functions.Add(mreader.ReadInt32(), new FunctionDeclaration() { function = functiondata });

                    mstream.Dispose();
                }
                catch (EndOfStreamException)
                {
                    break;
                }
            }
            //Invoke the MAIN method
            source.BaseStream.Position = beginningoffile;
            return method.Invoke(new VMObject[0]);

            #endregion
        }
コード例 #2
0
ファイル: Class1.cs プロジェクト: TheProjecter/xvar
        public void compileXVARScript(StreamReader source, ImportedObject[] imports, BinaryWriter output)
        {
            Dictionary<string, VMObject> objects = new Dictionary<string, VMObject>();
            double objPos = 0;
            #region Import logic
            output.Write(imports.ToArray().Length);
            foreach (ImportedObject e in imports)
            {
                objects.Add(e.Name, e.VObject);
                if (e.VObject.refValue >= objPos)
                {
                    //Write the reference value as a double!
                    output.Write(e.VObject.refValue);
                    //Whether or not to literally interpolate the value
                    output.Write(e.VObject.storeAsLiteral);
                    //TODO here
                    //Somehow convert the native functions relating to the object into virtual XVAR function
                    //definitions
                    MethodInfo[] methods = e.VObject.GetType().GetMethods();
                    try
                    {
                        int methodindex = 0;
                        foreach (MethodInfo et in methods)
                        {

                            e.VObject.functions.Add(methodindex, new FunctionDeclaration() { nativeMethod = et });
                            e.VObject.functionIdentifiers.Add(et.Name, methodindex);

                            methodindex += 1;
                        }
                    }
                    catch (Exception)
                    {
                    //Must have already been added
                    }
                    //END TODO here
                    if (e.VObject.storeAsLiteral)
                    {
                        byte[] data = e.VObject.Serialize();
                        output.Write(data.Length);
                        output.Write(data);
                    }

                    objPos = e.VObject.refValue + 1;

                }
            }
            #endregion
               //Opcode 4 = Internal function offset declaration (long)

            #region Compilation logic
            long lastfunctionoffset = 0;
            bool hascalled = false;
            long spos = output.BaseStream.Position;
             int funcID = 0;
            output.Write((long)0);
            long zpos = output.BaseStream.Position;
            string currentFunction = "";
            FunctionDeclaration mdec = new FunctionDeclaration();
            Dictionary<string, long> lostandfound = new Dictionary<string, long>();
            VMObject parentObject = null;
            while (!source.EndOfStream)
            {

                string instruction = source.ReadLine();

                string[] parts = intellisplit(instruction);
                if (parts[0] == "function")
                {
                    mdec = new FunctionDeclaration();
                    output.BaseStream.Position = lastfunctionoffset;
                    //Length of function
                    output.Write((int)0);
                    currentFunction = parts[3];
                    //Return type
                    foreach (KeyValuePair<double, Type> e in VMObject.types)
                    {
                        if (e.Value.Name == parts[1])
                        {
                            output.Write(e.Key);
                            break;
                        }
                    }
                    //Associate function with object

                    VMObject obj = objects[parts[2]];
                    parentObject = obj;
                    output.Write(obj.refValue);
                    int ival = obj.functions.Count+1;
                    funcID = ival;
                    obj.functionIdentifiers.Add(parts[3], ival);

                    //Write out the index of the function
                    output.Write(ival);
                }
                if (parts[0] == "ndfunction")
                {
                    long yval = output.BaseStream.Position;
                    int tval = (int)(output.BaseStream.Position - lastfunctionoffset);
                    output.BaseStream.Position = lastfunctionoffset;
                    //Write function length
                    output.Write(tval);
                    //Data's already been written. Seek to beginning of stream!
                    output.BaseStream.Position = yval;
                    //Read the function back in
                    output.BaseStream.Position = lastfunctionoffset;
                    //Read function byte array
                    byte[] mray = new byte[tval];
                    output.BaseStream.Read(mray,0,mray.Length);
                    mdec.function = mray;
                   long previous = lastfunctionoffset;
                    parentObject.functions.Add(funcID, mdec);

                    lastfunctionoffset = output.BaseStream.Position;
                    if (lostandfound.Keys.Contains(currentFunction))
                    {
                        output.BaseStream.Position = lostandfound[currentFunction];
                        output.Write(previous);
                        output.BaseStream.Position = lastfunctionoffset;
                    }
                }
                if (parts[0] == "unalloc")
                {
                //Opcode 3
                    try
                    {
                        output.Write((byte)3);
                        output.Write(objects[parts[1]].refValue);
                        objects.Remove(parts[1]);
                    }
                    catch (KeyNotFoundException)
                    {
                        throw new NullReferenceException("Invalid reference. Variable " + parts[1] + " has not been declared.");
                    }
                }
                if (parts[0] == "stralloc")
                {
                    //Opcode 2
                    output.Write((byte)2);
                    //Store the string to a variable
                    parts[1] = parts[1].Replace("\"", "");
                    output.Write(parts[1]);

                    if (objects.Keys.Contains(parts[2]))
                    {
                        objects[parts[2]] = new VMString(parts[1]) { refValue = objPos };
                    }
                    else
                    {
                        objects.Add(parts[2], new VMString(parts[1]) { refValue = objPos });

                    }
                    output.Write(objPos);
                    objPos += 1;
                }

                if (parts[0] == "ndinit")
                {
                    if (!hascalled)
                    {
                        long cpos = output.BaseStream.Position;

                        output.BaseStream.Position = spos;
                        output.Write(cpos-zpos);
                        output.BaseStream.Position = cpos;
                        hascalled = true;
                        lastfunctionoffset = cpos;
                    }
                    else
                    {
                        throw new ArgumentException("endinit may only be called once per session! What were you thinking?!?!?");
                    }
                }
                if (parts[0] == "call")
                {
                    //Write out opcode (as byte)

                    VMObject currentObj = objects[parts[1]];
                    if (!currentObj.functionIdentifiers.ContainsKey(parts[2]))
                    {
                        output.Write((byte)4);
                        long ntpos = output.BaseStream.Position;
                        //Function offset to be determined
                        output.Write((long)-1);
                        lostandfound.Add(parts[2], ntpos);
                    }
                    else
                    {

                        output.Write((byte)0);
                        try
                        {

                            //Write out index of reference object (as double)
                            output.Write(currentObj.refValue);
                            try
                            {

                                FunctionDeclaration function = currentObj.functions[currentObj.functionIdentifiers[parts[2]]];
                                //Write out index of function (as int32)
                                output.Write(currentObj.functionIdentifiers[parts[2]]);
                                //Write out length of parameters (as int32)
                                string[] args;
                                try
                                {
                                    args = parts[3].Split(",".ToArray(), StringSplitOptions.RemoveEmptyEntries);
                                    if (args[0] == "null")
                                    {
                                        args = new string[0];
                                    }
                                }
                                catch (Exception)
                                {
                                    args = new string[0];
                                }
                                output.Write(args.Length);
                                foreach (string et in args)
                                {
                                    //Write out each reference as a double
                                    output.Write(objects[et].refValue);
                                }
                                if (parts.Length == 5)
                                {
                                    //Whether or not the output should be assigned to a variable
                                    output.Write(true);
                                    //The variable to assign it to
                                    if (objects.ContainsKey(parts[4]))
                                    {
                                        output.Write(objects[parts[4]].refValue);
                                    }
                                    else
                                    {
                                        VMObject tobj = (VMObject)function.returnType.GetConstructor(new Type[0]).Invoke(null);
                                        tobj.refValue = objPos;
                                        //Populate the object's methods

                                        objects.Add(parts[4], tobj);
                                        output.Write(objPos);
                                        objPos += 1;
                                    }
                                }
                                else
                                {
                                    output.Write(false);
                                }
                            }
                            catch (AccessViolationException)
                            {

                            }
                        }
                        catch (KeyNotFoundException)
                        {
                            throw new NullReferenceException("Invalid reference. Variable " + parts[1] + " has not been declared.");
                        }
                    }
                }
            }
            #endregion
        }