Пример #1
0
        private void CompilePop(GMLToken _tok, eVM_Type _type)
        {
            switch (_tok.Token)
            {
            case eToken.eVariable:
            case eToken.eDot:
                if (_tok.Children.Count >= 2)
                {
                    int num = 0;
                    CompileExpression(_tok.Children[0]);
                    if (TypeStack.Peek() != eVM_Type.eVMT_Int)
                    {
                        Emit(eVM_Instruction.eVMI_CONV, TypeStack.Pop(), eVM_Type.eVMT_Int);
                        TypeStack.Push(eVM_Type.eVMT_Int);
                    }
                    if (_tok.Children[1].Children.Count > 0)
                    {
                        CompileExpression(_tok.Children[1].Children[0]);
                        if (TypeStack.Peek() != eVM_Type.eVMT_Int)
                        {
                            Emit(eVM_Instruction.eVMI_CONV, TypeStack.Pop(), eVM_Type.eVMT_Int);
                            TypeStack.Push(eVM_Type.eVMT_Int);
                        }
                        if (_tok.Children[1].Children.Count > 1)
                        {
                            EmitI(eVM_Instruction.eVMI_PUSH, 32000);
                            Emit(eVM_Instruction.eVMI_MUL, eVM_Type.eVMT_Int, eVM_Type.eVMT_Int);
                            CompileExpression(_tok.Children[1].Children[1]);
                            if (TypeStack.Peek() != eVM_Type.eVMT_Int)
                            {
                                Emit(eVM_Instruction.eVMI_CONV, TypeStack.Pop(), eVM_Type.eVMT_Int);
                                TypeStack.Push(eVM_Type.eVMT_Int);
                            }
                            Emit(eVM_Instruction.eVMI_ADD, eVM_Type.eVMT_Int, eVM_Type.eVMT_Int);
                            TypeStack.Pop();
                        }
                        TypeStack.Pop();
                    }
                    else
                    {
                        num |= int.MinValue;
                    }
                    TypeStack.Pop();
                    EmitIVar(eVM_Instruction.eVMI_POP, _tok.Children[1].Id | num, _type);
                    TypeStack.Push(eVM_Type.eVMT_Variable);
                }
                else
                {
                    Error("Malformed variable reference", _tok);
                }
                break;

            case eToken.eConstant:
                Error("Unsure where these come from", _tok);
                break;
            }
        }
Пример #2
0
        private void BinaryTypeCoercion(GMLToken _tok, int _parmNum)
        {
            eVM_Type eVM_Type = TypeStack.Peek();

            switch (_tok.Children[1].Token)
            {
            case eToken.eNot:
            case eToken.eLess:
            case eToken.eLessEqual:
            case eToken.eEqual:
            case eToken.eNotEqual:
            case eToken.eGreaterEqual:
            case eToken.eGreater:
            case eToken.eBitNegate:
                break;

            case eToken.ePlus:
            case eToken.eMinus:
            case eToken.eTime:
            case eToken.eDivide:
            case eToken.eDiv:
            case eToken.eMod:
                if (eVM_Type == eVM_Type.eVMT_Bool)
                {
                    TypeStack.Pop();
                    Emit(eVM_Instruction.eVMI_CONV, eVM_Type, eVM_Type.eVMT_Int);
                    TypeStack.Push(eVM_Type.eVMT_Int);
                }
                break;

            case eToken.eAnd:
            case eToken.eOr:
            case eToken.eXor:
                if (eVM_Type != eVM_Type.eVMT_Bool)
                {
                    TypeStack.Pop();
                    Emit(eVM_Instruction.eVMI_CONV, eVM_Type, eVM_Type.eVMT_Bool);
                    TypeStack.Push(eVM_Type.eVMT_Bool);
                }
                break;

            case eToken.eBitOr:
            case eToken.eBitAnd:
            case eToken.eBitXor:
            case eToken.eBitShiftLeft:
            case eToken.eBitShiftRight:
                if (eVM_Type == eVM_Type.eVMT_Int)
                {
                    TypeStack.Pop();
                    Emit(eVM_Instruction.eVMI_CONV, eVM_Type, eVM_Type.eVMT_Int);
                    TypeStack.Push(eVM_Type.eVMT_Int);
                }
                break;
            }
        }
