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

  1. /*
  2.  *        実行処理
  3.  *
  4.  *        1994.5.22        T.Kobayashi
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <assert.h>
  11.  
  12. #include "exec.h"
  13. #include "err.h"
  14.  
  15. #include "inlib.h"
  16.  
  17. static    void    ExecOpeBoolean( int, int, DataStruct* );
  18. static    void    ExecOpeInt( int, int, DataStruct* );
  19. static    void    ExecOpeReal( int, int, DataStruct* );
  20. extern    int    (*BreakCheck)(void);
  21.  
  22. /*
  23.  *        式の実行
  24.  */
  25. void    ExecExpression()
  26. {
  27.     DataStruct    *buf, ary ;
  28.  
  29.     if ((*BreakCheck)()) {
  30.         ExecError("強制終了しました");
  31.     }
  32.  
  33.     for(;;)
  34.     {
  35.         switch( ExecPtr->type )
  36.         {
  37.             /*    定数    */
  38.             case CODE_CONST :
  39.                 StackPush( & ExecPtr->c.data );
  40.                 GotoNextCode();
  41.                 break ;
  42.  
  43.             /*    変数|関数    */
  44.             case CODE_IDENT :
  45.                 if ( ExecPtr->ident.itype & IDENT_FUNC )
  46.                 {
  47.                     ExecFunction( ExecPtr );
  48.                 }
  49.                 else
  50.                 {
  51.                     buf = ExecRefVar();
  52.                     if ( buf->type == TYPE_NOASN )
  53.                         ExecError( "代入されていない変数を参照しました。" );
  54.                     StackPush( buf );
  55.                 }
  56.                 break ;
  57.  
  58.             /*    演算子    */
  59.             case CODE_OPERATOR :
  60.                 if ( ExecPtr->ope.otype == OPE_EXP_END )
  61.                 {
  62.                     GotoNextCode();
  63.                     return ;
  64.                 }
  65.                 else if ( ExecPtr->ope.otype < OPE_SINGLE )
  66.                 {
  67.                     buf = StackTop();
  68.                     ExecOpe( ExecPtr->ope.otype, 1, buf );
  69.                     GotoNextCode();
  70.                 }
  71.                 else
  72.                 {
  73.                     buf = StackTop() - 1 ;
  74.                     ExecOpe( ExecPtr->ope.otype, 2, buf );
  75.                     GotoNextCode();
  76.                     StackRelease( buf );
  77.                 }
  78.                 break ;
  79.  
  80.             /*    配列    */
  81.             case CODE_ARRAY :
  82.                 ary.type = TYPE_ARRAY ;
  83.                 ary.ad.size = ExecPtr->ary.asize ;
  84.                 ary.ad.ary = StackTop() - ary.ad.size + 1 ;
  85.                 StackPush( &ary );
  86.                 GotoNextCode();
  87.                 break ;
  88.             default:
  89.                 assert( FALSE );
  90.         }
  91.         if ( ExecPtr == NULL )
  92.         {
  93.             ExecError( "式の途中でファイルエンドになりました" );
  94.         }
  95.     }
  96. }
  97.  
  98. /*    演算子の処理    */
  99. void    ExecOpe( ope, args, buf )
  100. int        ope ;
  101. int        args ;
  102. DataStruct    *buf ;
  103. {
  104.     switch( buf->type )
  105.     {
  106.         case TYPE_OBJECT:
  107.             CallFunctionLocal( ope, args, buf );
  108.             break ;
  109.         case TYPE_BOOLEAN:
  110.             ExecOpeBoolean( ope, args, buf );
  111.             break ;
  112.         case TYPE_INT:
  113.             ExecOpeInt( ope, args, buf );
  114.             break ;
  115.         case TYPE_REAL:
  116.             ExecOpeReal( ope, args, buf );
  117.             break ;
  118.         case TYPE_ARRAY:
  119.         case TYPE_TYPE:
  120.         case TYPE_FUNC:
  121.             if ( ope == OPE_EQ )
  122.             {
  123.                 buf[0].type = TYPE_BOOLEAN ;
  124.                 buf[0].ld.l = ( buf[0].td.t == buf[1].td.t );
  125.             }
  126.             else if ( ope == OPE_NOTEQ )
  127.             {
  128.                 buf[0].type = TYPE_BOOLEAN ;
  129.                 buf[0].ld.l = ( buf[0].td.t != buf[1].td.t );
  130.             }
  131.             else
  132.                 ExecError( "演算の型が不正です。" );
  133.             break ;
  134.         default:
  135.             assert( FALSE );
  136.     }
  137. }
  138.  
  139. static    void    ExecOpeBoolean( ope, args, buf )
  140. int        ope ;
  141. int        args ;
  142. DataStruct    *buf ;
  143. {
  144.     if ( args >= 2 && ! ( buf[1].type & (TYPE_BOOLEAN|TYPE_INT) ) )
  145.     {
  146.         ExecError( "論理演算の型が不正です。" );
  147.     }
  148.  
  149.     switch( ope )
  150.     {
  151.         case OPE_NOT:
  152.             buf->ld.l = ! buf->ld.l ;
  153.             break ;
  154.         case OPE_AND:
  155.             buf->ld.l = ( buf[0].ld.l && buf[1].ld.l );
  156.             break ;
  157.         case OPE_OR:
  158.             buf->ld.l = ( buf[0].ld.l || buf[1].ld.l );
  159.             break ;
  160.         case OPE_XOR:
  161.             buf->ld.l = ( buf[0].ld.l ^ buf[1].ld.l );
  162.             break ;
  163.         case OPE_EQ:
  164.             buf->ld.l = ( buf[0].ld.l == buf[1].ld.l );
  165.             break ;
  166.         case OPE_NOTEQ:
  167.             buf->ld.l = ( buf[0].ld.l != buf[1].ld.l );
  168.             break ;
  169.         default:
  170.             ExecError( "論理演算の演算子が不正です。" );
  171.     }
  172. }
  173.  
  174. static    void    ExecOpeInt( ope, args, buf )
  175. int        ope ;
  176. int        args ;
  177. DataStruct    *buf ;
  178. {
  179.     if ( args >= 2 && ! ( buf[1].type & (TYPE_BOOLEAN|TYPE_INT|TYPE_REAL) ) )
  180.     {
  181.         ExecError( "整数演算の型が不正です。" );
  182.     }
  183.     if ( buf[1].type == TYPE_REAL )
  184.     {
  185.         buf[1].type = TYPE_INT ;
  186.         buf[1].id.i = (int)( buf[1].rd.r );
  187.     }
  188.  
  189. #if    0
  190.     printf( "ExecOpeInt( %d )\n", ope );
  191. #endif
  192.  
  193.     switch( ope )
  194.     {
  195.         case OPE_NOT:
  196.             buf->id.i = ! buf->id.i ;
  197.             break ;
  198.         case OPE_MINUS1:
  199.             buf->id.i = - buf->id.i ;
  200.             break ;
  201.         case OPE_PLUS:
  202.             buf->id.i = buf[0].id.i + buf[1].id.i ;
  203.             break ;
  204.         case OPE_MINUS:
  205.             buf->id.i = buf[0].id.i - buf[1].id.i ;
  206.             break ;
  207.         case OPE_INC:
  208.             buf->id.i ++ ;
  209.             break ;
  210.         case OPE_DEC:
  211.             buf->id.i -- ;
  212.             break ;
  213.         case OPE_MULT:
  214.             buf->id.i = buf[0].id.i * buf[1].id.i ;
  215.             break ;
  216.         case OPE_DIVIDE:
  217.             if (buf[1].id.i != 0) {
  218.                 buf->id.i = buf[0].id.i / buf[1].id.i ;
  219.             }
  220.             break ;
  221.         case OPE_MOD:
  222.             buf->id.i = buf[0].id.i % buf[1].id.i ;
  223.             break ;
  224.         case OPE_LSFT:
  225.             buf->id.i = buf[0].id.i << buf[1].id.i ;
  226.             break ;
  227.         case OPE_RSFT:
  228.             buf->id.i = buf[0].id.i >> buf[1].id.i ;
  229.             break ;
  230.         case OPE_LSS:
  231.             buf->type = TYPE_BOOLEAN ;
  232.             buf->ld.l = ( buf[0].id.i < buf[1].id.i );
  233.             break ;
  234.         case OPE_GTR:
  235.             buf->type = TYPE_BOOLEAN ;
  236.             buf->ld.l = ( buf[0].id.i > buf[1].id.i );
  237.             break ;
  238.         case OPE_LSSEQ:
  239.             buf->type = TYPE_BOOLEAN ;
  240.             buf->ld.l = ( buf[0].id.i <= buf[1].id.i );
  241.             break ;
  242.         case OPE_GTREQ:
  243.             buf->type = TYPE_BOOLEAN ;
  244.             buf->ld.l = ( buf[0].id.i >= buf[1].id.i );
  245.             break ;
  246.         case OPE_EQ:
  247.             buf->type = TYPE_BOOLEAN ;
  248.             buf->ld.l = ( buf[0].id.i == buf[1].id.i );
  249.             break ;
  250.         case OPE_NOTEQ:
  251.             buf->type = TYPE_BOOLEAN ;
  252.             buf->ld.l = ( buf[0].id.i != buf[1].id.i );
  253.             break ;
  254.         case OPE_AND:
  255.             buf->id.i = ( buf[0].id.i & buf[1].id.i );
  256.             break ;
  257.         case OPE_OR:
  258.             buf->id.i = ( buf[0].id.i | buf[1].id.i );
  259.             break ;
  260.         case OPE_XOR:
  261.             buf->id.i = ( buf[0].id.i ^ buf[1].id.i );
  262.             break ;
  263.         default:
  264.             ExecError( "整数演算の演算子が不正です。" );
  265.     }
  266. }
  267.  
  268. static    void    ExecOpeReal( ope, args, buf )
  269. int        ope ;
  270. int        args ;
  271. DataStruct    *buf ;
  272. {
  273.     if ( args >= 2 && ! ( buf[1].type & (TYPE_BOOLEAN|TYPE_INT|TYPE_REAL) ) )
  274.     {
  275.         ExecError( "実数演算の型が不正です。" );
  276.     }
  277.     if ( buf[1].type & (TYPE_BOOLEAN|TYPE_INT) )
  278.     {
  279.         buf[1].type = TYPE_REAL ;
  280.         buf[1].rd.r = (float)( buf[1].id.i );
  281.     }
  282.  
  283.     switch( ope )
  284.     {
  285.         case OPE_MINUS1:
  286.             buf->rd.r = - buf->rd.r ;
  287.             break ;
  288.         case OPE_PLUS:
  289.             buf->rd.r = buf[0].rd.r + buf[1].rd.r ;
  290.             break ;
  291.         case OPE_MINUS:
  292.             buf->rd.r = buf[0].rd.r - buf[1].rd.r ;
  293.             break ;
  294.         case OPE_INC:
  295.             buf->rd.r ++ ;
  296.             break ;
  297.         case OPE_DEC:
  298.             buf->rd.r -- ;
  299.             break ;
  300.         case OPE_MULT:
  301.             buf->rd.r = buf[0].rd.r * buf[1].rd.r ;
  302.             break ;
  303.         case OPE_DIVIDE:
  304.             if (buf[1].rd.r > 1e-64 || buf[1].rd.r < -1e-64) {
  305.                 buf->rd.r = buf[0].rd.r / buf[1].rd.r ;
  306.             }
  307.             break ;
  308.         case OPE_LSS:
  309.             buf->type = TYPE_BOOLEAN ;
  310.             buf->ld.l = ( buf[0].rd.r < buf[1].rd.r );
  311.             break ;
  312.         case OPE_GTR:
  313.             buf->type = TYPE_BOOLEAN ;
  314.             buf->ld.l = ( buf[0].rd.r > buf[1].rd.r );
  315.             break ;
  316.         case OPE_LSSEQ:
  317.             buf->type = TYPE_BOOLEAN ;
  318.             buf->ld.l = ( buf[0].rd.r <= buf[1].rd.r );
  319.             break ;
  320.         case OPE_GTREQ:
  321.             buf->type = TYPE_BOOLEAN ;
  322.             buf->ld.l = ( buf[0].rd.r >= buf[1].rd.r );
  323.             break ;
  324.         case OPE_EQ:
  325.             buf->type = TYPE_BOOLEAN ;
  326.             buf->ld.l = ( buf[0].rd.r == buf[1].rd.r );
  327.             break ;
  328.         case OPE_NOTEQ:
  329.             buf->type = TYPE_BOOLEAN ;
  330.             buf->ld.l = ( buf[0].rd.r != buf[1].rd.r );
  331.             break ;
  332.         default:
  333.             ExecError( "実数演算の演算子が不正です。" );
  334.             break ;
  335.     }
  336. }
  337.