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

📄 code_emit.cpp

📁 < Game Script Mastery>> source code
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*

    Project.

        XSC - The XtremeScript Compiler Version 0.8

    Abstract.

        Code emission module

    Date Created.

        9.2.2002

    Author.

        Alex Varanese

*/

// ---- Include Files -------------------------------------------------------------------------

    #include "code_emit.h"

// ---- Globals -------------------------------------------------------------------------------

    FILE * g_pOutputFile = NULL;                        // Pointer to the output file

    // ---- Instruction Mnemonics -------------------------------------------------------------

        // These mnemonics are mapped to each I-code instruction, allowing the emitter to
        // easily translate I-code to XVM assembly

        char ppstrMnemonics [][ 12 ] =
        {
            "Mov",
            "Add", "Sub", "Mul", "Div", "Mod", "Exp", "Neg", "Inc", "Dec",
            "And", "Or", "XOr", "Not", "ShL", "ShR",
            "Concat", "GetChar", "SetChar",
            "Jmp", "JE", "JNE", "JG", "JL", "JGE", "JLE",
            "Push", "Pop",
            "Call", "Ret", "CallHost",
            "Pause", "Exit"
        };

// ---- Functions -----------------------------------------------------------------------------

    /******************************************************************************************
    *
    *   EmitHeader ()
    *
    *   Emits the script's header comments.
    */

    void EmitHeader ()
    {
        // Get the current time

        time_t CurrTimeMs;
        struct tm * pCurrTime;
        CurrTimeMs = time ( NULL );
        pCurrTime = localtime ( & CurrTimeMs );      

        // Emit the filename

        fprintf ( g_pOutputFile, "; %s\n\n", g_pstrOutputFilename );

        // Emit the rest of the header

        fprintf ( g_pOutputFile, "; Source File: %s\n", g_pstrSourceFilename );
        fprintf ( g_pOutputFile, "; XSC Version: %d.%d\n", VERSION_MAJOR, VERSION_MINOR );
        fprintf ( g_pOutputFile, ";   Timestamp: %s\n", asctime ( pCurrTime ) );
    }

    /******************************************************************************************
    *
    *   EmitDirectives ()
    *
    *   Emits the script's directives.
    */

    void EmitDirectives ()
    {
        // If directives were emitted, this is set to TRUE so we remember to insert extra line
        // breaks after them

        int iAddNewline = FALSE;

        // If the stack size has been set, emit a SetStackSize directive

        if ( g_ScriptHeader.iStackSize )
        {
            fprintf ( g_pOutputFile, "\tSetStackSize %d\n", g_ScriptHeader.iStackSize );
            iAddNewline = TRUE;
        }

        // If the priority has been set, emit a SetPriority directive

        if ( g_ScriptHeader.iPriorityType != PRIORITY_NONE )
        {
            fprintf ( g_pOutputFile, "\tSetPriority " );
            switch ( g_ScriptHeader.iPriorityType )
            {
                // Low rank

                case PRIORITY_LOW:
                    fprintf ( g_pOutputFile, PRIORITY_LOW_KEYWORD );
                    break;

                // Medium rank

                case PRIORITY_MED:
                    fprintf ( g_pOutputFile, PRIORITY_MED_KEYWORD );
                    break;

                // High rank

                case PRIORITY_HIGH:
                    fprintf ( g_pOutputFile, PRIORITY_HIGH_KEYWORD );
                    break;

                // User-defined timeslice

                case PRIORITY_USER:
                    fprintf ( g_pOutputFile, "%d", g_ScriptHeader.iUserPriority );
                    break;
            }
            fprintf ( g_pOutputFile, "\n" );

            iAddNewline = TRUE;
        }

        // If necessary, insert an extra line break

        if ( iAddNewline )
            fprintf ( g_pOutputFile, "\n" );
    }

    /******************************************************************************************
    *
    *   EmitScopeSymbols ()
    *
    *   Emits the symbol declarations of the specified scope
    */

    void EmitScopeSymbols ( int iScope, int iType )
    {
        // If declarations were emitted, this is set to TRUE so we remember to insert extra
        // line breaks after them
        
        int iAddNewline = FALSE;

        // Local symbol node pointer

        SymbolNode * pCurrSymbol;

        // Loop through each symbol in the table to find the match

        for ( int iCurrSymbolIndex = 0; iCurrSymbolIndex < g_SymbolTable.iNodeCount; ++ iCurrSymbolIndex )
        {
            // Get the current symbol structure

            pCurrSymbol = GetSymbolByIndex ( iCurrSymbolIndex );

            // If the scopes and parameter flags match, emit the declaration

            if ( pCurrSymbol->iScope == iScope && pCurrSymbol->iType == iType )
            {
                // Print one tab stop for global declarations, and two for locals

                fprintf ( g_pOutputFile, "\t" );
                if ( iScope != SCOPE_GLOBAL )
                    fprintf ( g_pOutputFile, "\t" );

                // Is the symbol a parameter?

                if ( pCurrSymbol->iType == SYMBOL_TYPE_PARAM )
                    fprintf ( g_pOutputFile, "Param %s", pCurrSymbol->pstrIdent );

                // Is the symbol a variable?

                if ( pCurrSymbol->iType == SYMBOL_TYPE_VAR )
                {
                    fprintf ( g_pOutputFile, "Var %s", pCurrSymbol->pstrIdent );

                    // If the variable is an array, add the size declaration

                    if ( pCurrSymbol->iSize > 1 )
                        fprintf ( g_pOutputFile, " [ %d ]", pCurrSymbol->iSize );
                }

                fprintf ( g_pOutputFile, "\n" );
                iAddNewline = TRUE;
            }
        }

        // If necessary, insert an extra line break

        if ( iAddNewline )
            fprintf ( g_pOutputFile, "\n" );
    }

    /******************************************************************************************
    *
    *   EmitFunc ()
    *   
    *   Emits a function, its local declarations, and its code.
    */

    void EmitFunc ( FuncNode * pFunc )
    {
        // Emit the function declaration name and opening brace

        fprintf ( g_pOutputFile, "\tFunc %s\n", pFunc->pstrName );
        fprintf ( g_pOutputFile, "\t{\n" );

        // Emit parameter declarations

        EmitScopeSymbols ( pFunc->iIndex, SYMBOL_TYPE_PARAM );

        // Emit local variable declarations

        EmitScopeSymbols ( pFunc->iIndex, SYMBOL_TYPE_VAR );

        // Does the function have an I-code block?

        if ( pFunc->ICodeStream.iNodeCount > 0 )
        {
            // Used to determine if the current line is the first

            int iIsFirstSourceLine = TRUE;

            // Yes, so loop through each I-code node to emit the code

            for ( int iCurrInstrIndex = 0; iCurrInstrIndex < pFunc->ICodeStream.iNodeCount; ++ iCurrInstrIndex )
            {
                // Get the I-code instruction structure at the current node

                ICodeNode * pCurrNode = GetICodeNodeByImpIndex ( pFunc->iIndex, iCurrInstrIndex );

                // Determine the node type

                switch ( pCurrNode->iType)
                {
                    // Source code annotation

                    case ICODE_NODE_SOURCE_LINE:
                    {
                        // Make a local copy of the source line

                        char * pstrSourceLine = pCurrNode->pstrSourceLine;

                        // If the last character of the line is a line break, clip it

                        int iLastCharIndex = strlen ( pstrSourceLine ) - 1;
                        if ( pstrSourceLine [ iLastCharIndex ] == '\n' )

⌨️ 快捷键说明

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