Beispiel #1
0
        private void CompileRepeat(GMLToken _tok)
        {
            VMLabel vMLabel  = new VMLabel("End", VMB);
            VMLabel vMLabel2 = new VMLabel("Repeat", VMB);

            CompileExpression(_tok.Children[0]);
            eVM_Type eVM_Type = TypeStack.Pop();

            if (eVM_Type != eVM_Type.eVMT_Int)
            {
                Emit(eVM_Instruction.eVMI_CONV, eVM_Type, eVM_Type.eVMT_Int);
            }
            Emit(eVM_Instruction.eVMI_DUP, eVM_Type.eVMT_Int);
            EmitI(eVM_Instruction.eVMI_PUSH, 0);
            Emit(eVM_Instruction.eVMI_SET_LE, eVM_Type.eVMT_Int, eVM_Type.eVMT_Int);
            Emit(eVM_Instruction.eVMI_BTRUE, vMLabel);
            LoopEnv.Push(vMLabel2);
            LoopEndEnv.Push(vMLabel);
            vMLabel2.Mark(VMB.Buffer.Position);
            CompileStatement(_tok.Children[1]);
            EmitI(eVM_Instruction.eVMI_PUSH, 1);
            Emit(eVM_Instruction.eVMI_SUB, eVM_Type.eVMT_Int, eVM_Type.eVMT_Int);
            Emit(eVM_Instruction.eVMI_DUP, eVM_Type.eVMT_Int);
            Emit(eVM_Instruction.eVMI_CONV, eVM_Type.eVMT_Int, eVM_Type.eVMT_Bool);
            Emit(eVM_Instruction.eVMI_BTRUE, vMLabel2);
            vMLabel.Mark(VMB.Buffer.Position);
            Emit(eVM_Instruction.eVMI_POPNULL, eVM_Type.eVMT_Int);
            LoopEnv.Pop();
            LoopEndEnv.Pop();
        }
Beispiel #2
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;
            }
        }
Beispiel #3
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;
            }
        }
Beispiel #4
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;
            }
        }
Beispiel #5
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);
 }
Beispiel #6
0
        private int TypeSize(eVM_Type _t)
        {
            int result = 0;

            switch (_t)
            {
            case eVM_Type.eVMT_Double:
                result = 8;
                break;

            case eVM_Type.eVMT_Long:
                result = 8;
                break;

            case eVM_Type.eVMT_String:
                result = 4;
                break;

            case eVM_Type.eVMT_Variable:
                result = 12;
                break;

            case eVM_Type.eVMT_Float:
                result = 4;
                break;

            case eVM_Type.eVMT_Bool:
                result = 4;
                break;

            case eVM_Type.eVMT_Int:
                result = 4;
                break;
            }
            return(result);
        }
