home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1997 March / VPR9703A.ISO / VPR_DATA / DOGA / SOURCES / POLYEDIT.LZH / ML / EXEC2.C < prev    next >
C/C++ Source or Header  |  1996-02-16  |  9KB  |  486 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    int        CallFunctionSub( FuncBuffer*, int, int, DataStruct* );
  18. static    void    ReturnValue( DataStruct* );
  19. static    void    DataArrayAlloc( DataStruct*, int, int* );
  20. static    void    Assign( DataStruct*, DataStruct* );
  21.  
  22. /*
  23.  *        関数の実行
  24.  */
  25. void    ExecFunction( code )
  26. CodeStruct    *code ;
  27. {
  28.     int        ident, args ;
  29.     DataStruct    *top ;
  30.  
  31.     assert( code->type == CODE_IDENT && ( code->ident.itype & IDENT_FUNC ) );
  32.     ident = code->ident.ident ;
  33.     GotoNextCode();
  34.  
  35.     top = StackTop() ;
  36.     args = top->id.i ;
  37.     /*StackPop();*/
  38.     CallFunctionLocal( ident, args, top - args );
  39.     /*StackRelease( top - args );*/
  40. }
  41.  
  42. int        CallFunctionLocal( ident, args, arg )
  43. int        ident, args ;
  44. DataStruct    *arg ;
  45. {
  46.     int            class ;
  47.     FuncBuffer    *func ;
  48.  
  49.     if ( arg->type == TYPE_OBJECT )
  50.     {
  51.         class = arg->od.ptr->type ;
  52.         while( class != 0 && ClassList[class].func[ident].type == FUNC_NO )
  53.         {
  54.             class = ClassList[class].parent ;
  55.         }
  56.         func = ClassList[class].func ;
  57.     }
  58.     else
  59.         func = ClassList[0].func ;
  60.  
  61.     return CallFunctionSub( func, ident, args, arg );
  62. }
  63.  
  64. int        CallFunctionLocalParent( cls, ident, args, arg )
  65. int        cls, ident, args ;
  66. DataStruct    *arg ;
  67. {
  68.     FuncBuffer    *func ;
  69.  
  70.     assert( cls > 0 );
  71.     cls = ClassList[cls].parent ;
  72.     while( cls != 0 && ClassList[cls].func[ident].type == FUNC_NO )
  73.     {
  74.         cls = ClassList[cls].parent ;
  75.     }
  76.     func = ClassList[cls].func ;
  77.     return CallFunctionSub( func, ident, args, arg );
  78. }
  79.  
  80. static    int        CallFunctionSub( func, ident, args, arg )
  81. FuncBuffer    *func ;
  82. int        ident, args ;
  83. DataStruct    *arg ;
  84. {
  85.     if ( func[ident].type == FUNC_NO )
  86.     {
  87.         if ( ident < FUNC_START )
  88.         {
  89.             ExecError( "演算子が定義されていません。" );
  90.         }
  91.         else
  92.         {
  93.             ExecError( "関数 %s が定義されていません。", IdentFunction->name[ident] );
  94.         }
  95.     }
  96.  
  97.     if ( func[ident].type == FUNC_SYS )
  98.     {
  99.         /*    組み込み関数    */
  100.         int        (*sysfunc)(int ident, int args, DataStruct *buf);
  101.  
  102.         sysfunc = func[ident].ptr ;
  103.         assert( sysfunc != NULL );
  104.         if ( (*sysfunc)( ident, args, arg ) == RETURN_RETURN )
  105.         {
  106.             ReturnValue( arg );
  107.             return RETURN_RETURN ;
  108.         }
  109.         else
  110.         {
  111.             StackRelease( arg );
  112.             return RETURN_VOID ;
  113.         }
  114.     }
  115.     else
  116.     {
  117.         /*    ユーザ定義関数    */
  118.         int            ret ;
  119.         int            vars, frame ;
  120.         DataStruct    *curlocal ;
  121.         CodeStruct    *curptr ;
  122.         CodeStruct    *usrfunc ;
  123.  
  124.         usrfunc = func[ident].ptr ;
  125.         vars = usrfunc->c.data.id.i ;
  126.  
  127.         /*    実行アドレス、ベースポインタの退避    */
  128.         curptr = ExecPtr ;
  129.         curlocal = DataLocalVar ;
  130.  
  131.         /*    実行    */
  132.         ExecPtr = usrfunc ;
  133.         GotoNextCode();
  134.         assert( ExecPtr->c.data.type == TYPE_INT );
  135. #if    0
  136.         if ( args > vars )
  137.             ExecError( "引数の数が多すぎます" );
  138. #endif
  139.  
  140.         frame = StackTop() - arg + 1 ;        /*    確保しているスタックフレーム    */
  141.         vars = ExecPtr->c.data.id.i ;        /*    ローカル変数    */
  142.         if ( frame < vars )
  143.             StackAlloc( vars - frame );
  144.  
  145.         DataLocalVar = arg ;
  146.         GotoNextCode();
  147.         ret = ExecSentense();
  148.         if ( ret == RETURN_RETURN )
  149.             ReturnValue( arg );
  150.         else
  151.             StackRelease( arg );
  152.  
  153.         /*    実行アドレス、ベースポインタの復帰    */
  154.         ExecPtr = curptr ;
  155.         DataLocalVar = curlocal ;
  156.  
  157.         return ret ;
  158.     }
  159. }
  160.  
  161. /*    戻り値を引数先頭アドレスにコピーする    */
  162. static    void    ReturnValue( arg )
  163. DataStruct    *arg ;
  164. {
  165.     DataStruct    *top ;
  166.  
  167.     top = StackTop();
  168.     if ( arg == top )
  169.         return ;
  170.  
  171.     if ( arg->type == TYPE_OBJECT )
  172.         ObjectFree( arg->od.ptr );
  173.     if ( top->type == TYPE_OBJECT )
  174.     {
  175.         arg->type = TYPE_OBJECT ;
  176.         arg->od.ptr = ObjectCopy( top->od.ptr );
  177.     }
  178.     else
  179.         *arg = *top ;
  180.     StackRelease( arg );
  181. }
  182.  
  183.  
  184. /*
  185.  *        return 文の実行
  186.  */
  187. int        ExecReturn()
  188. {
  189.     GotoNextCode();
  190.     ExecExpression();
  191.     return RETURN_RETURN ;
  192. }
  193.  
  194.  
  195. /*
  196.  *        変数宣言の実行
  197.  */
  198. void    ExecVar()
  199. {
  200.     int        i, no, dim ;
  201.     int        *dimary ;
  202.     CodeStruct    *code ;
  203.     DataStruct    *top ;
  204.     DataStruct    *buf ;
  205.  
  206.     GotoNextCode();
  207.     code = ExecPtr ;
  208.  
  209.     while( code->type != CODE_OPERATOR || code->ope.otype != OPE_EXP_END )
  210.     {
  211.         assert( code->type == CODE_IDENT );
  212.         no = code->ident.ident ;    /*    識別子コード    */
  213.         if ( code->ident.itype & ( IDENT_ARY ) )
  214.         {
  215.             /*    配列の次数の計算    */
  216.             GotoNextCode();
  217.             ExecExpression();
  218.  
  219.             /*    次数    */
  220.             top = StackTop();
  221.             assert( top->type == TYPE_INT );
  222.             dim = top->id.i ;
  223.             assert( dim >= 1 );
  224.             StackPop();
  225.             dimary = _alloca( sizeof( int ) * dim );
  226.             for( i = dim - 1 ; i >= 0 ; i-- )
  227.             {
  228.                 top = StackTop();
  229.                 assert( top->type == TYPE_INT );
  230.                 dimary[i] = top->id.i ;
  231.                 StackPop();
  232.             }
  233.  
  234.             switch( code->ident.itype & (IDENT_VAR|IDENT_ARY) )
  235.             {
  236.                 case IDENT_GLOBAL|IDENT_ARY:
  237.                     buf = & DataGlobalVar[no] ;
  238.                     break ;
  239.                 case IDENT_LOCAL|IDENT_ARY:
  240.                     buf = & DataLocalVar[no] ;
  241.                     break ;
  242.                 default:
  243.                     assert( FALSE );
  244.             }
  245.             if ( buf->type & TYPE_ARRAY )
  246.                 ExecError( "配列を2度宣言しようとしました。" );
  247.             DataArrayAlloc( buf, dim, dimary );
  248.         }
  249.         else
  250.         {
  251.             buf = ExecRefVar();
  252.             ExecExpression();
  253.             Assign( buf, StackTop() );
  254.             StackPop();
  255.         }
  256.         code = ExecPtr ;
  257.     }
  258.     GotoNextCode();
  259. }
  260.  
  261. /*    配列バッファの確保    */
  262. static    void    DataArrayAlloc( buf, dim, dimary )
  263. DataStruct    *buf ;
  264. int            dim ;
  265. int            *dimary ;
  266. {
  267.     int        i, n ;
  268.  
  269.     n = dimary[0] ;
  270.     if ( n < 0 || 0xFFFF < n )
  271.         ExecError( "配列のサイズが不正です" );
  272.  
  273.     buf->type = TYPE_ARRAY ;
  274.     buf->ad.size = n ;
  275.     buf->ad.ary = StackAlloc( n );
  276.  
  277.     if ( dim > 1 )
  278.     {
  279.         buf = buf->ad.ary ;
  280.         for( i = 0 ; i < n ; i++ )
  281.         {
  282.             DataArrayAlloc( buf, dim-1, dimary+1 );
  283.             buf++ ;
  284.         }
  285.     }
  286. }
  287.  
  288. /*
  289.  *        代入文の実行
  290.  */
  291. void    ExecAssign( stype )
  292. int        stype ;
  293. {
  294.     DataStruct    *buf, *top = StackTop();
  295.  
  296.     /*    識別子    */
  297.     GotoNextCode();
  298.     buf = ExecRefVar();
  299.  
  300.     /*    式    */
  301.     ExecExpression();
  302.  
  303.     Assign( buf, StackTop() );
  304.     StackRelease( top );
  305. }
  306.  
  307. /*
  308.  *        演算子付き代入文の実行
  309.  */
  310. void    ExecAssignOpe( stype )
  311. int        stype ;
  312. {
  313.     int            ope ;
  314.     DataStruct    *buf, *top ;
  315.  
  316.     /*    識別子    */
  317.     GotoNextCode();
  318.     buf = ExecRefVar();
  319.     StackPush( buf );
  320.     top = StackTop();
  321.  
  322.     /*    式    */
  323.     ExecExpression();
  324.  
  325.     switch( stype )
  326.     {
  327.         case SENT_ASN_PLUS:
  328.             ope = OPE_PLUS ;
  329.             break ;
  330.         case SENT_ASN_MINUS:
  331.             ope = OPE_MINUS ;
  332.             break ;
  333.         case SENT_ASN_MULT:
  334.             ope = OPE_MULT ;
  335.             break ;
  336.         case SENT_ASN_DIVIDE:
  337.             ope = OPE_DIVIDE ;
  338.             break ;
  339.         case SENT_ASN_AND:
  340.             ope = OPE_AND ;
  341.             break ;
  342.         case SENT_ASN_OR:
  343.             ope = OPE_OR ;
  344.             break ;
  345.         default:
  346.             assert( FALSE );
  347.     }
  348.     ExecOpe( ope, 2, top );
  349.     Assign( buf, top );
  350.     StackRelease( top - 1 );
  351. }
  352.  
  353. /*
  354.  *        インクリメント代入文の実行
  355.  */
  356. void    ExecAssignInc( stype )
  357. int        stype ;
  358. {
  359.     int            ope ;
  360.     DataStruct    *buf, *top ;
  361.  
  362.     /*    識別子    */
  363.     GotoNextCode();
  364.     buf = ExecRefVar();
  365.     StackPush( buf );
  366.     top = StackTop();
  367.  
  368.     switch( stype )
  369.     {
  370.         case SENT_ASN_INC:
  371.             ope = OPE_INC ;
  372.             break ;
  373.         case SENT_ASN_DEC:
  374.             ope = OPE_DEC ;
  375.             break ;
  376.         default:
  377.             assert( FALSE );
  378.     }
  379.     ExecOpe( ope, 1, top );
  380.     GotoNextCode();
  381.     Assign( buf, top );
  382.     StackRelease( top - 1 );
  383. }
  384.  
  385. /*    代入    */
  386. static    void    Assign( buf, top )
  387. DataStruct    *buf, *top ;
  388. {
  389.     if ( buf->type & TYPE_OBJECT )
  390.         ObjectFree( buf->od.ptr );
  391.  
  392.     if ( top->type & ( TYPE_BOOLEAN|TYPE_INT|TYPE_REAL|TYPE_TYPE|TYPE_FUNC ) )
  393.     {
  394.         *buf = *top ;
  395.     }
  396.     else if ( top->type & TYPE_ARRAY )
  397.     {
  398.         if ( buf->type & TYPE_ARRAY )
  399.         {
  400.             int        i, size ;
  401.             if ( buf->ad.size != top->ad.size )
  402.                 ExecError( "大きさの異なる配列は代入できません。" );
  403.             size = buf->ad.size ;
  404.             buf = buf->ad.ary ;
  405.             top = top->ad.ary ;
  406.             for( i = 0 ; i < size ; i++ )
  407.             {
  408.                 Assign( buf, top );
  409.                 top++ ;
  410.                 buf++ ;
  411.             }
  412.         }
  413.         else
  414.             *buf = *top ;
  415.     }
  416.     else if ( top->type & TYPE_OBJECT )
  417.     {
  418.         buf->type = TYPE_OBJECT ;
  419.         buf->od.ptr = ObjectCopy( top->od.ptr );
  420.     }
  421. }
  422.  
  423. /*
  424.  *        変数の参照
  425.  */
  426. DataStruct    *ExecRefVar()
  427. {
  428.     int        no, dim, i, n ;
  429.     DataStruct    *top ;
  430.     DataStruct    *buf ;
  431.     CodeStruct    *code = ExecPtr ;
  432.  
  433.     no = code->ident.ident ;    /*    識別子コード    */
  434.     if ( code->ident.itype & IDENT_ARY )
  435.     {
  436.         /*    配列    */
  437.         GotoNextCode();
  438.         ExecExpression();
  439.         top = StackTop();
  440.         assert( top->type == TYPE_INT );
  441.         dim = top->id.i ;                    /*    次数    */
  442.         assert( dim >= 1 );
  443.         StackPop();
  444.         switch( code->ident.itype & (IDENT_VAR|IDENT_ARY) )
  445.         {
  446.             case IDENT_GLOBAL|IDENT_ARY:
  447.                 buf = & DataGlobalVar[no] ;
  448.                 break ;
  449.             case IDENT_LOCAL|IDENT_ARY:
  450.                 buf = & DataLocalVar[no] ;
  451.                 break ;
  452.             default:
  453.                 assert( FALSE );
  454.         }
  455.         top = StackTop() - dim + 1 ;
  456.         for( i = 0 ; i < dim ; i++ )
  457.         {
  458.             if ( ( top->type & (TYPE_INT|TYPE_BOOLEAN) ) == 0 )
  459.                 ExecError( "配列の添え字の型が不正です" );
  460.             n = top->id.i ;
  461.             if ( n < 0 || buf->ad.size <= n )
  462.                 ExecError( "配列の添え字が不正です" );
  463.             buf = (DataStruct*)(buf->ad.ary) + n ;
  464.             top ++ ;
  465.         }
  466.         StackRelease( StackTop() - dim );
  467.     }
  468.     else
  469.     {
  470.         switch( code->ident.itype & IDENT_VAR )
  471.         {
  472.             case IDENT_GLOBAL :
  473.                 buf = & DataGlobalVar[no] ;
  474.                 break ;
  475.             case IDENT_LOCAL :
  476.                 buf = & DataLocalVar[no] ;
  477.                 break ;
  478.             default:
  479.                 assert( FALSE );
  480.         }
  481.         GotoNextCode();
  482.     }
  483.     return buf ;
  484. }
  485.  
  486.