home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1997 March / VPR9703A.ISO / VPR_DATA / DOGA / SOURCES / POLYEDIT.LZH / ML / ML.C < prev    next >
C/C++ Source or Header  |  1996-06-21  |  12KB  |  450 lines

  1. /*
  2.  *        マクロ言語ライブラリ(公開関数)
  3.  *
  4.  *        1994.5.2        T.Koabayashi
  5.  *
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <assert.h>
  12. #include <sys\stat.h>
  13.  
  14. #include "parse.h"
  15. #include "exec.h"
  16. #include "strclass.h"
  17.  
  18. #include "lib.h"
  19. #include "inlib.h"
  20.  
  21. extern    int        (**SystemFunc)();
  22.  
  23. static    int        ForceDumpMode = FALSE;
  24. static    int        BreakNone(void);
  25.  
  26. int        (*ErrorExec)();
  27. int        (*BreakCheck)(void) = BreakNone;
  28.  
  29. int        __MLInit( func )
  30. void    *func ;
  31. {
  32. #ifdef DYNAMIC
  33.     if ( func != NULL )
  34.         SystemFunc = (int(**)())func ;
  35. #endif
  36.  
  37.     ErrorExec = MessageError ;
  38.     BreakCheck = BreakNone;
  39.     ParseDebug = FALSE ;
  40.     ExecDebug = FALSE ;
  41.  
  42.     return 0 ;
  43. }
  44.  
  45. /*    デバッグモードの設定    */
  46. void    DebugMode( parse, exec )
  47. int        parse, exec ;
  48. {
  49.     ParseDebug = parse ;
  50.     ExecDebug = exec ;
  51. }
  52.  
  53. /*    中間コードバッファサイズ    */
  54. void    SetMaxCodeSize( size )
  55. int        size ;
  56. {
  57.     MaxCodeSize = size ;
  58. }
  59.  
  60. /*    大域変数の最大数    */
  61. void    SetMaxGlobals( size )
  62. int        size ;
  63. {
  64.     MaxGlobals = size ;
  65. }
  66.  
  67. /*    関数の最大数    */
  68. void    SetMaxFunctions( size )
  69. int        size ;
  70. {
  71.     MaxFunctions = size ;
  72. }
  73.  
  74. /*    スタックサイズの最大数    */
  75. void    SetMaxStacks( size )
  76. int        size ;
  77. {
  78.     MaxStacks = size ;
  79. }
  80.  
  81. /*    初期化    */
  82. void    ParseInit()
  83. {
  84.     Parse3Init();
  85.     ScannerInit();
  86.     CodeInit( MaxCodeSize );
  87.  
  88.     IdentGlobalVar = IdentAlloc( MaxGlobals, 0 );
  89.     IdentLocalVar = NULL ;
  90.     IdentFunction = IdentAlloc( MaxFunctions, FUNC_START );
  91.  
  92.     ObjectInit();
  93.     ObjectSetClass( "", MaxFunctions, -1 );
  94.  
  95.     SetStdFunction();
  96.  
  97.     TopLevel = TRUE ;
  98.  
  99.     StringInit();
  100.     FileioInit();
  101. }
  102.  
  103. /*    終了処理    */
  104. void    ParseExit()
  105. {
  106.     CodeExit();
  107.     IdentFree( IdentGlobalVar );
  108.     IdentFree( IdentFunction );
  109.     ObjectExit();
  110. }
  111.  
  112. #if 0
  113. /*        最後まで文を評価    */
  114. void    ParseSentenseAll( filename )
  115. char    *filename ;
  116. {
  117.     TopLevel = TRUE ;
  118.     FileOpen( filename );
  119.     while( ParseSentense() );
  120. }
  121. #endif
  122.  
  123. #if defined(X68K)
  124.     #define MAGICSTR "X68k    "
  125. #elif defined(PC98)
  126.     #define MAGICSTR "PC98    "
  127. #elif defined(PC)
  128.     #define MAGICSTR "IBMPC   "
  129. #elif defined(WINDOWS)
  130.     #define MAGICSTR "WINDOWS "
  131. #else
  132.     #error "X68K or PC98 or PC or WINDOWS must be defined"
  133. #endif
  134.  
  135. #define MAGICSIZE 16
  136. typedef struct {
  137.     char    Magic[MAGICSIZE];
  138.     int        IdentGlobalSize;
  139.     int        IdentFunctionSize;
  140.     int        FuncSize;
  141.     int        CodeSize;
  142.     char    *CodeBeginPtr;
  143. }    PreCompileData;
  144.  
  145. void    DumpMode( int flag )
  146. {
  147.     ForceDumpMode = flag;
  148. }
  149.  
  150. static    void    ParseSentenseAllOnly( char *filename )
  151. {
  152.     TopLevel = TRUE ;
  153.     FileOpen( filename );
  154.     while( ParseSentense() );
  155.     FileClose();
  156.     IdentPrivate( IdentGlobalVar );
  157.     IdentPrivate( IdentFunction );
  158. }
  159.  
  160. /*        最後まで文を評価    */
  161. void    ParseSentenseAll( filename )
  162. char    *filename ;
  163. {
  164.     char fileprecomp[512];
  165.     FILE *fp;
  166.     PreCompileData *data;
  167.     struct stat mstat, mcstat ;
  168.     int size;
  169.  
  170.     strcpy(fileprecomp, filename);
  171.     strcat(fileprecomp, "c");
  172.     if ((fp = fopen(fileprecomp, "rb")) == NULL) {
  173.         if (ForceDumpMode == FALSE) {
  174.             ParseSentenseAllOnly(filename);
  175.             return;
  176.         }
  177.         data = NULL;
  178.     } else {
  179.         stat( fileprecomp, &mcstat );
  180.         data = MemoryAlloc( mcstat.st_size + 1 );
  181.         size = fread( data, 1, mcstat.st_size, fp );
  182.         fclose(fp);
  183.         stat( filename, &mstat );
  184.     }
  185.     if (ForceDumpMode == FALSE
  186.      && mstat.st_mtime <= mcstat.st_mtime && mcstat.st_size > sizeof(PreCompileData)
  187.      && size == mcstat.st_size && strncmp(data->Magic, MAGICSTR, strlen(MAGICSTR)) == 0) {
  188.         int i, ident;
  189.         char *CodeBegin, *CodeEnd;
  190.         char *name;
  191.         IdentBuffer *pGlobalVar, *pFunction;
  192.         FuncBuffer *pFunctionBuffer;
  193.         CodeStruct *code;
  194.         Object *obj;
  195.         int    *realGlobalIdent, *realFunctionIdent;
  196.  
  197.         pGlobalVar = (IdentBuffer*)((char*)data + sizeof(PreCompileData));
  198.         pFunction = (IdentBuffer*)((char*)pGlobalVar + data->IdentGlobalSize);
  199.         pFunctionBuffer = (FuncBuffer*)((char*)pFunction + data->IdentFunctionSize);
  200.         code = (CodeStruct*)((char*)pFunctionBuffer + data->FuncSize);
  201.         obj = (Object*)((char*)code + data->CodeSize);
  202.  
  203.         pGlobalVar->flag = (char*)( pGlobalVar + 1 );
  204.         pGlobalVar->name = (IdentName*)( pGlobalVar->flag + pGlobalVar->max );
  205.         realGlobalIdent = MemoryAlloc(sizeof(int) * pGlobalVar->max);
  206.  
  207.         pFunction->flag = (char*)( pFunction + 1 );
  208.         pFunction->name = (IdentName*)( pFunction->flag + pFunction->max );
  209.         realFunctionIdent = MemoryAlloc(sizeof(int) * pFunction->max);
  210.  
  211.         CodeBegin = (char*)CodeAlloc(data->CodeSize) ;
  212.         CodeEnd = (char*)CodeNextPtr();
  213.  
  214.  
  215. /*
  216. printf("Read PreCompile MacroFile\n");
  217. printf("HeaderSize        = %6d\n", sizeof(PreCompileData));
  218. printf("IdentGlobalSize   = %6d\n", data->IdentGlobalSize);
  219. printf("IdentFunctionSize = %6d\n", data->IdentFunctionSize);
  220. printf("CodeSize          = %6d\n", data->CodeSize);
  221. printf("CodeBegin         = %8x\n", data->CodeBeginPtr);
  222. printf("CodeBegin         = %8x\n", CodeBegin);
  223. */
  224.  
  225.         memcpy(CodeBegin, code, data->CodeSize);
  226.  
  227.         InputFile = fileprecomp;
  228.         name = MemoryAlloc(strlen(filename)+1);
  229.         strcpy(name, filename);
  230.         code = (CodeStruct*)CodeBegin;
  231.  
  232.         for (i = 0; i < pGlobalVar->count; i++) {
  233.             ident = -1;
  234.             if (pGlobalVar->flag[i] != IDENT_RESERVE) {
  235.                 if ((ident = IdentSearch(IdentGlobalVar, pGlobalVar->name[i])) < 0) {
  236.                     ident = IdentAppend(IdentGlobalVar, pGlobalVar->name[i], pGlobalVar->flag[i]);
  237. /*printf("NewGlobalVar  %16s : %5d ->%5d\n", pGlobalVar->name[i], i, ident);*/
  238.                 }
  239.             }
  240.             realGlobalIdent[i] = ident;
  241.         }
  242.  
  243.         for (i = FUNC_START; i < pFunction->count; i++) {
  244.             ident = -1;
  245.             if (pFunction->flag[i] != IDENT_RESERVE) {
  246.                 if ((ident = IdentSearch(IdentFunction, pFunction->name[i])) < 0) {
  247.                     ident = IdentAppend(IdentFunction, pFunction->name[i], pFunction->flag[i]);
  248.                 }
  249.                 if (data->CodeBeginPtr <= (char*)pFunctionBuffer[i].ptr
  250.                  && (char*)pFunctionBuffer[i].ptr < data->CodeBeginPtr + data->CodeSize) {
  251.                     ClassList[0].func[ident].type = FUNC_USR;
  252.                     ClassList[0].func[ident].name = IdentFunction->name[ident];
  253.                     ClassList[0].func[ident].ptr = CodeBegin
  254.                             + ((char*)pFunctionBuffer[i].ptr - (char*)data->CodeBeginPtr);
  255.                 }
  256.             }
  257.             realFunctionIdent[i] = ident;
  258.         }
  259.  
  260.         while (code != NULL && (char*)code < CodeEnd) {
  261. /*printf("Code = %08x\n", code);*/
  262.             if (code->type == CODE_CONST) {
  263.                 if (code->c.data.type == TYPE_OBJECT) {
  264.                      int osize = ((obj->size+3)/4)*4;
  265.                      code->c.data.od.ptr = ObjectDup(obj);
  266.                      obj = (Object*)((char*)obj + sizeof(Object) + osize);
  267. /*                     obj = (Object*)((char*)obj + sizeof(Object) + obj->size);*/
  268. /*
  269. printf("Object(%3d)       = %8x (%d)\n", code->c.data.od.ptr->type, code->c.data.od.ptr, osize);
  270. */
  271.                 } else if (code->c.data.type == TYPE_FUNC
  272.                         && code->c.data.funcd.ident >= FUNC_START) {
  273.                     code->c.data.funcd.ident = realFunctionIdent[code->c.data.funcd.ident];
  274.                 }
  275.             } else if (code->type == CODE_SENTENSE) {
  276.                 code->sent.file = name;
  277. /*printf("Sentense : %8x ->", code->sent.next);*/
  278.                 code->sent.next = CodeBegin
  279.                                 + ((char*)code->sent.next - (char*)data->CodeBeginPtr);
  280. /*printf(" %8x\n", code->sent.next);*/
  281.                 if (code->sent.stype == SENT_DO
  282.                  || code->sent.stype == SENT_COMPLEX) {
  283.                     code = CodeNext(code);
  284.                     code->c.data.id.i = (int)CodeBegin
  285.                                 + ((char*)code->c.data.id.i - (char*)data->CodeBeginPtr);
  286.                 }
  287.             } else if (code->type == CODE_IDENT) {
  288.                 if (code->ident.itype & IDENT_GLOBAL) {
  289.                     code->ident.ident = realGlobalIdent[code->ident.ident];
  290.                 } else if (code->ident.itype & IDENT_FUNC
  291.                         && code->ident.ident >= FUNC_START) {
  292.                     code->ident.ident = realFunctionIdent[code->ident.ident];
  293.                 }
  294.             }
  295.  
  296.             code = CodeNext(code);
  297.         }
  298.  
  299.  
  300.         MemoryFree(realFunctionIdent);
  301.         MemoryFree(realGlobalIdent);
  302.         MemoryFree(data);
  303.         IdentPrivate( IdentGlobalVar );
  304.         IdentPrivate( IdentFunction );
  305.     } else {
  306.         char *CodeBegin, *CodeEnd;
  307.         int    pCodeSize, IdentGlobalSize, IdentFunctionSize, FuncSize;
  308.  
  309.         if (data != NULL) {
  310.             MemoryFree(data);
  311.         }
  312.  
  313.         CodeBegin = (char*)CodeNextPtr();
  314.  
  315.         TopLevel = TRUE ;
  316.         FileOpen( filename );
  317.         while( ParseSentense() );
  318.         FileClose();
  319.  
  320.         CodeEnd = (char*)CodeNextPtr();
  321.         pCodeSize = (char*)CodeEnd - (char*)CodeBegin;
  322.  
  323. /*        pCodeSize = ((pCodeSize +3)/4)*4;*/
  324.  
  325.         if ((fp = fopen(fileprecomp, "wb")) == NULL) {
  326.             IdentPrivate( IdentGlobalVar );
  327.             IdentPrivate( IdentFunction );
  328.             return;
  329.         }
  330.  
  331.         IdentGlobalSize = sizeof(IdentBuffer)
  332.                         + (sizeof(char) + sizeof(IdentName)) * IdentGlobalVar->max
  333.                         - sizeof(IdentName) * (IdentGlobalVar->max - IdentGlobalVar->count-1);
  334. /*        IdentGlobalSize = ((IdentGlobalSize+3)/4)*4;*/
  335.         IdentFunctionSize = sizeof(IdentBuffer)
  336.                           + (sizeof(char) + sizeof(IdentName)) * IdentFunction->max
  337.                           - sizeof(IdentName) * (IdentFunction->max - IdentFunction->count-1);
  338. /*        IdentFunctionSize = ((IdentFunctionSize+3)/4)*4;*/
  339.         FuncSize = sizeof(FuncBuffer) * IdentFunction->count;
  340.         data = MemoryAlloc( sizeof(PreCompileData) );
  341.         strcpy(data->Magic, MAGICSTR);
  342.         data->IdentGlobalSize = IdentGlobalSize;
  343.         data->IdentFunctionSize = IdentFunctionSize;
  344.         data->FuncSize = FuncSize;
  345.         data->CodeSize = pCodeSize;
  346.         data->CodeBeginPtr = CodeBegin;
  347. /*
  348. printf("Write PreCompile MacroFile\n");
  349. printf("Write PreCompile MacroFile\n");
  350. printf("HeaderSize        = %6d\n", sizeof(PreCompileData));
  351. printf("IdentGlobalSize   = %6d\n", IdentGlobalSize);
  352. printf("IdentFunctionSize = %6d\n", IdentFunctionSize);
  353. printf("CodeSize          = %6d\n", pCodeSize);
  354. printf("CodeBegin         = %8x\n", CodeBegin);
  355. */
  356.         if (fwrite(data, 1, sizeof(PreCompileData), fp) == sizeof(PreCompileData)
  357.          && fwrite(IdentGlobalVar, 1, IdentGlobalSize, fp) == IdentGlobalSize
  358.          && fwrite(IdentFunction, 1, IdentFunctionSize, fp) == IdentFunctionSize
  359.          && fwrite(ClassList[0].func, 1, FuncSize, fp) == FuncSize
  360.          && fwrite(CodeBegin, 1, pCodeSize, fp) == pCodeSize) {
  361.             CodeStruct *code;
  362.             code = (CodeStruct*)CodeBegin;
  363.             while (code != NULL && (char*)code < CodeEnd) {
  364.                 if (code->type == CODE_CONST
  365.                  && code->c.data.type == TYPE_OBJECT) {
  366.                      int osize = ((code->c.data.od.ptr->size+3)/4)*4;
  367.                     fwrite(code->c.data.od.ptr, 1, sizeof(Object) + osize, fp);
  368. /*
  369.                     fwrite(code->c.data.od.ptr, 1, sizeof(Object) + code->c.data.od.ptr->size, fp);
  370. printf("Object(%3d)       = %8x (%d)\n", code->c.data.od.ptr->type, code->c.data.od.ptr, osize);
  371. */
  372.                 }
  373.                 code = CodeNext(code);
  374.             }
  375.         }
  376.         fclose(fp);
  377.         MemoryFree(data);
  378.         IdentPrivate( IdentGlobalVar );
  379.         IdentPrivate( IdentFunction );
  380.     }
  381. }
  382.  
  383.  
  384. /*    現在のコードサイズ    */
  385. int        ReportCodeSize()
  386. {
  387.     return (char*)CodeNextPtr() - (char*)CodeTop() ;
  388. }
  389.  
  390. /*    識別子のレポート    */
  391. void    ReportIdent( global, func )
  392. int        *global, *func ;
  393. {
  394.     *global = IdentGlobalVar->count ;
  395.     *func = IdentFunction->count ;
  396. }
  397.  
  398. /*    実行系の初期化    */
  399. void    ExecInit()
  400. {
  401.     StackInit( MaxStacks );
  402.  
  403.     if ( IdentGlobalVar->count > 0 )
  404.         DataGlobalVar = StackAlloc( IdentGlobalVar->count );
  405.     else
  406.         DataGlobalVar = NULL ;
  407.     DataLocalVar = NULL ;
  408.  
  409.     ExecPtr = CodeTop();
  410. }
  411.  
  412. /*    実行系の終了処理    */
  413. void    ExecExit()
  414. {
  415.     StackExit();
  416. }
  417.  
  418. /*        最後まで文を実行    */
  419. void    ExecSentenseAll()
  420. {
  421.     while( ExecSentense() != RETURN_END );
  422. }
  423.  
  424. /*    文字列オブジェクトの設定    */
  425. void    StringToObject( buf, str )
  426. DataStruct    *buf ;
  427. char    *str ;
  428. {
  429.     if ( buf->type == TYPE_OBJECT )
  430.         ObjectFree( buf->od.ptr );
  431.  
  432.     buf->type = TYPE_OBJECT ;
  433.     buf->od.ptr = (Object*)StringSet( str );
  434. }
  435.  
  436. void SetBreakCheck(int (*func)(void))
  437. {
  438.     if (func == NULL) {
  439.         BreakCheck = BreakNone;
  440.     } else {
  441.         BreakCheck = func;
  442.     }
  443. }
  444.  
  445. static int BreakNone()
  446. {
  447.     return FALSE;
  448. }
  449.  
  450.