Deriving input stream ?

Discussion in 'C++' started by fabricemarchant@free.fr, May 21, 2006.

  1. Guest

    Hi !

    I've translated Andru Luvisi small LISP interpreter sl3.c
    http://www.sonoma.edu/users/l/luvisi/sl3.c

    in C++ in order to understand how it works and to experiment with small
    LISP.
    http://fabrice.marchant.free.fr/LISP/slf/060521/

    (For now, my C++ code isn't the result of an object analysis, just a
    translation from C, eliminating "switches" or "if ladders" for
    example.)

    As a LISP, the main loop is a "read, eval, print".

    Please, could you give me hints about the way to define a ">>" operator
    to replace the "readObj" function of LISP objects ?

    // Main loop, in slf.c++
    while( notExitFlag )
    cout << *readObj( )->eval( top_env ) << '\n';

    Thanks for advance.

    Fabrice
     
    , May 21, 2006
    #1
    1. Advertising

  2. <> wrote in message
    news:...
    : Please, could you give me hints about the way to define a ">>" operator
    : to replace the "readObj" function of LISP objects ?
    :
    : // Main loop, in slf.c++
    : while( notExitFlag )
    : cout << *readObj( )->eval( top_env ) << '\n';

    Since you're asking only about how to implement >>, I guess that you
    have "implemented" << using a conversion to string ?

    The proper way to define streaming operators is:
    ostream& operator << ( ostream& s, MyClass const& obj ) { ... }
    istream& operator >> ( istream& s, MyClass& obj ) { ... }
    They are non-member functions. [ NB: both have to "return s;" ]

    But you can declare them within the class, as friends, if
    these functions need access to private members:
    friend ostream& operator << ( ostream& s, MyClass const& obj );
    friend istream& operator >> ( istream& s, MyClass& obj );


    Amicalement --Ivan
    --
    http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form
     
    Ivan Vecerina, May 22, 2006
    #2
    1. Advertising

  3. Guest

    Thanks for your explanations, Ivan.

    ---------- About output -----------

    > Since you're asking only about how to implement >>, I guess that you
    > have "implemented" << using a conversion to string ?


    No, I did this way :

    class obj {

    public:
    ....
    virtual ostream&
    print( ostream& os ) const { return os; }
    ....
    };

    ostream& operator<<( ostream& os, const obj& ob ) {

    return ob.print( os );
    }

    These are printable classes that derives from base "obj" :

    class nilObj: public obj {
    public:
    ....
    ostream&
    print( ostream& os ) const { return os << "()"; }
    ....
    };

    class symbol: public obj {
    public:
    ....
    print( ostream& os ) const { return os << name(); }

    string
    name( void ) const { return _M_name; }

    private:
    string _M_name;
    };

    And so on, for other derived objects.

    You speak about string conversion, please how could I use this here ?

    ---------- About input -----------

    > The proper way to define streaming operators is:
    > ostream& operator << ( ostream& s, MyClass const& obj ) { ... }
    > istream& operator >> ( istream& s, MyClass& obj ) { ... }
    > They are non-member functions. [ NB: both have to "return s;" ]


    > But you can declare them within the class, as friends, if
    > these functions need access to private members:
    > friend ostream& operator << ( ostream& s, MyClass const& obj );
    > friend istream& operator >> ( istream& s, MyClass& obj );


    I know these but do not see how to implement things in the aim to be
    used like this :

    obj i;
    cin >> i; // <- How to prepare the job for this ?
    cout << *i.eval( top_env ) << '\n';

    I wanted to be able to write the read of different kind of objects (
    nil, symbol, cons, proc ) this simple way.

    Regards

    Fabrice
     
    , May 23, 2006
    #3
  4. Jim Langston Guest

    <> wrote in message
    news:...

    >> The proper way to define streaming operators is:
    >> ostream& operator << ( ostream& s, MyClass const& obj ) { ... }
    >> istream& operator >> ( istream& s, MyClass& obj ) { ... }
    >> They are non-member functions. [ NB: both have to "return s;" ]

    >
    >> But you can declare them within the class, as friends, if
    >> these functions need access to private members:
    >> friend ostream& operator << ( ostream& s, MyClass const& obj );
    >> friend istream& operator >> ( istream& s, MyClass& obj );

    >
    > I know these but do not see how to implement things in the aim to be
    > used like this :
    >
    > obj i;
    > cin >> i; // <- How to prepare the job for this ?
    > cout << *i.eval( top_env ) << '\n';
    >
    > I wanted to be able to write the read of different kind of objects (
    > nil, symbol, cons, proc ) this simple way.


    You just input them. I do this quite a bit in my program, I'll try to show
    a rather simple example.

    This one is not simple but I'll cut out a lot of stuff just so you get the
    idea. So it may not compile as is.

    class CHealth
    {
    public:
    // Snipped - Not needed for example
    private:
    // Lot of other stuff snipped here
    int OverallMax_; int Overall_;
    int HeadMax_;
    int Head_;
    int TorsoMax_;
    int Torso_;
    int LeftArmMax_;
    int LeftArm_;
    int RightArmMax_;
    int RightArm_;
    int LeftLegMax_;
    int LeftLeg_;
    int RightLegMax_;
    int RightLeg_;
    int LeftWingMax_;
    int LeftWing_;
    int RightWingMax_;
    int RightWing_;
    };

    std::istream& operator>>( std::istream& is, CHealth& Health)
    {
    is >> Health.OverallMax_ >> Health.Overall_ >> Health.HeadMax_ >>
    Health.Head_ >> Health.TorsoMax_ >> Health.Torso_ >>
    Health.LeftArmMax_ >> Health.LeftArm_ >> Health.RightArmMax_ >>
    Health.RightArm_ >>
    Health.LeftLegMax_ >> Health.LeftLeg_ >> Health.RightLegMax_ >>
    Health.RightLeg_ >>
    Health.LeftWingMax_ >> Health.LeftWing_ >> Health.RightWingMax_ >>
    Health.RightWing_;

    // Snipped checking of some values and setting values in class that were
    also snipped,
    // such as Dead_, LeftArmDisabled_, etc...

    return is;
    }

    std::eek:stream& operator<<( std::eek:stream& os, CHealth& Health)
    {
    os << Health.OverallMax_ << " " << Health.Overall_ << " " <<
    Health.HeadMax_ << " " << Health.Head_ << " " <<
    Health.TorsoMax_ << " " << Health.Torso_ << " " <<
    Health.LeftArmMax_ << " " << Health.LeftArm_ << " " <<
    Health.RightArmMax_ << " " << Health.RightArm_ << " " <<
    Health.LeftLegMax_ << " " << Health.LeftLeg_ << " " <<
    Health.RightLegMax_ << " " << Health.RightLeg_ << " " <<
    Health.LeftWingMax_ << " " << Health.LeftWing_ << " " <<
    Health.RightWingMax_ << " " << Health.RightWing_;
    return os;

    }
     
    Jim Langston, May 24, 2006
    #4
  5. Guest

    Hi Jim !

    Thanks for your answer.

    Apologizes for the delay.
    I understand what you do for the input of your numerous fields
    structure but I can't imagine how to apply this in my case where the
    input objects - all derived from the "obj" base type - can be "cons" (
    lists ) or symbols or nil...

    http://fabrice.marchant.free.fr/LISP/slf/060521/input.c

    Regards fabrice
     
    , May 27, 2006
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Rasmusson, Lars
    Replies:
    1
    Views:
    782
    popov
    Apr 30, 2004
  2. Replies:
    9
    Views:
    675
    Alex Buell
    Apr 27, 2006
  3. Kashif Ur Rehman
    Replies:
    2
    Views:
    899
    Tom Hawtin
    May 17, 2007
  4. Christopher Pisz

    Deriving from StreamBuf - input buffer

    Christopher Pisz, Dec 9, 2007, in forum: C++
    Replies:
    7
    Views:
    1,928
    James Kanze
    Dec 11, 2007
  5. Dan Smithers

    Deriving my own stream class

    Dan Smithers, Jun 17, 2008, in forum: C++
    Replies:
    6
    Views:
    589
    Bernd Strieder
    Jun 18, 2008
Loading...

Share This Page