Esempio n. 1
0
extern  bool    WndEvalInspectExpr( char *item, bool pop )
/********************************************************/
{
    char        *old;
    char        buff[12],*p;
    bool        rc;

    if( ispunct(item[0]) &&
      ( item[1] == '\0' || ( ispunct( item[1] ) && item[2] == '\0' ) ) ) {
        // nyi - pui - use SSL
        p = StrCopy( item, StrCopy( "operator", buff ) );
        if( item[0] == '[' && item[1] == '\0' ) {
            StrCopy( "]", p );
        } else if( item[0] == '(' && item[1] == '\0' ) {
            StrCopy( ")", p );
        }
        old = ReScan( buff );
    } else {
        old = ReScan( item );
    }
    _SwitchOn( SW_CALL_FATAL );
    _SwitchOn( SW_ERR_IN_TXTBUFF );
    _SwitchOn( SW_NO_DISAMBIGUATOR );
    rc = ( Spawn( DoLValExpr ) == 0 );
    _SwitchOff( SW_CALL_FATAL );
    _SwitchOff( SW_NO_DISAMBIGUATOR );
    _SwitchOff( SW_ERR_IN_TXTBUFF );
    ReScan( old );
    if( pop && rc ) PopEntry();
    return( rc );
}
Esempio n. 2
0
void MakeMemoryAddr( bool pops, memory_expr def_seg, address *val )
{
    if( ExprSP->flags & SF_LOCATION ) {
        ExprSP->flags &= ~(SF_LOCATION|SF_IMP_ADDR);
        ExprSP->v.addr = ExprSP->v.loc.e[0].u.addr;
        ExprSP->info.kind = TK_ADDRESS;
        ExprSP->info.modifier = TM_FAR;
    }
    switch( ExprSP->info.kind ) {
    case TK_ADDRESS:
    case TK_POINTER:
        if( (ExprSP->info.modifier & TM_MOD_MASK) != TM_NEAR ) break;
        /* fall through */
    default:
        DefAddr( def_seg, val );
        AddrFix( val );
        //NYI: lost address abstraction
        PushInt( val->mach.segment );
        SwapStack( 1 );
        MakeAddr();
    }
    *val = ExprSP->v.addr;
    AddrFloat( val );
    if( pops ) PopEntry();
}
Esempio n. 3
0
inspect_type WndGetExprSPInspectType( address *paddr )
{
    sym_info    info;
    DIPHDL( sym, sh );

    LValue( ExprSP );
    *paddr = NilAddr;
    if( ExprSP->info.kind == TK_FUNCTION ) {
        ExprValue( ExprSP );
        *paddr = ExprSP->v.addr;
        PopEntry();
        return( INSP_CODE );
    } else if( (ExprSP->flags & SF_LOCATION) && ExprSP->th != NULL && !IsInternalMod( TypeMod( ExprSP->th ) ) ) {
        if( ExprSP->v.loc.num == 1 && ExprSP->v.loc.e[0].type == LT_ADDR ) {
            *paddr = ExprSP->v.loc.e[0].u.addr;
        }
        PopEntry();
        return( INSP_DATA );
    } else {
        if( (ExprSP->flags & SF_LOCATION) && ExprSP->v.loc.e[0].type == LT_ADDR ) {
            *paddr = ExprSP->v.loc.e[0].u.addr;
        } else if( ExprSP->info.kind == TK_ADDRESS
                || ExprSP->info.kind == TK_POINTER ) {
            *paddr = ExprSP->v.addr;
        }
        if( !IS_NIL_ADDR( (*paddr) ) ) {
            AddrFloat( paddr );
            if( DeAliasAddrSym( NO_MOD, *paddr, sh ) != SR_NONE ) {
                SymInfo( sh, ExprSP->lc, &info );
                PopEntry();
                switch( info.kind ) {
                case SK_CODE:
                case SK_PROCEDURE:
                    return( INSP_CODE );
                    break;
                default:
                    return( INSP_RAW_DATA );
                    break;
                }
            }
        }
    }
    ExprValue( ExprSP );
    MakeMemoryAddr( TRUE, EXPR_DATA, paddr );
    return( INSP_RAW_DATA );
}
Esempio n. 4
0
unsigned_64 ReqU64Expr( void )
{
    unsigned_64 rtn;

    NormalExpr();
    ConvertTo( ExprSP, TK_INTEGER, TM_UNSIGNED, sizeof( ExprSP->v.uint ) );
    rtn = ExprSP->v.uint;
    PopEntry();
    return( rtn );
}
Esempio n. 5
0
xreal ReqXRealExpr( void )
{
    xreal v;

    NormalExpr();
    ConvertTo( ExprSP, TK_REAL, TM_NONE, sizeof( ExprSP->v.real ) );
    v = ExprSP->v.real;
    PopEntry();
    return( v );
}
Esempio n. 6
0
void ProcAssign( void )
{
    char        *startpos;

    if( !AdvMachState( ACTION_ASSIGNMENT ) ) {
        FlushEOC();
        return;
    }
    startpos = ScanPos();
    NormalExpr();
    PopEntry();
    ReqEOC();
    RecordCommand( startpos, CMD_ASSIGN );
}
Esempio n. 7
0
static void DoMinusScaled( void )
{
    stack_entry *left;

    left = StkEntry( 1 );
    LRValue( left );
    RValue( ExprSP );
    switch( left->info.kind ) {
    case TK_POINTER:
        switch( ExprSP->info.kind ) {
        case TK_POINTER:
            /* Have to check if base type sizes are the same */
            PushBaseSize();
            DupStack();
            SwapStack( 3 );
            PushBaseSize();
            MoveSP( 1 );
            SwapStack( 3 );
            MoveSP( -1 );
            if( !TstEQ( 1 ) ) {
                Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
            }
            PopEntry();
            MoveSP( 1 );
            DoMinus();
            MoveSP( -1 );
            DoDiv();
            return;
        default:
            ScaleInt();
            break;
        }
        break;
    default:
        switch( ExprSP->info.kind ) {
        case TK_POINTER:
            Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
            break;
        }
    }
    DoMinus();
}
Esempio n. 8
0
bool PerformExplicitCall( address start, mad_string ctype, unsigned num_parms )
{
    bool                ret;
    stack_entry         *src;
    address             stack;
    unsigned            align;
    unsigned long       amount;
    mad_type_info       mti;

    stack = GetRegSP();
    GetMADTypeDefaultAt( stack, MTK_INTEGER, &mti );
    align = mti.b.bits / BITS_PER_BYTE;
    for( ; num_parms != 0; --num_parms ) {
        if( ExprSP->v.loc.e[0].type!=LT_ADDR && ExprSP->v.loc.e[0].u.p==NULL ) {
            /* push item */
            src = StkEntry( 1 );
            amount = (src->info.size + (align-1)) & -align;
            if( _IsOff( SW_STACK_GROWS_UP ) ) {
                stack.mach.offset -= amount;
            }
            LocationCreate( &ExprSP->v.loc, LT_ADDR, &stack );
            if( _IsOn( SW_STACK_GROWS_UP ) ) {
                stack.mach.offset += amount;
            }
            ExprSP->info = src->info;
            ExprSP->flags |= SF_LOCATION;
            ExprSP->th = NULL;
        }
        SwapStack( 1 );
        DoAssign();
        PopEntry();
    }
    AddrFix( &start );
    SetRegSP( stack );
    MADCallBuildFrame( ctype, start, start, &DbgRegs->mr, &DbgRegs->mr );
    DbgTmpBrk.loc.addr = start;
    NullStatus( &DbgTmpBrk );
    DbgTmpBrk.status.b.active = TRUE;
    ret = CallRoutine();
    NullStatus( &DbgTmpBrk );
    return( ret );
}
Esempio n. 9
0
static unsigned MechNum( unsigned select, unsigned parm )
{
    switch( select ) {
    case 0:
        Num = parm;
        break;
    case 1:
        Num += parm;
        break;
    case 2:
        PushInt( Num );
        break;
    case 3:
        /* need to check that top stack entry is an integer value here? */
        Num = U32FetchTrunc( ExprSP->v.uint );
        PopEntry();
        break;
    }
    return( 0 );
}
Esempio n. 10
0
static ssl_value MechNum( unsigned select, ssl_value parm )
{
    switch( select ) {
    case 0:
        Num = SSL2INT( parm );
        break;
    case 1:
        Num += SSL2INT( parm );
        break;
    case 2:
        PushInt( Num );
        break;
    case 3:
        /* need to check that top stack entry is an integer value here? */
        Num = I32FetchTrunc( ExprSP->v.sint );
        PopEntry();
        break;
    }
    return( 0 );
}
Esempio n. 11
0
static void MemMod( mad_type_handle mth, mad_type_kind mas )
{
    item_mach           item;
    item_type           ops;
    address             addr;
    mad_type_info       mti;

    ops = IT_ERR | IT_INC;
    if( mas & MAS_IO ) {
        ops |= IT_IO;
        addr.mach.offset = ReqExpr();
    } else {
        addr = GetDataDot();
        OptMemAddr( EXPR_DATA, &addr );
    }
    if( CurrToken == T_COMMA )
        Scan();
    MADTypeInfo( mth, &mti );
    while( !ScanEOC() ) {
        if( !( ops & IT_IO ) ) {
            SetDataDot( addr );
        }
        if( CurrToken != T_COMMA ) {
            NormalExpr();
            ToItemMAD( ExprSP, &item, &mti );
            PopEntry();
            if( CurrToken != T_COMMA && !ScanEOC() ) {
                Error( ERR_LOC, LIT_ENG( ERR_WANT_EOC ) );
            }
            ItemPutMAD( &addr, &item, ops, mth );
        }
        if( CurrToken == T_COMMA ) {
            Scan();
        }
    }
    if( !(ops & IT_IO) ) {
        DbgUpdate( UP_MEM_CHANGE | UP_CODE_ADDR_CHANGE | UP_REG_CHANGE );
    }
}
Esempio n. 12
0
void ProcDo( void )
{
    NormalExpr();
    PopEntry();
    ReqEOC();
}
Esempio n. 13
0
static unsigned MechPush_n_Pop( unsigned select, unsigned parm )
{
    location_list       ll;
    dip_type_info       ti;
    unsigned            result;
    const static unsigned       TypeTbl[] = {
        TI_CREATE( TK_VOID,     TM_NONE,         0 ),
        TI_CREATE( TK_INTEGER,  TM_UNSIGNED,     1 ),
        TI_CREATE( TK_INTEGER,  TM_SIGNED,       1 ),
        TI_CREATE( TK_INTEGER,  TM_UNSIGNED,     2 ),
        TI_CREATE( TK_INTEGER,  TM_SIGNED,       2 ),
        TI_CREATE( TK_INTEGER,  TM_UNSIGNED,     4 ),
        TI_CREATE( TK_INTEGER,  TM_SIGNED,       4 ),
        TI_CREATE( TK_REAL,     TM_NONE,         4 ),
        TI_CREATE( TK_REAL,     TM_NONE,         8 ),
        TI_CREATE( TK_COMPLEX,  TM_NONE,         8 ),
        TI_CREATE( TK_COMPLEX,  TM_NONE,        16 ),
    };

    result = FALSE;
    switch( select ) {
    case 0:
        PushInt( parm );
        break;
    case 1:
        PushAddr( GetDotAddr() );
        break;
    case 2:
        ParseRegSet( TRUE, &ll, &ti );
        if( ti.size != 0 ) {
            if( ti.kind == TK_NONE ) Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
            PushLocation( &ll, &ti );
            result = TRUE;
        }
        break;
    case 3:
        if( CurrToken == T_INT_NUM ) {
            PushNum64( IntNumVal() );
            Scan();
            result = TRUE;
        } else if( CurrToken == T_REAL_NUM ) {
            PushRealNum( RealNumVal() );
            Scan();
            result = TRUE;
        } else {
            result = FALSE;
        }
        break;
    case 4:
        BasicType( TypeTbl[ parm ] );
        break;
    case 5:
        DupStack();
        break;
    case 6:
        PopEntry();
        break;
    case 7:
        PushString();
        break;
    case 8:
        /* here because old debuggers will always return FALSE */
        switch( parm & SSL_VERSION_MAJOR_MASK ) {
        case SSL_VERSION_MAJOR_CURR:
            break;
        default:
            return( FALSE );
        }
        #if SSL_VERSION_MINOR_CURR != 0
            if( (parm & SSL_VERSION_MINOR_MASK) > SS_MINOR_VERSION_CURR ) {
                return( FALSE );
            }
        #endif
        result = TRUE;
        break;
    case 9:
        BasicType( parm );
        break;
    }
    return( result );
}
Esempio n. 14
0
static unsigned MechDo( unsigned select, unsigned parm )
{
    unsigned long       size;
    unsigned            result = 0;
    DIPHDL( type, th );
    dip_type_info       info;
    mad_type_info       mti;

    switch( select ) {
    case 0:
        DoAssign();
        break;
    case 1:
        DoMul();
        break;
    case 2:
        DoDiv();
        break;
    case 3:
        DoMod();
        break;
    case 4:
        DoMinus();
        break;
    case 5:
        DoShift();
        break;
    case 6:
        DoAnd();
        break;
    case 7:
        DoXor();
        break;
    case 8:
        DoOr();
        break;
    case 9:
        DoAddr();
        break;
    case 10:
        ClassToTypeInfo( parm, &info );
        DoPoints( info.kind );
        break;
    case 11:
        DoField();
        break;
    case 12:
        DoCall( Num, parm );
        break;
    case 13:
        DoConvert();
        break;
    case 14:
        DoPlus();
        break;
    case 15:
        MakeAddr();
        break;
    case 16:
        result = TstEQ( parm );
        break;
    case 17:
        result = TstLT( parm );
        break;
    case 18:
        result = TstTrue( parm );
        break;
    case 19:
        result = TstExist( parm );
        break;
    case 20:
        size = ExprSP->info.size;
        PopEntry();
        PushNum( size );
        break;
    case 21:
        TypeBase( ExprSP->th, th, NULL, NULL );
        PopEntry();
        PushType( th );
        break;
    case 22:
        GetMADTypeDefault( MTK_ADDRESS, &mti );
        size = (mti.b.bits - mti.a.seg.bits) / BITS_PER_BYTE;
        if( parm ) {
            size += sizeof( addr_seg );
            TypePointer( ExprSP->th, TM_FAR, size, th );
        } else {
            TypePointer( ExprSP->th, TM_NEAR, size, th );
        }
        PopEntry();
        PushType( th );
        break;
    case 23:
        result = UserType( th );
        if( result ) {
            PopEntry();
            PushType( th );
        }
        break;
    case 24:
        DoMakeComplex();
        break;
    case 25:
        DoStringConcat();
        break;
    case 26:
        DoLConvert();
        break;
    case 27:
        DoPlusScaled();
        break;
    case 28:
        DoMinusScaled();
        break;
    case 29:
        DoPoints( TI_KIND_EXTRACT( parm ) );
        break;
    case 30:
        info.kind = TK_POINTER;
        info.size = TI_SIZE_EXTRACT( parm );
        info.modifier = TI_MOD_EXTRACT( parm );
        FillInDefaults( &info );
        TypePointer( ExprSP->th, info.modifier, info.size, th );
        PopEntry();
        PushType( th );
        break;
    case 31:
        if( parm ) {
            /* file scope */
            if( ExprSP->flags & SF_NAME ) {
                ExprSP->v.li.file_scope = TRUE;
            } else {
                Error( ERR_LOC, LIT( ERR_WANT_NAME ) );
            }
        } else {
            /* in a namespace */
            DoScope();
        }
        break;
    }
    return( result );
}
Esempio n. 15
0
static unsigned MechMisc( unsigned select, unsigned parm )
{
    long                value;
    unsigned            result = 0;
    mad_type_info       mti;

    switch( select ) {
    case 0:
        ExprAddrDepth += parm;
        result = ExprAddrDepth;
        break;
    case 1:
        if( _IsOn( SW_EXPR_IS_CALL ) && ExprAddrDepth == 0 ) {
            result = TRUE;
        } else {
            result = FALSE;
        }
        break;
    case 2:
        SkipCount += parm;
        break;
    case 3:
        result = SkipCount;
        break;
    case 4:
        //never called
        break;
    case 5:
        if( ScanSavePtr >= MAX_SCANSAVE_PTRS )
            Error( ERR_INTERNAL, LIT( ERR_TOO_MANY_SCANSAVE ) );
        CurrScan[ScanSavePtr++] = ScanPos();
        break;
    case 6:
        if( ScanSavePtr <= 0 ) Error( ERR_INTERNAL, LIT( ERR_TOO_MANY_SCANRESTORE ) );
        ReScan( CurrScan[--ScanSavePtr] );
        break;
    case 7:
        if( ScanSavePtr <= 0 ) Error( ERR_INTERNAL, LIT( ERR_TOO_MANY_SCANRESTORE ) );
        --ScanSavePtr;
        break;
    case 8:
        if( parm ) {        /* start scan string */
            scan_string = TRUE;
            ReScan( ScanPos() );
        } else {            /* end scan string */
            scan_string = FALSE;
            ReScan( ScanPos() );
        }
        break;
    case 9:
        ReScan( ScanPos() + (int)parm );
        break;
    case 10:
        AddChar();
        break;
    case 11:
        AddCEscapeChar();
        break;
    case 12:
        AddActualChar( '\0' );
        break;
    case 13:
        ScanCCharNum = parm;
        break;
    case 14:
        if( NestedCallLevel == MAX_NESTED_CALL - 1 ) {
            Error( ERR_NONE, LIT( ERR_TOO_MANY_CALLS ) );
        } else {
            PgmStackUsage[ ++NestedCallLevel ] = 0;
        }
        break;
    case 15:
        RValue( ExprSP );
        ConvertTo( ExprSP, TK_INTEGER, TM_SIGNED, 4 );
        value = U32FetchTrunc( ExprSP->v.uint ) - 1;
        PopEntry();
        if( ExprSP->info.kind == TK_STRING ) {
            if( value < 0 || value >= ExprSP->info.size ) {
                Error( ERR_NONE, LIT( ERR_BAD_SUBSTRING_INDEX ) );
            }
            LocationAdd( &ExprSP->v.string.loc, value*8 );
            ExprSP->info.size -= value;
            ExprSP->v.string.ss_offset = value;
        } else {
            Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
        }
        break;
    case 16:
        RValue( ExprSP );
        ConvertTo( ExprSP, TK_INTEGER, TM_SIGNED, 4 );
        value = U32FetchTrunc( ExprSP->v.sint ) - 1;
        PopEntry();
        if( ExprSP->info.kind == TK_STRING ) {
            value -= ExprSP->v.string.ss_offset;
            if( value < 0 || value >= ExprSP->info.size ) {
                Error( ERR_NONE, LIT( ERR_BAD_SUBSTRING_INDEX ) );
            }
            ExprSP->info.size = value;
        } else {
            Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
        }
        break;
    case 17:
        EvalSubstring = parm;
        if( parm ) ExprSP->v.string.ss_offset = 0;
        break;
    case 18:
        result = EvalSubstring;
        break;
    case 19:
        FreePgmStack( TRUE );
        break;
    case 20:
        switch( parm ) { // nyi - begin temp
        case SSL_CASE_SENSITIVE:
            _SwitchOn( SW_CASE_SENSITIVE );
            break;
        case SSL_SIDE_EFFECT:
            _SwitchOn( SW_SIDE_EFFECT );
            break;
        //case SSL_32_BIT:
        //    _SwitchOn( SW_32_BIT );
        //    break;
        }
        break;
    case 21:
        switch( parm ) {
        case SSL_CASE_SENSITIVE:
            _SwitchOff( SW_CASE_SENSITIVE );
            break;
        case SSL_SIDE_EFFECT:
            _SwitchOff( SW_SIDE_EFFECT );
            break;
        //case SSL_32_BIT:
        //    _SwitchOff( SW_32_BIT );
        //    break;
        }
        break;
    case 22:
        switch( parm ) {
        case SSL_CASE_SENSITIVE:
            result = _IsOn( SW_CASE_SENSITIVE );
            break;
        case SSL_SIDE_EFFECT:
            result = _IsOn( SW_SIDE_EFFECT );
            break;
        case SSL_32_BIT:
            GetMADTypeDefault( MTK_INTEGER, &mti );
            result = (mti.b.bits >= 32);
            break;
        }
        break;
    case 23: // nyi - end temp
        MarkArrayOrder( parm );
        break;
    case 24:
        StartSubscript();
        break;
    case 25:
        AddSubscript();
        break;
    case 26:
        EndSubscript();
        break;
    }
    return( result );
}
Esempio n. 16
0
static ssl_value MechPush_n_Pop( unsigned select, ssl_value parm )
{
    location_list           ll;
    dig_type_info           ti;
    ssl_value               result;
    static const unsigned   TypeTbl[] = {
        TI_CREATE( TK_VOID,     TM_NONE,         0 ),
        TI_CREATE( TK_INTEGER,  TM_UNSIGNED,     1 ),
        TI_CREATE( TK_INTEGER,  TM_SIGNED,       1 ),
        TI_CREATE( TK_INTEGER,  TM_UNSIGNED,     2 ),
        TI_CREATE( TK_INTEGER,  TM_SIGNED,       2 ),
        TI_CREATE( TK_INTEGER,  TM_UNSIGNED,     4 ),
        TI_CREATE( TK_INTEGER,  TM_SIGNED,       4 ),
        TI_CREATE( TK_REAL,     TM_NONE,         4 ),
        TI_CREATE( TK_REAL,     TM_NONE,         8 ),
        TI_CREATE( TK_COMPLEX,  TM_NONE,         8 ),
        TI_CREATE( TK_COMPLEX,  TM_NONE,        16 ),
    };

    result = 0;
    switch( select ) {
    case 0:
        PushInt( SSL2INT( parm ) );
        break;
    case 1:
        PushAddr( GetDotAddr() );
        break;
    case 2:
        ParseRegSet( true, &ll, &ti );
        if( ti.size != 0 ) {
            if( ti.kind == TK_NONE )
                Error( ERR_NONE, LIT_ENG( ERR_ILL_TYPE ) );
            PushLocation( &ll, &ti );
            result = true;
        }
        break;
    case 3:
        if( CurrToken == T_INT_NUM ) {
            PushNum64( IntNumVal() );
            Scan();
            result = true;
        } else if( CurrToken == T_REAL_NUM ) {
            PushRealNum( RealNumVal() );
            Scan();
            result = true;
        }
        break;
    case 4:
        BasicType( TypeTbl[parm] );
        break;
    case 5:
        DupStack();
        break;
    case 6:
        PopEntry();
        break;
    case 7:
        PushString();
        break;
    case 8:
        /* here because old debuggers will always return false */
        if( (parm & SSL_VERSION_MAJOR_MASK) != SSL_VERSION_MAJOR_CURR ) {
            break;
        }
#if SSL_VERSION_MINOR_CURR != 0
        if( (parm & SSL_VERSION_MINOR_MASK) > SS_MINOR_VERSION_CURR ) {
            break;
        }
#endif
        result = true;
        break;
    case 9:
        BasicType( parm );
        break;
    }
    return( result );
}
Esempio n. 17
0
static ssl_value MechDo( unsigned select, ssl_value parm )
{
    unsigned long       size;
    ssl_value           result;
    DIPHDL( type, th );
    dig_type_info       ti;
    mad_type_info       mti;

    result = 0;
    switch( select ) {
    case 0:
        DoAssign();
        break;
    case 1:
        DoMul();
        break;
    case 2:
        DoDiv();
        break;
    case 3:
        DoMod();
        break;
    case 4:
        DoMinus();
        break;
    case 5:
        DoShift();
        break;
    case 6:
        DoAnd();
        break;
    case 7:
        DoXor();
        break;
    case 8:
        DoOr();
        break;
    case 9:
        DoAddr();
        break;
    case 10:
        ClassToTypeInfo( parm, &ti );
        DoPoints( ti.kind );
        break;
    case 11:
        DoField();
        break;
    case 12:
        DoCall( Num, SSL2BOOL( parm ) );
        break;
    case 13:
        DoConvert();
        break;
    case 14:
        DoPlus();
        break;
    case 15:
        MakeAddr();
        break;
    case 16:
        result = ( TstEQ( SSL2INT( parm ) ) != 0 );
        break;
    case 17:
        result = ( TstLT( SSL2INT( parm ) ) != 0 );
        break;
    case 18:
        result = ( TstTrue( SSL2INT( parm ) ) != 0 );
        break;
    case 19:
        result = ( TstExist( SSL2INT( parm ) ) != 0 );
        break;
    case 20:
        size = ExprSP->ti.size;
        PopEntry();
        PushNum( size );
        break;
    case 21:
        DIPTypeBase( ExprSP->th, th, NULL, NULL );
        PopEntry();
        PushType( th );
        break;
    case 22:
        GetMADTypeDefault( MTK_ADDRESS, &mti );
        size = BITS2BYTES( mti.b.bits - mti.a.seg.bits );
        if( parm ) {
            size += sizeof( addr_seg );
            DIPTypePointer( ExprSP->th, TM_FAR, size, th );
        } else {
            DIPTypePointer( ExprSP->th, TM_NEAR, size, th );
        }
        PopEntry();
        PushType( th );
        break;
    case 23:
        result = UserType( th );
        if( result ) {
            PopEntry();
            PushType( th );
        }
        break;
    case 24:
        DoMakeComplex();
        break;
    case 25:
        DoStringConcat();
        break;
    case 26:
        DoLConvert();
        break;
    case 27:
        DoPlusScaled();
        break;
    case 28:
        DoMinusScaled();
        break;
    case 29:
        DoPoints( TI_KIND_EXTRACT( parm ) );
        break;
    case 30:
        ti.kind = TK_POINTER;
        ti.size = TI_SIZE_EXTRACT( parm );
        ti.modifier = TI_MOD_EXTRACT( parm );
        ti.deref = false;
        FillInDefaults( &ti );
        DIPTypePointer( ExprSP->th, ti.modifier, ti.size, th );
        PopEntry();
        PushType( th );
        break;
    case 31:
        if( SSL2BOOL( parm ) ) {
            /* file scope */
            if( ExprSP->flags & SF_NAME ) {
                ExprSP->v.li.file_scope = true;
            } else {
                Error( ERR_LOC, LIT_ENG( ERR_WANT_NAME ) );
            }
        } else {
            /* in a namespace */
            DoScope();
        }
        break;
    }
    return( result );
}