summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib94/warrior.cpp38
-rw-r--r--warriors/dwarf-replicator.red2
-rw-r--r--warriors/dwarf.red4
-rw-r--r--warriors/epson.red6
4 files changed, 43 insertions, 7 deletions
diff --git a/lib94/warrior.cpp b/lib94/warrior.cpp
index e5b0095..6efa409 100644
--- a/lib94/warrior.cpp
+++ b/lib94/warrior.cpp
@@ -73,6 +73,17 @@ namespace lib94 {
}
};
+ struct negative_number_expr : public number_expr {
+ std::unique_ptr<number_expr> inner;
+
+ virtual std::optional<number_t> to_number(const std::map<std::string, number_t> &label_offsets, const std::map<std::string, number_t> &macro_values, number_t this_offset) {
+ std::optional<number_t> inner_result = inner->to_number(label_offsets, macro_values, this_offset);
+ if (inner_result.has_value())
+ return LIB94_CORE_SIZE - inner_result.value();
+ return {};
+ }
+ };
+
bool valid_label(std::string candidate) {
if (candidate == "")
return false;
@@ -91,8 +102,21 @@ namespace lib94 {
size_t layers = 0;
for (int i = part.size() - 1; i >= 0; --i)
- if (layers == 0 && candidates.find(part[i]) != std::string::npos)
+ if (layers == 0 && candidates.find(part[i]) != std::string::npos) {
+
+ if (part[i] == '-' || part[i] == '+') {
+ for (int j = i - 1; j >= 0; --j) {
+ if (isalnum(part[j]) || part[j] == '_' || part[j] == ')')
+ return i;
+ if (part[j] != ' ')
+ break;
+ }
+ continue;
+ }
+
return i;
+ }
+
else if (part[i] == ')')
++layers;
else if (part[i] == '(')
@@ -157,6 +181,18 @@ namespace lib94 {
if (part[0] == '(' && part[part.size() - 1] == ')')
return to_number_expr(part.substr(1, part.size() - 2));
+ if (part[0] == '+')
+ return to_number_expr(part.substr(1));
+
+ if (part[0] == '-') {
+ std::optional<std::unique_ptr<number_expr>> inner = to_number_expr(part.substr(1));
+ if (!inner.has_value())
+ return {};
+ std::unique_ptr<negative_number_expr> expr = std::make_unique<negative_number_expr>();
+ expr->inner = std::move(inner.value());
+ return expr;
+ }
+
try {
size_t count;
number_t number = std::stoul(part, &count);
diff --git a/warriors/dwarf-replicator.red b/warriors/dwarf-replicator.red
index f301a05..01a1494 100644
--- a/warriors/dwarf-replicator.red
+++ b/warriors/dwarf-replicator.red
@@ -37,7 +37,7 @@ dwarf:
core_clear:
mov end, end + 1
- add.ab #1, 0-1
+ add.ab #1, -1
jmp 2
dat
diff --git a/warriors/dwarf.red b/warriors/dwarf.red
index e0e2638..d2df37e 100644
--- a/warriors/dwarf.red
+++ b/warriors/dwarf.red
@@ -2,5 +2,5 @@
;name Dwarf
mov 3, 7
-add.ab #4, 0-1
-jmp 0-2
+add.ab #4, -1
+jmp -2
diff --git a/warriors/epson.red b/warriors/epson.red
index b0409f0..a327807 100644
--- a/warriors/epson.red
+++ b/warriors/epson.red
@@ -6,7 +6,7 @@ period equ 10
scan_init equ end - (end - scan) % period + period
scan:
- seq.i 0 - period, scan_init
+ seq.i -period, scan_init
jmp found
found_ret:
@@ -18,13 +18,13 @@ found_ret:
jmn.a scan, scan
clear:
- mov end, 0 - 1
+ mov end, - 1
sub.ab #2, clear
seq.ab #end - clear - (end - clear) % 2 + 3, clear
jmp clear
- mov.ab #0 - 1, clear
+ mov.ab #-1, clear
jmp clear
scan_add: