Signed-off-by: erick-alcachofa <erick@artichoke.dev>
This commit addresses several critical issues in the recursive descent
parser, specifically regarding the handling of empty constructs,
statement termination, and AST representation of nested scopes. These
changes bring the implementation in line with the Artichoke EBNF
specification.
* **CodeBlock as Statement:** Added `CodeBlockStmtNode` to the
`StatementNode` variant. This allows a bare `{}` to be treated as a
valid statement, enabling manual scoping within functions.
* **Visitor Support:** Updated `toDot.cpp` (Graphviz) and `toString.cpp`
(Pretty-print) to support the new `CodeBlockStmtNode` during AST
traversal.
* **Empty Member Lists:** Implemented a pre-loop check for the closing
brace `}` in `parseStruct` and `parseEnum`. This prevents the parser
from attempting to parse members in empty declarations (e.g., `struct
Empty {}`).
* **Diagnostic Accuracy:** Enhanced the member-parsing loop to provide
better error context. If a member is not followed by a comma or a
closing brace, the parser now explicitly suggests `',' or '}'` as the
expected tokens.
* **Nested Scopes:** The parser now correctly identifies a `{` at the
start of a statement and dispatches to `parseCodeBlock`.
* **Empty Code Blocks:** Added a guard in the block-parsing loop to
check for `}` immediately after `{`, allowing functions or nested
scopes to be empty.
* **C-Style For-Loops:** Replaced `match` with `matchAndConsume` for the
initialization semicolon. This allows the parser to correctly handle
loops where the initialization is omitted (e.g., `for (; 1; 1)`).
* **Correctness:** Resolves parser hangs or errors when encountering
empty blocks.
* **Compliance:** Fully supports the EBNF definition of zero-or-more
members/statements.
* **Visuals:** AST diagrams now accurately reflect nested block
structures.
Signed-off-by: erick-alcachofa <erick@artichoke.dev>
Complete the transition from a declarations-only parser to a functional
imperative parser. This commit introduces the implementation for all
major statement types, loop constructs, and core control flow logic.
- **Match Case Update**: Updated `grammar.ebnf` to use pipe delimiters
`|id|` for unwrapped variables in match cases, replacing the previous
parenthetical syntax.
- **Labels**: Implemented loop labeling using the `ident := loop`
syntax. Labels are validated to ensure they only prefix valid loop
constructs.
- **Labels and Ranges**: Standardized the use of the `:=` operator for
both loop labels (`label := loop`) and range-for declarations (`let i
:= range`).
- **Conditional Branches**:
- Fully implemented `if` and `else` statements.
- Added support for optional variable unwrapping (e.g., `if (expr)
|val|`).
- Supported `else if` chaining by recursively parsing if-statements
within else-branches.
- **Loops**:
- **C-Style For**: Implemented `for (init; cond; post)` with
optional initializers and post-loop expressions.
- **Range For**: Implemented `for (let i := range)` with mutability
controls.
- **While & Do-While**: Implemented standard condition-based loops.
- **Infinite Loop**: Added the explicit `loop` keyword for infinite
iteration.
- **Loop Dispatch**: Added a lookahead mechanism in
`parseForLoopStatement` to differentiate between C-style and
Range-style loops based on token positioning.
- **Variables**: Implemented `let`/`def` parsing within local scopes,
including type annotations and initializers.
- **Defer Logic**: Implemented `defer` and `errdefer` for scope-guarded
execution.
- **Jumps**: Implemented `break`, `continue` (with optional label
targets), and `return` (with optional expressions).
- **Match & Switch**: Fully implemented branch parsing, with possible
default cases via the `_` (underscore) keyword.
- **Expression Integration**: Stubbed `parseExpression` in a new
`Expressions.cpp` to serve as the integration point for value parsing.
- **OverloadSet**: Integrated `OverloadSet` utility in `Statements.cpp`
to cleanly handle AST node variant visitation for label injection.
- **Error Handling**: Standardized error reporting across all new paths
using `langException`, providing specific "expected" messages for
delimiters and keywords.
Signed-off-by: erick-alcachofa <erick@artichoke.dev>
Relocate core parsing utility methods from the header to the
implementation file to reduce header bloat and improve compilation
times.
- **Parser API**: Moved the definitions of `consume()`,
`matchAndConsume()`, and `match()` from `Parser.hpp` to `Parser.cpp`.
- **Cleanup**: Removed an unused `<print>` include in `Types.cpp`
discovered during the refactor.
- **Organization**: Methods are now declared in the header and defined
in the source file, maintaining a cleaner separation between interface
and implementation.
Signed-off-by: erick-alcachofa <erick@artichoke.dev>
Major refactoring of the Parser and Tokenizer components to improve code
maintainability, strengthen error messaging, and streamline AST
generation.
This version intentionally focuses on top-level declarations, with
statement parsing stubbed for the next development phase.
- **Path Sanitization**: Added `sanitizePath` to extract filenames from
input paths, ensuring consistent `unitName` identification regardless
of directory depth.
- **Improved Output**: Wrapped AST string output in Markdown code blocks
and added a commented-out entry for the new DOT graph visualization.
- **Unified Consumption**: Replaced manual token checks with a more
robust `consume()` method that leverages `peekExpect()` for
centralized error handling.
- **New Predicates**: Introduced `match()` and `matchAndConsume()`
helpers to handle optional tokens and branching logic without
redundant peek/consume calls.
- **Exception Handling**: Standardized the use of `langException` across
all parsing functions, providing more descriptive "Expected X, found
Y" messages.
- **Declarations**: Refactored `parseTopLevelDeclaration` and
sub-parsers (Module, Struct, Enum, Fn) to use the new matching
patterns.
- **Looping Logic**: Replaced recursive-style parsing loops with
`while(keepParsing)` iterative blocks to prevent stack depth issues
and clarify termination conditions (e.g., finding a closing brace or
failing to find a comma).
- **Namespaced Identifiers**: Rewrote `parseNamespacedIdentifier` to
correctly handle multi-part paths (`A::B::C`) and edge cases.
- **Generic Support**: Improved handling of generic parameter and
argument lists, ensuring strict enforcement of delimiters like `<` and
`>`.
- **Contextual Errors**: Updated `peekExpect` to accept a custom
`message` string, allowing the parser to describe *what* it was
looking for (e.g., "Expected ';'").
- **Token Lookahead**: Enhanced `peek` and `peekExpect` reliability with
better bounds checking and buffer management.
- **Removed `lib/src/Parser/AST/AST.cpp`**: Deleted the monolithic AST
stringification file in favor of the previously introduced modular
implementations.
- **Build System**: Updated `.gitignore` to ignore
`cpm-package-lock.cmake`.
Signed-off-by: erick-alcachofa <erick@artichoke.dev>
This commit refactors the AST printing functionality by moving the
human-readable `toString` implementation into its own file
(`lib/src/Parser/AST/toString.cpp`) and introducing a new `toDot`
function in `lib/src/Parser/AST/toDot.cpp` for generating Graphviz DOT
format output.
The `AST.hpp` header is updated to declare both the new `toDot` function
and the modified `toString` function, which now uses an optional
`prefix` parameter for prettier tree output. The `Token.hpp`/`Token.cpp`
files are also adjusted to have `toString(const TokenV &)` return a
`std::string_view`, and `toString(const Token &)` provides a cleaner
string representation using only the token's value.
Signed-off-by: erick-alcachofa <erick@artichoke.dev>
This commit introduces the foundational structure for the parser and
Abstract Syntax Tree (AST). It includes a new `Parser.hpp` header that
outlines the primary parsing functions for top-level declarations like
`modules`, `structs`, `enums`, and `functions`. It also adds a
`toString` function for the AST to aid in debugging and visualization.
The commit also updates the `Expected.hpp` utility by adding new error
codes like `ecUnexpectedToken`, `ecExpectedSemicolon`,
`ecImportInsideModule`, and `ecUnimplemented` to provide more granular
and descriptive parsing errors. The `Tokenizer` has been updated to use
these new, more specific exceptions.
Signed-off-by: erick-alcachofa <erick@artichoke.dev>
This commit refactors several AST nodes to use `Optional<T>` for fields
that are not always present. This includes `attribute` in
`ReflectionExpression`, `elseBranch` in `IfStatement` and
`WhileStatement`, `defaultCase` in `MatchStatement` and
`SwitchStatement`, and `preLoop` and `postLoop` in `CForStatement`. This
change improves the robustness and clarity of the AST by explicitly
modeling optionality.
Signed-off-by: erick-alcachofa <erick@artichoke.dev>
This commit adds `Uninitialized` to several enums in `Common.hpp` to
ensure they are properly initialized.
It also adds missing binary operators like `BitAnd`, `BitXor`,
`Adition`, and `Multiplication`. This change improves the robustness and
functionality of the AST parser.
Signed-off-by: erick-alcachofa <erick@artichoke.dev>
This commit introduces an utility factory function and structural
improvements to the Abstract Syntax Tree (AST).
* Adds a new `ASTNodePtr` C++20 concept to constrain template types to
be `std::unique_ptr`s pointing to AST nodes.
* Introduces a `MakeNode<T>()` factory function that uses this concept
to simplify and standardize the creation of new nodes.
* Fixed `NamespacedType` and added the missing `NamespacedIdentifier`
node.
Signed-off-by: erick-alcachofa <erick@artichoke.dev>
This commit refactors the AST (Abstract Syntax Tree) to improve code
organization, clarity, and maintainability. The large single-file AST
definition has been split into multiple, logically grouped header files.
The key changes are:
- **New File Structure**: The single `Node.hpp` file is replaced by a
modular structure consisting of `Common.hpp`, `Declarations.hpp`,
`Expressions.hpp`, `Literals.hpp`, `Statements.hpp`, and a new central
`AST.hpp` header.
- **Improved Naming**: All AST node structs and their aliases have been
renamed to follow a consistent `[NodeName][NodeType]` convention, such
as `StructDeclaration` and `StructDeclNode`.
- **Namespace Change**: The `node` namespace has been replaced by
`arti::lang::ast::nodes` to provide better encapsulation and prevent
naming conflicts.
- **Type Aliases**: Helper aliases like `String`, `Vector`, and
`Variant` have been introduced to simplify the code.
Signed-off-by: erick-alcachofa <erick@artichoke.dev>
Introduces the comprehensive header file for the Abstract Syntax Tree,
providing the foundational structures for the parser and subsequent
compiler stages.
This initial version defines all node types required to represent the
language's grammar, including:
- Top-level program structure and module declarations.
- All statement types, including control flow, loops, and deferrals.
- A semantic expression tree designed for a Pratt parser (Unary, Binary,
Function Calls, etc.).
- A robust, recursive type system for handling complex type signatures.
The design employs modern C++ for safety and clarity:
- `std::unique_ptr` establishes clear ownership of child nodes.
- `std::variant` provides type-safe polymorphism for Statement,
Expression, and Declaration nodes.
- `std::optional` is used to accurately model optional grammar rules.
- `SourceLocation` is included in every node to support detailed error
reporting.