⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zvm.cpp

📁 自己开发的类汇编语言脚本语言虚拟机
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                    // 打印操作信息

                    PrintOpIndir ( 0 );
                    printf ( ", " );
                    PrintOpValue ( 1 );

                    break;
                }

                case INSTR_GETCHAR:
                {
                    // 局部赋值目的操作数

                    Value   Dest    = ResolveOpValue ( 0 );

                    // 局部复制源操作数字符串

                    char    *pstrSourceString   = ResolveOpAsString ( 1 );

                    // 检测目的操作数是否已经是字符串

                    char    *pstrNewString;
                    if ( Dest.iType == OP_TYPE_STRING )
                    {
                        // 目的操作数是字符串,确保字符串空间大于二

                        if ( strlen ( Dest.pstrStringLiteral ) >= 1 )
                        {
                            pstrNewString   = Dest.pstrStringLiteral;
                        }
                        else
                        {
                            delete  Dest.pstrStringLiteral;
                            pstrNewString   = new char [ 2 ];
                        }
                    }
                    else
                    {
                        // 目的操作数不是字符串,更改操作数类型为字符串类型,
                        // 并为新字符串分配2字节空间

                        Dest.iType      = OP_TYPE_STRING;
                        pstrNewString   = new char [ 2 ];
                    }

                    // 取得索引

                    int     iSourceIndex    = ResolveOpAsInt ( 2 );

                    // 从源串索引位置取得字符

                    pstrNewString [ 0 ]     = pstrSourceString [ iSourceIndex ];
                    pstrNewString [ 1 ]     = '\0';

                    // 将新串写入到 临时复制的目的操作数中

                    Dest.pstrStringLiteral  = pstrNewString;

                    // 将Dest写回目的操作数

                    *ResolveOpPntr ( 0 )    = Dest;

                    // 打印操作信息

                    PrintOpIndir ( 0 );
                    printf ( ", " );
                    PrintOpValue ( 1 );
                    printf ( ", " );
                    PrintOpValue ( 2 );

                    break;
                }

                case INSTR_SETCHAR:
                {
                    // 检测目的操作数是否是字符串

                    if ( ResolveOpType ( 0 ) != OP_TYPE_STRING )
                    {
                        break;
                    }

                    // 取得索引

                    int     iDestIndex      = ResolveOpAsInt ( 1 );

                    // 取得包含要设置字符的字符串

                    char    *pstrSourceString   = ResolveOpAsString ( 2 );

                    // 更新目的操作数索引位置的字符

                    ResolveOpPntr ( 0 ) ->pstrStringLiteral [ iDestIndex ] = pstrSourceString [ 0 ];

                    // 打印操作信息

                    PrintOpIndir ( 0 );
                    printf ( ", " );
                    PrintOpValue ( 1 );
                    printf ( ", " );
                    PrintOpValue ( 2 );

                    break;
                }

                // ---- 跳转指令

                case INSTR_JMP:
                {
                    // 取得目标指令索引

                    int     iTargetIndex    = ResolveOpAsInstrIndex ( 0 );

                    // 更改指令技术到目标指令

                    g_Script.InstrStream.iCurrInstr = iTargetIndex;

                    // 打印操作信息

                    PrintOpValue ( 0 );

                    break;
                }

                case INSTR_JE:
				case INSTR_JNE:
				case INSTR_JG:
				case INSTR_JL:
  				case INSTR_JGE:
				case INSTR_JLE:
                {
                    // 取得两个操作数

                    Value   op0     = ResolveOpValue ( 0 );
                    Value   op1     = ResolveOpValue ( 1 );

                    // 取得目标指令索引 (保存在操作数2中)

                    int     iTargetIndex    = ResolveOpAsInstrIndex ( 2 );

                    // 根据不同指令,决定是否跳转

                    bool    bJump   = false;

                    switch ( iOpCode )
                    {
                        // je

                        case INSTR_JE:

                            switch ( op0.iType )
                            {
                                case OP_TYPE_INT:
                                    if ( op0.iIntLiteral == op1.iIntLiteral )
                                    {
                                        bJump   = true;
                                    }
                                    break;

                                case OP_TYPE_FLOAT:
                                    if ( op0.fFloatLiteral == op1.fFloatLiteral )
                                    {
                                        bJump   = true;
                                    }
                                    break;

                                case OP_TYPE_STRING:
                                    if ( strcmp ( op0.pstrStringLiteral, op1.pstrStringLiteral ) == 0 )
                                    {
                                        bJump   = true;
                                    }
                                    break;
                            }

                            break;

                        // jne

                        case INSTR_JNE:

                            switch ( op0.iType )
                            {
                                case OP_TYPE_INT:
                                    if ( op0.iIntLiteral != op1.iIntLiteral )
                                    {
                                        bJump   = true;
                                    }
                                    break;

                                case OP_TYPE_FLOAT:
                                    if ( op0.fFloatLiteral != op1.fFloatLiteral )
                                    {
                                        bJump   = true;
                                    }
                                    break;

                                case OP_TYPE_STRING:
                                    if ( strcmp ( op0.pstrStringLiteral, op1.pstrStringLiteral ) != 0 )
                                    {
                                        bJump   = true;
                                    }
                                    break;
                            }

                            break;

                        // jg

                        case INSTR_JG:

                            if ( op0.iType == OP_TYPE_INT )
                            {
                                if ( op0.iIntLiteral > op1.iIntLiteral )
                                {
                                    bJump   = true;
                                }
                            }
                            else
                            {
                                if ( op0.fFloatLiteral > op1.fFloatLiteral )
                                {
                                    bJump   = true;
                                }
                            }

                            break;

                        // jl
                
                        case INSTR_JL:

                            if ( op0.iType == OP_TYPE_INT )
                            {
                                if ( op0.iIntLiteral < op1.iIntLiteral )
                                {
                                    bJump   = true;
                                }
                            }
                            else
                            {
                                if ( op0.fFloatLiteral < op1.fFloatLiteral )
                                {
                                    bJump   = true;
                                }
                            }

                            break;

                        // jge

                        case INSTR_JGE:

                            if ( op0.iType == OP_TYPE_INT )
                            {
                                if ( op0.iIntLiteral >= op1.iIntLiteral )
                                {
                                    bJump   = true;
                                }
                            }
                            else
                            {
                                if ( op0.fFloatLiteral >= op1.fFloatLiteral )
                                {
                                    bJump   = true;
                                }
                            }

                            break;

                        // jle

                        case INSTR_JLE:

                            if ( op0.iType == OP_TYPE_INT )
                            {
                                if ( op0.iIntLiteral <= op1.iIntLiteral )
                                {
                                    bJump   = true;
                                }
                            }
                            else
                            {
                                if ( op0.fFloatLiteral <= op1.fFloatLiteral )
                                {
                                    bJump   = true;
                                }
                            }

                            break;
                    }

                    // 打印操作信息

                    PrintOpValue ( 0 );
                    printf ( ", " );
                    PrintOpValue ( 1 );
                    printf ( ", " );
                    PrintOpValue ( 2 );
                    printf ( " " );

                    // 检测 bJump 标志,决定是否跳转

                    if ( bJump == true )
                    {
                        g_Script.InstrStream.iCurrInstr = iTargetIndex;
                        printf ( "true" );
                    }
                    else
                    {
                        printf ( "false" );
                    }

                    break;
                }

                // ---- 堆栈操作指令

                case INSTR_PUSH:
                {
                    // 局部赋值目的操作数

                    Value   Source  = ResolveOpValue ( 0 );

                    // 压栈

                    Push ( Source );

                    // 打印操作信息

                    PrintOpValue ( 0 );

                    break;
                }

                case INSTR_POP:
                {
                    // 弹出值并存入目的操作数

                    *ResolveOpPntr ( 0 ) = Pop();

                    // 打印操作信息

                    PrintOpValue ( 0 );
                    
                    break;
                }

                // ---- 函数调用

                case INSTR_CALL:
                {
                    // 从目的操作数取得函数索引并进而取得函数节点

                    int     iFuncIndex  = ResolveOpAsFuncIndex ( 0 );
                    Func    Dest        = GetFunc ( iFuncIndex );

                    // 取得 call 指令之后一条指令的索引,即返回地址,并压栈

                    Value   ReturnAddr;
                    ReturnAddr.iInstrIndex  = g_Script.InstrStream.iCurrInstr + 1;
                    Push ( ReturnAddr );

                    // 压入堆栈框架 + 1的空间 (额外的一个空间是给函数索引的,函数索引紧跟在在堆栈框架之后)

                    PushFrame ( Dest.iLocalDataSize + 1 );
                
                    // 写函数索引以及先前堆栈框架索引

                    Value   FuncIndex;
                    FuncIndex.iFuncIndex    = iFuncIndex;
                    FuncIndex.iOffsetIndex  = g_Script.Stack.iFrameIndex;  // 先前堆栈框架索引存储在 iOffsetIndex 中
                    SetStackValue ( g_Script.Stack.iTopIndex - 1, FuncIndex );

                    // 跳转到函数入口

                    g_Script.InstrStream.iCurrInstr = Dest.iEntryPoint;

                    printf ( " $$[ %d ]$$", g_Script.InstrStream.iCurrInstr );

                    // 打印一些信息

                    printf ( "%d ( Entry Point: %d, Frame Size: %d )", iFuncIndex, Dest.iEntryPoint, Dest.iStackFrameSize ); 

                    break;
                }

                case INSTR_RET:
                {
                    // 弹出函数索引

                    Value   FuncIndex   = Pop ();
                    Func    CurrFunc    = GetFunc ( FuncIndex.iFuncIndex );
                    int     iFrameIndex = FuncIndex.iOffsetIndex;

                    // 取得返回地址

                    Value   ReturnAddr  = GetStackValue ( g_Script.Stack.iTopIndex - CurrFunc.iLocalDataSize - 1 );

                    // 弹出堆栈框架

                    PopFrame ( CurrFunc.iStackFrameSize );

                    // 存储先前的堆栈索引

                    g_Script.Stack.iFrameIndex  = iFrameIndex;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -