Skip to content

Commit ba2c8ee

Browse files
committed
added dir operation
1 parent 9641ef3 commit ba2c8ee

File tree

13 files changed

+170
-33
lines changed

13 files changed

+170
-33
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@ To install or update LODA, please follow the [installation instructions](https:/
22

33
## [Unreleased]
44

5+
## v25.3.29
6+
7+
### Features
8+
9+
* Added `dir` operation for repeated division
10+
511
## v25.2.15
612

713
### Bugfixes

src/eval/interpreter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ Number Interpreter::calc(const Operation::Type type, const Number& target,
5959
case Operation::Type::DIF: {
6060
return Semantics::dif(target, source);
6161
}
62+
case Operation::Type::DIR: {
63+
return Semantics::dir(target, source);
64+
}
6265
case Operation::Type::MOD: {
6366
return Semantics::mod(target, source);
6467
}

src/eval/optimizer.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ bool Optimizer::optimize(Program &p) const {
5656
if (collapseMovLoops(p)) {
5757
changed = true;
5858
}
59+
if (collapseDifLoops(p)) {
60+
changed = true;
61+
}
5962
if (collapseArithmeticLoops(p)) {
6063
changed = true;
6164
}
@@ -705,6 +708,31 @@ bool Optimizer::collapseMovLoops(Program &p) const {
705708
return changed;
706709
}
707710

711+
bool Optimizer::collapseDifLoops(Program &p) const {
712+
bool changed = false;
713+
for (size_t i = 0; i + 2 < p.ops.size(); i++) {
714+
if (p.ops[i].type != Operation::Type::LPB ||
715+
p.ops[i + 1].type != Operation::Type::DIF ||
716+
p.ops[i + 2].type != Operation::Type::LPE) {
717+
continue;
718+
}
719+
const auto &lpb = p.ops[i];
720+
const auto &dif = p.ops[i + 1];
721+
if (lpb.source != Operand(Operand::Type::CONSTANT, 1) ||
722+
lpb.target.type != Operand::Type::DIRECT ||
723+
dif.source.type != Operand::Type::CONSTANT ||
724+
dif.target != lpb.target) {
725+
continue;
726+
}
727+
const auto val = dif.source.value;
728+
p.ops.erase(p.ops.begin() + i + 1, p.ops.begin() + i + 3);
729+
p.ops[i] = Operation(Operation::Type::DIR, lpb.target,
730+
Operand(Operand::Type::CONSTANT, val));
731+
changed = true;
732+
}
733+
return changed;
734+
}
735+
708736
bool Optimizer::collapseArithmeticLoops(Program &p) const {
709737
if (ProgramUtil::hasIndirectOperand(p)) {
710738
return false;

src/eval/optimizer.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ class Optimizer {
3333

3434
bool collapseMovLoops(Program &p) const;
3535

36+
bool collapseDifLoops(Program &p) const;
37+
3638
bool collapseArithmeticLoops(Program &p) const;
3739

3840
bool pullUpMov(Program &p) const;

src/eval/semantics.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,21 @@ Number Semantics::dif(const Number& a, const Number& b) {
3939
return (a == mul(b, d)) ? d : a;
4040
}
4141

42+
Number Semantics::dir(const Number& a, const Number& b) {
43+
if (a == Number::INF || b == Number::INF) {
44+
return Number::INF;
45+
}
46+
auto aa = a;
47+
while (true) {
48+
auto r = dif(aa, b);
49+
if (abs(r) == abs(aa)) {
50+
break;
51+
}
52+
aa = r;
53+
}
54+
return aa;
55+
}
56+
4257
Number Semantics::mod(const Number& a, const Number& b) {
4358
auto r = a;
4459
r %= b;

src/eval/semantics.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ class Semantics {
1616

1717
static Number dif(const Number& a, const Number& b);
1818

19+
static Number dir(const Number& a, const Number& b);
20+
1921
static Number mod(const Number& a, const Number& b);
2022

2123
static Number pow(const Number& base, const Number& exp);

src/lang/program.cpp

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,19 @@
22

33
#include <stdexcept>
44

5-
const std::array<Operation::Type, 33> Operation::Types = {
5+
const std::array<Operation::Type, 34> Operation::Types = {
66
Operation::Type::NOP, Operation::Type::MOV, Operation::Type::ADD,
77
Operation::Type::SUB, Operation::Type::TRN, Operation::Type::MUL,
8-
Operation::Type::DIV, Operation::Type::DIF, Operation::Type::MOD,
9-
Operation::Type::POW, Operation::Type::GCD, Operation::Type::LEX,
10-
Operation::Type::BIN, Operation::Type::LOG, Operation::Type::NRT,
11-
Operation::Type::DGS, Operation::Type::DGR, Operation::Type::EQU,
12-
Operation::Type::NEQ, Operation::Type::LEQ, Operation::Type::GEQ,
13-
Operation::Type::MIN, Operation::Type::MAX, Operation::Type::BAN,
14-
Operation::Type::BOR, Operation::Type::BXO, Operation::Type::LPB,
15-
Operation::Type::LPE, Operation::Type::CLR, Operation::Type::SRT,
16-
Operation::Type::SEQ, Operation::Type::PRG, Operation::Type::DBG,
8+
Operation::Type::DIV, Operation::Type::DIF, Operation::Type::DIR,
9+
Operation::Type::MOD, Operation::Type::POW, Operation::Type::GCD,
10+
Operation::Type::LEX, Operation::Type::BIN, Operation::Type::LOG,
11+
Operation::Type::NRT, Operation::Type::DGS, Operation::Type::DGR,
12+
Operation::Type::EQU, Operation::Type::NEQ, Operation::Type::LEQ,
13+
Operation::Type::GEQ, Operation::Type::MIN, Operation::Type::MAX,
14+
Operation::Type::BAN, Operation::Type::BOR, Operation::Type::BXO,
15+
Operation::Type::LPB, Operation::Type::LPE, Operation::Type::CLR,
16+
Operation::Type::SRT, Operation::Type::SEQ, Operation::Type::PRG,
17+
Operation::Type::DBG,
1718
};
1819

1920
const Operation::Metadata& Operation::Metadata::get(Type t) {
@@ -33,6 +34,8 @@ const Operation::Metadata& Operation::Metadata::get(Type t) {
3334
Operation::Type::DIV, "div", 2, true, true, true};
3435
static Operation::Metadata dif{
3536
Operation::Type::DIF, "dif", 2, true, true, true};
37+
static Operation::Metadata dir{
38+
Operation::Type::DIR, "dir", 2, true, true, true};
3639
static Operation::Metadata mod{
3740
Operation::Type::MOD, "mod", 2, true, true, true};
3841
static Operation::Metadata pow{
@@ -100,6 +103,8 @@ const Operation::Metadata& Operation::Metadata::get(Type t) {
100103
return div;
101104
case Operation::Type::DIF:
102105
return dif;
106+
case Operation::Type::DIR:
107+
return dir;
103108
case Operation::Type::MOD:
104109
return mod;
105110
case Operation::Type::POW:
@@ -167,12 +172,6 @@ const Operation::Metadata& Operation::Metadata::get(const std::string& name) {
167172
if (name == "cmp") {
168173
return get(Operation::Type::EQU);
169174
}
170-
if (name == "dis") {
171-
return get(Operation::Type::DGS);
172-
}
173-
if (name == "dir") {
174-
return get(Operation::Type::DGR);
175-
}
176175
throw std::runtime_error("invalid operation: " + name);
177176
}
178177

src/lang/program.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class Operation {
4242
MUL, // multiplication
4343
DIV, // division
4444
DIF, // conditional division
45+
DIR, // repeated division
4546
MOD, // modulo
4647
POW, // power
4748
GCD, // greatest common divisor
@@ -70,7 +71,7 @@ class Operation {
7071
__COUNT // number of operation types
7172
};
7273

73-
static const std::array<Type, 33> Types;
74+
static const std::array<Type, 34> Types;
7475

7576
class Metadata {
7677
public:

src/lang/program_util.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ bool ProgramUtil::isNop(const Operation &op) {
5858
((op.type == Operation::Type::MUL ||
5959
op.type == Operation::Type::DIV ||
6060
op.type == Operation::Type::DIF ||
61+
op.type == Operation::Type::DIR ||
6162
op.type == Operation::Type::POW ||
6263
op.type == Operation::Type::BIN))) {
6364
return true;
@@ -516,16 +517,17 @@ void ProgramUtil::avoidNopOrOverflow(Operation &op) {
516517
}
517518
if ((op.source.value == 0 || op.source.value == 1) &&
518519
(op.type == Operation::Type::MUL || op.type == Operation::Type::DIV ||
519-
op.type == Operation::Type::DIF || op.type == Operation::Type::MOD ||
520-
op.type == Operation::Type::POW || op.type == Operation::Type::GCD ||
521-
op.type == Operation::Type::BIN)) {
520+
op.type == Operation::Type::DIF || op.type == Operation::Type::DIR ||
521+
op.type == Operation::Type::MOD || op.type == Operation::Type::POW ||
522+
op.type == Operation::Type::GCD || op.type == Operation::Type::BIN)) {
522523
op.source.value = 2;
523524
}
524525
} else if (op.source.type == Operand::Type::DIRECT) {
525526
if ((op.source.value == op.target.value) &&
526527
(op.type == Operation::Type::MOV || op.type == Operation::Type::DIV ||
527-
op.type == Operation::Type::DIF || op.type == Operation::Type::MOD ||
528-
op.type == Operation::Type::GCD || op.type == Operation::Type::BIN)) {
528+
op.type == Operation::Type::DIF || op.type == Operation::Type::DIR ||
529+
op.type == Operation::Type::MOD || op.type == Operation::Type::GCD ||
530+
op.type == Operation::Type::BIN)) {
529531
op.target.value += Number::ONE;
530532
}
531533
}

src/mine/iterator.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ bool Iterator::inc(Operation& op) {
8181
return true;
8282

8383
case Operation::Type::DIF:
84+
op.type = Operation::Type::DIR;
85+
return true;
86+
87+
case Operation::Type::DIR:
8488
op.type = Operation::Type::MOD;
8589
return true;
8690

@@ -176,17 +180,18 @@ bool Iterator::shouldSkip(const Operation& op) {
176180
(op.type == Operation::Type::ADD || op.type == Operation::Type::SUB ||
177181
op.type == Operation::Type::TRN || op.type == Operation::Type::MUL ||
178182
op.type == Operation::Type::DIV || op.type == Operation::Type::DIF ||
179-
op.type == Operation::Type::MOD || op.type == Operation::Type::GCD ||
180-
op.type == Operation::Type::LEX || op.type == Operation::Type::BIN ||
181-
op.type == Operation::Type::EQU || op.type == Operation::Type::NEQ)) {
183+
op.type == Operation::Type::DIR || op.type == Operation::Type::MOD ||
184+
op.type == Operation::Type::GCD || op.type == Operation::Type::LEX ||
185+
op.type == Operation::Type::BIN || op.type == Operation::Type::EQU ||
186+
op.type == Operation::Type::NEQ)) {
182187
return true;
183188
}
184189
if (op.source == CONSTANT_ZERO &&
185190
(op.type == Operation::Type::MUL || op.type == Operation::Type::DIV ||
186-
op.type == Operation::Type::DIF || op.type == Operation::Type::MOD ||
187-
op.type == Operation::Type::POW || op.type == Operation::Type::GCD ||
188-
op.type == Operation::Type::LEX || op.type == Operation::Type::BIN ||
189-
op.type == Operation::Type::LPB)) {
191+
op.type == Operation::Type::DIF || op.type == Operation::Type::DIR ||
192+
op.type == Operation::Type::MOD || op.type == Operation::Type::POW ||
193+
op.type == Operation::Type::GCD || op.type == Operation::Type::LEX ||
194+
op.type == Operation::Type::BIN || op.type == Operation::Type::LPB)) {
190195
return true;
191196
}
192197
if (op.source == CONSTANT_ONE &&

0 commit comments

Comments
 (0)