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:
2026-08-21 20:35:20 +01:00
parent 3e3fb6c39d
commit 556bb631f6
5 changed files with 73 additions and 52 deletions
+6 -2
View File
@@ -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++;
+14 -11
View File
@@ -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
+15
View File
@@ -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{
+32 -33
View File
@@ -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) {
+5 -5
View File
@@ -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) == '}'