Skip to content

Releases: rail5/bashpp

v0.8.7

23 Mar 01:03
7d88b66

Choose a tag to compare

  • Lexer bug fix: Only register elif/else/fi as keywords if they're
    lvalues
  • Build system: Simplified and generalized build system with
    auto-discovered sources
    Refactored the build system to remove per- directory object rules
    and replace them with a single generic pattern that mirrors the
    source tree into bin/obj.
  • Code style improvements:
    Replaced global bpp_exit_code with data member of the Listener class
    Replaced pointer arithmetic in parse_arguments() with std::span usage
    Added default case to xgetopt switch
    No need to explicitly default virtual destructors for LSP message
    base types
    Explicit member initialization everywhere
    Use emplace_back() for temporaries
    Explicitly handle ownership semantics in BashppParser
    Use BashppParser.setInputFromFilePath instead of from FilePtr where
    ownership may be ambiguous
    bpp-lsp: Moved URI validation to freestanding function
    Option parsing: Allow non-regular files (such as /dev/null) for output,
    just check whether we have write permission
  • Test suite: Added '-c' option to benchmark compile times without actually
    running the compiled tests
  • Parser: error out of datamember declarations when given an lvalue object
    reference instead of a proper object instantiation

v0.8.6

16 Feb 05:09
2f602c2

Choose a tag to compare

  • Supershells: Preserve stderr as subshells do
    Supershells in Bash++ now handle stderr identically to subshell
    substitution, matching Bash 5.3's native supershells.
    Previously, supershells in 5.2-compatibility mode discarded stderr; now it
    is preserved.
    Added regression test for supershell stderr handling.
  • Dynamic cast codegen: Don't force-quote reference code
    Fixed edge-case bug where generated code for dynamic casts would
    incorrectly add quotes around the reference code. Now preserves original
    quoting as written in source.
    Added regression test for dynamic cast quoting.
  • Parser: Never override lexer's positive lvalue judgment
    Fixed bug where parser could incorrectly override the lexer's
    determination that a token could be an lvalue.
    Ensures correct handling of lvalue/rvalue distinctions, especially around
    redirections and pipes.
    Added regression test for this behavior.
  • Test suite: Run tests for Bash 5.2 and 5.3
    Tests are now run twice if Bash >=5.3 is installed:
    once for 5.2 compatibility, once for 5.3.

v0.8.5

15 Feb 02:51
9b944c1

Choose a tag to compare

  • Bug fix: bpp-lsp: Don't re-throw exceptions
    When the input stream is unexpectedly halted, make sure we go through our
    necessary clean-up procedure. Re-throwing the received exception in this
    case would suddenly halt the program sans clean-up.
  • Bug fix: bpp: Concatenated lvalues in the parser
    Updated the parser grammar to allow operative command words to be
    composed of multiple adjacent tokens, matching Bash's behavior for
    command names.
    Added accompanying regression test
  • Replaced homegrown CLI option parsing with XGetOpt
    Vendored XGetOpt header in src/include

v0.8.4

04 Feb 07:52
5cb608a

Choose a tag to compare

  • Lexer/Parser/AST:
    Full and proper support for array indexing in object references and lvalue
    assignments; parser and listener logic updated accordingly.
    Bug fix: Properly lex isolated digits in heredoc content and escaped dollar
    signs in string interpolations.
    Improved error handling: Parser errors are now propagated to listeners and
    main program logic, enabling better diagnostics and LSP support.
    Added new test cases for parser errors and self-reference outside of class
    context.
    Bug fix: Verify we're inside a class if processing a self-reference.
    Improved output line comparison in the test suite.
  • Standard Library:
    All container empty methods now return status code
    (0 if empty, 1 otherwise) instead of echoing "true"/"false", for
    shell-friendly checks.
    Documentation and test cases updated to reflect new empty method behavior
    Consistent return conventions across Array, Stack, Queue, SharedArray,
    SharedStack, SharedQueue, SharedVar, TypedArray, TypedStack, and TypedQueue
  • Documentation:
    Added and clarified language specification pages, including a new page on
    the "entity" concept.
    Improved CONTRIBUTING.md with style guidelines and examples.
    Added PR template and clarified how to add test cases.
  • Language Server:
    Bug fix: If the input stream is halted, clean up and exit rather than
    hanging.
    Improved debounce logic for didChange notifications.
    Bug fix: Provide completions after 'this'/'super' keywords.
    Improved error propagation and diagnostics for parser errors.

