Fixing addressing
- Fix double resolve bug in address handler - Fix multiple major issues with next_closing and prev_opening functions. - add `=` ed command. - Other minor fixes.
This commit is contained in:
@@ -26,8 +26,12 @@ Address::Result Address::handle(BEd &ctx, std::string &cmd, uint64_t &i) {
|
|||||||
curr.offset = 0;
|
curr.offset = 0;
|
||||||
prev_given = false;
|
prev_given = false;
|
||||||
} else {
|
} else {
|
||||||
if (cmd[i] == ';')
|
if (cmd[i] == ';') {
|
||||||
ctx.active->jump(curr.resolve(ctx));
|
uint64_t resolved = curr.resolve(ctx);
|
||||||
|
ctx.active->jump(resolved);
|
||||||
|
curr.base = Number(resolved);
|
||||||
|
curr.offset = 0;
|
||||||
|
}
|
||||||
prev_given = true;
|
prev_given = true;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
|
|||||||
@@ -6,9 +6,7 @@ uint64_t Address::resolve(BEd &ctx) {
|
|||||||
uint64_t result = std::visit(
|
uint64_t result = std::visit(
|
||||||
[&](auto const &addr) -> uint64_t {
|
[&](auto const &addr) -> uint64_t {
|
||||||
uint64_t line = 0;
|
uint64_t line = 0;
|
||||||
|
|
||||||
using T = std::decay_t<decltype(addr)>;
|
using T = std::decay_t<decltype(addr)>;
|
||||||
|
|
||||||
if constexpr (std::is_same_v<T, std::monostate>) {
|
if constexpr (std::is_same_v<T, std::monostate>) {
|
||||||
throw address_error("empty address");
|
throw address_error("empty address");
|
||||||
} else if constexpr (std::is_same_v<T, None>) {
|
} else if constexpr (std::is_same_v<T, None>) {
|
||||||
@@ -21,27 +19,32 @@ uint64_t Address::resolve(BEd &ctx) {
|
|||||||
line = addr.i;
|
line = addr.i;
|
||||||
} else if constexpr (std::is_same_v<T, Block>) {
|
} else if constexpr (std::is_same_v<T, Block>) {
|
||||||
if (addr.dir == Direction::Forward) {
|
if (addr.dir == Direction::Forward) {
|
||||||
if (ctx.active->parser)
|
if (ctx.active->parser) {
|
||||||
line = ctx.active->parser->next_closing(ctx.active->line);
|
if (ctx.active->line == 0)
|
||||||
else
|
ctx.active->line = 1;
|
||||||
|
line = ctx.active->parser->next_closing(ctx.active->line - 1) + 1;
|
||||||
|
if (line > ctx.active->vase.lines())
|
||||||
|
line = ctx.active->vase.lines();
|
||||||
|
} else {
|
||||||
line = ctx.active->line + 10;
|
line = ctx.active->line + 10;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (ctx.active->parser) {
|
||||||
|
if (ctx.active->line == 0)
|
||||||
|
ctx.active->line = 1;
|
||||||
|
line = ctx.active->parser->prev_opening(ctx.active->line - 1) + 1;
|
||||||
} else {
|
} else {
|
||||||
if (ctx.active->parser)
|
|
||||||
line = ctx.active->parser->prev_opening(ctx.active->line);
|
|
||||||
else
|
|
||||||
line = ctx.active->line - 10;
|
line = ctx.active->line - 10;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
throw ed_error("Unhandled address given.");
|
throw ed_error("Unhandled address given.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset < 0 && line < (uint64_t)-offset)
|
if (offset < 0 && line < (uint64_t)-offset)
|
||||||
throw address_error("Can't have negative addresses");
|
throw address_error("Can't have negative addresses");
|
||||||
line += offset;
|
line += offset;
|
||||||
|
|
||||||
if (line > ctx.active->vase.lines())
|
if (line > ctx.active->vase.lines())
|
||||||
throw address_error("Line number too high.");
|
throw address_error("Line number too high.");
|
||||||
|
|
||||||
return line;
|
return line;
|
||||||
},
|
},
|
||||||
base
|
base
|
||||||
|
|||||||
@@ -101,6 +101,21 @@ void Command::register_posix(BEd &ctx) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
ctx.commands.insert(
|
||||||
|
"=",
|
||||||
|
Command{
|
||||||
|
.address_mode = Command::AddressMode::Single,
|
||||||
|
.suffix = Command::SuffixKind::Suffix,
|
||||||
|
.desc = "Print line number",
|
||||||
|
.accept_zero = false,
|
||||||
|
.handle = [](BEd &ctx, std::span<const uint64_t> addresses, std::string_view) {
|
||||||
|
if (!addresses.size())
|
||||||
|
std::cout << ctx.active->vase.lines() << std::endl;
|
||||||
|
else
|
||||||
|
std::cout << addresses[0] << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
ctx.commands.insert(
|
ctx.commands.insert(
|
||||||
"debug",
|
"debug",
|
||||||
Command{
|
Command{
|
||||||
|
|||||||
@@ -260,66 +260,65 @@ void Parser::modify(vase::Vase &vase, uint64_t target, uint64_t count) {
|
|||||||
|
|
||||||
uint64_t Parser::next_closing(uint64_t line) {
|
uint64_t Parser::next_closing(uint64_t line) {
|
||||||
if (!root)
|
if (!root)
|
||||||
return line + 10;
|
return UINT64_MAX;
|
||||||
uint64_t relative;
|
uint64_t relative = 0;
|
||||||
TreeCursor c(root, line, &relative);
|
TreeCursor c(root, line, &relative);
|
||||||
uint64_t at = line - relative;
|
uint64_t line_offset = line - relative;
|
||||||
uint32_t from = (uint32_t)relative;
|
int level = 0;
|
||||||
bool first = true;
|
bool first_leaf = true;
|
||||||
int depth = 0;
|
|
||||||
while (c.leaf) {
|
while (c.leaf) {
|
||||||
auto *leaf = c.leaf;
|
auto *leaf = c.leaf;
|
||||||
for (uint32_t i = 0; i < leaf->n; ++i) {
|
for (uint32_t i = 0; i < leaf->n; ++i) {
|
||||||
uint32_t block = leaf->blocks[i];
|
uint32_t block = leaf->blocks[i];
|
||||||
uint32_t pos = block & ParseStateLeaf::LINE_MASK;
|
uint32_t pos = block & ParseStateLeaf::LINE_MASK;
|
||||||
if (first && pos <= from)
|
if (first_leaf && pos <= relative)
|
||||||
continue;
|
continue;
|
||||||
if (block & ParseStateLeaf::IS_CLOSING) {
|
bool closing = block & ParseStateLeaf::IS_CLOSING;
|
||||||
if (depth == 0)
|
if (closing) {
|
||||||
return at + pos;
|
if (level == 0)
|
||||||
--depth;
|
return line_offset + pos;
|
||||||
|
--level;
|
||||||
} else {
|
} else {
|
||||||
++depth;
|
++level;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
at += leaf->lines();
|
line_offset += leaf->lines();
|
||||||
first = false;
|
|
||||||
c.next();
|
c.next();
|
||||||
|
first_leaf = false;
|
||||||
}
|
}
|
||||||
return line + 10;
|
return UINT64_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t Parser::prev_opening(uint64_t line) {
|
uint64_t Parser::prev_opening(uint64_t line) {
|
||||||
if (!root)
|
if (!root)
|
||||||
return line >= 10 ? line - 10 : 0;
|
return 0;
|
||||||
uint64_t relative;
|
uint64_t relative = 0;
|
||||||
TreeCursor c(root, line, &relative);
|
TreeCursor c(root, line, &relative);
|
||||||
uint64_t at = line - relative;
|
uint64_t line_offset = line - relative;
|
||||||
uint32_t from = (uint32_t)relative;
|
int level = 0;
|
||||||
bool first = true;
|
bool first_leaf = true;
|
||||||
int depth = 0;
|
|
||||||
while (c.leaf) {
|
while (c.leaf) {
|
||||||
auto *leaf = c.leaf;
|
auto *leaf = c.leaf;
|
||||||
for (uint32_t i = leaf->n; i-- > 0;) {
|
for (int32_t i = (int32_t)leaf->n - 1; i >= 0; --i) {
|
||||||
uint32_t block = leaf->blocks[i];
|
uint32_t block = leaf->blocks[i];
|
||||||
uint32_t pos = block & ParseStateLeaf::LINE_MASK;
|
uint32_t pos = block & ParseStateLeaf::LINE_MASK;
|
||||||
if (first && pos >= from)
|
if (first_leaf && pos >= relative)
|
||||||
continue;
|
continue;
|
||||||
if (!(block & ParseStateLeaf::IS_CLOSING)) {
|
bool closing = block & ParseStateLeaf::IS_CLOSING;
|
||||||
if (depth == 0)
|
if (!closing) {
|
||||||
return at + pos;
|
if (level == 0)
|
||||||
--depth;
|
return line_offset + pos;
|
||||||
|
--level;
|
||||||
} else {
|
} else {
|
||||||
++depth;
|
++level;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.prev();
|
c.prev();
|
||||||
if (!c.leaf)
|
first_leaf = false;
|
||||||
break;
|
if (c.leaf)
|
||||||
at -= c.leaf->lines();
|
line_offset -= c.leaf->lines();
|
||||||
first = false;
|
|
||||||
}
|
}
|
||||||
return line >= 10 ? line - 10 : 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<Parser::Iterator> Parser::get_hl(vase::Vase &vase, uint64_t target) {
|
std::optional<Parser::Iterator> Parser::get_hl(vase::Vase &vase, uint64_t target) {
|
||||||
|
|||||||
@@ -1003,14 +1003,14 @@ bool handle_syntax(RubyParser &p, std::vector<Token> *tokens, std::vector<ParseE
|
|||||||
j++;
|
j++;
|
||||||
if (p.i + j >= p.len())
|
if (p.i + j >= p.len())
|
||||||
return false;
|
return false;
|
||||||
if (
|
if (p.peek(j) == '&'
|
||||||
p.peek(j) == '-'
|
|
||||||
|| p.peek(j) == '&'
|
|
||||||
|| p.peek(j) == '%'
|
|| p.peek(j) == '%'
|
||||||
|| p.peek(j) == ':'
|
|| p.peek(j) == ':') {
|
||||||
) {
|
|
||||||
if (p.peek(j + 1) == ' ' || p.peek(j + 1) == '>')
|
if (p.peek(j + 1) == ' ' || p.peek(j + 1) == '>')
|
||||||
return false;
|
return false;
|
||||||
|
} else if (p.peek(j) == '-') {
|
||||||
|
if (p.peek(j + 1) != '>')
|
||||||
|
return false;
|
||||||
} else if (
|
} else if (
|
||||||
p.peek(j) == ']'
|
p.peek(j) == ']'
|
||||||
|| p.peek(j) == '}'
|
|| p.peek(j) == '}'
|
||||||
|
|||||||
Reference in New Issue
Block a user