unary + and - in compiler

This commit is contained in:
Benji Dial 2023-05-30 01:07:38 -04:00
parent fbabd9f801
commit 78835a06e4
4 changed files with 43 additions and 7 deletions

View file

@ -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);

View file

@ -37,7 +37,7 @@ dwarf:
core_clear:
mov end, end + 1
add.ab #1, 0-1
add.ab #1, -1
jmp 2
dat

View file

@ -2,5 +2,5 @@
;name Dwarf
mov 3, 7
add.ab #4, 0-1
jmp 0-2
add.ab #4, -1
jmp -2

View file

@ -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: