diff --git a/pub/src/edif.cpp b/pub/src/edif.cpp index a2c05c1bee3e8908070b59ded82b8b84832ec884..2011f670647b0af7428d0912e55531ffb1fbfec1 100644 --- a/pub/src/edif.cpp +++ b/pub/src/edif.cpp @@ -365,19 +365,18 @@ void NEdif::EditCoord( string which ) { NOlm::SelAssert(); - NOlm::IterateO fiter; CVariable cvar( which ); - if ( !cvar.defined() ) { - printf( "! invalid coordinate %s\n", which.c_str() ); - return; - } - CCoord new_co, old_co; + + CCoord new_co; new_co.Ask( (which+" coordinate").c_str() ); // no-overwrite mode is broken since 28aug08 + + NOlm::IterateO fiter; POlo fin; while( fin = fiter() ) { POlo fout = fin; - + + CCoord old_co; if ( cvar.typ==CVariable::_X ) { old_co = fin->xco; fout->xco = new_co; diff --git a/pub/src/expr.cpp b/pub/src/expr.cpp index 173795f6ac67b47684bedc62cb84aeded75a9381..2d6b44f78bde35bfe40aa43a26574db581851f62 100644 --- a/pub/src/expr.cpp +++ b/pub/src/expr.cpp @@ -89,9 +89,11 @@ string CContext::info() const //! Variables may be unnumbered (x,y,i,j,k,f,...) or numbered (z0,p0,...). CVariable::CVariable( string s ) - // NOTE: As long as this constructor is called by the parser and not + // WARNING TO PROGRAMMERS: + // As long as this constructor is called by the parser and not // by the lexical analyzer, string s may contain more than just the // parameter name. Everything after the parameter name must be ignored. + // In other words: the stupid .substr(0,2) are NOT superfluous. { num = 0; int isub; @@ -103,29 +105,29 @@ CVariable::CVariable( string s ) } else if ( nsub==2 && c=='p' ) { typ = _FP; // fit parameter num = isub; - } else if ( s=="z+" ) { + } else if ( s.substr(0,2)=="z+" ) { typ = _Z; // new z value num = -1; } else if ( nsub==2 && c=='z' ) { typ = _Z; // z value num = isub; - } else if ( s=="nj" ) { + } else if ( s.substr(0,2)=="nj" ) { typ = _NJ; // number of spectra in file - } else if ( s=="ni" ) { + } else if ( s.substr(0,2)=="ni" ) { typ = _NI; // number of points in spectrum - } else if ( s=="x" ) { + } else if ( c=='x' ) { typ = _X; // x value - } else if ( s=="y" ) { + } else if ( c=='y' ) { typ = _Y; // y value - } else if ( s=="dy" ) { + } else if ( s.substr(0,2)=="dy" ) { typ = _DY; // y value - } else if ( s=="f" ) { + } else if ( c=='f' ) { typ = _FC; // fit curve - } else if ( s=="k" ) { + } else if ( c=='k' ) { typ = _K; // internal file index - } else if ( s=="j" ) { + } else if ( c=='j' ) { typ = _J; // index of current spectrum - } else if ( s=="i" ) { + } else if ( c=='i' ) { typ = _I; // index of current point } else { typ = _NOREF; @@ -190,6 +192,7 @@ string CVariable::var_info() const //* (references, typically used as endpoints of CTree's) *// //***************************************************************************// +//! Constructor. CRef::CRef( string s, PTree _tk, PTree _tj, PTree _ti ) // NOTE: As long as this constructor is called by the parser and not @@ -201,72 +204,74 @@ CRef::CRef( string s, PTree _tk, PTree _tj, PTree _ti ) throw string( "BUG: invalid cross reference: index cannot be indexed" ); } + +//! Evaluate this reference in given context. Result returned in ret. + void CRef::ref_val( CTOut *ret, const CContext *ctx ) const { - // get file index k and set file reference f: + // get file index k uint k; if (tk) tk->tree_uival( &k, ctx ); else k = ctx->k; if ( k==(uint)-1 ) - throw string( "index k out of context or out of bounds" ); + throw string( "k-dependent expression out of context or " + "k out of bounds" ); if ( k>=NOlm::MOM.size()) throw string( "index k=" + strg(k) + " out of bounds" ); + // return k-dependent reference: if ( typ == _K ) { ret->set_u( k ); return; } + // proceed with file reference f[k]: POlo f = NOlm::MOM[k]; // get spectrum index j: uint j; - if ( specwise() ) { - if ( tj ) { - tj->tree_uival( &j, ctx ); - } else { - j = ctx->j; - } - if ( j>=f->nJ() ) - throw string( "index j=" + strg(j) + " out of bounds" ); - } else if ( tj ) - throw string( "index j out of context" ); - - if ( typ == _J ) { + if ( tj ) { + tj->tree_uival( &j, ctx ); + } else { + j = ctx->j; + } + if ( j==(uint)-1 ) + throw string( "j-dependent expression out of context or " + "j out of bounds" ); + if ( j>=f->nJ() ) + throw string( "index j=" + strg(j) + " out of bounds" ); + + // Return k-j-dependent reference: + if ( typ == _J ) { ret->set_u( ctx->j ); return; - } - - // check i: - if ( !pointwise() && ti ) - throw string( "index i out of context" ); - - // Reference for any file type ? - if ( typ==CRef::_NJ ) { + } else if ( typ==_NJ ) { ret->set_u( f->nJ() ); return; + } else if ( typ == _Z ) { + if ( num>= f->nZ() ) + throw ( "invalid reference " + var_info() ); + ret->set_d( f->V[j]->z[num] ); + return; } - // Reference for data or curve file ? + // References for data file POld fd = P2D( f ); - POlc fc = P2C( f ); if ( fd ) { PSpec sj = fd->VS(j); if ( typ==_I || typ == _X || typ == _Y || typ == _DY ) { if ( typ==_DY && !sj->dy.size() ) throw string( "dy not set" ); if ( ctx->dim_1() ) { - // get point index i: uint i; if ( ti ) { ti->tree_uival( &i, ctx ); } else { i = ctx->i; if ( i==(uint)-1 ) - throw string( - "ref_val: in pointwise operation missing i" ); + throw string( "missing index i" ); } if( i>= sj->size() ) throw string( "i out of range" ); @@ -283,7 +288,6 @@ void CRef::ref_val( CTOut *ret, const CContext *ctx ) const } } else if ( ctx->dim_vi() ) { ret->preset_vd( ctx->nv ); - uint i; if ( ti ) { CContext myctx = *ctx; myctx.reqDim = CContext::_1; @@ -293,6 +297,7 @@ void CRef::ref_val( CTOut *ret, const CContext *ctx ) const ret->dvd.clear(); for( uint ii=0; ii<ctx->nv; ++ii ){ myctx.i = ii; + uint i; ti->tree_uival( &i, &myctx ); if( i >= sj->size() ) throw string( "i out of range" ); @@ -327,15 +332,16 @@ void CRef::ref_val( CTOut *ret, const CContext *ctx ) const } } } - } else if ( typ == _Z ) { - if ( num>= fd->nZ() ) - throw( "invalid z ref(" + var_info() + ") in data file" ); - ret->set_d( sj->z[num] ); } else if ( typ == _NI ) { ret->set_d( sj->size() ); } else throw( "invalid ref(" + var_info() + ") in data file" ); - } else if ( fc ) { + return; + } + + // References for curve file: + POlc fc = P2C( f ); + if ( fc ) { PCurve cj = fc->VC(j); if ( typ == _FP ) { if ( num>= fc->nPar() ) @@ -345,18 +351,17 @@ void CRef::ref_val( CTOut *ret, const CContext *ctx ) const if ( num>= CCurve::mQuality ) throw( "invalid fm ref(" + var_info() + ") in curve file" ); ret->set_d( cj->Quality[num] ); - } else if ( typ == _Z ) { - if ( num>= fc->nZ() ) - throw( "invalid z ref(" + var_info() + ") in curve file" ); - ret->set_d( cj->z[num] ); } else if ( typ == _FC ) { ret->set_cr( fc, k, j ); } else throw( "invalid ref(" + var_info() + ") in curve file" ); - } else - throw string( "BUG: ref->eval unexpected else" ); + return; + } } + +//! Description of reference (for use in ??) + void CRef::coord( CCoord *ret, uint k_in ) const { if (isindex()) { @@ -391,9 +396,6 @@ void CRef::coord( CCoord *ret, uint k_in ) const POld fd = P2D( f ); POlc fc = P2C( f ); if ( fd ) { - if (!indatafile()) - throw( "coord: ref " + var_info() + - " not allowed in data file " + strg(k) ); if ( typ == _X ) *ret = fd->xco; else if ( typ == _Y ) @@ -407,11 +409,8 @@ void CRef::coord( CCoord *ret, uint k_in ) const else if ( typ == _NI ) *ret = CCoord("#points", ""); else - throw( "coord: data:ref(" + var_info() + ") nyi" ); + throw( "Reference " + var_info() + " not allowed in data file" ); } else if ( fc ) { - if (!incurvefile()) - throw( "coord: ref " + var_info() + - " not allowed in curve file " + strg(k) ); if ( typ == _FP ) *ret = fc->PCo[num]; else if ( typ == _FM ) @@ -423,7 +422,7 @@ void CRef::coord( CCoord *ret, uint k_in ) const else if ( typ == _NJ ) *ret = CCoord("#spectra", ""); else - throw( "coord: curv:ref " + var_info() + " nyi" ); + throw( "Reference " + var_info() + " not allowed in curve file" ); } else throw string( "BUG: ref->coord unexpected else" ); } @@ -818,8 +817,6 @@ void CTree::tree_val( CTOut *ret, const CContext *ctx ) const // evaluate function reference: CTOut frf; ref->ref_val( &frf, ctx ); - if( !frf.is_curveref() ) - throw string( "unexpected return type in function reference" ); // evaluate function argument: CTOut rarg; arg[0]->tree_val( &rarg, ctx ); diff --git a/pub/src/expr.h b/pub/src/expr.h index 6c9abe91ab6e4e5c515224f7ecc01d244ce2e48d..1510891d9fe2666b114fea265f0a52050482fe9d 100644 --- a/pub/src/expr.h +++ b/pub/src/expr.h @@ -63,7 +63,6 @@ class CTOut { typ = _OF; cr.fc = fc_; cr.k = k_; cr.j = j_; }; bool is_scalar() const { return typ==_OI || typ==_OD; }; bool is_vector() const { return typ==_OVD; }; - bool is_curveref() const { return typ==_OF; }; double to_d( int i ) const { return is_scalar() ? d : vd[i]; } void to_vd( vector<double> *vd_out ) const { if( is_scalar() ) { @@ -93,8 +92,6 @@ class CVariable { CVariable( TTyp _typ=_NOREF, uint _num=0 ) : typ(_typ), num(_num) {}; CVariable( const string s ); - bool defined() const { - return typ!=_NOREF; }; bool isindex() const { return typ==_K || typ==_J || typ==_I; }; bool issize() const { @@ -106,17 +103,8 @@ class CVariable { bool specwise() const { return pointwise() || typ==_Z || typ==_FP || typ==_FM || typ==_J || typ==_NI || typ==_FC; }; - bool unspecific() const { - return isindex() || issize(); }; - bool indatafile() const { - return unspecific() || typ==_X || typ==_Y || typ==_DY || typ==_Z; }; - bool incurvefile() const { - return (unspecific() && !pointwise()) - || typ==_FC || typ==_FP || typ==_FM || typ==_Z ; }; bool numbered() const { return typ==_FP || typ==_FM || typ==_Z; }; - bool assignable() const { - return defined() && !unspecific(); }; CVariable errvar() const; diff --git a/pub/src/opr.cpp b/pub/src/opr.cpp index 7cdaa5b7444160596161c25f9a0401a2d0bd2d19..614b4067ce972789051a6029a2a3af1241b6306e 100644 --- a/pub/src/opr.cpp +++ b/pub/src/opr.cpp @@ -152,8 +152,6 @@ void NOperate::Pointwise( string llabel ) NOlm::SelAssert(); CVariable lref(llabel); - if ( !lref.defined() ) - throw "invalid left-hand side " + llabel; string expr = sask("Function ?"); if (expr=="") return;