/
Sapphire/bin/
Sapphire/db/
Sapphire/db/OLC_rooms/
Sapphire/db/abi/
Sapphire/db/em_src/
Sapphire/db/helps/
Sapphire/db/helps/emman/ifunc/
Sapphire/db/npcs/Tatt/
Sapphire/db/objects/Tatt/
Sapphire/db/q_data/
Sapphire/db/rooms/Tatt/
Sapphire/doc/
Sapphire/doc/em/
Sapphire/etc/
Sapphire/src/abic/
Sapphire/src/areacon/
Sapphire/src/client/
Sapphire/src/embc/
Sapphire/src/emi/
Sapphire/src/emi/test/
Sapphire/src/include/
Sapphire/src/sapphire/em/
Sapphire/src/tcon/
/*
 * Copyright (C) 1995-1997 Christopher D. Granz
 *
 * This header may not be removed.
 *
 * Refer to the file "License" included in this package for further
 * information and before using any of the following.
 */

#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>

#include "emerald.h"
#include "embc.h"


/*
 * Globals
 */
char                                                          cNullChar;

const struct code_name_type                           cnKeywordTable[] =
{
    { "END",                 INSTR_END                 },
    { "NEW_INT",             INSTR_NEW_INT             },
    { "NEW_FLOAT",           INSTR_NEW_FLOAT           },
    { "NEW_STRING",          INSTR_NEW_STRING          },
    { "NEW_OBJECT",          INSTR_NEW_OBJECT          },
    { "NEW_ARRAY",           INSTR_NEW_ARRAY           },
    { "PUSH_ZERO",           INSTR_PUSH_ZERO           },
    { "PUSH_ONE",            INSTR_PUSH_ONE            },
    { "PUSH_INT1",           INSTR_PUSH_INT1           },
    { "PUSH_INT2",           INSTR_PUSH_INT2           },
    { "PUSH_INT4",           INSTR_PUSH_INT4           },
    { "PUSH_FLOAT4",         INSTR_PUSH_FLOAT4         },
    { "PUSH_FLOAT8",         INSTR_PUSH_FLOAT8         },
    { "PUSH_STRING",         INSTR_PUSH_STRING         },
    { "PUSH_ARRAY",          INSTR_PUSH_ARRAY          },
    { "PUSH_GLOBAL",         INSTR_PUSH_GLOBAL         },
    { "PUSH_LOCAL",          INSTR_PUSH_LOCAL          },
    { "PUSH_INDEX",          INSTR_PUSH_INDEX          },
    { "POP",                 INSTR_POP                 },
    { "CLEAR_GLOBAL",        INSTR_CLEAR_GLOBAL        },
    { "CLEAR_LOCAL",         INSTR_CLEAR_LOCAL         },
    { "ASSIGN_GLOBAL",       INSTR_ASSIGN_GLOBAL       },
    { "ASSIGN_LOCAL",        INSTR_ASSIGN_LOCAL        },
    { "ASSIGN_INDEX",        INSTR_ASSIGN_INDEX        },
    { "MULTIPLY",            INSTR_MULTIPLY            },
    { "DIVIDE",              INSTR_DIVIDE              },
    { "MODULUS",             INSTR_MODULUS             },
    { "ADD",                 INSTR_ADD                 },
    { "SUBTRACT",            INSTR_SUBTRACT            },
    { "RSHIFT",              INSTR_RSHIFT              },
    { "LSHIFT",              INSTR_LSHIFT              },
    { "AND",                 INSTR_AND                 },
    { "XOR",                 INSTR_XOR                 },
    { "OR",                  INSTR_OR                  },
    { "ONES_COMPLEMENT",     INSTR_ONES_COMPLEMENT     },
    { "JUMP",                INSTR_JUMP                },
    { "CAST",                INSTR_CAST                },
    { "COMPARE",             INSTR_COMPARE             },
    { "CALL_BUILTIN_FUNC",   INSTR_CALL_BUILTIN_FUNC   },
    { "CALL_FUNC",           INSTR_CALL_FUNC           },
    { "RETURN",              INSTR_RETURN              },
    { NULL,                  0                         }
};


/*
 * Functions
 */
