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

📄 code_emit.cpp

📁 < Game Script Mastery>> source code
💻 CPP
📖 第 1 页 / 共 2 页
字号:
                            pstrSourceLine [ iLastCharIndex ] = '\0';

                        // Emit the comment, but only prepend it with a line break if it's not the
                        // first one

                        if ( ! iIsFirstSourceLine )
                            fprintf ( g_pOutputFile, "\n" );

                        fprintf ( g_pOutputFile, "\t\t; %s\n\n", pstrSourceLine );
                        
                        break;
                    }

                    // An I-code instruction

                    case ICODE_NODE_INSTR:
                    {
                        // Emit the opcode

                        fprintf ( g_pOutputFile, "\t\t%s", ppstrMnemonics [ pCurrNode->Instr.iOpcode ] );

                        // Determine the number of operands

                        int iOpCount = pCurrNode->Instr.OpList.iNodeCount;

                        // If there are operands to emit, follow the instruction with some space

                        if ( iOpCount )
                        {
                            // All instructions get at least one tab

                            fprintf ( g_pOutputFile, "\t" );

                            // If it's less than a tab stop's width in characters, however, they get a
                            // second

                            if ( strlen ( ppstrMnemonics [ pCurrNode->Instr.iOpcode ] ) < TAB_STOP_WIDTH )
                                fprintf ( g_pOutputFile, "\t" );
                        }

                        // Emit each operand

                        for ( int iCurrOpIndex = 0; iCurrOpIndex < iOpCount; ++ iCurrOpIndex )
                        {
                            // Get a pointer to the operand structure

                            Op * pOp = GetICodeOpByIndex ( pCurrNode, iCurrOpIndex );

                            // Emit the operand based on its type

                            switch ( pOp->iType )
                            {
                                // Integer literal

                                case OP_TYPE_INT:
                                    fprintf ( g_pOutputFile, "%d", pOp->iIntLiteral );
                                    break;

                                // Float literal

                                case OP_TYPE_FLOAT:
                                    fprintf ( g_pOutputFile, "%f", pOp->fFloatLiteral );
                                    break;

                                // String literal

                                case OP_TYPE_STRING_INDEX:
                                    fprintf ( g_pOutputFile, "\"%s\"", GetStringByIndex ( & g_StringTable, pOp->iStringIndex ) );
                                    break;

                                // Variable

                                case OP_TYPE_VAR:
                                    fprintf ( g_pOutputFile, "%s", GetSymbolByIndex ( pOp->iSymbolIndex )->pstrIdent );
                                    break;

                                // Array index absolute

                                case OP_TYPE_ARRAY_INDEX_ABS:
                                    fprintf ( g_pOutputFile, "%s [ %d ]", GetSymbolByIndex ( pOp->iSymbolIndex )->pstrIdent,
                                                                          pOp->iOffset );
                                    break;

                                // Array index variable

                                case OP_TYPE_ARRAY_INDEX_VAR:
                                    fprintf ( g_pOutputFile, "%s [ %s ]", GetSymbolByIndex ( pOp->iSymbolIndex )->pstrIdent,
                                                                          GetSymbolByIndex ( pOp->iOffsetSymbolIndex )->pstrIdent );
                                    break;

                                // Function

                                case OP_TYPE_FUNC_INDEX:
                                    fprintf ( g_pOutputFile, "%s", GetFuncByIndex ( pOp->iSymbolIndex )->pstrName );
                                    break;

                                // Register (just _RetVal for now)

                                case OP_TYPE_REG:
                                    fprintf ( g_pOutputFile, "_RetVal" );
                                    break;

                                // Jump target index

                                case OP_TYPE_JUMP_TARGET_INDEX:
                                    fprintf ( g_pOutputFile, "_L%d", pOp->iJumpTargetIndex );
                                    break;
                            }

                            // If the operand isn't the last one, append it with a comma and space

                            if ( iCurrOpIndex != iOpCount - 1 )
                                fprintf ( g_pOutputFile, ", " );
                        }

                        // Finish the line

                        fprintf ( g_pOutputFile, "\n" );

                        break;
                    }

                    // A jump target

                    case ICODE_NODE_JUMP_TARGET:
                    {
                        // Emit a label in the format _LX, where X is the jump target

                        fprintf ( g_pOutputFile, "\t_L%d:\n", pCurrNode->iJumpTargetIndex );
                    }
                }

                // Update the first line flag

                if ( iIsFirstSourceLine )
                    iIsFirstSourceLine = FALSE;
            }
        }
        else
        {
            // No, so emit a comment saying so

            fprintf ( g_pOutputFile, "\t\t; (No code)\n" );
        }

        // Emit the closing brace

        fprintf ( g_pOutputFile, "\t}" );
    }

    /******************************************************************************************
    *
    *   EmitCode ()
    *
    *   Translates the I-code representation of the script to an ASCII-foramtted XVM assembly
    *   file.
    */

    void EmitCode ()
    {
        // ---- Open the output file

        if ( ! ( g_pOutputFile = fopen ( g_pstrOutputFilename, "wb" ) ) )
            ExitOnError ( "Could not open output file for output" );

        // ---- Emit the header

        EmitHeader ();

        // ---- Emit directives

        fprintf ( g_pOutputFile, "; ---- Directives -----------------------------------------------------------------------------\n\n" );

        EmitDirectives ();

        // ---- Emit global variable declarations

        fprintf ( g_pOutputFile, "; ---- Global Variables -----------------------------------------------------------------------\n\n" );

        // Emit the globals by printing all non-parameter symbols in the global scope

        EmitScopeSymbols ( SCOPE_GLOBAL, SYMBOL_TYPE_VAR );

        // ---- Emit functions

        fprintf ( g_pOutputFile, "; ---- Functions ------------------------------------------------------------------------------\n\n" );

        // Local node for traversing lists

        LinkedListNode * pNode = g_FuncTable.pHead;

        // Local function node pointer

        FuncNode * pCurrFunc;

        // Pointer to hold the _Main () function, if it's found

        FuncNode * pMainFunc = NULL;

        // Loop through each function and emit its declaration and code, if functions exist

        if ( g_FuncTable.iNodeCount > 0 )
        {
            while ( TRUE )
            {
                // Get a pointer to the node

                pCurrFunc = ( FuncNode * ) pNode->pData;

                // Don't emit host API function nodes

                if ( ! pCurrFunc->iIsHostAPI )
                {
                    // Is the current function _Main ()?

                    if ( stricmp ( pCurrFunc->pstrName, MAIN_FUNC_NAME ) == 0 )
                    {
                        // Yes, so save the pointer for later (and don't emit it yet)

                        pMainFunc = pCurrFunc;
                    }
                    else
                    {
                        // No, so emit it

                        EmitFunc ( pCurrFunc );
                        fprintf ( g_pOutputFile, "\n\n" );
                    }
                }

                // Move to the next node

                pNode = pNode->pNext;
                if ( ! pNode )
                    break;
            }
        }

        // ---- Emit _Main ()
    
        fprintf ( g_pOutputFile, "; ---- Main -----------------------------------------------------------------------------------" );

        // If the last pass over the functions found a _Main () function. emit it

        if ( pMainFunc )
        {
            fprintf ( g_pOutputFile, "\n\n" );
            EmitFunc ( pMainFunc );
        }

        // ---- Close output file

        fclose ( g_pOutputFile );
    }

⌨️ 快捷键说明

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