41 /* api any lispobj must implement */
42 virtual eObjectType
getObjectType() const = 0;
44 /* create a fresh one */
45 virtual Obj
* create(void) const = 0;
48 virtual Obj
* clone(void) const = 0;
51 virtual void print(std::ostream
& out
) const = 0;
53 /* check a string to see if it represents this kind of object */
54 //virtual bool identify(std::string in) const = 0;
56 /* compare by value */
57 virtual bool operator==(const Obj
* other
) = 0;
59 inline bool hasRef() {
60 return (references_
!= 0);
63 inline void incRef() {
67 inline void decRef() {
68 assert(references_
!= 0);
75 Obj(const Obj
& other
) {};
76 Obj
& operator=(const Obj
& other
) {};
78 std::size_t references_
;
82 typedef long FixnumValue
;
83 typedef double FloatnumValue
;
84 typedef std::string StringValue
;
88 /** The lisp environment: an associative container that associates symbols
89 with their properties **/
95 /** parent namespace **/
98 // to do -- this needs to be a hash table or something
99 // with faster lookup.
100 typedef std::pair
<Obj
*,Obj
*> Binding
;
102 std::vector
<Binding
> env_
;
105 * detect if a symbol is bound
112 IsBound(Obj
* bound
) :
116 bool operator()(const Env::Binding
& binding
) {
117 return (bound_
== binding
.first
);
119 }; /* class IsBound */
125 void operator()(const Env::Binding
& binding
) {
126 binding
.first
->decRef();
127 binding
.second
->decRef();
128 if (!binding
.first
->hasRef())
129 delete binding
.first
;
130 if (!binding
.second
->hasRef())
131 delete binding
.second
;
136 static Env
*root_environment
;
137 static Env
*current_environment
;
145 root_environment
= this;
146 current_environment
= this;
154 std::size_t add(Obj
* obj
)
156 Binding
bind(obj
, NULL
);
158 std::size_t result
= env_
.size();
159 env_
.push_back(bind
);
163 // test if object has been bound by value
164 bool isBound(Obj
* obj
)
166 std::vector
<Binding
>::iterator result
= std::find_if(env_
.begin(), env_
.end(), IsBound(obj
));
167 if ((result
== env_
.end()) && (parent_
!= NULL
))
168 return parent_
->isBound(obj
);
170 return (result
!= env_
.end());
174 //! return pointer to bound object that has same value
177 std::vector
<Binding
>::iterator result
;
178 result
= std::find_if(env_
.begin(), env_
.end(), IsBound(obj
));
179 if (result
== env_
.end()) {
182 return parent_
->bound(obj
);
186 return result
->first
;
190 // return pointer to bound value
191 Obj
* boundto(Obj
* obj
)
193 std::vector
<Binding
>::iterator result
;
194 result
= std::find_if(env_
.begin(), env_
.end(), IsBound(obj
));
195 if (result
== env_
.end())
197 return parent_
->boundto(obj
);
201 return result
->second
;
205 std::size_t bind(Obj
*value
, Obj
* binding
)
207 Obj
*bindee
= bound(value
);
210 Binding
bind(bindee
, binding
);
213 std::size_t result
= env_
.size();
214 env_
.push_back(bind
);
218 void unbind(Obj
*value
)
220 std::vector
<Binding
>::iterator binder
;
221 binder
= std::find_if(env_
.begin(), env_
.end(), IsBound(value
));
222 if (binder
== env_
.end()) {
224 parent_
->unbind(value
);
229 DecBindingRef finalizer
;
238 current_environment
= new Env(this);
239 return current_environment
;
244 DecBindingRef finalizer
;
245 for_each(env_
.begin(), env_
.end(), finalizer
);
247 assert(this == Env::current_environment
);
248 Env::current_environment
= parent_
;