Beispiel #7
0
        private void CompileAssign(GMLToken _tok)
        {
            switch (_tok.Children[1].Token)
            {
            case eToken.eAssign:
                CompileExpression(_tok.Children[2]);
                CompilePop(_tok.Children[0], TypeStack.Pop());
                break;

            case eToken.eAssignPlus:
            {
                CompileVariable(_tok.Children[0]);
                TypeStack.Pop();
                CompileExpression(_tok.Children[2]);
                eVM_Type eVM_Type3 = TypeStack.Pop();
                if (eVM_Type3 == eVM_Type.eVMT_Bool)
                {
                    Emit(eVM_Instruction.eVMI_CONV, eVM_Type3, eVM_Type.eVMT_Int);
                    eVM_Type3 = eVM_Type.eVMT_Int;
                }
                Emit(eVM_Instruction.eVMI_ADD, eVM_Type3, eVM_Type.eVMT_Variable);
                CompilePop(_tok.Children[0], eVM_Type.eVMT_Variable);
                break;
            }

            case eToken.eAssignMinus:
            {
                CompileVariable(_tok.Children[0]);
                TypeStack.Pop();
                CompileExpression(_tok.Children[2]);
                eVM_Type eVM_Type7 = TypeStack.Pop();
                if (eVM_Type7 == eVM_Type.eVMT_Bool)
                {
                    Emit(eVM_Instruction.eVMI_CONV, eVM_Type7, eVM_Type.eVMT_Int);
                    eVM_Type7 = eVM_Type.eVMT_Int;
                }
                Emit(eVM_Instruction.eVMI_SUB, eVM_Type7, eVM_Type.eVMT_Variable);
                CompilePop(_tok.Children[0], eVM_Type.eVMT_Variable);
                break;
            }

            case eToken.eAssignTimes:
            {
                CompileVariable(_tok.Children[0]);
                TypeStack.Pop();
                CompileExpression(_tok.Children[2]);
                eVM_Type eVM_Type2 = TypeStack.Pop();
                if (eVM_Type2 == eVM_Type.eVMT_Bool)
                {
                    Emit(eVM_Instruction.eVMI_CONV, eVM_Type2, eVM_Type.eVMT_Int);
                    eVM_Type2 = eVM_Type.eVMT_Int;
                }
                Emit(eVM_Instruction.eVMI_MUL, eVM_Type2, eVM_Type.eVMT_Variable);
                CompilePop(_tok.Children[0], eVM_Type.eVMT_Variable);
                break;
            }

            case eToken.eAssignDivide:
            {
                CompileVariable(_tok.Children[0]);
                TypeStack.Pop();
                CompileExpression(_tok.Children[2]);
                eVM_Type eVM_Type6 = TypeStack.Pop();
                if (eVM_Type6 == eVM_Type.eVMT_Bool)
                {
                    Emit(eVM_Instruction.eVMI_CONV, eVM_Type6, eVM_Type.eVMT_Int);
                    eVM_Type6 = eVM_Type.eVMT_Int;
                }
                Emit(eVM_Instruction.eVMI_DIV, eVM_Type6, eVM_Type.eVMT_Variable);
                CompilePop(_tok.Children[0], eVM_Type.eVMT_Variable);
                break;
            }

            case eToken.eAssignOr:
            {
                CompileVariable(_tok.Children[0]);
                TypeStack.Pop();
                CompileExpression(_tok.Children[2]);
                eVM_Type eVM_Type4 = TypeStack.Pop();
                if (eVM_Type4 != eVM_Type.eVMT_Int && eVM_Type4 != eVM_Type.eVMT_Long)
                {
                    Emit(eVM_Instruction.eVMI_CONV, eVM_Type4, eVM_Type.eVMT_Int);
                    eVM_Type4 = eVM_Type.eVMT_Int;
                }
                Emit(eVM_Instruction.eVMI_OR, eVM_Type4, eVM_Type.eVMT_Variable);
                CompilePop(_tok.Children[0], eVM_Type.eVMT_Variable);
                break;
            }

            case eToken.eAssignAnd:
            {
                CompileVariable(_tok.Children[0]);
                TypeStack.Pop();
                CompileExpression(_tok.Children[2]);
                eVM_Type eVM_Type5 = TypeStack.Pop();
                if (eVM_Type5 != eVM_Type.eVMT_Int && eVM_Type5 != eVM_Type.eVMT_Long)
                {
                    Emit(eVM_Instruction.eVMI_CONV, eVM_Type5, eVM_Type.eVMT_Int);
                    eVM_Type5 = eVM_Type.eVMT_Int;
                }
                Emit(eVM_Instruction.eVMI_AND, eVM_Type5, eVM_Type.eVMT_Variable);
                CompilePop(_tok.Children[0], eVM_Type.eVMT_Variable);
                break;
            }

            case eToken.eAssignXor:
            {
                CompileVariable(_tok.Children[0]);
                TypeStack.Pop();
                CompileExpression(_tok.Children[2]);
                eVM_Type eVM_Type = TypeStack.Pop();
                if (eVM_Type != eVM_Type.eVMT_Int && eVM_Type != eVM_Type.eVMT_Long)
                {
                    Emit(eVM_Instruction.eVMI_CONV, eVM_Type, eVM_Type.eVMT_Int);
                    eVM_Type = eVM_Type.eVMT_Int;
                }
                Emit(eVM_Instruction.eVMI_XOR, eVM_Type, eVM_Type.eVMT_Variable);
                CompilePop(_tok.Children[0], eVM_Type.eVMT_Variable);
                break;
            }
            }
        }
Beispiel #8
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;
            }
        }
Beispiel #9
0
 private void EmitIVar(eVM_Instruction _inst, int _var, eVM_Type _target)
 {
     VMB.Add(VMBuffer.EncodeInstructionArg((int)_inst, VMBuffer.EncodeArgDouble(5, (int)_target)));
     VMB.Buffer.WriteInteger(_var);
 }
Beispiel #10
0
 private void Emit(eVM_Instruction _inst, eVM_Type _type1, eVM_Type _type2)
 {
     VMB.Add(VMBuffer.EncodeInstructionArg((int)_inst, VMBuffer.EncodeArgDouble((int)_type1, (int)_type2)));
 }
Beispiel #11
0
 private void Emit(eVM_Instruction _inst, eVM_Type _type1)
 {
     VMB.Add(VMBuffer.EncodeInstructionArg((int)_inst, (int)_type1));
 }