diff options
-rw-r--r-- | lib94/warrior.cpp | 38 | ||||
-rw-r--r-- | warriors/dwarf-replicator.red | 2 | ||||
-rw-r--r-- | warriors/dwarf.red | 4 | ||||
-rw-r--r-- | warriors/epson.red | 6 |
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> ¯o_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: |