예제 #1
0
static  void    ChkIOErr( cg_name io_stat ) {
//===========================================

// Check for i/o errors.

    label_handle        eq_label;

    io_stat = CGUnary( O_POINTS, io_stat, TY_INTEGER );
    if( ( EndEqLabel != 0 ) && ( ErrEqLabel != 0 ) ) {
        eq_label = BENewLabel();
        CG3WayControl( io_stat, GetLabel( EndEqLabel ), eq_label,
                       GetLabel( ErrEqLabel ) );
        CGControl( O_LABEL, NULL, eq_label );
        BEFiniLabel( eq_label );
    } else if( EndEqLabel != 0 ) {
        CGControl( O_IF_TRUE,
                   CGCompare( O_LT, io_stat, CGInteger( 0, TY_INTEGER ),
                              TY_INTEGER ),
                   GetLabel( EndEqLabel ) );
    } else if( ErrEqLabel != 0 ) {
        CGControl( O_IF_TRUE,
                   CGCompare( O_NE, io_stat, CGInteger( 0, TY_INTEGER ),
                              TY_INTEGER ),
                   GetLabel( ErrEqLabel ) );
    } else if( IOStatSpecified ) {
        IOSLabel = BENewLabel();
        CGControl( O_IF_TRUE,
                   CGCompare( O_NE, io_stat, CGInteger( 0, TY_INTEGER ),
                              TY_INTEGER ),
                   IOSLabel );
    } else {
        CGDone( io_stat );
    }
}
예제 #2
0
static  void    Equivalent( cg_op op_code ) {
//===========================================


    cg_name     op1;
    cg_name     op2;
    unsigned_16 typ_info;
    cg_type     typ1;
    cg_type     typ2;

    typ_info = GetU16();
    typ1 = GetType1( typ_info );
    typ2 = GetType2( typ_info );
    op1 = XPopValue( typ1 );
    op2 = XPopValue( typ2 );
    typ1 = CGType( op1 );
    if( typ1 != TY_BOOLEAN ) {
        op1 = CGCompare( O_NE, op1, CGInteger( 0, typ1 ), typ1 );
    }
    typ2 = CGType( op2 );
    if( typ2 != TY_BOOLEAN ) {
        op2 = CGCompare( O_NE, op2, CGInteger( 0, typ2 ), typ2 );
    }
    XPush( CGCompare( op_code, op1, op2, TY_UINT_1 ) );
}
예제 #3
0
static  void    CCCmp( cg_op op, cg_name a, cg_name b, cg_name c, cg_name d ) {
//=============================================================================

// Complex/Complex compare.

    cg_type     res_type;
    cg_op       flow_op;

    res_type = ResCGType( CGType( a ), CGType( c ) );
    if( op == O_EQ ) {
       flow_op = O_FLOW_AND;
    } else {
       flow_op = O_FLOW_OR;
    }
    XPush( CGFlow( flow_op, CGCompare( op, a, c, res_type ),
                            CGCompare( op, b, d, res_type ) ) );
}
예제 #4
0
void    FCIfArith( void ) {
//===================

// Set up control structure for arithmetic if.

    cg_name     if_expr;
    sym_id      lt;
    sym_id      eq;
    sym_id      gt;
    cg_type     typ;

    typ = GetType( GetU16() );
    if_expr = XPopValue( typ );
    lt = GetPtr();
    eq = GetPtr();
    gt = GetPtr();
    if( lt == gt ) {
        CGControl( O_IF_TRUE,
                   CGCompare( O_EQ, if_expr, CGInteger( 0, typ ), typ ),
                   GetStmtLabel( eq ) );
        CGControl( O_GOTO, NULL, GetStmtLabel( lt ) );
    } else if( lt == eq ) {
        CGControl( O_IF_TRUE,
                   CGCompare( O_GT, if_expr, CGInteger( 0, typ ), typ ),
                   GetStmtLabel( gt ) );
        CGControl( O_GOTO, NULL, GetStmtLabel( eq ) );
    } else if( eq == gt ) {
        CGControl( O_IF_TRUE,
                   CGCompare( O_LT, if_expr, CGInteger( 0, typ ), typ ),
                   GetStmtLabel( lt ) );
        CGControl( O_GOTO, NULL, GetStmtLabel( eq ) );
    } else {
        CG3WayControl( if_expr, GetStmtLabel( lt ), GetStmtLabel( eq ),
                       GetStmtLabel( gt ) );
    }
    RefStmtLabel( lt );
    RefStmtLabel( eq );
    RefStmtLabel( gt );
}
예제 #5
0
void    FCAllocated( void ) {
//=====================

// Generate code for ALLOCATED intrinsic function.

    uint                type;
    cg_name             fl;

    type = GetU16();
    fl = XPop();

    if( type & ALLOC_STRING ) {
        fl = CGUnary( O_POINTS, fl, T_POINTER );
    }
    XPush( CGCompare( O_NE, fl, CGInteger( 0, T_POINTER ), T_POINTER ) );
}
예제 #6
0
void    FCJmpFalse( void ) {
//====================

    unsigned_16 typ_info;
    cg_type     typ;
    cg_name     bool_expr;

    typ_info = GetU16();
    typ = GetType( typ_info );
    if( IntType( typ_info ) ) {
        bool_expr = CGCompare( O_NE, XPopValue( typ ),
                               CGInteger( 0, typ ), typ );
    } else {
        bool_expr = XPopValue( typ );
    }
    CGControl( O_IF_FALSE, bool_expr, GetLabel( GetU16() ) );
}
예제 #7
0
static  void    DoStructArrayIO( tmp_handle num_elts, struct field *fieldz ) {
//============================================================================

// Perform structure array i/o.

    label_handle        label;

    label = BENewLabel();
    CGControl( O_LABEL, NULL, label );
    StructIO( fieldz );
    CGControl( O_IF_TRUE,
               CGCompare( O_NE,
                          CGAssign( TmpPtr( num_elts, TY_INT_4 ),
                                    CGBinary( O_MINUS,
                                              TmpVal( num_elts, TY_INT_4 ),
                                              CGInteger( 1, TY_INTEGER ),
                                              TY_INT_4 ),
                                    TY_INT_4 ),
                          CGInteger( 0, TY_INTEGER ), TY_INT_4 ),
               label );
    BEFiniLabel( label );
}
예제 #8
0
void            FCAllocate( void ) {
//============================

    call_handle         handle;
    sym_id              arr;
    act_dim_list        *dim;
    uint                num;
    unsigned_16         alloc_flags;
    cg_name             expr_stat;
    cg_name             expr_loc;
    cg_name             fl;
    label_handle        label;

    num = 0;
    SymPush( NULL );
    for(;;) {
        arr = GetPtr();
        if( arr == NULL ) break;
        // check if array is already allocated before filling in ADV
        label = BENewLabel();
        fl = getFlags( arr );
        fl = CGBinary( O_AND, fl, CGInteger( ALLOC_MEM, T_UINT_2 ), T_UINT_2 );
        CGControl( O_IF_TRUE, CGCompare( O_NE, fl,
                                CGInteger( 0, T_UINT_2 ), T_UINT_2 ), label );
        FCodeSequence(); // fill in the ADV, SCB or RCB
        CGControl( O_LABEL, NULL, label );
        BEFiniLabel( label );
        SymPush( arr );
        ++num;
    }
    alloc_flags = GetU16();
    if( alloc_flags & ALLOC_NONE ) {
        expr_loc = CGInteger( 0, T_POINTER );
    } else {
        FCodeSequence();
        if( alloc_flags & ALLOC_LOC ) {
            expr_loc = XPopValue( T_INT_4 );
            if( alloc_flags & ALLOC_STAT ) {
                FCodeSequence();
                expr_stat = XPop();
            }
        } else {
            expr_stat = XPop();
        }
    }
    handle = InitCall( RT_ALLOCATE );
    for(;;) {
        arr = SymPop();
        if( arr == NULL ) break;
        if( arr->ns.flags & SY_SUBSCRIPTED ) {
            dim = arr->ns.si.va.dim_ext;
            CGAddParm( handle, CGInteger( _SymSize( arr ), T_INT_4 ),
                       T_INT_4 );
            CGAddParm( handle, CGInteger( _DimCount( dim->dim_flags ),
                                          T_INTEGER ),
                       T_INTEGER );
            CGAddParm( handle, GetAdv( arr ), T_LOCAL_POINTER );
        }
        CGAddParm( handle, CGFEName( arr, T_POINTER ), T_POINTER );
        CGAddParm( handle, getFlags( arr ), FLAG_PARM_TYPE );
    }
    if( alloc_flags & ALLOC_NONE ) {
        CGAddParm( handle, expr_loc, T_POINTER );
    } else {
        if( alloc_flags & ALLOC_LOC ) {
            CGAddParm( handle, expr_loc, T_INT_4 );
        }
        if( alloc_flags & ALLOC_STAT ) {
            CGAddParm( handle, expr_stat, T_POINTER );
        }
    }
    CGAddParm( handle, CGInteger( num, T_INTEGER ), T_INTEGER );
    CGAddParm( handle, CGInteger( alloc_flags, T_UINT_2 ), FLAG_PARM_TYPE );
    CGDone( CGCall( handle ) );
}