Skip to content

Enhancement: Introduce Result type for parser error handling #142

Description

@clank-hayen

Problem

The parser currently uses exceptions for error handling:

throw runtime_error("expected 'or' handler (return, fail, match, block, continue, or break) at line " + to_string(or_line));

This approach has issues:

  1. Control flow is hard to follow - exceptions can propagate unexpectedly
  2. No recovery possible - the parser stops at first error
  3. Inconsistent with codegen - which uses C++ exceptions but typechecker collects errors

Current State

  • Lexer: Throws `runtime_error` on invalid input
  • Parser: Throws `runtime_error` on syntax errors
  • Typechecker: Collects errors in `TypeCheckerState.errors` vector (good pattern!)
  • Codegen: Returns strings, no explicit error handling

Suggested Solution

Adopt a Result pattern similar to what typechecker does:

// Option 1: Use expected-like type
template<typename T>
using ParseResult = std::expected<T, ParseError>;

// Option 2: Follow typechecker pattern
struct ParserState {
    vector<ParseError> errors;
    // ...
};

// Continue parsing after errors
void report_error(ParserState& state, const string& msg, int line) {
    state.errors.push_back({msg, line, state.filename});
    synchronize(state);  // Skip to next statement
}

This would allow:

  • Collecting multiple errors in a single parse
  • Better error recovery
  • Consistent error handling across the compiler

Implementation Notes

  • Start with parser, extend to lexer later
  • Add synchronization points to recover from errors
  • Follow the existing typechecker pattern

Priority

Medium - Current exception-based approach works but limits error reporting quality.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions