From 637b3c1ebb0da67e65a73b6a450bee77ea0e885a Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de>
Date: Sun, 18 Oct 2015 19:39:21 +0200
Subject: [PATCH] repair coord

---
 pub/lib/edif.cpp     |  12 +--
 pub/lib/expr.hpp     |   2 +-
 pub/lib/file_in.cpp  |   1 -
 pub/lib/func.cpp     |  64 ++++++-------
 pub/lib/func.hpp     |   8 +-
 pub/lib/node.cpp     | 207 +++++++++++++++++++------------------------
 pub/lib/node.hpp     |  49 +++++-----
 pub/lib/olf.cpp      | 112 +++++++++++------------
 pub/lib/olf.hpp      |  13 +--
 pub/lib/opr.cpp      |   5 +-
 pub/lib/slice.cpp    |   1 -
 pub/lib/xax_lex.lpp  |   1 -
 pub/lib/xax_yacc.ypp |   1 -
 13 files changed, 227 insertions(+), 249 deletions(-)

diff --git a/pub/lib/edif.cpp b/pub/lib/edif.cpp
index 76047313..dff8dfb3 100644
--- a/pub/lib/edif.cpp
+++ b/pub/lib/edif.cpp
@@ -212,12 +212,12 @@ void NEdif::edit_coord( string which )
     NOlm::IterateO fiter;
     // check whether all files have the same coordinate:
     POlo fin = fiter();
-    CCoord old_co = fin->coord( &var );
+    CCoord old_co = fin->coord( var );
     bool uniform = true;
     bool multifile = false;
     while ( fin = fiter() ) {
         multifile = true;
-        if ( fin->coord( &var )!=old_co ) {
+        if ( fin->coord( var )!=old_co ) {
             uniform = false;
             break;
         }
@@ -227,7 +227,7 @@ void NEdif::edit_coord( string which )
     if ( multifile && !uniform ) {
         fiter.reset();
         while ( fin = fiter() ) {
-            cout << "  file " << fiter.k() << ": " << fin->coord( &var ) <<"\n";
+            cout << "  file " << fiter.k() << ": " << fin->coord( var ) <<"\n";
         }
     }
     string in = sask( "Coordinate "+which+": name(unit)" +
@@ -236,20 +236,20 @@ void NEdif::edit_coord( string which )
     fiter.reset();
     if ( multifile && in=="f" ) {
         while ( fin = fiter() ) {
-            old_co = fin->coord( &var );
+            old_co = fin->coord( var );
             in = sask( "Coordinate "+which+" for file "+S(fiter.k())+": name(unit)",
                        old_co.str_compact() );
             CCoord new_co(in);
             fin->lDoc.push_back( "ec"+string(which)+" "+new_co.str_compact()+
                                  " # old: " + old_co.str_compact() );
-            fin->set_coord( &var, new_co );
+            fin->set_coord( var, new_co );
         }
     } else {
         CCoord new_co(in);
         while ( fin = fiter() ) {
             fin->lDoc.push_back( "ec"+string(which)+" "+new_co.str_compact()+
                                  " # old: " + old_co.str_compact() );
-            fin->set_coord( &var, new_co );
+            fin->set_coord( var, new_co );
         }
     }
 }
diff --git a/pub/lib/expr.hpp b/pub/lib/expr.hpp
index a9e7c40b..86a4fb76 100644
--- a/pub/lib/expr.hpp
+++ b/pub/lib/expr.hpp
@@ -91,7 +91,7 @@ class CNode {
     //! API for tree evaluation: compute an array.
     void tree_vec_val( vector<double> *ret, vector<double> *dret, int k=-1, int j=-1 ) const;
 
-    virtual void set_coord( CCoord& ret, int k=-1 ) const =0;
+    virtual CCoord node_coord( int k=-1 ) const =0;
     virtual string tree_info() const =0;  //!< introspection, for debugging
 
     static RObj eval( string expr );
diff --git a/pub/lib/file_in.cpp b/pub/lib/file_in.cpp
index 2216fb65..d760a59c 100644
--- a/pub/lib/file_in.cpp
+++ b/pub/lib/file_in.cpp
@@ -22,7 +22,6 @@
 
 #include "olf.hpp"
 #include "mem.hpp"
-#include "var.hpp"
 #include "slice.hpp"
 #include "obj.hpp"
 #include "expr.hpp"
diff --git a/pub/lib/func.cpp b/pub/lib/func.cpp
index add46d9a..eb098577 100644
--- a/pub/lib/func.cpp
+++ b/pub/lib/func.cpp
@@ -61,64 +61,64 @@ const CTypedFunc* CFunc::find_tyfu( string intypes, bool want_error ) const
 
 //! Return default coordinate of function of one argument.
 
-CCoord CFunc::coord( CCoord *co1 ) const
+CCoord CFunc::coord( const CCoord& co1 ) const
 {
-    CCoord co = *co1;
+    CCoord co = co1;
     if        (tag=="0-") {
-        co.name = "-" + co1->name;
+        co.name = "-" + co1.name;
     } else if (tag=="ln") {
-        co.name = "ln " + co1->name;
+        co.name = "ln " + co1.name;
     } else if (tag=="lg") {
-        co.name = "lg " + co1->name;
+        co.name = "lg " + co1.name;
     } else if (tag=="sqrt") {
-        co.name = "sqrt (" + co1->name + ")";
-        co.unit = co1->unit=="" ? "" : "(" + co1->unit + ")^1/2";
+        co.name = "sqrt (" + co1.name + ")";
+        co.unit = co1.unit=="" ? "" : "(" + co1.unit + ")^1/2";
     } else {
-        co.name = tag + "(" + co1->name + ")";
+        co.name = tag + "(" + co1.name + ")";
     }
     return co;
 }
 
 //! Return default coordinate of function of two arguments.
 
-CCoord CFunc::coord( class CCoord *co1, class CCoord *co2 ) const
+CCoord CFunc::coord( const CCoord& co1, const CCoord& co2 ) const
 {
-    CCoord co = *co1;
+    CCoord co = co1;
 
     if ( tag=="+" || tag=="-" ) {
-        if( co1->name==co2->name ){
-            if( co1->unit!=co2->unit )
+        if( co1.name==co2.name ){
+            if( co1.unit!=co2.unit )
                 throw S("same coordinate name and different units in additive operation");
-            co = *co1;
+            co = co1;
         } else {
-            co.name = co1->name + tag + co2->name;
-            if ( co1->unit=="" )
+            co.name = co1.name + tag + co2.name;
+            if ( co1.unit=="" )
                 co.unit = "";
-            else if ( co2->unit!="" && co2->unit!=co1->unit) {
-                cout << "? different units " << co1->unit << " and " <<
-                    co2->unit << " in additive operation\n";
+            else if ( co2.unit!="" && co2.unit!=co1.unit) {
+                cout << "? different units " << co1.unit << " and " <<
+                    co2.unit << " in additive operation\n";
                 co.unit = "";
             } else
-                co.unit = co1->unit;
+                co.unit = co1.unit;
         }
     } else if ( tag=="*" || tag=="/" ) {
-        co.name = co1->name + tag + co2->name;
-        if     ( co1->unit!="" && co2->unit!="" )
-            co.unit = co1->unit + tag + co2->unit;
-        else if( co1->unit!="" )
-            co.unit = co1->unit;
-        else if( co2->unit!="" )
-            co.unit = tag=="*" ? co2->unit : "1/(" + co2->unit + ")";
+        co.name = co1.name + tag + co2.name;
+        if     ( co1.unit!="" && co2.unit!="" )
+            co.unit = co1.unit + tag + co2.unit;
+        else if( co1.unit!="" )
+            co.unit = co1.unit;
+        else if( co2.unit!="" )
+            co.unit = tag=="*" ? co2.unit : "1/(" + co2.unit + ")";
         else
             co.unit = "";
     } else if ( tag=="^" ) {
-        if (co2->unit != "") {
+        if (co2.unit != "") {
             cout << "? exponent is not dimensionless\n";
         }
-        co.name = co1->name + "^" + co2->name;
-        co.unit = co1->unit=="" ? "" : ( co1->unit + "^<val>" );
+        co.name = co1.name + "^" + co2.name;
+        co.unit = co1.unit=="" ? "" : ( co1.unit + "^<val>" );
     } else {
-        co.name = tag + "(" + co1->name + "," + co2->name + ")";
+        co.name = tag + "(" + co1.name + "," + co2.name + ")";
         co.unit = "";
     }
     return co;
@@ -126,11 +126,11 @@ CCoord CFunc::coord( class CCoord *co1, class CCoord *co2 ) const
 
 //! Return default coordinate of function of three arguments.
 
-CCoord CFunc::coord( class CCoord *co1, class CCoord *co2, class CCoord *co3 )
+CCoord CFunc::coord( const CCoord& co1, const CCoord& co2, const CCoord& co3 )
     const
 {
     CCoord co;
-    co.name = tag + "(" + co1->name + "," + co2->name + "," + co3->name + ")";
+    co.name = tag + "(" + co1.name + "," + co2.name + "," + co3.name + ")";
     co.unit = "";
     return co;
 }
diff --git a/pub/lib/func.hpp b/pub/lib/func.hpp
index a3ebd228..6c54d292 100644
--- a/pub/lib/func.hpp
+++ b/pub/lib/func.hpp
@@ -11,6 +11,8 @@
 
 typedef void   (*funcPtr)(void); // generic pointer-to-function type
 
+class CCoord;
+
 class CTypedFunc {
  public:
     const string outtype;
@@ -33,7 +35,7 @@ class CFunc {
         : tag(_tag), narg(_narg), explanation(_explanation), precedence(_precedence) {};
     const CTypedFunc* find_exact_tyfu( string intypes ) const;
     const CTypedFunc* find_tyfu( string intypes, bool want_error ) const;
-    class CCoord coord( class CCoord *co ) const;
-    class CCoord coord( class CCoord *co1, class CCoord *co2 ) const;
-    class CCoord coord( class CCoord *co1, class CCoord *co2, class CCoord *co3 ) const;
+    class CCoord coord( const CCoord& co ) const;
+    class CCoord coord( const CCoord& co1, const CCoord& co2 ) const;
+    class CCoord coord( const CCoord& co1, const CCoord& co2, const CCoord& co3 ) const;
 };
diff --git a/pub/lib/node.cpp b/pub/lib/node.cpp
index 6c74dfdd..8a7a4c3a 100644
--- a/pub/lib/node.cpp
+++ b/pub/lib/node.cpp
@@ -19,7 +19,6 @@
 #include "fregistry.hpp"
 #include "geni.hpp"
 #include "integrate.hpp"
-#include "var.hpp"
 #include "obj.hpp"
 #include "expr.hpp"
 #include "node.hpp"
@@ -282,23 +281,17 @@ RObj CNodeFun::tree_val( const CContext& ctx ) const
 }
 
 
-void CNodeFun1::set_coord( CCoord& ret, int k ) const {
-    CCoord r;
-    arg[0]->set_coord( r, k );
-    ret = fu->coord( &r );
+CCoord CNodeFun1::node_coord( int k ) const
+{
+    return fu->coord( arg[0]->node_coord( k ) );
 }
-void CNodeFun2::set_coord( CCoord& ret, int k ) const {
-    CCoord r[2];
-    arg[0]->set_coord( r[0], k );
-    arg[1]->set_coord( r[1], k );
-    ret = fu->coord( r+0, r+1 );
+CCoord CNodeFun2::node_coord( int k ) const
+{
+    return fu->coord( arg[0]->node_coord( k ), arg[1]->node_coord( k ) );
 }
-void CNodeFun3::set_coord( CCoord& ret, int k ) const {
-    CCoord r[3];
-    arg[0]->set_coord( r[0], k );
-    arg[1]->set_coord( r[1], k );
-    arg[2]->set_coord( r[2], k );
-    ret = fu->coord( r+0, r+1, r+2 );
+CCoord CNodeFun3::node_coord( int k ) const
+{
+    return fu->coord( arg[0]->node_coord( k ), arg[1]->node_coord( k ), arg[2]->node_coord( k ) );
 }
 
 //! Returns string representation of this node.
@@ -370,12 +363,8 @@ RObj CNodeRange::tree_val( const CContext& ctx ) const
     }
 }
 
-void CNodeRange::set_coord( CCoord& ret, int k ) const {
-    CCoord r[3];
-    arg[0]->set_coord( r[0], k );
-    arg[1]->set_coord( r[1], k );
-    arg[2]->set_coord( r[2], k );
-    ret.name = "range";
+CCoord CNodeRange::node_coord( int k ) const {
+    return CCoord("range", "");
 }
 
 //! Returns string representation of this node.
@@ -469,12 +458,8 @@ RObj CNodeList::tree_val( const CContext& ctx ) const
     }
 }
 
-void CNodeList::set_coord( CCoord& ret, int k ) const {
-    CCoord r[3];
-    arg[0]->set_coord( r[0], k );
-    arg[1]->set_coord( r[1], k );
-    arg[2]->set_coord( r[2], k );
-    ret.name = "list";
+CCoord CNodeList::node_coord( int k ) const {
+    return CCoord( "list", "" );
 }
 
 //! Returns string representation of this node.
@@ -558,12 +543,11 @@ RObj CNodeGeni::tree_val( const CContext& ctx ) const
     }
 }
 
-void CNodeGeni::set_coord( CCoord& ret, int k ) const {
+CCoord CNodeGeni::node_coord( int k ) const {
     string rnam = geni->name+"(";
     vector<string> argunit;
     for ( int iarg=0; iarg<narg; ++iarg ){
-        CCoord carg;
-        arg[iarg]->set_coord( carg, k );
+        CCoord carg = arg[iarg]->node_coord( k );
         argunit.push_back( carg.unit );
         rnam += carg.name;
         rnam += iarg==narg-1 ? ")" : ",";
@@ -585,8 +569,7 @@ void CNodeGeni::set_coord( CCoord& ret, int k ) const {
     } else {
         throw  "BUG: unforeseen unit hint '" + geni->unit_hint + "'";
     }
-
-    ret = CCoord( rnam, runit );
+    return CCoord( rnam, runit );
 }
 
 
@@ -649,7 +632,7 @@ RObj CNodeCvin::tree_val( const CContext& ctx ) const
     }
 }
 
-void CNodeCvin::set_coord( CCoord& ret, int k ) const {
+CCoord CNodeCvin::node_coord( int k ) const {
 //*
 //*     CCoord r[maxarg];
 //*     for ( int iarg=0; iarg<narg; ++iarg )
@@ -660,6 +643,7 @@ void CNodeCvin::set_coord( CCoord& ret, int k ) const {
 //*         ret = fu->coord( r+0, r+1 );
 //*     else if ( const CFunc3* fu = dynamic_cast<const CFunc3*>( fun ) )
 //*         ret = fu->coord( r+0, r+1, r+2 );
+    return CCoord( "TODO:CvinCoord", "" );
 }
 
 //! Returns string representation of this node.
@@ -691,9 +675,9 @@ RObj CNodeVal::tree_val( const CContext& ctx ) const
     return val;
 }
 
-void CNodeVal::set_coord( CCoord& ret, int k ) const
+CCoord CNodeVal::node_coord( int k ) const
 {
-    ret = CCoord(val->to_s(), "");
+    return CCoord(val->to_s(), "");
 }
 
 string CNodeVal::tree_info() const
@@ -765,18 +749,40 @@ RObj CNodeFile::tree_val( const CContext& ctx ) const
     }
 }
 
+CCoord CNodeFile::node_coord( int _k ) const
+{
+    try {
+        int k;
+        if (ref->tk) {
+            CContext ctx( _k, 0, 0 ); // cross fingers that the i=0 result also works for other i
+            k = ref->tk->tree_val_idx( ctx, "k" );
+        } else {
+            k = _k;
+        }
+        ROlo f = NOlm::mem_get(k);
+        return file_coord( f );
+    } catch( string& ex ) {
+        throw "BUG: cannot construct coordinate of "+name()+" {"+ref->ref_info()+"}:\n  "+ex;
+    }
+}
+
 RObj CNodeFileNJ::tree_val_scalar( const CContext& ctx ) const
 {
-    POlo f = NOlm::mem_get( ref->get_k( ctx ) );
+    ROlo f = NOlm::mem_get( ref->get_k( ctx ) );
     return RObjInt( new CObjInt( f->nJ() ) );
 }
     
 RObj CNodeFileR::tree_val_scalar( const CContext& ctx ) const
 {
-    POlo f = NOlm::mem_get( ref->get_k( ctx ) );
+    ROlo f = NOlm::mem_get( ref->get_k( ctx ) );
     return RObjDbl( new CObjDbl( f->RPar[num].val ) );
 }
     
+CCoord CNodeFileR::file_coord( ROlo f ) const
+{
+    return f->RPar[num].Co;
+}
+
 
 //**************************************************************************************************
 //* CNodeSlice/Spec/Curve: slice-wide information
@@ -785,23 +791,33 @@ RObj CNodeFileR::tree_val_scalar( const CContext& ctx ) const
 
 RObj CNodeSliceZ::tree_val_scalar( const CContext& ctx ) const
 {
-    POlo f = NOlm::mem_get( ref->get_k( ctx ) );
+    ROlo f = NOlm::mem_get( ref->get_k( ctx ) );
     int j = PCAST<const CRef2>(ref)->get_j( ctx, f->nJ() );
-    return f->V[j]->z[num];
+    RSlice s = f->V[j];
+    if ( num<0 || num>=s->z.size() )
+        throw "z"+S(num)+" requested, while only "+S(s->z.size())+" z entries are defined";
+    return s->z[num];
 }
     
+CCoord CNodeSliceZ::file_coord( ROlo f ) const
+{
+    if ( num<0 || num>=f->ZCo.size() )
+        throw "z"+S(num)+" requested, while only "+S(f->ZCo.size())+" z coordinates are defined";
+    return f->ZCo[num];
+}
+
 RObj CNodeSpecNI::tree_val_scalar( const CContext& ctx ) const
 {
-    POlo f = NOlm::mem_get( ref->get_k( ctx ) );
-    POld fd = P2D( f );
+    ROlo f = NOlm::mem_get( ref->get_k( ctx ) );
+    ROld fd = R2D( f );
     int j = PCAST<const CRef2>(ref)->get_j( ctx, f->nJ() );
     return RObjInt( new CObjInt( fd->VS(j)->size() ) );
 }
     
 RObj CNodeCurve::tree_val_scalar( const CContext& ctx ) const
 {
-    POlo f = NOlm::mem_get( ref->get_k( ctx ) );
-    POlc fc = P2C( f );
+    ROlo f = NOlm::mem_get( ref->get_k( ctx ) );
+    ROlc fc = R2C( f );
     int j = PCAST<const CRef2>(ref)->get_j( ctx, f->nJ() );
     return curve_val_scalar( fc->VC(j) );
 }
@@ -812,6 +828,15 @@ RObj CNodeCurveP::curve_val_scalar( RCurve c ) const
     return RObjDbl( new CObjDbl( c->P[num] ) );
 }
 
+CCoord CNodeCurveP::file_coord( ROlo f ) const
+{
+    ROlc fc = R2C(f);
+    if ( num<0 || num>=fc->PCo.size() )
+        throw "p"+S(num)+" requested, while only "+S(fc->PCo.size())+" z coordinates are defined";
+    return fc->PCo[num];
+}
+
+
 RObj CNodeCurveOutcome::curve_val_scalar( RCurve c ) const
 {
     return RObjInt( new CObjInt( c->fitOutcome ) );
@@ -854,8 +879,8 @@ RObj CNodePoint::tree_val( const CContext& ctx ) const
 
 RObj CNodePoint::tree_val_point( const CContext& ctx, int i ) const
 {
-    POlo f = NOlm::mem_get( ref->get_k( ctx ) );
-    POld fd = P2D( f );
+    ROlo f = NOlm::mem_get( ref->get_k( ctx ) );
+    ROld fd = R2D( f );
     int j = PCAST<const CRef2>(ref)->get_j( ctx, f->nJ() );
     RSpec s = fd->VS(j);
     if ( i<0 || i>= s->size() )
@@ -868,8 +893,8 @@ RObj CNodePoint::tree_val_vector( const CContext& ctx ) const
 {
     if ( ctx.dim!=CContext::_VI )
         throw S("BUG: unexpected context in tree_val_vector");
-    POlo f = NOlm::mem_get( ref->get_k( ctx ) );
-    POld fd = P2D( f );
+    ROlo f = NOlm::mem_get( ref->get_k( ctx ) );
+    ROld fd = R2D( f );
     int j = PCAST<const CRef2>(ref)->get_j( ctx, f->nJ() );
     RSpec s = fd->VS(j);
     int n = ctx.nv;
@@ -891,6 +916,11 @@ RObj CNodePointX::spec_val_vector( RSpec s, int n, bool want_error ) const
     return RObjVecDbl( new CObjVecDbl( vector<double>(s->x.begin(), s->x.begin()+n ) ) );
 }
 
+CCoord CNodePointX::file_coord( ROlo f ) const
+{
+    return R2D(f)->xco;
+}
+
 
 RObj CNodePointY::spec_val_point( RSpec s, int i, bool want_error ) const
 {
@@ -907,6 +937,11 @@ RObj CNodePointY::spec_val_vector( RSpec s, int n, bool want_error ) const
         RObjVecDbl( new CObjVecDbl( vector<double>(s->y.begin(), s->y.begin()+n ) ) );
 }
 
+CCoord CNodePointY::file_coord( ROlo f ) const
+{
+    return R2D(f)->yco;
+}
+
 
 RObj CNodePointDY::spec_val_point( RSpec s, int i, bool want_error ) const
 {
@@ -920,71 +955,11 @@ RObj CNodePointDY::spec_val_vector( RSpec s, int n, bool want_error ) const
     return RObjVecDbl( new CObjVecDbl( vector<double>(s->dy.begin(), s->dy.begin()+n ) ) );
 }
 
-/*
-void CNodeIva::set_coord( CCoord& ret, int k_in ) const
+CCoord CNodePointDY::file_coord( ROlo f ) const
 {
-    int k;
-    if (PCAST<const CRef2>(ref)->tk) {
-        // get k from reference :
-        CContext ctx( k_in );
-        k = PCAST<const CRef2>(ref)->tk->tree_val_idx( ctx, "K" );
-    } else {
-        k = k_in;
-    }
-    POlo f = NOlm::mem_get(k);
-
-    if  ( var->categ == VCateg::Z ) {
-        if (var->num>=f->ZCo.size())
-            throw "set_coord: z" + S(var->num) + " undefined";
-        ret = f->ZCo[var->num];
-    } else if  ( var->categ == VCateg::R ) {
-        if (var->num>=f->RPar.size())
-            throw "set_coord: r" + S(var->num) + " undefined";
-        ret = f->RPar[var->num].Co;
-    } else if ( var->categ == VCateg::NJ ) {
-        ret = CCoord("#spectra", "");
-    } else {
-        POld fd = P2D( f );
-        POlc fc = P2C( f );
-        if         ( fd ) {
-            if       ( var->categ == VCateg::X )
-                ret = fd->xco;
-            else if  ( var->categ == VCateg::Y )
-                ret = fd->yco;
-            else if  ( var->categ == VCateg::DY )
-                ret = CCoord( "d"+fd->yco.name, fd->yco.unit );
-            else if  ( var->categ == VCateg::NI )
-                ret = CCoord("#points", "");
-            else
-                throw "data file has no " + var->var_info();
-        } else if ( fc ) {
-            if     ( var->categ == VCateg::CP ) {
-                if( var->num>=fc->nP )
-                    throw "invalid reference p" + S(var->num);
-                ret = fc->PCo[var->num];
-            }
-            else if ( var->categ == VCateg::COUTCOME )
-                ret = CCoord("fit_outcome", "");
-            else if ( var->categ == VCateg::CCHI2 )
-                ret = CCoord("chi2", "");
-            else if ( var->categ == VCateg::CR2 )
-                ret = CCoord("R2", "");
-            else if ( var->categ == VCateg::C )
-                ret = CCoord(fc->expr,"");
-            else
-                throw "curve file has no " + var->var_info();
-        } else
-            throw S("BUG: PCAST<const CRef2>(ref)->set_coord unexpected else");
-    }
+    return CCoord( "d"+R2D(f)->yco.name, R2D(f)->yco.unit );
 }
 
-//! Returns string representation of this node.
-
-string CNodeIva::tree_info() const
-{
-    return "ref[" + var->var_info() + "]";
-}
-*/
 
 //**************************************************************************************************
 //* CNodeIdf: identifier node
@@ -1001,9 +976,9 @@ RObj CNodeIdf::tree_val( const CContext& ctx ) const
     return ret;
 }
 
-void CNodeIdf::set_coord( CCoord& ret, int k ) const
+CCoord CNodeIdf::node_coord( int k ) const
 {
-    ret = CCoord( idf, "" );  // primitiver gehts nicht
+    return CCoord( idf, "" );  // primitiver gehts nicht
 }
 
 
@@ -1049,8 +1024,8 @@ RObj CNodeCev::tree_val( const CContext& ctx ) const
     }
 }
 
-void CNodeCev::set_coord( CCoord& ret, int k ) const {
-    ret = CCoord( "c", "" ); } // primitiver gehts nicht
+CCoord CNodeCev::node_coord( int k ) const {
+    return CCoord( "c", "" ); } // primitiver gehts nicht
 
 
 //**************************************************************************************************
@@ -1341,7 +1316,7 @@ RObjVecDbl CNodeDirac::convolve( const CContext& ctx, double theshift, const PSp
     return ret;
 }
 
-void CNodeDirac::set_coord( CCoord& ret, int k ) const
+CCoord CNodeDirac::node_coord( int k ) const
 {
-    ret = CCoord("resol", "");
+    return CCoord("resol", "");
 }
diff --git a/pub/lib/node.hpp b/pub/lib/node.hpp
index be2b0ebb..0b38cad7 100644
--- a/pub/lib/node.hpp
+++ b/pub/lib/node.hpp
@@ -9,8 +9,6 @@
 
 //! Base class CNode is declared elsewhere (expr.hpp).
 
-typedef std::shared_ptr<class CVar> PVar;
-
 
 //! Node with a few arguments. Pure virtual base class.
 
@@ -37,7 +35,7 @@ class CNodeFun: public CNodeWithArgs {
  public:
     CNodeFun( int _narg, const class CFunc* _fu ) : CNodeWithArgs(_narg), fu(_fu) {};
     RObj tree_val( const CContext& ctx ) const;
-    virtual void set_coord( CCoord& ret, int k ) const =0;
+    virtual CCoord node_coord( int k ) const =0;
     virtual string tree_info() const =0;
 };
 
@@ -47,7 +45,7 @@ class CNodeFun: public CNodeWithArgs {
 class CNodeFun1: public CNodeFun {
  public:
     CNodeFun1( const class CFunc *_fu, RNode a0 );
-    void set_coord( CCoord& ret, int k ) const;
+    CCoord node_coord( int k ) const;
     string tree_info() const;
 };
 
@@ -57,7 +55,7 @@ class CNodeFun1: public CNodeFun {
 class CNodeFun2: public CNodeFun {
  public:
     CNodeFun2( const class CFunc *_fu, RNode a0, RNode a1 );
-    void set_coord( CCoord& ret, int k ) const;
+    CCoord node_coord( int k ) const;
     string tree_info() const;
 };
 
@@ -67,7 +65,7 @@ class CNodeFun2: public CNodeFun {
 class CNodeFun3: public CNodeFun {
  public:
     CNodeFun3( const class CFunc *_fu, RNode a0, RNode a1, RNode a2 );
-    void set_coord( CCoord& ret, int k ) const;
+    CCoord node_coord( int k ) const;
     string tree_info() const;
 };
 
@@ -82,7 +80,7 @@ class CNodeRange: public CNodeWithArgs {
         : CNodeWithArgs(3), inclusive_end(_inclusive_end)
         { arg[0] = _beg; arg[1] = _end; arg[2] = _step; };
     RObj tree_val( const CContext& ctx ) const;
-    void set_coord( CCoord& ret, int k ) const;
+    CCoord node_coord( int k ) const;
     string tree_info() const;
     bool looks_like_indices() const { return !arg[0] || arg[0]->looks_like_indices(); }
 };
@@ -95,7 +93,7 @@ class CNodeList: public CNodeWithArgs {
     CNodeList( RNode _list, RNode _incr );
     vector<RNode> args() const { return arg; };
     RObj tree_val( const CContext& ctx ) const;
-    void set_coord( CCoord& ret, int k ) const;
+    CCoord node_coord( int k ) const;
     string tree_info() const;
     bool looks_like_indices() const { return arg[0] && arg[0]->looks_like_indices(); }
 };
@@ -112,7 +110,7 @@ class CNodeGeni: public CNodeWithArgs {
     CNodeGeni( const class CGeni *_geni, RNode a0, RNode a1 );
     bool k_dependent() const { return true; }
     RObj tree_val( const CContext& ctx ) const;
-    void set_coord( CCoord& ret, int k ) const;
+    CCoord node_coord( int k ) const;
     string tree_info() const;
 };
 
@@ -127,7 +125,7 @@ class CNodeCvin: public CNodeWithArgs {
     CNodeCvin( const class CCvin *_cvin, RRef _ref, RNode a0, RNode a1 );
     bool k_dependent() const { return true; }
     RObj tree_val( const CContext& ctx ) const;
-    void set_coord( CCoord& ret, int k ) const;
+    CCoord node_coord( int k ) const;
     string tree_info() const;
 };
 
@@ -142,7 +140,7 @@ class CNodeVal: public CNode {
     CNodeVal( double _val );
     CNodeVal( int _val );
     RObj tree_val( const CContext& ctx ) const;
-    void set_coord( CCoord& ret, int k ) const;
+    CCoord node_coord( int k ) const;
     string tree_info() const;
     bool looks_like_indices() const;
 };
@@ -161,7 +159,7 @@ class CNodeIdx: public CNode {
 class CNodeIdxI: public CNodeIdx {
  public:
     RObj tree_val( const CContext& ctx ) const;
-    void set_coord( CCoord& ret, int k ) const { ret = CCoord("i", ""); }
+    CCoord node_coord( int k ) const { return CCoord("i", ""); }
     string tree_info() const { return "i {index}"; }
     bool i_dependent() const { return true; }
 };
@@ -172,7 +170,7 @@ class CNodeIdxI: public CNodeIdx {
 class CNodeIdxJ: public CNodeIdx {
  public:
     RObj tree_val( const CContext& ctx ) const;
-    void set_coord( CCoord& ret, int k ) const { ret = CCoord("j", ""); }
+    CCoord node_coord( int k ) const { return CCoord("j", ""); }
     string tree_info() const { return "j {index}"; }
 };
 
@@ -182,7 +180,7 @@ class CNodeIdxJ: public CNodeIdx {
 class CNodeIdxK: public CNodeIdx {
  public:
     RObj tree_val( const CContext& ctx ) const;
-    void set_coord( CCoord& ret, int k ) const { ret = CCoord("k", ""); }
+    CCoord node_coord( int k ) const { return CCoord("k", ""); }
     string tree_info() const { return "k {index}"; }
 };
 
@@ -192,7 +190,7 @@ class CNodeIdxK: public CNodeIdx {
 class CNodeSessionNK: public CNode {
  public:
     RObj tree_val( const CContext& ctx ) const;
-    void set_coord( CCoord& ret, int k ) const { ret = CCoord("nk", ""); }
+    CCoord node_coord( int k ) const { return CCoord("nk", ""); }
     string tree_info() const { return "nk {number of online files}"; }
 };
 
@@ -203,6 +201,7 @@ class CNodeFile: public CNode {
  private:
     virtual RObj tree_val_scalar( const CContext& ctx ) const {
         throw S("BUG: unforeseen call to CNodeFile::tree_val_scalar"); }
+    virtual CCoord file_coord( ROlo f ) const { return CCoord(name(), ""); }
  protected:
     RRef ref;
  public:
@@ -210,7 +209,7 @@ class CNodeFile: public CNode {
     bool k_dependent() const { return true; }
     RObj tree_val( const CContext& ctx ) const;
     string tree_info() const { return name() + "[" + ref->ref_info() + "]"; }
-    void set_coord( CCoord& ret, int k ) const { ret = CCoord(name(), ""); }
+    CCoord node_coord( int k ) const;
     virtual string name() const = 0;
 };
 
@@ -232,6 +231,7 @@ class CNodeFileR: public CNodeFile {
     int num;
  public:
     CNodeFileR( int _num, RRef _ref ) : CNodeFile( _ref), num(_num) {}
+    CCoord file_coord( ROlo f ) const;
     string name() const { return "r" + S(num); }
     RObj tree_val_scalar( const CContext& ctx ) const;
 };
@@ -252,6 +252,7 @@ class CNodeSliceZ: public CNodeSlice {
     int num;
  public:
     CNodeSliceZ( int _num, RRef _ref ) : CNodeSlice( _ref), num(_num) {}
+    CCoord file_coord( ROlo f ) const;
     string name() const { return "z" + S(num); }
     RObj tree_val_scalar( const CContext& ctx ) const;
 };
@@ -284,6 +285,7 @@ class CNodeCurveP: public CNodeCurve {
     int num;
  public:
     CNodeCurveP( int _num, RRef _ref ) : CNodeCurve( _ref), num(_num) {}
+    CCoord file_coord( ROlo f ) const;
     string name() const { return "p" + S(num); }
     RObj curve_val_scalar( RCurve c ) const;
     int npar() const { return num+1; }
@@ -340,6 +342,7 @@ class CNodePoint: public CNodeSlice {
 class CNodePointX: public CNodePoint {
  public:
     CNodePointX( RRef _ref ) : CNodePoint( _ref ) {}
+    CCoord file_coord( ROlo f ) const;
     string name() const { return "x"; }
     RObj spec_val_point( RSpec s, int i, bool want_error ) const;
     RObj spec_val_vector( RSpec s, int n, bool want_error ) const;
@@ -351,6 +354,7 @@ class CNodePointX: public CNodePoint {
 class CNodePointY: public CNodePoint {
  public:
     CNodePointY( RRef _ref ) : CNodePoint( _ref ) {}
+    CCoord file_coord( ROlo f ) const;
     string name() const { return "y"; }
     RObj spec_val_point( RSpec s, int i, bool want_error ) const;
     RObj spec_val_vector( RSpec s, int n, bool want_error ) const;
@@ -362,6 +366,7 @@ class CNodePointY: public CNodePoint {
 class CNodePointDY: public CNodePoint {
  public:
     CNodePointDY( RRef _ref ) : CNodePoint( _ref ) {}
+    CCoord file_coord( ROlo f ) const;
     string name() const { return "dy"; }
     RObj spec_val_point( RSpec s, int i, bool want_error ) const;
     RObj spec_val_vector( RSpec s, int n, bool want_error ) const;
@@ -376,7 +381,7 @@ class CNodeIdf: public CNode {
  public:
     CNodeIdf( string _s );
     RObj tree_val( const CContext& ctx ) const;
-    void set_coord( CCoord& ret, int k ) const;
+    CCoord node_coord( int k ) const;
     string tree_info() const { return "$"; }
 };
 
@@ -388,8 +393,8 @@ class CNodeDummy: public CNode {
     CNodeDummy() {}
     RObj tree_val( const CContext& ctx ) const;
     bool has_dummy() const { return true; } // this node _is_ t, so it has t
-    void set_coord( CCoord& ret, int k ) const {
-        throw "BUG: CNodeDummy::set_coord not expected to be needed"; }
+    CCoord node_coord( int k ) const {
+        throw "BUG: CNodeDummy::node_coord not expected to be needed"; }
     string tree_info() const { return "farg"; }
 };
 
@@ -406,7 +411,7 @@ class CNodeCev: public CNode {
     bool has_dummy() const { return arg->has_dummy(); }
     bool has_conv() const { return arg->has_conv(); }
     RObj tree_val( const CContext& ctx ) const;
-    void set_coord( CCoord& ret, int k ) const;
+    CCoord node_coord( int k ) const;
     string tree_info() const { return "c[" + ref->ref_info() + "]"; }
 };
 
@@ -440,7 +445,7 @@ class CNodeConvBase: public CNodeMixin {
     bool k_dependent() const { return theory->k_dependent() || shift->k_dependent(); }
     bool i_dependent() const { return theory->i_dependent() || shift->i_dependent(); }
     bool has_dummy() const { return theory->has_dummy(); }
-    void set_coord( CCoord& ret, int k ) const { theory->set_coord( ret, k ); }
+    CCoord node_coord( int k ) const { return theory->node_coord( k ); }
 };
 
 
@@ -482,6 +487,6 @@ class CNodeDirac: public CNodeMixin {
     RObjVecDbl convolve( const CContext& ctx, double theshift, const PSpec& sv,
                          double conv_norm, double conv_step ) const;
     bool has_dummy() const { return true; } // has implicit t dependence
-    void set_coord( CCoord& ret, int k ) const;
+    CCoord node_coord( int k ) const;
     string tree_info() const { return "resol(" + shift->tree_info() + ")"; }
 };
diff --git a/pub/lib/olf.cpp b/pub/lib/olf.cpp
index 9d3c0cd1..be1ff345 100644
--- a/pub/lib/olf.cpp
+++ b/pub/lib/olf.cpp
@@ -164,96 +164,96 @@ PCurve COlc::VC( int j ) const
 
 //! Return one coordinate.
 
-CCoord COld::coord( CVar* var ) const
+CCoord COld::coord( const CVar& var ) const
 {
-    if        ( var->categ==VCateg::X ) {
+    if        ( var.categ==VCateg::X ) {
         return xco;
-    } else if ( var->categ==VCateg::Y ) {
+    } else if ( var.categ==VCateg::Y ) {
         return yco;
-    } else if ( var->categ==VCateg::Z ) {
-        if( var->num >= nZ() )
-            throw "coordinate " + var->var_info() + " not defined";
-        return ZCo[var->num];
-    } else if ( var->categ==VCateg::R ) {
-        if( var->num >= RPar.size() )
-            throw "coordinate " + var->var_info() + " not defined";
-        return RPar[var->num].Co;
+    } else if ( var.categ==VCateg::Z ) {
+        if( var.num >= nZ() )
+            throw "coordinate " + var.var_info() + " not defined";
+        return ZCo[var.num];
+    } else if ( var.categ==VCateg::R ) {
+        if( var.num >= RPar.size() )
+            throw "coordinate " + var.var_info() + " not defined";
+        return RPar[var.num].Co;
     } else {
-        throw "variable " + var->var_info() + " not defined for curve file";
+        throw "variable " + var.var_info() + " not defined for curve file";
     }
 }
 
 
 //! Return one coordinate.
 
-CCoord COlc::coord( CVar* var ) const
+CCoord COlc::coord( const CVar& var ) const
 {
-    if        ( var->categ==VCateg::X ) {
+    if        ( var.categ==VCateg::X ) {
         return xco;
-    } else if ( var->categ==VCateg::Y ) {
+    } else if ( var.categ==VCateg::Y ) {
         return yco;
-    } else if ( var->categ==VCateg::Z ) {
-        if( var->num >= nZ() )
-            throw "coordinate " + var->var_info() + " not defined";
-        return ZCo[var->num];
-    } else if ( var->categ==VCateg::CP ) {
-        if( var->num >= nP )
-            throw "coordinate " + var->var_info() + " not defined";
-        return PCo[var->num];
-    } else if ( var->categ==VCateg::R ) {
-        if( var->num >= RPar.size() )
-            throw "coordinate " + var->var_info() + " not defined";
-        return RPar[var->num].Co;
+    } else if ( var.categ==VCateg::Z ) {
+        if( var.num >= nZ() )
+            throw "coordinate " + var.var_info() + " not defined";
+        return ZCo[var.num];
+    } else if ( var.categ==VCateg::CP ) {
+        if( var.num >= nP )
+            throw "coordinate " + var.var_info() + " not defined";
+        return PCo[var.num];
+    } else if ( var.categ==VCateg::R ) {
+        if( var.num >= RPar.size() )
+            throw "coordinate " + var.var_info() + " not defined";
+        return RPar[var.num].Co;
     } else {
-        throw "variable " + var->var_info() + " not defined for curve file";
+        throw "variable " + var.var_info() + " not defined for curve file";
     }
 }
 
 
 //! Change one coordinate.
 
-void COld::set_coord( CVar* var, CCoord& co )
+void COld::set_coord( const CVar& var, CCoord& co )
 {
-    if        ( var->categ==VCateg::X ) {
+    if        ( var.categ==VCateg::X ) {
         xco = co;
-    } else if ( var->categ==VCateg::Y ) {
+    } else if ( var.categ==VCateg::Y ) {
         yco = co;
-    } else if ( var->categ==VCateg::Z ) {
-        if( var->num >= nZ() )
-            throw "coordinate " + var->var_info() + " not defined";
-        ZCo[var->num] = co;
-    } else if ( var->categ==VCateg::R ) {
-        if( var->num >= RPar.size() )
-            throw "coordinate " + var->var_info() + " not defined";
-        RPar[var->num].Co = co;
+    } else if ( var.categ==VCateg::Z ) {
+        if( var.num >= nZ() )
+            throw "coordinate " + var.var_info() + " not defined";
+        ZCo[var.num] = co;
+    } else if ( var.categ==VCateg::R ) {
+        if( var.num >= RPar.size() )
+            throw "coordinate " + var.var_info() + " not defined";
+        RPar[var.num].Co = co;
     } else {
-        throw "variable " + var->var_info() + " not defined for curve file";
+        throw "variable " + var.var_info() + " not defined for curve file";
     }
 }
 
 
 //! Change one coordinate.
 
-void COlc::set_coord( CVar* var, CCoord& co )
+void COlc::set_coord( const CVar& var, CCoord& co )
 {
-    if        ( var->categ==VCateg::X ) {
+    if        ( var.categ==VCateg::X ) {
         xco = co;
-    } else if ( var->categ==VCateg::Y ) {
+    } else if ( var.categ==VCateg::Y ) {
         yco = co;
-    } else if ( var->categ==VCateg::Z ) {
-        if( var->num >= nZ() )
-            throw "coordinate " + var->var_info() + " not defined";
-        ZCo[var->num] = co;
-    } else if ( var->categ==VCateg::CP ) {
-        if( var->num >= nP )
-            throw "coordinate " + var->var_info() + " not defined";
-        PCo[var->num] = co;
-    } else if ( var->categ==VCateg::R ) {
-        if( var->num >= RPar.size() )
-            throw "coordinate " + var->var_info() + " not defined";
-        RPar[var->num] = co;
+    } else if ( var.categ==VCateg::Z ) {
+        if( var.num >= nZ() )
+            throw "coordinate " + var.var_info() + " not defined";
+        ZCo[var.num] = co;
+    } else if ( var.categ==VCateg::CP ) {
+        if( var.num >= nP )
+            throw "coordinate " + var.var_info() + " not defined";
+        PCo[var.num] = co;
+    } else if ( var.categ==VCateg::R ) {
+        if( var.num >= RPar.size() )
+            throw "coordinate " + var.var_info() + " not defined";
+        RPar[var.num] = co;
     } else {
-        throw "variable " + var->var_info() + " not defined for curve file";
+        throw "variable " + var.var_info() + " not defined for curve file";
     }
 }
 
diff --git a/pub/lib/olf.hpp b/pub/lib/olf.hpp
index fb0bf2bf..bf6864ea 100644
--- a/pub/lib/olf.hpp
+++ b/pub/lib/olf.hpp
@@ -10,6 +10,7 @@
 #include "ptr.hpp"
 #include "coord.hpp"
 
+class Var;
 
 //! Online object. Virtual base class for COld, COlc.
 
@@ -41,8 +42,8 @@ class COlo {
     RObj z( int j, int iz ) const;
     virtual PSlice new_slice( int j ) const = 0;
     virtual POlo new_olo( bool modified=true ) const = 0;
-    virtual CCoord coord( class CVar* var ) const = 0;
-    virtual void set_coord( class CVar* var, CCoord& co ) = 0;
+    virtual CCoord coord( const CVar& var ) const = 0;
+    virtual void set_coord( const CVar& var, CCoord& co ) = 0;
 };
 
 
@@ -61,8 +62,8 @@ class COld : public COlo {
     void copy_mainvec( ROlo fin );
 
     // Overloaded functions:
-    void set_coord( class CVar* var, CCoord& co );
-    CCoord coord( class CVar* var ) const;
+    void set_coord( const CVar& var, CCoord& co );
+    CCoord coord( const CVar& var ) const;
 
     // Functions specific to data file:
     void purge_dy();
@@ -116,8 +117,8 @@ public:
     void copy_mainvec( ROlo fin );
 
     // Overloaded functions:
-    void set_coord( class CVar* var, CCoord& co );
-    CCoord coord( class CVar* var ) const;
+    void set_coord( const CVar& var, CCoord& co );
+    CCoord coord( const CVar& var ) const;
 
     // Pertinent functions:
     bool has_global_par() const;
diff --git a/pub/lib/opr.cpp b/pub/lib/opr.cpp
index a3d47604..3ea6bd0d 100644
--- a/pub/lib/opr.cpp
+++ b/pub/lib/opr.cpp
@@ -173,8 +173,7 @@ void NOperate::Pointwise( string llabel )
         if( lref.categ!=VCateg::CP )
             fout->lDoc.push_back( "o" + lref.var_info() + " " + expr);
 
-        CCoord co;
-        T->set_coord( co, k );
+        CCoord co = T->node_coord( k );
         if        ( lref.categ==VCateg::X ) {
             fout->xco = co;
         } else if ( lref.categ==VCateg::Y ) {
@@ -283,7 +282,7 @@ void NOperate::Integral()
             fout->lDoc.push_back( "oi " +expr );
             fout->ZCo.pop_back();
             fout->xco = fin->ZCo.back();
-            T->set_coord( fout->yco, k );
+            fout->yco = T->node_coord( k );
             sout = PSpec( new CSpec );
             sout->z = fin->V[0]->z;
             sout->z.pop_back();
diff --git a/pub/lib/slice.cpp b/pub/lib/slice.cpp
index 05a4af7d..115f1d72 100644
--- a/pub/lib/slice.cpp
+++ b/pub/lib/slice.cpp
@@ -18,7 +18,6 @@
 #include "ptr.hpp"
 #include "obj.hpp"
 #include "slice.hpp"
-#include "var.hpp"
 
 
 //**************************************************************************************************
diff --git a/pub/lib/xax_lex.lpp b/pub/lib/xax_lex.lpp
index 180c8be1..12b43a9e 100644
--- a/pub/lib/xax_lex.lpp
+++ b/pub/lib/xax_lex.lpp
@@ -29,7 +29,6 @@
 #include "integrate.hpp"
 #include "reg.hpp"
 #include "obj.hpp"
-#include "var.hpp"
 #include "expr.hpp"
 #include "coord.hpp"
 #include "node.hpp"
diff --git a/pub/lib/xax_yacc.ypp b/pub/lib/xax_yacc.ypp
index 0d56b4d1..28b3376c 100644
--- a/pub/lib/xax_yacc.ypp
+++ b/pub/lib/xax_yacc.ypp
@@ -17,7 +17,6 @@
 #include "ptr.hpp"
 #include "func.hpp"
 #include "fregistry.hpp"
-#include "var.hpp"
 #include "obj.hpp"
 #include "expr.hpp"
 #include "coord.hpp"
-- 
GitLab