v0.8.3

29 Jan 11:37
85a492d

Choose a tag to compare

  • Internal system methods refactored:
    Treat all internal system methods (such as __new, __delete, __copy) as
    ordinary methods.
  • Removed special-casing for system methods; they are now generated,
    overridden, and dispatched using the same mechanisms as user-defined
    methods.
  • Improved method override and inheritance logic for system methods, ensuring
    correct virtual/override semantics.
  • Refactored code generation for object creation, deletion, and copying to
    use generated methods (__new, __delete, __copy) instead of templates or
    global functions.
  • Enhanced constructor and destructor handling for better inheritance and
    chaining.
  • Added comprehensive regression tests for copy, delete, and constructor
    chaining behaviors.
  • Code cleanup and improved error propagation in method prologues.

v0.8.2

28 Jan 12:00
6cb5929

Choose a tag to compare

  • bpp: Code entities: When adding objects, don't force quotes around the
    assignment value
  • bpp: Throw a detailed syntax error if a data member's name is not unique

v0.8.1

28 Jan 04:48
bed7da8

Choose a tag to compare

  • bpp: Enhanced method override tracking and reference propagation:
    Added weak pointer tracking for overridden methods in bpp_entity and
    bpp_method.
    Improved reference propagation for "find all references" and "rename
    symbol".
  • bpp: Refactored method inheritance and constructor codegen for
    virtual/override correctness:
    Improved vTable and constructor call code generation.
    Centralized constructor call logic.
    Optimized method inheritance and override tracking.
  • bpp: Bug fix: for/select statements: Ensure code buffers are flushed.
  • bpp: More efficient CRTP: Removed std::invoke and map, use switch with
    if constexpr.
  • bpp: FlatIntervalTree: Replaced IntervalTree for better cache locality and
    performance.
  • bpp: Error handling improvements:
    Preserve node children for diagnostics.
    Unified InternalError and SyntaxError handling.
    Improved error reporting and tree traversal.
    Display 1-indexed line/column numbers in error messages.
  • bpp-lsp: Bug fix: Properly identify entities as lvalues in assignments in
    the language server.
  • bpp-lsp: Adaptive debounce timing for didChange notifications in the
    language server
    Debounce interval now adapts to reparse durations.
    Simplified unsaved changes tracking.
    Improved logging and thread safety.
  • bpp-lsp: Bug fix: Provide completions after 'this'/'super' keywords in the
    language server.
  • bpp-lsp: Changed global BashppServer instance to pointer for better server
    lifetime control.
  • libstd-bpp: STL: Use supershells, remove head/tail dependencies, use sed.
  • Test suite: Use supershells for faster execution.

v0.8.0

25 Jan 08:31
6afee0c

Choose a tag to compare

This is a MASSIVE upgrade involving a MASSIVE speed increase.

Here is an article about this change: https://log.bpp.sh/2026/01/25/the-parser-is-dead-long-live-the-parser.html

  • Rewrote the entire lexer/parser using Flex/Bison instead of ANTLR4
    This also comes with a MASSIVE parser speed-up. It's orders of
    magnitude faster than it was before.
    This also means we now manually build and traverse our own AST,
    giving us greater control.
    This is arguably the biggest internal change to the compiler since
    the v0.1 release.
  • Fixed #10 incidentally as a consequence of the parser rewrite.
    All generated pre- and post-code for Bash++ constructs is now
    guaranteed to only run in the event that the main code itself runs.
  • bpp-lsp: Added a '-b' / '--target-bash' option to the language server
    This mirrors the same option in the compiler, and affects some
    diagnostics and warnings about compatibility.
  • Reworked ObjectReference handling from the ground-up
  • Solved a few memory leaks by removing owning pointers where owneship
    was neither necessary nor desirable
  • Fixed parsing and handling of heredocs
    Previously, the parser naively assumed that the heredoc header/delim
    had to immediately precede the heredoc content. There is no such
    restriction imposed by Bash. We now parse accurately
  • Preserve exit status codes of executed commands using the new __repeat
    system function