int main( int iArgC, char *pArgV[] )
{
    FILE *pFile;
    FILE *pFileOut;
    char cBuf[1028];
    char *pBuf;
    char c[2];
    int i;

    if ( iArgC < 2 )
    {
        fprintf( stderr,
          "\nUsage: %s [-c|d] <object files|code files>\n", pArgV[0] );
        return ( 0 );
    }

    if ( iArgC > 1 )
    {
        strncpy( cBuf, pArgV[1], 1024 );
        cBuf[1024] = '\0';
        pFile      = open_file( cBuf, "r" );

        if ( iArgC > 2 )
            strncpy( cBuf, pArgV[2], 1024 );
        else
        {
            pBuf   = strrchr( cBuf, '.' );

            if ( !strcmp( pBuf, ".emb" ) || !strcmp( pBuf, ".EMB" ) )
                strcpy( pBuf, ".emo" );
            else
                strcat( pBuf, ".emo" );
        }
    }
    else
    {
        pFile      = stdin;
        strcpy( cBuf, "_a.emo" );
    }

    if ( ( pFileOut = fopen( cBuf, "wb" ) ) == NULL )
    {
        fprintf( stderr, "\n%s: %s.\n", pArgV[0], strerror( errno ) );

        if ( pFile != stdin )
            close_file( pFile );

        return ( 0 );
    }

    if ( pFile != stdin )
        fprintf( stderr, "%s: %s -> %s\n", pArgV[0], pArgV[1], cBuf );

    c[0]       = fget_letter( pFile );

    while ( feof( pFile ) == 0 )
    {
        switch ( c[0] )
        {
          case 'I':
          case 'i':
              pBuf         = fget_word( pFile );

              for ( i = 0; cnKeywordTable[i].pKeyword != NULL; i++ )
              {
                  if ( strcmp( cnKeywordTable[i].pKeyword, pBuf ) == 0 )
                      break;
              }

              if ( cnKeywordTable[i].pKeyword == NULL )
              {
                  error( "Unknown instruction `%s'.", pBuf );
                  break;
              }

              i = fwrite( &cnKeywordTable[i].iByteCode, 1, 1, pFileOut );

              if ( i < 0 )
                  error( "%s: %s.", cBuf, strerror( errno ) );

              break;

          case 'L':
          case 'l':
              pBuf         = fget_word( pFile );

              if ( strcmp( pBuf, "int1" ) == 0 )
              {
                  char cV  = (char) atoi( fget_word( pFile ) );

                  i        = fwrite( &cV, sizeof( char ), 1, pFileOut );

                  if ( i < 0 )
                      error( "%s: %s.", cBuf, strerror( errno ) );
              }
              else if ( strcmp( pBuf, "int2" ) == 0 )
              {
                  i2 iV    = (i2) atoi( fget_word( pFile ) );

                  i        = fwrite( &iV, sizeof( i2 ), 1, pFileOut );

                  if ( i < 0 )
                      error( "%s: %s.", cBuf, strerror( errno ) );
              }
              else if ( strcmp( pBuf, "int4" ) == 0 )
              {
                  i4 iV    = (i4) atol( fget_word( pFile ) );

                  i        = fwrite( &iV, sizeof( i4 ), 1, pFileOut );

                  if ( i < 0 )
                      error( "%s: %s.", cBuf, strerror( errno ) );
              }
              else if ( strcmp( pBuf, "float4" ) == 0 )
              {
                  f4 fV    = (f4) atof( fget_word( pFile ) );

                  i        = fwrite( &fV, sizeof( f4 ), 1, pFileOut );

                  if ( i < 0 )
                      error( "%s: %s.", cBuf, strerror( errno ) );
              }
              else if ( strcmp( pBuf, "float8" ) == 0 )
              {
                  f8 fV    = (f8) strtod( fget_word( pFile ),
                                    (char **) NULL );

                  i        = fwrite( &fV, sizeof( f8 ), 1, pFileOut );

                  if ( i < 0 )
                      error( "%s: %s.", cBuf, strerror( errno ) );
              }
              else if ( strcmp( pBuf, "string" ) == 0 )
              {
                  pBuf     = fget_string( pFile );
                  i        = fwrite( pBuf, 1, strlen( pBuf ), pFileOut );

                  if ( i < 0 )
                      error( "%s: %s.", cBuf, strerror( errno ) );
              }
              else
                  error( "Unknown literal type `%s'.", pBuf );

              break;

          default :
              error( "Unknown symbol `%s'.", c );
              /* Fall through. */

          case ';':
              while ( c[0] != '\n' && c[0] != EOF )
                  c[0]     = getc( pFile );

              if ( c[0] == '\n' )
                  lCurrentLine++;

              break;
        }

        c[0]               = fget_letter( pFile );
    }

    fclose( pFileOut );

    if ( pFile != stdin )
        close_file( pFile );

    return ( 0 );
}


/*
 * End of main.c
 */