Пример #3
0
        private void CompileUnary(GMLToken _tok)
        {
            CompileExpression(_tok.Children[0]);
            eVM_Type eVM_Type = TypeStack.Peek();

            switch (_tok.Id)
            {
            case 203:
                switch (eVM_Type)
                {
                case eVM_Type.eVMT_String:
                case eVM_Type.eVMT_Error:
                    Error("Unable to Not a string", _tok);
                    break;

                case eVM_Type.eVMT_Double:
                case eVM_Type.eVMT_Float:
                case eVM_Type.eVMT_Int:
                case eVM_Type.eVMT_Long:
                case eVM_Type.eVMT_Variable:
                    TypeStack.Pop();
                    Emit(eVM_Instruction.eVMI_CONV, eVM_Type, eVM_Type.eVMT_Bool);
                    TypeStack.Push(eVM_Type.eVMT_Bool);
                    eVM_Type = eVM_Type.eVMT_Bool;
                    break;
                }
                Emit(eVM_Instruction.eVMI_NOT, eVM_Type);
                break;

            case 211:
                Emit(eVM_Instruction.eVMI_NEG, eVM_Type);
                break;

            case 220:
                switch (eVM_Type)
                {
                case eVM_Type.eVMT_String:
                case eVM_Type.eVMT_Error:
                    Error("Unable to Negate a string", _tok);
                    break;

                case eVM_Type.eVMT_Double:
                case eVM_Type.eVMT_Float:
                case eVM_Type.eVMT_Variable:
                    TypeStack.Pop();
                    Emit(eVM_Instruction.eVMI_CONV, eVM_Type, eVM_Type.eVMT_Int);
                    TypeStack.Push(eVM_Type.eVMT_Int);
                    eVM_Type = eVM_Type.eVMT_Int;
                    break;
                }
                Emit(eVM_Instruction.eVMI_NOT, eVM_Type);
                break;
            }
        }
Пример #4
0
 private void CompileFunction(GMLToken _tok)
 {
     foreach (GMLToken child in _tok.Children)
     {
         CompileExpression(child);
         eVM_Type eVM_Type = TypeStack.Pop();
         if (eVM_Type != eVM_Type.eVMT_Variable)
         {
             Emit(eVM_Instruction.eVMI_CONV, eVM_Type, eVM_Type.eVMT_Variable);
         }
     }
     EmitI(eVM_Instruction.eVMI_CALL, _tok.Id);
     TypeStack.Push(GMAssetCompiler.eVM_Type.eVMT_Variable);
 }
        /// <summary>
        /// Emit code to load a value onto the stack
        /// </summary>
        /// <param name="name"></param>
        /// <param name="types"></param>
        public void Load(VariableName name, TypeStack <TEmit> types)
        {
            // Check if we know what type this variable is
            var type = _types.TypeOf(name) ?? StackType.YololValue;

            if (_cache.ContainsKey(name))
            {
                var local = _cache[name];
                _emitter.LoadLocal(local.Local);

                ConvertType(local.Type, type);
                types.Push(type);
            }
            else
            {
                // Load from backing store
                EmitLoadValue(name);

                // Unbox it to that type (bypassing dynamic type checking)
                StaticUnbox(type);
                types.Push(type);
            }
        }
Пример #6
0
        private void CompileConstant(GMLToken _tok)
        {
            switch (_tok.Value.Kind)
            {
            case eKind.eConstant:
                Error("constant token", _tok);
                break;

            case eKind.eNone:
                Error("None constant token", _tok);
                break;

            case eKind.eNumber:
            {
                double num = (long)_tok.Value.ValueI;
                if (num == _tok.Value.ValueI)
                {
                    long num2 = (long)_tok.Value.ValueI;
                    if (num2 > int.MaxValue || num2 < int.MinValue)
                    {
                        EmitI(eVM_Instruction.eVMI_PUSH, num2);
                        TypeStack.Push(eVM_Type.eVMT_Long);
                    }
                    else if (num2 > 32767 || num2 < -32768)
                    {
                        EmitI(eVM_Instruction.eVMI_PUSH, (int)num2);
                        TypeStack.Push(eVM_Type.eVMT_Int);
                    }
                    else
                    {
                        VMB.Add(VMBuffer.EncodeInstructionArg(192, 15) | (int)(num2 & 0xFFFF));
                        TypeStack.Push(eVM_Type.eVMT_Int);
                    }
                }
                else
                {
                    EmitI(eVM_Instruction.eVMI_PUSH, _tok.Value.ValueI);
                    TypeStack.Push(eVM_Type.eVMT_Double);
                }
                break;
            }

            case eKind.eString:
                EmitI(eVM_Instruction.eVMI_PUSH, _tok.Value.ValueS);
                TypeStack.Push(eVM_Type.eVMT_String);
                break;
            }
        }
Пример #7
0
        private bool SubsumedInner(DataType type1, DataType type2, TypeStack typeStack)
        {
            if (typeStack.Contains(type1, type2))
            {
                return(true);
            }

            if (type1.IsUnknownType() || type1 == DataType.None || type1.Equals(type2))
            {
                return(true);
            }

            if (type1 is TupleType tuple1 && type2 is TupleType tuple2)
            {
                List <DataType> elems1 = tuple1.eltTypes;
                List <DataType> elems2 = tuple2.eltTypes;

                if (elems1.Count == elems2.Count)
                {
                    typeStack.Push(type1, type2);
                    for (int i = 0; i < elems1.Count; i++)
                    {
                        if (!SubsumedInner(elems1[i], elems2[i], typeStack))
                        {
                            typeStack.Pop(type1, type2);
                            return(false);
                        }
                    }
                }
                return(true);
            }

            if (type1 is ListType list1 && type2 is ListType list2)
            {
                return(SubsumedInner(list1.ToTupleType(), list2.ToTupleType(), typeStack));
            }
            return(false);
        }
