Deriving input stream ?

F

fabricemarchant

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
 
I

Ivan Vecerina

: 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
 
F

fabricemarchant

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
 
J

Jim Langston

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;

}
 
F

fabricemarchant

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,763
Messages
2,569,562
Members
45,038
Latest member
OrderProperKetocapsules

Latest Threads

Top