v0.7.1

19 Aug 16:23
3eff378

Choose a tag to compare

  • Compile with C++23 standard
  • bpp-lsp: Eliminate deadlock potential in ProgramPool
    Restrict ourselves to only one mutex, and use atomic operations on
    the snapshot state instead of relying on a secondary mutex which
    could otherwise potentially cause deadlock
  • bpp-lsp: Bug fix: avoid re-parsing twice
  • docs: Cleaned up synopsis on manual page for 'typeof'

v0.7.0

18 Aug 15:40
a1fc3c6

Choose a tag to compare

  • bpp: Added typeof operator: Returns a pointer's class name as a
    string
  • Dynamic casts: return nonzero exit code if the cast fails under any
    circumstances
  • bpp: Allow dynamic_casts to resolve the target class dynamically at
    runtime
    With this update:
    • @dynamic_cast<$shell_var> and @dynamic_cast<@object.reference> are now valid syntax
    • If a shell variable or object reference are given as the target 'cast-to' class, the compiler will expect to resolve the class type at runtime
    • @dynamic_cast<ClassName> is still absolutely valid syntax, however, ClassName being invalid will no longer result in a syntax error, but will instead give a warning that 'ClassName' does not refer to any known class and that the cast may fail at runtime
  • Error reporting overhaul: Better and more conscious UTF8 handling
    Removed the 'position_unknown' checks; we no longer have to deal
    with unknown positions now that we're not relying on ANTLR's built-
    in position tracking
    Separation of concerns: moved padding, etc, utf8 procedures to
    helper functions rather than complicating things by inlining
    everything
  • Bug fix in entity resolution: Declare all temporary variables local
    if possible
    If we're inside a class, a supershell, or bash function, it's
    possible for us to declare all temporary variables 'local', and we
    absolutely should
    This fixes a bug with nested object references. For example,
    @this.member=@(echo @this.member and then some)
    If the temporary variables necessary to access this.member are not
    declared local, then:
    • The pre-code necessary to access this.member precedes that assignment statement
    • Then, we enter the supershell in the rvalue of the assignment statement, which also contains a reference to this.member
    • So, once again we generate the pre-code necessary to access it, we access it,
    • AND THEN we execute the post-code necesary to clear the memory
    • That memory having been cleared, we return from the supershell context to the broader assignment statement
      And we find that we no longer know where to put the rvalue.
      The variables which told us how to access this.member have been
      cleared from inside the supershell.
      If we declare all temporary variables local however, then the pre-
      and post-code within the supershell is entirely isolated from the
      pre- and post-code of the surrounding assignment statement.
  • STL: Added Typed versions of arrays, stacks and queues
    With our new dynamic cast semantics permitting runtime
    evaluation of the target (casted) type, runtime type restrictions
    become enforceable and typed containers such as these become
    possible
  • STL: Added TypedShared classes: Shared (concurrency-safe) data
    structures with runtime type enforcement on their elements
  • bpp-lsp: Wrap program parsing in try-catch
    No need to crash if there's a ParseCancellationException etc.
    The lexer & parser still need a full rewrite.
  • bpp-lsp: ProgramPool: Verify parsing was successful before changing
    pool state
    This prevents crashes which may come from storing 'nullptr' parse
    results in the program pool's state, and later (unthinkingly) using
    them as if they were valid pointers. It also prevents us from losing
    diagnostic information about programs which have been parsed, which
    have also undergone incomplete updates that can't yet be fully
    re-parsed.
  • bpp-lsp: Keep state AND snapshot of state
    This eliminates any slight possibility for race conditions, where
    one thread may jump the queue and access an element of the
    ProgramPool's state while another thread is simultaneously modifying
    it