void ArrayIO( RTCODE num_array, RTCODE chr_array ) { //===================================================== // Output an array. sym_id arr; sym_id field; cg_name addr; cg_name num_elts; cg_name elt_size; arr = GetPtr(); field = GetPtr(); if( field == NULL ) { addr = SymAddr( arr ); num_elts = ArrayNumElts( arr ); if( arr->ns.typ == FT_CHAR ) { ChrArrayIO( chr_array, addr, num_elts, ArrayEltSize( arr ) ); } else { NumArrayIO( num_array, addr, num_elts, ParmType( arr->ns.typ, arr->ns.xt.size ) ); } } else { // must be a array field in a structure addr = XPop(); num_elts = FieldArrayNumElts( field ); if( field->fd.typ == FT_CHAR ) { elt_size = CGInteger( field->fd.xt.size, TY_INTEGER ); ChrArrayIO( chr_array, addr, num_elts, elt_size ); } else { NumArrayIO( num_array, addr, num_elts, ParmType( field->fd.typ, field->fd.xt.size ) ); } } }
void PushComplex( sym_id sym ) { //================================= // Push a complex number. XPush( SymAddr( sym ) ); }
cg_name SymValue( sym_id sym ) { //============================== // Generate value of a symbol. return( CGUnary( O_POINTS, SymAddr( sym ), F772CGType( sym ) ) ); }
void FCAssign( void ) { //================== // Process ASSIGN statement. sym_id stmt; stmt = GetPtr(); if( stmt->u.st.flags & SN_FORMAT ) { CGDone( CGAssign( SymAddr( GetPtr() ), CGBackName( GetFmtLabel( stmt->u.st.address ), TY_LOCAL_POINTER ), TY_LOCAL_POINTER ) ); } else { CGDone( CGAssign( SymAddr( GetPtr() ), CGInteger( stmt->u.st.address, TY_INTEGER ), TY_INTEGER ) ); RefStmtLabel( stmt ); } }
cg_name CharItemLen( sym_id sym ) { //================================= // Get element size for character*(*) variables, functions and arrays. if( sym->ns.flags & SY_SUBSCRIPTED ) { return( CharArrLength( sym ) ); } else { return( SCBLength( SymAddr( sym ) ) ); } }
static void StructArrayIO( void ) { //=============================== // Perform structure array i/o. sym_id arr; tmp_handle num_elts; arr = GetPtr(); num_elts = MkTmp( ArrayNumElts( arr ), TY_INT_4 ); TmpStructPtr = MkTmp( SymAddr( arr ), TY_POINTER ); DoStructArrayIO( num_elts, arr->ns.xt.record->fl.fields ); }
void FCFmtAssign( void ) { //===================== // Set FORMAT string for: // ASSIGN 10 TO I // PRINT I, ... // 10 FORMAT( ... ) call_handle handle; handle = InitCall( RT_SET_FMT ); CGAddParm( handle, CGUnary( O_POINTS, SymAddr( GetPtr() ), TY_POINTER ), TY_POINTER ); CGDone( CGCall( handle ) ); }
void FCPush( void ) { //================ // Process PUSH F-Code. sym_id sym; sym = GetPtr(); if( TypeCmplx( sym->ns.typ ) ) { PushComplex( sym ); } else { XPush( SymAddr( sym ) ); } }
void FCFmtArrScan( void ) { //====================== // Call runtime routine to scan a format specification from a character // array. call_handle handle; sym_id sym; sym = GetPtr(); handle = InitCall( RT_FMT_ARR_SCAN ); CGAddParm( handle, CGInteger( GetU16(), TY_UNSIGNED ), TY_UNSIGNED ); CGAddParm( handle, ArrayEltSize( sym ), TY_UNSIGNED ); CGAddParm( handle, ArrayNumElts( sym ), TY_INT_4 ); CGAddParm( handle, SymAddr( sym ), TY_POINTER ); CGDone( CGCall( handle ) ); }
void FCIntlArrSet( void ) { //====================== // Call runtime routine to set internal file to character array. call_handle handle; sym_id sym; sym_id scb; sym = GetPtr(); scb = GetPtr(); CGTrash( CGAssign( SCBLenAddr( CGFEName( scb, TY_POINTER ) ), ArrayEltSize( sym ), TY_INTEGER ) ); CGTrash( CGAssign( SCBPtrAddr( CGFEName( scb, TY_POINTER ) ), SymAddr( sym ), TY_POINTER ) ); handle = InitCall( RT_SET_INTL ); CGAddParm( handle, ArrayNumElts( sym ), TY_INT_4 ); CGAddParm( handle, CGFEName( scb, TY_POINTER ), TY_POINTER ); CGDone( CGCall( handle ) ); }
void FCSetNml( void ) { //================== // Set NAMELIST format. call_handle handle; sym_id nl; grp_entry *ge; NmlSpecified = TRUE; handle = InitCall( RT_SET_NML ); nl = GetPtr(); ReverseList( &nl->nl.group_list ); ge = nl->nl.group_list; while( ge != NULL ) { CGAddParm( handle, SymAddr( ge->sym ), TY_POINTER ); ge = ge->link; } ReverseList( &nl->nl.group_list ); CGAddParm( handle, CGBackName( nl->nl.address, TY_POINTER ), TY_POINTER ); CGDone( CGCall( handle ) ); }
void FCSFCall( void ) { //================== // Call a statement function. sym_id sf; sym_id sf_arg; sym_id tmp; cg_type sf_type; cg_name arg_list; cg_name value; cg_cmplx z; obj_ptr curr_obj; sf = GetPtr(); arg_list = NULL; value = NULL; sf_type = 0; for(;;) { sf_arg = GetPtr(); if( sf_arg == NULL ) break; if( sf_arg->u.ns.u1.s.typ == FT_CHAR ) { value = Concat( 1, CGFEName( sf_arg, TY_CHAR ) ); } else { sf_type = F772CGType( sf_arg ); if( TypeCmplx( sf_arg->u.ns.u1.s.typ ) ) { XPopCmplx( &z, sf_type ); sf_type = CmplxBaseType( sf_type ); value = ImagPtr( SymAddr( sf_arg ), sf_type ); CGTrash( CGAssign( value, z.imagpart, sf_type ) ); value = CGFEName( sf_arg, sf_type ); value = CGAssign( value, z.realpart, sf_type ); } else { value = CGFEName( sf_arg, sf_type ); value = CGAssign( value, XPopValue( sf_type ), sf_type ); } } if( arg_list == NULL ) { arg_list = value; } else { arg_list = CGBinary( O_COMMA, arg_list, value, TY_DEFAULT ); } } if( sf->u.ns.u1.s.typ == FT_CHAR ) { tmp = GetPtr(); value = CGUnary( O_POINTS, CGFEName( tmp, TY_CHAR ), TY_CHAR ); value = CGAssign( CGFEName( sf, TY_CHAR ), value, TY_CHAR ); if( arg_list == NULL ) { arg_list = value; } else { arg_list = CGBinary( O_COMMA, arg_list, value, TY_DEFAULT ); } value = CGFEName( tmp, TY_CHAR ); } else { sf_type = F772CGType( sf ); if( !(OZOpts & OZOPT_O_INLINE) ) { value = CGUnary( O_POINTS, CGFEName( sf, sf_type ), sf_type ); } } if( OZOpts & OZOPT_O_INLINE ) { if( arg_list != NULL ) { CGTrash( arg_list ); } curr_obj = FCodeSeek( sf->u.ns.si.sf.u.sequence ); GetObjPtr(); FCodeSequence(); FCodeSeek( curr_obj ); if( sf->u.ns.u1.s.typ == FT_CHAR ) { CGTrash( XPop() ); XPush( value ); } else if( TypeCmplx( sf->u.ns.u1.s.typ ) ) { XPopCmplx( &z, sf_type ); sf_type = CmplxBaseType( sf_type ); XPush( TmpVal( MkTmp( z.imagpart, sf_type ), sf_type ) ); XPush( TmpVal( MkTmp( z.realpart, sf_type ), sf_type ) ); } else { XPush( TmpVal( MkTmp( XPopValue( sf_type ), sf_type ), sf_type ) ); } } else { value = CGWarp( arg_list, GetLabel( sf->u.ns.si.sf.u.location ), value ); // consider: y = f( a, f( b, c, d ), e ) // make sure that inner reference to f gets evaluated before we assign // arguments for outer reference value = CGEval( value ); if( TypeCmplx( sf->u.ns.u1.s.typ ) ) { SplitCmplx( TmpPtr( MkTmp( value, sf_type ), sf_type ), sf_type ); } else { XPush( value ); } RefStmtFunc( sf ); } }
void CmplxAssign( sym_id sym, cg_type dst_typ, cg_type src_typ ) { //=========================================================================== // Do complex assignment. cg_type typ; cg_name dest; cg_name dest_1; cg_name dest_2; cg_cmplx z; uint_16 flags; temp_handle tr; temp_handle ti; flags = sym->u.ns.flags; dest = NULL; if( (flags & SY_CLASS) == SY_SUBPROGRAM ) { // assigning to statement function if( (OZOpts & OZOPT_O_INLINE) == 0 ) { dest = SymAddr( sym ); } } else { // check for structure type before checking for array // Consider: A(1).X = A(2).X // where A is an array of structures containing complex field X if( sym->u.ns.u1.s.typ == FT_STRUCTURE ) { dest = XPop(); GetU16(); // ignore structure information } else if( flags & SY_SUBSCRIPTED ) { dest = XPop(); } else { dest = SymAddr( sym ); } } typ = CmplxBaseType( dst_typ ); if( ( src_typ != TY_COMPLEX ) && ( src_typ != TY_DCOMPLEX ) && ( src_typ != TY_XCOMPLEX ) ) { z.realpart = XPopValue( src_typ ); z.imagpart = CGInteger( 0, typ ); } else { XPopCmplx( &z, src_typ ); z.imagpart = CGEval( z.imagpart ); } z.realpart = CGEval( z.realpart ); // Before assigning the real and imaginary parts, force evaluation of each. // Consider: Z = Z * Z // The above expression will be evaluated as follows. // z.r = z.r*z.r - z.i*z.i // z.i = z.r*z.i + z.r*z.i // In the expression that evaluates the imaginary part, the value of "z.r" // must be the original value and not the new value. if( ((flags & SY_CLASS) == SY_SUBPROGRAM) && (OZOpts & OZOPT_O_INLINE) ) { XPush( z.imagpart ); XPush( z.realpart ); return; } // Code to avoid the criss cross problem // i.e. z = complx(imag(z), real(z)) // or similar problems due to overwriting of one part with the other // before accessing it. // This should not affect efficiency (for optimized code) very much // because the temps will not be used when they are not required tr = CGTemp( typ ); ti = CGTemp( typ ); CGDone( CGAssign( CGTempName( tr, typ ), z.realpart, typ ) ); CGDone( CGAssign( CGTempName( ti, typ ), z.imagpart, typ ) ); CloneCGName( dest, &dest_1, &dest_2 ); XPush( CGAssign( ImagPtr( dest_2, typ ), CGUnary( O_POINTS, CGTempName( ti, typ ), typ ), typ ) ); XPush( CGAssign( dest_1, CGUnary( O_POINTS, CGTempName( tr, typ ), typ ), typ ) ); }
void FCPop( void ) { //=============== // Process POP F-Code. sym_id sym; cg_name dst; unsigned_16 typ_info; cg_type dst_typ; cg_type src_typ; sym_id fd; sym = GetPtr(); typ_info = GetU16(); dst_typ = GetType1( typ_info ); src_typ = GetType2( typ_info ); if( ( dst_typ == TY_COMPLEX ) || ( dst_typ == TY_DCOMPLEX ) || ( dst_typ == TY_XCOMPLEX ) ) { CmplxAssign( sym, dst_typ, src_typ ); } else { if( (sym->ns.flags & SY_CLASS) == SY_SUBPROGRAM ) { // it's a statement function if( !(OZOpts & OZOPT_O_INLINE) ) { dst = SymAddr( sym ); } } else { fd = NULL; if( sym->ns.typ == FT_STRUCTURE ) { if( GetU16() ) { // target is a sub-field dst = XPop(); if( dst_typ == TY_USER_DEFINED ) { // sub-field is a structure or an array element fd = GetPtr(); } } else { dst = SymAddr( sym ); } } else if( sym->ns.flags & SY_SUBSCRIPTED ) { // target is an array element dst = XPop(); } else { dst = SymAddr( sym ); } if( dst_typ == TY_USER_DEFINED ) { if( fd == NULL ) { dst_typ = sym->ns.xt.record->cg_typ; } else { dst_typ = fd->fd.xt.record->cg_typ; } XPush( CGAssign( dst, CGUnary( O_POINTS, XPop(), dst_typ ), dst_typ ) ); return; } } if( (src_typ == TY_COMPLEX) || (src_typ == TY_DCOMPLEX) || (src_typ == TY_XCOMPLEX) ) { Cmplx2Scalar(); src_typ = CmplxBaseType( src_typ ); } if( ((sym->ns.flags & SY_CLASS) == SY_SUBPROGRAM) && (OZOpts & OZOPT_O_INLINE ) ) return; XPush( CGAssign( dst, XPopValue( src_typ ), dst_typ ) ); } }