85 #include "guard_builder.h"
87 using namespace std::chrono;
88 using namespace r_code;
92 GuardBuilder::GuardBuilder() :
_Object() {
95 GuardBuilder::~GuardBuilder() {
98 void GuardBuilder::build(
Code *mdl, _Fact *premise_pattern, _Fact *cause_pattern, uint16 &write_index)
const {
100 mdl->code(MDL_FWD_GUARDS) = Atom::IPointer(++write_index);
101 mdl->code(write_index) = Atom::Set(0);
103 mdl->code(MDL_BWD_GUARDS) = Atom::IPointer(++write_index);
104 mdl->code(write_index) = Atom::Set(0);
109 TimingGuardBuilder::TimingGuardBuilder(microseconds period) : GuardBuilder(), period_(period) {
112 TimingGuardBuilder::~TimingGuardBuilder() {
115 void TimingGuardBuilder::write_guard(
Code *mdl, uint16 l, uint16 r, uint16 opcode, microseconds offset, uint16 &write_index, uint16 &extent_index)
const {
117 mdl->code(++write_index) = Atom::AssignmentPointer(l, ++extent_index);
118 mdl->code(extent_index) = Atom::Operator(opcode, 2);
119 mdl->code(++extent_index) = Atom::VLPointer(r);
120 uint16 index = extent_index + 2;
121 mdl->code(++extent_index) = Atom::IPointer(index);
122 Utils::SetDurationStruct(mdl, ++extent_index, offset);
126 void TimingGuardBuilder::_build(
Code *mdl, uint16 t0, uint16 t1, uint16 &write_index)
const {
128 Code *rhs_val = mdl->get_reference(1);
129 uint16 t2 = rhs_val->code(FACT_AFTER).asIndex();
130 uint16 t3 = rhs_val->code(FACT_BEFORE).asIndex();
132 mdl->code(MDL_FWD_GUARDS) = Atom::IPointer(++write_index);
133 mdl->code(write_index) = Atom::Set(2);
135 uint16 extent_index = write_index + 2;
137 write_guard(mdl, t2, t0, Opcodes::Add, period_, write_index, extent_index);
138 write_guard(mdl, t3, t1, Opcodes::Add, period_, write_index, extent_index);
140 write_index = extent_index;
141 mdl->code(MDL_BWD_GUARDS) = Atom::IPointer(++write_index);
142 mdl->code(write_index) = Atom::Set(2);
144 extent_index = write_index + 2;
146 write_guard(mdl, t0, t2, Opcodes::Sub, period_, write_index, extent_index);
147 write_guard(mdl, t1, t3, Opcodes::Sub, period_, write_index, extent_index);
149 write_index = extent_index;
152 void TimingGuardBuilder::build(
Code *mdl, _Fact *premise_pattern, _Fact *cause_pattern, uint16 &write_index)
const {
156 uint16 tpl_arg_set_index = mdl->code(MDL_TPL_ARGS).asIndex();
157 if (mdl->code(tpl_arg_set_index).getAtomCount() == 0) {
159 Code *lhs_val = mdl->get_reference(0);
160 t0 = lhs_val->code(FACT_AFTER).asIndex();
161 t1 = lhs_val->code(FACT_BEFORE).asIndex();
168 _build(mdl, t0, t1, write_index);
173 SGuardBuilder::SGuardBuilder(microseconds period, microseconds offset) : TimingGuardBuilder(period), offset_(offset) {
176 SGuardBuilder::~SGuardBuilder() {
179 void SGuardBuilder::_build(
Code *mdl, uint16 q0, uint16 t0, uint16 t1, uint16 &write_index)
const {
181 Code *rhs = mdl->get_reference(1);
182 uint16 t2 = rhs->code(FACT_AFTER).asIndex();
183 uint16 t3 = rhs->code(FACT_BEFORE).asIndex();
184 uint16 q1 = rhs->get_reference(0)->code(MK_VAL_VALUE).asIndex();
186 Code *lhs = mdl->get_reference(0);
187 uint16 speed_t0 = lhs->code(FACT_AFTER).asIndex();
188 uint16 speed_t1 = lhs->code(FACT_BEFORE).asIndex();
189 uint16 speed_value = lhs->get_reference(0)->code(MK_VAL_VALUE).asIndex();
191 mdl->code(MDL_FWD_GUARDS) = Atom::IPointer(++write_index);
192 mdl->code(write_index) = Atom::Set(3);
194 uint16 extent_index = write_index + 3;
196 write_guard(mdl, t2, t0, Opcodes::Add, period_, write_index, extent_index);
197 write_guard(mdl, t3, t1, Opcodes::Add, period_, write_index, extent_index);
199 mdl->code(++write_index) = Atom::AssignmentPointer(q1, ++extent_index);
200 mdl->code(extent_index) = Atom::Operator(Opcodes::Add, 2);
201 mdl->code(++extent_index) = Atom::VLPointer(q0);
202 uint16 index = extent_index + 2;
203 mdl->code(++extent_index) = Atom::IPointer(index);
204 mdl->code(++extent_index) = Atom::Operator(Opcodes::Mul, 2);
205 mdl->code(++extent_index) = Atom::VLPointer(speed_value);
206 index = extent_index + 2;
207 mdl->code(++extent_index) = Atom::IPointer(index);
208 Utils::SetDurationStruct(mdl, ++extent_index, period_);
211 write_index = extent_index;
212 mdl->code(MDL_BWD_GUARDS) = Atom::IPointer(++write_index);
213 mdl->code(write_index) = Atom::Set(5);
215 extent_index = write_index + 5;
217 write_guard(mdl, t0, t2, Opcodes::Sub, period_, write_index, extent_index);
218 write_guard(mdl, t1, t3, Opcodes::Sub, period_, write_index, extent_index);
220 write_guard(mdl, speed_t0, t2, Opcodes::Sub, offset_, write_index, extent_index);
221 write_guard(mdl, speed_t1, t3, Opcodes::Sub, period_, write_index, extent_index);
223 mdl->code(++write_index) = Atom::AssignmentPointer(speed_value, ++extent_index);
224 mdl->code(extent_index) = Atom::Operator(Opcodes::Div, 2);
225 index = extent_index + 3;
226 mdl->code(++extent_index) = Atom::IPointer(index);
227 index = extent_index + 5;
228 mdl->code(++extent_index) = Atom::IPointer(index);
229 mdl->code(++extent_index) = Atom::Operator(Opcodes::Sub, 2);
230 mdl->code(++extent_index) = Atom::VLPointer(q1);
231 mdl->code(++extent_index) = Atom::VLPointer(q0);
232 Utils::SetDurationStruct(mdl, ++extent_index, period_);
235 write_index = extent_index;
238 void SGuardBuilder::build(
Code *mdl, _Fact *premise_pattern, _Fact *cause_pattern, uint16 &write_index)
const {
243 uint16 tpl_arg_set_index = mdl->code(MDL_TPL_ARGS).asIndex();
244 if (mdl->code(tpl_arg_set_index).getAtomCount() == 0) {
246 q0 = premise_pattern->get_reference(0)->code(MK_VAL_VALUE).asIndex();
247 t0 = premise_pattern->code(FACT_AFTER).asIndex();
248 t1 = premise_pattern->code(FACT_BEFORE).asIndex();
256 _build(mdl, q0, t0, t1, write_index);
265 NoArgCmdGuardBuilder::~NoArgCmdGuardBuilder() {
268 void NoArgCmdGuardBuilder::_build(
Code *mdl, uint16 q0, uint16 t0, uint16 t1, uint16 &write_index)
const {
270 Code *rhs = mdl->get_reference(1);
271 uint16 t2 = rhs->code(FACT_AFTER).asIndex();
272 uint16 t3 = rhs->code(FACT_BEFORE).asIndex();
274 Code *lhs = mdl->get_reference(0);
275 uint16 cmd_t0 = lhs->code(FACT_AFTER).asIndex();
276 uint16 cmd_t1 = lhs->code(FACT_BEFORE).asIndex();
278 mdl->code(MDL_FWD_GUARDS) = Atom::IPointer(++write_index);
279 mdl->code(write_index) = Atom::Set(2);
281 uint16 extent_index = write_index + 2;
283 write_guard(mdl, t2, t0, Opcodes::Add, period_, write_index, extent_index);
284 write_guard(mdl, t3, t1, Opcodes::Add, period_, write_index, extent_index);
286 write_index = extent_index;
287 mdl->code(MDL_BWD_GUARDS) = Atom::IPointer(++write_index);
289 mdl->code(write_index) = Atom::Set(4);
290 extent_index = write_index + 4;
292 write_guard(mdl, t0, t2, Opcodes::Sub, period_, write_index, extent_index);
293 write_guard(mdl, t1, t3, Opcodes::Sub, period_, write_index, extent_index);
295 write_guard(mdl, cmd_t0, t2, Opcodes::Sub, offset_, write_index, extent_index);
296 write_guard(mdl, cmd_t1, t3, Opcodes::Sub, period_, write_index, extent_index);
298 write_index = extent_index;
301 void NoArgCmdGuardBuilder::build(
Code *mdl, _Fact *premise_pattern, _Fact *cause_pattern, uint16 &write_index)
const {
306 uint16 tpl_arg_set_index = mdl->code(MDL_TPL_ARGS).asIndex();
307 if (mdl->code(tpl_arg_set_index).getAtomCount() == 0) {
309 q0 = premise_pattern->get_reference(0)->code(MK_VAL_VALUE).asIndex();
310 t0 = premise_pattern->code(FACT_AFTER).asIndex();
311 t1 = premise_pattern->code(FACT_BEFORE).asIndex();
319 _build(mdl, q0, t0, t1, write_index);
324 CmdGuardBuilder::CmdGuardBuilder(microseconds period, microseconds offset, uint16 cmd_arg_index) : TimingGuardBuilder(period), offset_(offset), cmd_arg_index_(cmd_arg_index) {
327 CmdGuardBuilder::~CmdGuardBuilder() {
330 void CmdGuardBuilder::_build(
Code *mdl, uint16 fwd_opcode, uint16 bwd_opcode, uint16 q0, uint16 t0, uint16 t1, uint16 &write_index)
const {
332 Code *rhs = mdl->get_reference(1);
333 uint16 t2 = rhs->code(FACT_AFTER).asIndex();
334 uint16 t3 = rhs->code(FACT_BEFORE).asIndex();
335 uint16 q1 = rhs->get_reference(0)->code(MK_VAL_VALUE).asIndex();
337 Code *lhs = mdl->get_reference(0);
338 uint16 cmd_t0 = lhs->code(FACT_AFTER).asIndex();
339 uint16 cmd_t1 = lhs->code(FACT_BEFORE).asIndex();
340 uint16 cmd_arg = lhs->get_reference(0)->code(cmd_arg_index_).asIndex();
342 mdl->code(MDL_FWD_GUARDS) = Atom::IPointer(++write_index);
343 mdl->code(write_index) = Atom::Set(3);
345 uint16 extent_index = write_index + 3;
347 write_guard(mdl, t2, t0, Opcodes::Add, period_, write_index, extent_index);
348 write_guard(mdl, t3, t1, Opcodes::Add, period_, write_index, extent_index);
350 mdl->code(++write_index) = Atom::AssignmentPointer(q1, ++extent_index);
351 mdl->code(extent_index) = Atom::Operator(fwd_opcode, 2);
352 mdl->code(++extent_index) = Atom::VLPointer(q0);
353 mdl->code(++extent_index) = Atom::VLPointer(cmd_arg);
356 write_index = extent_index;
357 mdl->code(MDL_BWD_GUARDS) = Atom::IPointer(++write_index);
358 mdl->code(write_index) = Atom::Set(5);
360 extent_index = write_index + 5;
362 write_guard(mdl, t0, t2, Opcodes::Sub, period_, write_index, extent_index);
363 write_guard(mdl, t1, t3, Opcodes::Sub, period_, write_index, extent_index);
365 write_guard(mdl, cmd_t0, t2, Opcodes::Sub, offset_, write_index, extent_index);
366 write_guard(mdl, cmd_t1, t3, Opcodes::Sub, period_, write_index, extent_index);
368 mdl->code(++write_index) = Atom::AssignmentPointer(cmd_arg, ++extent_index);
369 mdl->code(extent_index) = Atom::Operator(bwd_opcode, 2);
370 mdl->code(++extent_index) = Atom::VLPointer(q1);
371 mdl->code(++extent_index) = Atom::VLPointer(q0);
374 write_index = extent_index;
377 void CmdGuardBuilder::_build(
Code *mdl, uint16 fwd_opcode, uint16 bwd_opcode, _Fact *premise_pattern, _Fact *cause_pattern, uint16 &write_index)
const {
382 uint16 tpl_arg_set_index = mdl->code(MDL_TPL_ARGS).asIndex();
383 if (mdl->code(tpl_arg_set_index).getAtomCount() == 0) {
385 q0 = premise_pattern->get_reference(0)->code(MK_VAL_VALUE).asIndex();
386 t0 = premise_pattern->code(FACT_AFTER).asIndex();
387 t1 = premise_pattern->code(FACT_BEFORE).asIndex();
395 _build(mdl, fwd_opcode, bwd_opcode, q0, t0, t1, write_index);
400 MCGuardBuilder::MCGuardBuilder(microseconds period, microseconds offset, float32 cmd_arg_index) : CmdGuardBuilder(period, offset, cmd_arg_index) {
403 MCGuardBuilder::~MCGuardBuilder() {
406 void MCGuardBuilder::build(
Code *mdl, _Fact *premise_pattern, _Fact *cause_pattern, uint16 &write_index)
const {
408 _build(mdl, Opcodes::Mul, Opcodes::Div, premise_pattern, cause_pattern, write_index);
413 ACGuardBuilder::ACGuardBuilder(microseconds period, microseconds offset, uint16 cmd_arg_index) : CmdGuardBuilder(period, offset, cmd_arg_index) {
416 ACGuardBuilder::~ACGuardBuilder() {
419 void ACGuardBuilder::build(
Code *mdl, _Fact *premise_pattern, _Fact *cause_pattern, uint16 &write_index)
const {
421 _build(mdl, Opcodes::Add, Opcodes::Sub, premise_pattern, cause_pattern, write_index);
426 ConstGuardBuilder::ConstGuardBuilder(microseconds period, float32 constant, microseconds offset) : TimingGuardBuilder(period), constant_(constant), offset_(offset) {
429 ConstGuardBuilder::~ConstGuardBuilder() {
432 void ConstGuardBuilder::_build(
Code *mdl, uint16 fwd_opcode, uint16 bwd_opcode, uint16 q0, uint16 t0, uint16 t1, uint16 &write_index)
const {
434 Code *rhs = mdl->get_reference(1);
435 uint16 t2 = rhs->code(FACT_AFTER).asIndex();
436 uint16 t3 = rhs->code(FACT_BEFORE).asIndex();
437 uint16 q1 = rhs->get_reference(0)->code(MK_VAL_VALUE).asIndex();
439 Code *lhs = mdl->get_reference(1);
440 uint16 t4 = lhs->code(FACT_AFTER).asIndex();
441 uint16 t5 = lhs->code(FACT_BEFORE).asIndex();
443 mdl->code(MDL_FWD_GUARDS) = Atom::IPointer(++write_index);
444 mdl->code(write_index) = Atom::Set(3);
446 uint16 extent_index = write_index + 3;
448 write_guard(mdl, t2, t0, Opcodes::Add, period_, write_index, extent_index);
449 write_guard(mdl, t3, t1, Opcodes::Add, period_, write_index, extent_index);
451 mdl->code(++write_index) = Atom::AssignmentPointer(q1, ++extent_index);
452 mdl->code(extent_index) = Atom::Operator(fwd_opcode, 2);
453 mdl->code(++extent_index) = Atom::VLPointer(q0);
454 mdl->code(++extent_index) = Atom::Float(constant_);
457 write_index = extent_index;
458 mdl->code(MDL_BWD_GUARDS) = Atom::IPointer(++write_index);
459 mdl->code(write_index) = Atom::Set(5);
461 extent_index = write_index + 5;
463 write_guard(mdl, t0, t2, Opcodes::Sub, period_, write_index, extent_index);
464 write_guard(mdl, t1, t3, Opcodes::Sub, period_, write_index, extent_index);
466 write_guard(mdl, t4, t2, Opcodes::Sub, offset_, write_index, extent_index);
467 write_guard(mdl, t5, t3, Opcodes::Sub, period_, write_index, extent_index);
469 mdl->code(++write_index) = Atom::AssignmentPointer(q0, ++extent_index);
470 mdl->code(extent_index) = Atom::Operator(bwd_opcode, 2);
471 mdl->code(++extent_index) = Atom::VLPointer(q1);
472 mdl->code(++extent_index) = Atom::Float(constant_);
475 write_index = extent_index;
478 void ConstGuardBuilder::_build(
Code *mdl, uint16 fwd_opcode, uint16 bwd_opcode, _Fact *premise_pattern, _Fact *cause_pattern, uint16 &write_index)
const {
483 uint16 tpl_arg_set_index = mdl->code(MDL_TPL_ARGS).asIndex();
484 if (mdl->code(tpl_arg_set_index).getAtomCount() == 0) {
486 q0 = premise_pattern->get_reference(0)->code(MK_VAL_VALUE).asIndex();
487 t0 = premise_pattern->code(FACT_AFTER).asIndex();
488 t1 = premise_pattern->code(FACT_BEFORE).asIndex();
496 _build(mdl, fwd_opcode, bwd_opcode, q0, t0, t1, write_index);
501 MGuardBuilder::MGuardBuilder(microseconds period, float32 constant, microseconds offset) : ConstGuardBuilder(period, constant, offset) {
504 MGuardBuilder::~MGuardBuilder() {
507 void MGuardBuilder::build(
Code *mdl, _Fact *premise_pattern, _Fact *cause_pattern, uint16 &write_index)
const {
509 _build(mdl, Opcodes::Mul, Opcodes::Div, premise_pattern, cause_pattern, write_index);
514 AGuardBuilder::AGuardBuilder(microseconds period, float32 constant, microseconds offset) : ConstGuardBuilder(period, constant, offset) {
517 AGuardBuilder::~AGuardBuilder() {
520 void AGuardBuilder::build(
Code *mdl, _Fact *premise_pattern, _Fact *cause_pattern, uint16 &write_index)
const {
522 _build(mdl, Opcodes::Add, Opcodes::Sub, premise_pattern, cause_pattern, write_index);
527 ConstBwdArgCmdGuardBuilder::ConstBwdArgCmdGuardBuilder(microseconds period, microseconds offset, uint16 cmd_arg_index, _Fact* cause) : TimingGuardBuilder(period), offset_(offset), cmd_arg_index_(cmd_arg_index), cause_(cause) {
530 ConstBwdArgCmdGuardBuilder::~ConstBwdArgCmdGuardBuilder() {
533 void ConstBwdArgCmdGuardBuilder::build(
Code* mdl, _Fact* premise_pattern, _Fact* cause_pattern, uint16& write_index)
const {
538 Code* rhs = mdl->get_reference(1);
539 uint16 t2 = rhs->code(FACT_AFTER).asIndex();
540 uint16 t3 = rhs->code(FACT_BEFORE).asIndex();
542 Code* lhs = mdl->get_reference(0);
543 uint16 cmd_t0 = lhs->code(FACT_AFTER).asIndex();
544 uint16 cmd_t1 = lhs->code(FACT_BEFORE).asIndex();
545 uint16 cmd_arg = lhs->get_reference(0)->code(cmd_arg_index_).asIndex();
547 mdl->code(MDL_FWD_GUARDS) = Atom::IPointer(++write_index);
548 mdl->code(write_index) = Atom::Set(2);
550 uint16 extent_index = write_index + 2;
552 write_guard(mdl, t2, t0, Opcodes::Add, period_, write_index, extent_index);
553 write_guard(mdl, t3, t1, Opcodes::Add, period_, write_index, extent_index);
555 write_index = extent_index;
556 mdl->code(MDL_BWD_GUARDS) = Atom::IPointer(++write_index);
557 mdl->code(write_index) = Atom::Set(5);
559 extent_index = write_index + 5;
561 write_guard(mdl, t0, t2, Opcodes::Sub, period_, write_index, extent_index);
562 write_guard(mdl, t1, t3, Opcodes::Sub, period_, write_index, extent_index);
564 write_guard(mdl, cmd_t0, t2, Opcodes::Sub, offset_, write_index, extent_index);
565 write_guard(mdl, cmd_t1, t3, Opcodes::Sub, period_, write_index, extent_index);
568 Atom cmd_arg_value = cause_->get_reference(0)->code(cmd_arg_index_);
569 mdl->code(++write_index) = Atom::AssignmentPointer(cmd_arg, ++extent_index);
570 if (cmd_arg_value.getDescriptor() == Atom::I_PTR &&
571 cause_->get_reference(0)->code(cmd_arg_value.asIndex()).getDescriptor() == Atom::OBJECT)
574 mdl, extent_index, &cause_->get_reference(0)->code(0), cmd_arg_value.asIndex());
575 else if (cmd_arg_value.isFloat()) {
577 mdl->code(extent_index) = Atom::Operator(Opcodes::Id, 1);
578 mdl->code(++extent_index) = cmd_arg_value;
582 write_index = extent_index;