From 556bb631f6b8a8e30594950678366503a3793e56 Mon Sep 17 00:00:00 2001 From: Syed Daanish Date: Fri, 21 Aug 2026 20:35:20 +0100 Subject: [PATCH] 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. --- src/internal/address/handle.cc | 8 +++- src/internal/address/resolve.cc | 25 ++++++------ src/internal/commands/commands.cc | 15 +++++++ src/internal/syntax/parser.cc | 65 +++++++++++++++---------------- src/internal/syntax/ruby/parse.cc | 12 +++--- 5 files changed, 73 insertions(+), 52 deletions(-) diff --git a/src/internal/address/handle.cc b/src/internal/address/handle.cc index bf607bd..a7b28f1 100644 --- a/src/internal/address/handle.cc +++ b/src/internal/address/handle.cc @@ -26,8 +26,12 @@ Address::Result Address::handle(BEd &ctx, std::string &cmd, uint64_t &i) { curr.offset = 0; prev_given = false; } else { - if (cmd[i] == ';') - ctx.active->jump(curr.resolve(ctx)); + if (cmd[i] == ';') { + uint64_t resolved = curr.resolve(ctx); + ctx.active->jump(resolved); + curr.base = Number(resolved); + curr.offset = 0; + } prev_given = true; } i++; diff --git a/src/internal/address/resolve.cc b/src/internal/address/resolve.cc index aad659f..249bc2b 100644 --- a/src/internal/address/resolve.cc +++ b/src/internal/address/resolve.cc @@ -6,9 +6,7 @@ uint64_t Address::resolve(BEd &ctx) { uint64_t result = std::visit( [&](auto const &addr) -> uint64_t { uint64_t line = 0; - using T = std::decay_t; - if constexpr (std::is_same_v) { throw address_error("empty address"); } else if constexpr (std::is_same_v) { @@ -21,27 +19,32 @@ uint64_t Address::resolve(BEd &ctx) { line = addr.i; } else if constexpr (std::is_same_v) { if (addr.dir == Direction::Forward) { - if (ctx.active->parser) - line = ctx.active->parser->next_closing(ctx.active->line); - else + if (ctx.active->parser) { + if (ctx.active->line == 0) + 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; + } } else { - if (ctx.active->parser) - line = ctx.active->parser->prev_opening(ctx.active->line); - 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 { line = ctx.active->line - 10; + } } } else { throw ed_error("Unhandled address given."); } - if (offset < 0 && line < (uint64_t)-offset) throw address_error("Can't have negative addresses"); line += offset; - if (line > ctx.active->vase.lines()) throw address_error("Line number too high."); - return line; }, base diff --git a/src/internal/commands/commands.cc b/src/internal/commands/commands.cc index e19365d..bbb9d63 100644 --- a/src/internal/commands/commands.cc +++ b/src/internal/commands/commands.cc @@ -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 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( "debug", Command{ diff --git a/src/internal/syntax/parser.cc b/src/internal/syntax/parser.cc index a8223d3..16aae73 100644 --- a/src/internal/syntax/parser.cc +++ b/src/internal/syntax/parser.cc @@ -260,66 +260,65 @@ void Parser::modify(vase::Vase &vase, uint64_t target, uint64_t count) { uint64_t Parser::next_closing(uint64_t line) { if (!root) - return line + 10; - uint64_t relative; + return UINT64_MAX; + uint64_t relative = 0; TreeCursor c(root, line, &relative); - uint64_t at = line - relative; - uint32_t from = (uint32_t)relative; - bool first = true; - int depth = 0; + uint64_t line_offset = line - relative; + int level = 0; + bool first_leaf = true; while (c.leaf) { auto *leaf = c.leaf; for (uint32_t i = 0; i < leaf->n; ++i) { uint32_t block = leaf->blocks[i]; uint32_t pos = block & ParseStateLeaf::LINE_MASK; - if (first && pos <= from) + if (first_leaf && pos <= relative) continue; - if (block & ParseStateLeaf::IS_CLOSING) { - if (depth == 0) - return at + pos; - --depth; + bool closing = block & ParseStateLeaf::IS_CLOSING; + if (closing) { + if (level == 0) + return line_offset + pos; + --level; } else { - ++depth; + ++level; } } - at += leaf->lines(); - first = false; + line_offset += leaf->lines(); c.next(); + first_leaf = false; } - return line + 10; + return UINT64_MAX; } uint64_t Parser::prev_opening(uint64_t line) { if (!root) - return line >= 10 ? line - 10 : 0; - uint64_t relative; + return 0; + uint64_t relative = 0; TreeCursor c(root, line, &relative); - uint64_t at = line - relative; - uint32_t from = (uint32_t)relative; - bool first = true; - int depth = 0; + uint64_t line_offset = line - relative; + int level = 0; + bool first_leaf = true; while (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 pos = block & ParseStateLeaf::LINE_MASK; - if (first && pos >= from) + if (first_leaf && pos >= relative) continue; - if (!(block & ParseStateLeaf::IS_CLOSING)) { - if (depth == 0) - return at + pos; - --depth; + bool closing = block & ParseStateLeaf::IS_CLOSING; + if (!closing) { + if (level == 0) + return line_offset + pos; + --level; } else { - ++depth; + ++level; } } c.prev(); - if (!c.leaf) - break; - at -= c.leaf->lines(); - first = false; + first_leaf = false; + if (c.leaf) + line_offset -= c.leaf->lines(); } - return line >= 10 ? line - 10 : 0; + return 0; } std::optional Parser::get_hl(vase::Vase &vase, uint64_t target) { diff --git a/src/internal/syntax/ruby/parse.cc b/src/internal/syntax/ruby/parse.cc index 9d3be86..2bbb1ad 100644 --- a/src/internal/syntax/ruby/parse.cc +++ b/src/internal/syntax/ruby/parse.cc @@ -1003,14 +1003,14 @@ bool handle_syntax(RubyParser &p, std::vector *tokens, std::vector= p.len()) return false; - if ( - p.peek(j) == '-' - || p.peek(j) == '&' - || p.peek(j) == '%' - || p.peek(j) == ':' - ) { + if (p.peek(j) == '&' + || p.peek(j) == '%' + || p.peek(j) == ':') { if (p.peek(j + 1) == ' ' || p.peek(j + 1) == '>') return false; + } else if (p.peek(j) == '-') { + if (p.peek(j + 1) != '>') + return false; } else if ( p.peek(j) == ']' || p.peek(j) == '}'