void DoPlus( void ) { stack_entry *left; left = StkEntry( 1 ); LRValue( left ); RValue( ExprSP ); switch( ExprSP->info.kind ) { case TK_POINTER: case TK_ADDRESS: /* get the pointer as the left operand */ left = ExprSP; SwapStack( 1 ); } AddOp( left, ExprSP ); switch( left->info.kind ) { case TK_BOOL: case TK_ENUM: case TK_CHAR: case TK_INTEGER: U64Add( &left->v.uint, &ExprSP->v.uint, &left->v.uint ); break; case TK_POINTER: case TK_ADDRESS: switch( ExprSP->info.kind ) { case TK_BOOL: case TK_ENUM: case TK_CHAR: case TK_INTEGER: break; default: Error( ERR_NONE, LIT_ENG( ERR_ILL_TYPE ) ); } if( (left->info.modifier & TM_MOD_MASK) == TM_NEAR ) { //NYI: 64 bit offsets left->v.addr.mach.offset += U32FetchTrunc( ExprSP->v.uint ); } else { //NYI: 64 bit offsets left->v.addr = AddrAdd( left->v.addr, U32FetchTrunc( ExprSP->v.uint ) ); } break; case TK_REAL: LDAdd( &left->v.real, &ExprSP->v.real, &left->v.real ); break; case TK_COMPLEX: LDAdd( &left->v.cmplx.re, &ExprSP->v.cmplx.re, &left->v.cmplx.re ); LDAdd( &left->v.cmplx.im, &ExprSP->v.cmplx.im, &left->v.cmplx.im ); break; default: Error( ERR_NONE, LIT_ENG( ERR_ILL_TYPE ) ); break; } CombineEntries( left, left, ExprSP ); }
unsigned ReqExpr( void ) { unsigned_64 tmp; tmp = ReqU64Expr(); return( U32FetchTrunc( tmp ) ); }
OVL_EXTERN bool ConvR10( stack_entry *entry, conv_class from ) { xreal tmp; switch( from ) { case U1: case U2: case U4: case U8: //NYI: 64 bit support DToLD( U32FetchTrunc( entry->v.uint ), &tmp ); break; case I1: case I2: case I4: case I8: //NYI: 64 bit support DToLD( I32FetchTrunc( entry->v.sint ), &tmp ); break; case F4: case F8: case F10: tmp = entry->v.real; break; case C8: case C16: case C20: tmp = entry->v.cmplx.re; break; default: return( FALSE ); } entry->v.real = tmp; return( TRUE ); }
void DoMinus( void ) { stack_entry *left; left = StkEntry( 1 ); LRValue( left ); RValue( ExprSP ); AddOp( left, ExprSP ); switch( left->info.kind ) { case TK_BOOL: case TK_ENUM: case TK_CHAR: case TK_INTEGER: U64Sub( &left->v.uint, &ExprSP->v.uint, &left->v.uint ); left->info.modifier = TM_SIGNED; break; case TK_POINTER: case TK_ADDRESS: switch( ExprSP->info.kind ) { case TK_BOOL: case TK_CHAR: case TK_ENUM: case TK_INTEGER: //NYI: 64 bit offsets left->v.addr = AddrAdd( left->v.addr, -U32FetchTrunc( ExprSP->v.uint ) ); break; case TK_POINTER: case TK_ADDRESS: I32ToI64( AddrDiff( left->v.addr, ExprSP->v.addr ), &left->v.sint ); left->info.kind = TK_INTEGER; left->info.modifier = TM_SIGNED; left->info.size = sizeof( signed_64 ); left->th = NULL; break; default: Error( ERR_NONE, LIT_ENG( ERR_ILL_TYPE ) ); } break; case TK_REAL: LDSub( &left->v.real, &ExprSP->v.real, &left->v.real ); break; case TK_COMPLEX: LDSub( &left->v.cmplx.re, &ExprSP->v.cmplx.re, &left->v.cmplx.re ); LDSub( &left->v.cmplx.im, &ExprSP->v.cmplx.im, &left->v.cmplx.im ); break; default: Error( ERR_NONE, LIT_ENG( ERR_ILL_TYPE ) ); break; } CombineEntries( left, left, ExprSP ); }
OVL_EXTERN bool ConvFP6( stack_entry *entry, conv_class from ) { address tmp; tmp = DefAddrSpaceForAddr( Context.execution ); switch( from ) { case U1: case U2: case U4: case U8: if( (entry->flags & SF_CONST) && U64Test( &entry->v.uint ) == 0 ) tmp = NilAddr; //NYI: 64 bit offsets tmp.mach.offset = U32FetchTrunc( entry->v.uint ); break; case I1: case I2: case I4: case I8: if( (entry->flags & SF_CONST) && I64Test( &entry->v.sint ) == 0 ) tmp = NilAddr; //NYI: 64 bit offsets tmp.mach.offset = U32FetchTrunc( entry->v.sint ); break; case NP2: case NP4: /* near pointers already have correct segment information filled in */ tmp = entry->v.addr; break; case FP4: case FP6: case HP4: tmp = entry->v.addr; break; default: return( FALSE ); } entry->v.addr = tmp; return( TRUE ); }
void DoAPoints( stack_entry *stk, type_kind def ) { stack_flags was_imp_addr; addr_off off; LRValue( stk ); was_imp_addr = stk->flags & SF_IMP_ADDR; switch( stk->info.kind ) { case TK_BOOL: case TK_ENUM: case TK_CHAR: case TK_INTEGER: //NYI: 64 bit offsets off = U32FetchTrunc( stk->v.uint ); stk->v.addr = DefAddrSpaceForAddr( Context.execution ); stk->v.addr.mach.offset = off; stk->info.modifier = TM_NEAR; /* fall through */ case TK_POINTER: case TK_ADDRESS: if( stk->th != NULL ) { LocationCreate( &stk->v.loc, LT_ADDR, &stk->v.addr ); DIPTypeBase( stk->th, stk->th, stk->lc, &stk->v.loc ); ClassifyEntry( stk, &stk->info ); if( stk->info.kind == TK_VOID ) { Error( ERR_NONE, LIT_ENG( ERR_VOID_BASE ) ); } } else { if( def == TK_NONE ) def = TK_INTEGER; stk->info.kind = def; switch( def ) { case TK_INTEGER: stk->info.modifier = TM_UNSIGNED; stk->info.size = DefaultSize( DK_INT ); break; case TK_ADDRESS: ExprSetAddrInfo( stk, false ); break; } LocationCreate( &stk->v.loc, LT_ADDR, &stk->v.addr ); } stk->flags |= SF_LOCATION | was_imp_addr; break; default: Error( ERR_NONE, LIT_ENG( ERR_ILL_TYPE ) ); break; } stk->flags &= ~SF_CONST; }
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 ); }
void ClassNum( stack_entry *entry ) { unsigned long val; entry->info.kind = TK_INTEGER; entry->flags &= ~SF_FORM_MASK; entry->flags |= SF_CONST; if( I64Test( &entry->v.sint ) < 0 ) { /* A bit backwards - if the top bit is on, it won't fit in in 63 bits. */ entry->info.modifier = TM_UNSIGNED; entry->info.size = sizeof( unsigned_64 ); return; } if( !U64IsU32( entry->v.uint ) ) { entry->info.modifier = TM_SIGNED; entry->info.size = sizeof( signed_64 ); return; } val = U32FetchTrunc( entry->v.uint ); if( val > 0x7fffffff ) { entry->info.modifier = TM_UNSIGNED; entry->info.size = sizeof( unsigned_32 ); } else if( DefaultSize( DK_INT ) > 2 ) { entry->info.modifier = TM_SIGNED; entry->info.size = sizeof( signed_32 ); } else if( val > 0xffff ) { entry->info.modifier = TM_SIGNED; entry->info.size = sizeof( signed_32 ); } else if( val > 0x7fff ) { entry->info.modifier = TM_UNSIGNED; entry->info.size = sizeof( unsigned_16 ); } else { entry->info.modifier = TM_SIGNED; entry->info.size = sizeof( signed_16 ); } }
static void CaseStmt( void ) { const_val val; NextToken(); if( SwitchStack ) { if( ConstExprAndType( &val ) ) { if( ( val.type == TYPE_ULONG64 ) && !U64IsU32( val.value ) ) { CErr1( ERR_CONSTANT_TOO_BIG ); } else if( ( val.type == TYPE_LONG64 ) && !I64IsI32( val.value ) ) { CErr1( ERR_CONSTANT_TOO_BIG ); } AddCaseLabel( U32FetchTrunc( val.value) ); } MustRecog( T_COLON ); if( CurToken == T_RIGHT_BRACE ) { CErr1( ERR_STMT_REQUIRED_AFTER_CASE ); } } else { CErr1( ERR_MISPLACED_CASE ); ConstExprAndType( &val ); /* grab constant expression */ MustRecog( T_COLON ); } }
OVL_EXTERN bool ConvNP4( stack_entry *entry, conv_class from ) { addr48_off tmp; switch( from ) { case U1: case U2: case U4: case U8: //NYI: 64 bit offsets tmp = U32FetchTrunc( entry->v.uint ); break; case I1: case I2: case I4: case I8: //NYI: 64 bit offsets tmp = I32FetchTrunc( entry->v.sint ); break; case NP2: case NP4: case FP4: case FP6: tmp = entry->v.addr.mach.offset; break; default: return( FALSE ); } if( (entry->flags & SF_CONST) && tmp == 0 ) { entry->v.addr = NilAddr; } else { entry->v.addr = DefAddrSpaceForAddr( Context.execution ); } entry->v.addr.mach.offset = tmp; return( TRUE ); }
OVL_EXTERN bool ConvC20( stack_entry *entry, conv_class from ) { xcomplex tmp; DToLD( 0.0, &tmp.im ); switch( from ) { case U1: case U2: case U4: case U8: //NYI: 64 bit support DToLD( U32FetchTrunc( entry->v.uint ), &tmp.re ); break; case I1: case I2: case I4: case I8: DToLD( I32FetchTrunc( entry->v.sint ), &tmp.re ); break; case F4: case F8: case F10: tmp.re = entry->v.real; break; case C8: case C16: case C20: tmp = entry->v.cmplx; break; default: return( false ); } entry->v.cmplx = tmp; return( true ); }
static unsigned MechGet( unsigned select, unsigned parm ) { unsigned result; DIPHDL( cue, ch ); sym_list *sym; address addr; unsigned old; char *save_scan; char *mod_name; unsigned mod_len; unsigned mod_spec_token; result = FALSE; switch( select ) { case 0: /* init */ memset( &CurrGet, 0, sizeof( CurrGet ) ); CurrGet.li.mod = NO_MOD; if( _IsOn( SW_CASE_SENSITIVE ) ) { CurrGet.li.case_sensitive = TRUE; } else { CurrGet.li.case_sensitive = FALSE; } break; case 1: /* fini */ switch( CurrGet.kind ) { case GET_NAME: PushName( &CurrGet.li ); break; case GET_OPERATOR: CurrGet.li.type = ST_OPERATOR; PushName( &CurrGet.li ); break; case GET_LNUM: switch( FindACue( ch ) ) { case SR_EXACT: break; case SR_CLOSEST: if( ClosestLineOk ) break; default: Error( ERR_NONE, LIT( ERR_NO_CODE ), CurrGet.li.name.len ); } PushAddr( CueAddr( ch ) ); break; } break; case 2: /* mod curr */ case 3: /* mod name lookup */ //NYI: temporary gunk CurrGet.multi_module = TRUE; CurrGet.li.mod = NO_MOD; save_scan = ScanPos(); ReScan( "@" ); mod_spec_token = CurrToken; ReScan( save_scan ); if( CurrToken == T_NAME ) { mod_name = NamePos(); mod_len = NameLen(); Scan(); } else { mod_name = NULL; mod_len = 0; } if( CurrToken == mod_spec_token ) { if( select == 2 ) { CurrGet.li.mod = ImagePrimary()->dip_handle; if( CurrGet.li.mod == NO_MOD ) { CurrGet.li.mod = ILL_MOD; /* cause lookup to fail */ } } else { CurrGet.li.mod = LookupImageName( CurrGet.li.name.start, CurrGet.li.name.len ); if( CurrGet.li.mod == NO_MOD ) { #define ANY_IMAGE_NAME "_anyimage" #define ANY_IMAGE_NAME_LEN (sizeof(ANY_IMAGE_NAME)-1) if( CurrGet.li.name.len != ANY_IMAGE_NAME_LEN || memicmp( CurrGet.li.name.start, ANY_IMAGE_NAME, ANY_IMAGE_NAME_LEN ) != 0 ) { Error( ERR_NONE, LIT( ERR_NO_IMAGE ), CurrGet.li.name.start, CurrGet.li.name.len ); } else { CurrGet.any_image = TRUE; } } } CurrGet.li.name.start = mod_name; CurrGet.li.name.len = mod_len; Scan(); } else { ReScan( save_scan ); } if( CurrGet.li.name.start != NULL ) { CurrGet.li.mod = LookupModName( CurrGet.li.mod, CurrGet.li.name.start, CurrGet.li.name.len ); if( CurrGet.li.mod == NO_MOD ) { Error( ERR_NONE, LIT( ERR_NO_MODULE ), CurrGet.li.name.start, CurrGet.li.name.len ); } CurrGet.multi_module = FALSE; } else if( !CurrGet.any_image && CurrGet.li.mod == NO_MOD ) { CurrGet.li.mod = CodeAddrMod; CurrGet.multi_module = FALSE; } break; case 4: /* file scope */ CurrGet.li.file_scope = TRUE; break; case 5: /* given scope */ CurrGet.li.file_scope = FALSE; break; case 6: /* scope lookup */ CurrGet.li.scope.start = CurrGet.li.name.start; CurrGet.li.scope.len = CurrGet.li.name.len; break; case 7: /* get name >>bool */ if( CurrToken == T_NAME ) { CurrGet.kind = GET_NAME; CurrGet.li.name.start = NamePos(); CurrGet.li.name.len = NameLen(); Scan(); result = TRUE; } break; case 8: /* get operator name */ CurrGet.kind = GET_OPERATOR; CurrGet.li.name.start = NamePos(); CurrGet.li.name.len = NameLen(); Scan(); break; case 9: /* get line number >>bool */ if( CurrToken == T_LEFT_BRACE ) { size_t len; /* Get a specfic file name for the module */ ScanQuote( &CurrGet.li.source.start, &len ); CurrGet.li.source.len = len; } if( CurrToken == T_INT_NUM ) { unsigned_64 tmp; result = TRUE; CurrGet.kind = GET_LNUM; old = SetCurrRadix( 10 ); tmp = IntNumVal(); CurrGet.li.name.len = U32FetchTrunc( tmp ); Scan(); SetCurrRadix( old ); } break; case 10: /* GetDtorName >>bool */ if( CurrToken == T_NAME ) { CurrGet.kind = GET_NAME; CurrGet.li.name.start = NamePos(); CurrGet.li.name.len = NameLen(); CurrGet.li.type = ST_DESTRUCTOR; addr = Context.execution; sym = LookupSymList( SS_SCOPED, &addr, FALSE, &CurrGet.li ); if( sym != NULL ) { PurgeSymHandles(); Scan(); result = TRUE; } else { CurrGet.li.type = ST_NONE; } } break; case 11: /* GetSetNameType(symbol_type) */ CurrGet.li.type = parm; break; case 12: /* GetQueryName >>bool */ CurrGet.kind = GET_NAME; addr = Context.execution; sym = LookupSymList( SS_SCOPED, &addr, FALSE, &CurrGet.li ); if( sym != NULL ) { PurgeSymHandles(); result = TRUE; } else { CurrGet.li.type = ST_NONE; } break; case 13: /* GetAddScope */ if( CurrGet.li.scope.len == 0 ) { CurrGet.li.scope = CurrGet.li.name; } else { CurrGet.li.scope.len = (CurrGet.li.name.start-CurrGet.li.scope.start) + CurrGet.li.name.len; } break; } return( result ); }
OVL_EXTERN bool ConvI2( stack_entry *entry, conv_class from ) { if( !ConvU8( entry, from ) ) return( false ); I32ToI64( (signed_16)U32FetchTrunc( entry->v.uint ), &entry->v.sint ); return( true ); }
OVL_EXTERN bool ConvI4( stack_entry *entry, conv_class from ) { if( !ConvU8( entry, from ) ) return( FALSE ); I32ToI64( (signed_32)U32FetchTrunc( entry->v.uint ), &entry->v.sint ); return( TRUE ); }
OVL_EXTERN bool ConvU2( stack_entry *entry, conv_class from ) { if( !ConvU8( entry, from ) ) return( FALSE ); U32ToU64( (unsigned_16)U32FetchTrunc( entry->v.uint ), &entry->v.uint ); return( TRUE ); }
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 ); }
/* * ConvertTo -- convert 'entry' to the given 'class'. * 'entry' should be an rvalue. */ void ConvertTo( stack_entry *entry, type_kind k, type_modifier m, unsigned s ) { conv_class from; char *dest; if( s == 0 && k == TK_INTEGER ) { s = DefaultSize( DK_INT ); } if( entry->info.kind == k && entry->info.modifier == m && entry->info.size == s ) return; from = ConvIdx( &entry->info ); switch( from ) { case U1: U32ToU64( U8FetchTrunc( entry->v.uint ), &entry->v.uint ); break; case U2: U32ToU64( U16FetchTrunc( entry->v.uint ), &entry->v.uint ); break; case U4: U32ToU64( U32FetchTrunc( entry->v.uint ), &entry->v.uint ); break; case I1: I32ToI64( I8FetchTrunc( entry->v.uint ), &entry->v.uint ); break; case I2: I32ToI64( I16FetchTrunc( entry->v.uint ), &entry->v.uint ); break; case I4: I32ToI64( I32FetchTrunc( entry->v.uint ), &entry->v.uint ); break; case F4: DToLD( (float)LDToD( &entry->v.real ), &entry->v.real ); break; case F8: DToLD( (double)LDToD( &entry->v.real ), &entry->v.real ); break; case C8: DToLD( (float)LDToD( &entry->v.cmplx.re ), &entry->v.cmplx.re ); DToLD( (float)LDToD( &entry->v.cmplx.im ), &entry->v.cmplx.im ); break; case C16: DToLD( (double)LDToD( &entry->v.cmplx.re ), &entry->v.cmplx.re ); DToLD( (double)LDToD( &entry->v.cmplx.im ), &entry->v.cmplx.im ); break; case NP2: case FP4: entry->v.addr.mach.offset &= 0xffff; break; case STR: if( k != TK_STRING ) { Error( ERR_NONE, LIT( ERR_TYPE_CONVERSION ) ); } if( s > entry->info.size ) { /* have to expand string */ _ChkAlloc( dest, s, LIT( ERR_NO_MEMORY_FOR_EXPR ) ); memcpy( dest, entry->v.string.loc.e[0].u.p, entry->info.size ); memset( &dest[entry->info.size], ' ', s - entry->info.size ); if( AllocatedString( entry ) ) { _Free( entry->v.string.allocated ); } entry->v.string.allocated = dest; LocationCreate( &entry->v.string.loc, LT_INTERNAL, dest ); } break; default: break; } entry->info.kind = k; entry->info.modifier = m; entry->info.size = s; if( !ConvFunc[ ConvIdx( &entry->info ) ]( entry, from ) ) { Error( ERR_NONE, LIT( ERR_TYPE_CONVERSION ) ); } entry->th = NULL; }
OVL_EXTERN bool ConvU4( stack_entry *entry, conv_class from ) { if( !ConvU8( entry, from ) ) return( false ); U32ToU64( (unsigned_32)U32FetchTrunc( entry->v.uint ), &entry->v.uint ); return( true ); }