85 #ifndef ipgm_context_h
86 #define ipgm_context_h
88 #include "../r_code/atom.h"
89 #include "../r_code/utils.h"
92 #include "pgm_overlay.h"
98 class InputLessPGMOverlay;
107 bool is_cmd_with_cptr()
const;
111 for (uint16 i = 0; i < destination->references_size(); ++i)
112 if (referenced_object == destination->get_reference(i)) {
114 destination->code(write_index) = Atom::RPointer(i);
118 destination->add_reference(referenced_object);
119 destination->code(write_index) = Atom::RPointer(destination->references_size() - 1);
122 static void addReference(
View *destination, uint16 write_index,
r_code::Code *referenced_object) {
125 if (destination->references_[0])
129 destination->references_[r_ptr_index] = referenced_object;
130 destination->code(write_index) = Atom::RPointer(r_ptr_index);
133 template<
class C>
void copy_structure(C *destination,
135 uint16 &extent_index,
136 bool dereference_cptr,
137 int32 pgm_index)
const {
139 if ((*
this)[0].getDescriptor() == Atom::OPERATOR && Operator::Get((*
this)[0].asOpcode()).is_syn()) {
142 c.copy_member(destination, write_index, extent_index, dereference_cptr, pgm_index);
145 destination->code(write_index++) = (*this)[0];
147 uint16 atom_count = get_children_count();
148 extent_index = write_index + atom_count;
150 switch ((*
this)[0].getDescriptor()) {
152 if ((*
this)[1].getDescriptor() == Atom::CODE_VL_PTR) {
154 Atom a = code_[(*this)[1].asIndex()];
155 if (a.getDescriptor() == Atom::I_PTR)
156 a = code_[a.asIndex()];
157 switch (a.getDescriptor()) {
158 case Atom::OUT_OBJ_PTR:
159 destination->code(write_index++) = Atom::CodeVLPointer(code_[(*
this)[1].asIndex()].asIndex());
161 case Atom::IN_OBJ_PTR:
162 destination->code(write_index++) = Atom::RPointer(1 + a.asInputIndex());
165 destination->code(write_index++) = (*this)[1];
169 destination->code(write_index++) = (*this)[1];
170 for (uint16 i = 2; i <= atom_count; ++i)
171 destination->code(write_index++) = (*this)[i];
173 case Atom::TIMESTAMP:
174 for (uint16 i = 1; i <= atom_count; ++i)
175 destination->code(write_index++) = (*this)[i];
178 for (uint16 i = 1; i <= atom_count; ++i)
179 destination->code(write_index++) = (*this)[i];
182 if (is_cmd_with_cptr()) {
184 for (uint16 i = 1; i <= atom_count; ++i) {
187 c.copy_member(destination, write_index++, extent_index, i != 2, pgm_index);
193 _pgm_index = pgm_index;
194 else if ((*
this)[0].getDescriptor() == Atom::OBJECT && ((*
this)[0].asOpcode() == Opcodes::Pgm || (*
this)[0].asOpcode() == Opcodes::AntiPgm))
199 for (uint16 i = 1; i <= atom_count; ++i) {
202 c.copy_member(destination, write_index++, extent_index, !(!dereference_cptr && i == 1), _pgm_index);
210 template<
class C>
void copy_member(C *destination,
212 uint16 &extent_index,
213 bool dereference_cptr,
214 int32 pgm_index)
const {
216 switch ((*
this)[0].getDescriptor()) {
218 case Atom::VALUE_PTR:
219 case Atom::IPGM_PTR: {
221 if (data_ == REFERENCE && index_ == 0) {
223 addReference(destination, write_index, object_);
227 if (code_[(*
this)[0].asIndex()].getDescriptor() == Atom::C_PTR) {
229 if (!dereference_cptr || (pgm_index > 0 && code_[(*
this)[0].asIndex() + 1].asIndex() > pgm_index)) {
232 destination->code(write_index) = Atom::IPointer(extent_index);
233 c.copy_structure(destination, extent_index, extent_index, dereference_cptr, pgm_index);
239 if (c[0].isStructural()) {
241 destination->code(write_index) = Atom::IPointer(extent_index);
242 if (pgm_index > 0 && index_ > pgm_index && data_ == STEM)
243 patch_code(index_, Atom::OutObjPointer(write_index));
244 c.copy_structure(destination, extent_index, extent_index, dereference_cptr, pgm_index);
246 destination->code(write_index) = c[0];
249 case Atom::CODE_VL_PTR:
250 switch (code_[(*
this)[0].asIndex()].getDescriptor()) {
252 addReference(destination, write_index, ((
InputLessPGMOverlay *)overlay_)->productions_[code_[(*
this)[0].asIndex()].asIndex()]);
255 if (code_[code_[(*
this)[0].asIndex()].asIndex()].getDescriptor() == Atom::IN_OBJ_PTR)
256 addReference(destination, write_index, ((
PGMOverlay *)overlay_)->getInputObject(code_[code_[(*
this)[0].asIndex()].asIndex()].asInputIndex()));
258 dereference().copy_member(destination, write_index, extent_index, dereference_cptr, pgm_index);
260 case Atom::OUT_OBJ_PTR:
261 destination->code(write_index) = Atom::CodeVLPointer(code_[(*
this)[0].asIndex()].asIndex());
263 case Atom::IN_OBJ_PTR:
264 case Atom::D_IN_OBJ_PTR: {
268 addReference(destination, write_index, c.object_);
269 else if (c[0].isStructural()) {
271 destination->code(write_index++) = Atom::IPointer(extent_index);
272 c.copy_structure(destination, extent_index, extent_index, dereference_cptr, pgm_index);
274 c.copy_member(destination, write_index, extent_index, dereference_cptr, pgm_index);
277 dereference().copy_member(destination, write_index, extent_index, dereference_cptr, pgm_index);
282 addReference(destination, write_index, object_->get_reference((*
this)[0].asIndex()));
285 addReference(destination, write_index, ((
InputLessPGMOverlay *)overlay_)->productions_[(*
this)[0].asIndex()]);
287 case Atom::IN_OBJ_PTR:
288 addReference(destination, write_index, ((
PGMOverlay *)overlay_)->getInputObject((*
this)[0].asIndex()));
290 case Atom::D_IN_OBJ_PTR: {
292 addReference(destination, write_index, c.object_);
294 }
case Atom::OPERATOR:
297 case Atom::INSTANTIATED_PROGRAM:
298 case Atom::INSTANTIATED_CPP_PROGRAM:
299 case Atom::INSTANTIATED_INPUT_LESS_PROGRAM:
300 case Atom::INSTANTIATED_ANTI_PROGRAM:
301 case Atom::COMPOSITE_STATE:
306 case Atom::TIMESTAMP:
309 destination->code(write_index) = Atom::IPointer(extent_index);
310 if (pgm_index > 0 && index_ > pgm_index && data_ == STEM)
311 patch_code(index_, Atom::OutObjPointer(write_index));
312 copy_structure(destination, extent_index, extent_index, dereference_cptr, pgm_index);
314 case Atom::T_WILDCARD:
315 destination->code(write_index) = (*this)[0];
318 destination->code(write_index) = (*this)[0];
319 if (pgm_index > 0 && index_ > pgm_index && data_ == STEM)
320 patch_code(index_, Atom::OutObjPointer(write_index));
325 void copy_structure_to_value_array(
bool prefix, uint16 write_index, uint16 &extent_index,
bool dereference_cptr);
326 void copy_member_to_value_array(uint16 child_index,
bool prefix, uint16 write_index, uint16 &extent_index,
bool dereference_cptr);
331 IPGMContext(
r_code::Code *
object,
View *view,
Atom *code, uint16 index,
InputLessPGMOverlay *
const overlay, Data data = STEM) :
_Context(code, index, overlay, data), object_(
object), view_(view) {}
340 Atom &get_atom(uint16 i)
const override {
return this->operator [](i); }
342 uint16 get_object_code_size()
const override {
return object_->code_size(); }
344 uint16 get_children_count()
const override {
349 object_->acq_markers();
350 c = object_->markers_.size();
351 object_->rel_markers();
354 object_->acq_views();
355 c = object_->views_.size();
356 object_->rel_views();
359 return code_[index_].getAtomCount();
382 bool evaluate()
const;
383 bool evaluate_no_dereference()
const;
395 bool operator ==(
const IPGMContext &c)
const;
396 bool operator !=(
const IPGMContext &c)
const;
398 IPGMContext get_child(uint16 index)
const {
402 return IPGMContext(object_, view_, code_, index_ + index, (InputLessPGMOverlay *)overlay_, STEM);
404 return IPGMContext(object_, view_, code_, index_ + index, (InputLessPGMOverlay *)overlay_, REFERENCE);
406 return IPGMContext(object_, view_, code_, index_ + index, NULL, VIEW);
411 object_->acq_markers();
412 for (m = object_->markers_.begin(); i < index - 1; ++i, ++m) {
414 if (m == object_->markers_.end()) {
416 object_->rel_markers();
417 return IPGMContext();
420 object_->rel_markers();
421 return IPGMContext(*m, 0);
425 std::unordered_set<r_code::_View *, r_code::_View::Hash, r_code::_View::Equal>::const_iterator v;
426 object_->acq_views();
427 for (v = object_->views_.begin(); i < index - 1; ++i, ++v) {
429 if (v == object_->views_.end()) {
431 object_->rel_views();
432 return IPGMContext();
435 object_->rel_views();
436 return IPGMContext(object_, (
r_exec::View*)*v, &(*v)->code(0), index_ + index, NULL, VIEW);
438 return IPGMContext(object_, view_, code_, index_ + index, (InputLessPGMOverlay *)overlay_, VALUE_ARRAY);
440 return IPGMContext();
448 return get_child(index).dereference();
451 Atom &operator [](uint16 i)
const {
return code_[index_ + i]; }
453 uint16 getIndex()
const {
return index_; }
455 IPGMContext dereference()
const;
456 void dereference_once();
458 bool is_reference()
const {
return data_ == REFERENCE; }
459 bool is_undefined()
const {
return data_ == UNDEFINED; }
461 void patch_input_code(uint16 pgm_code_index, uint16 input_index)
const { ((InputLessPGMOverlay *)overlay_)->patch_input_code(pgm_code_index, input_index, 0); }
463 uint16 addProduction(
r_code::Code *
object,
bool check_for_existence)
const;
465 template<
class C>
void copy(C *destination, uint16 write_index)
const {
467 uint16 extent_index = 0;
468 copy_structure(destination, write_index, extent_index,
true, -1);
471 template<
class C>
void copy(C *destination, uint16 write_index, uint16 &extent_index)
const {
473 copy_structure(destination, write_index, extent_index,
true, -1);
476 void copy_to_value_array(uint16 &position);
486 void getMember(
void *&
object, uint32 &view_oid, ObjectType &object_type, int16 &member_index)
const;
489 bool match(
const IPGMContext &input)
const;
492 r_code::Code *build_object(Atom head)
const {
return overlay_->build_object(head); }
495 static bool Ins(
const IPGMContext &context);
496 static bool Fvw(
const IPGMContext &context);
497 static bool Red(
const IPGMContext &context);