erick-alcachofa 9626ac07c8
refactor(AST): Make optional some fields in AST nodes
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.
2025-10-15 15:58:06 -06:00

239 lines
5.2 KiB
C++

#pragma once
#include <artichoke/Parser/AST/Common.hpp>
#include <artichoke/Parser/AST/Types.hpp>
#include <artichoke/Parser/AST/Expressions.hpp>
namespace arti::lang::ast {
namespace nodes {
/* Forward declaration of types */
/* Main declaration node types */
struct CodeBlockStatement;
struct VariableDeclStatement;
struct IfStatement;
struct ElseStatement;
struct DeferStatement;
struct ErrDeferStatement;
struct ReturnStatement;
struct BreakStatement;
struct ContinueStatement;
struct MatchStatement;
struct SwitchStatement;
struct CForStatement;
struct RangeForStatement;
struct WhileStatement;
struct DoWhileStatement;
struct InfLoopStatement;
struct ExpressionStatement;
/* Helper declaration node types */
struct MatchCase;
struct SwitchCase;
} // namespace nodes
/* Public Aliases */
using CodeBlockStmtNode = Ptr<nodes::CodeBlockStatement>;
using VariableStmtNode = Ptr<nodes::VariableDeclStatement>;
using IfStmtNode = Ptr<nodes::IfStatement>;
using ElseStmtNode = Ptr<nodes::ElseStatement>;
using DeferStmtNode = Ptr<nodes::DeferStatement>;
using ErrDeferStmtNode = Ptr<nodes::ErrDeferStatement>;
using ReturnStmtNode = Ptr<nodes::ReturnStatement>;
using BreakStmtNode = Ptr<nodes::BreakStatement>;
using ContinueStmtNode = Ptr<nodes::ContinueStatement>;
using MatchStmtNode = Ptr<nodes::MatchStatement>;
using SwitchStmtNode = Ptr<nodes::SwitchStatement>;
using CForStmtNode = Ptr<nodes::CForStatement>;
using RangeForStmtNode = Ptr<nodes::RangeForStatement>;
using WhileStmtNode = Ptr<nodes::WhileStatement>;
using DoWhileStmtNode = Ptr<nodes::DoWhileStatement>;
using InfLoopStmtNode = Ptr<nodes::InfLoopStatement>;
using ExpressionStmtNode = Ptr<nodes::ExpressionStatement>;
using MatchCaseNode = Ptr<nodes::MatchCase>;
using SwitchCaseNode = Ptr<nodes::SwitchCase>;
/* Variant nodes */
using StatementNode = Variant<
VariableStmtNode,
IfStmtNode,
DeferStmtNode,
ErrDeferStmtNode,
ReturnStmtNode,
BreakStmtNode,
ContinueStmtNode,
MatchStmtNode,
SwitchStmtNode,
CForStmtNode,
RangeForStmtNode,
WhileStmtNode,
DoWhileStmtNode,
InfLoopStmtNode,
ExpressionStmtNode
>;
using ElseBranchNode = Variant<
ElseStmtNode,
IfStmtNode
>;
using DeferableNode = Variant<
ExpressionStmtNode,
CodeBlockStmtNode
>;
using PreLoopStmtNode = Variant<
VariableStmtNode,
ExpressionStmtNode
>;
/* Node definitions */
struct nodes::CodeBlockStatement {
SourceLocation location;
Vector<StatementNode> statements;
};
struct nodes::VariableDeclStatement {
SourceLocation location;
String name;
Mutability mutability;
Optional<TypeNode> type;
Optional<ExpressionNode> initializer;
};
struct nodes::IfStatement {
SourceLocation location;
Optional<String> unwrappedVar;
ExpressionNode condition;
CodeBlockStmtNode body;
Optional<ElseBranchNode> elseBranch;
};
struct nodes::ElseStatement {
SourceLocation location;
Optional<String> unwrappedVar;
CodeBlockStmtNode body;
};
struct nodes::DeferStatement {
SourceLocation location;
DeferableNode body;
};
struct nodes::ErrDeferStatement {
SourceLocation location;
DeferableNode body;
};
struct nodes::ReturnStatement {
SourceLocation location;
Optional<ExpressionNode> value;
};
struct nodes::BreakStatement {
SourceLocation location;
Optional<String> label;
};
struct nodes::ContinueStatement {
SourceLocation location;
Optional<String> label;
};
struct nodes::MatchStatement {
SourceLocation location;
ExpressionNode value;
Vector<MatchCaseNode> matchCases;
Optional<CodeBlockStmtNode> defaultCase;
};
struct nodes::SwitchStatement {
SourceLocation location;
ExpressionNode value;
Vector<SwitchCaseNode> switchCases;
Optional<CodeBlockStmtNode> defaultCase;
};
struct nodes::CForStatement {
SourceLocation location;
Optional<String> label;
Optional<PreLoopStmtNode> preLoop;
ExpressionNode condition;
Optional<ExpressionNode> postLoop;
CodeBlockStmtNode body;
};
struct nodes::RangeForStatement {
SourceLocation location;
Optional<String> label;
String varName;
Mutability varMutability;
ExpressionNode range;
CodeBlockStmtNode body;
};
struct nodes::WhileStatement {
SourceLocation location;
Optional<String> label;
Optional<String> unwrappedVar;
ExpressionNode condition;
CodeBlockStmtNode body;
Optional<ElseBranchNode> elseBranch;
};
struct nodes::DoWhileStatement {
SourceLocation location;
Optional<String> label;
ExpressionNode condition;
CodeBlockStmtNode body;
};
struct nodes::InfLoopStatement {
SourceLocation location;
Optional<String> label;
CodeBlockStmtNode body;
};
struct nodes::ExpressionStatement {
SourceLocation location;
ExpressionNode expression;
};
struct nodes::MatchCase {
SourceLocation location;
TypeNode matchType;
Optional<String> unwrappedVar;
CodeBlockStmtNode body;
};
struct nodes::SwitchCase {
SourceLocation location;
ExpressionNode matchExpr;
CodeBlockStmtNode body;
};
} // namespace arti::lang::ast