Пример #8
0
        private void Initialize()
        {
            Contexts.Push(this);
            TypeStack.Push(ModelType);

            var serializable = Model as ISerializable;

            if (serializable != null)
            {
                var registrationInfo = ReferenceManager.GetInfo(serializable);

                //// Note: we need to use the x.Tag instead of x.Instance.ContextMode here because we might be serializing a different thing
                //switch ((SerializationContextMode)x.Tag)
                switch (ContextMode)
                {
                case SerializationContextMode.Serialization:
                    if (!registrationInfo.HasCalledSerializing)
                    {
                        serializable.StartSerialization();
                        registrationInfo.HasCalledSerializing = true;
                    }
                    break;

                case SerializationContextMode.Deserialization:
                    if (!registrationInfo.HasCalledDeserializing)
                    {
                        serializable.StartDeserialization();
                        registrationInfo.HasCalledDeserializing = true;
                    }
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
        }
Пример #9
0
        private void CompileBinary(GMLToken _tok)
        {
            CompileExpression(_tok.Children[0]);
            BinaryTypeCoercion(_tok, 1);
            CompileExpression(_tok.Children[2]);
            BinaryTypeCoercion(_tok, 2);
            eVM_Type eVM_Type  = TypeStack.Pop();
            eVM_Type eVM_Type2 = TypeStack.Pop();
            int      num       = TypeSize(eVM_Type);
            int      num2      = TypeSize(eVM_Type2);
            eVM_Type item      = (num > num2) ? eVM_Type : eVM_Type2;

            switch (_tok.Children[1].Token)
            {
            case eToken.eTime:
                Emit(eVM_Instruction.eVMI_MUL, eVM_Type, eVM_Type2);
                TypeStack.Push(item);
                break;

            case eToken.eDivide:
                Emit(eVM_Instruction.eVMI_DIV, eVM_Type, eVM_Type2);
                TypeStack.Push(item);
                break;

            case eToken.eDiv:
                Emit(eVM_Instruction.eVMI_REM, eVM_Type, eVM_Type2);
                TypeStack.Push(item);
                break;

            case eToken.eMod:
                Emit(eVM_Instruction.eVMI_MOD, eVM_Type, eVM_Type2);
                TypeStack.Push(item);
                break;

            case eToken.ePlus:
                Emit(eVM_Instruction.eVMI_ADD, eVM_Type, eVM_Type2);
                TypeStack.Push(item);
                break;

            case eToken.eMinus:
                Emit(eVM_Instruction.eVMI_SUB, eVM_Type, eVM_Type2);
                TypeStack.Push(item);
                break;

            case eToken.eLess:
                Emit(eVM_Instruction.eVMI_SET_LT, eVM_Type, eVM_Type2);
                TypeStack.Push(eVM_Type.eVMT_Bool);
                break;

            case eToken.eLessEqual:
                Emit(eVM_Instruction.eVMI_SET_LE, eVM_Type, eVM_Type2);
                TypeStack.Push(eVM_Type.eVMT_Bool);
                break;

            case eToken.eAssign:
            case eToken.eEqual:
                Emit(eVM_Instruction.eVMI_SET_EQ, eVM_Type, eVM_Type2);
                TypeStack.Push(eVM_Type.eVMT_Bool);
                break;

            case eToken.eNotEqual:
                Emit(eVM_Instruction.eVMI_SET_NE, eVM_Type, eVM_Type2);
                TypeStack.Push(eVM_Type.eVMT_Bool);
                break;

            case eToken.eGreaterEqual:
                Emit(eVM_Instruction.eVMI_SET_GE, eVM_Type, eVM_Type2);
                TypeStack.Push(eVM_Type.eVMT_Bool);
                break;

            case eToken.eGreater:
                Emit(eVM_Instruction.eVMI_SET_GT, eVM_Type, eVM_Type2);
                TypeStack.Push(eVM_Type.eVMT_Bool);
                break;

            case eToken.eAnd:
            case eToken.eBitAnd:
                Emit(eVM_Instruction.eVMI_AND, eVM_Type, eVM_Type2);
                TypeStack.Push(item);
                break;

            case eToken.eOr:
            case eToken.eBitOr:
                Emit(eVM_Instruction.eVMI_OR, eVM_Type, eVM_Type2);
                TypeStack.Push(item);
                break;

            case eToken.eXor:
            case eToken.eBitXor:
                Emit(eVM_Instruction.eVMI_XOR, eVM_Type, eVM_Type2);
                TypeStack.Push(item);
                break;

            case eToken.eBitShiftLeft:
                Emit(eVM_Instruction.eVMI_SHL, eVM_Type, eVM_Type2);
                TypeStack.Push(item);
                break;

            case eToken.eBitShiftRight:
                Emit(eVM_Instruction.eVMI_SHR, eVM_Type, eVM_Type2);
                TypeStack.Push(item);
                break;
            }
        }