diff --git a/src/ast.rs b/src/ast.rs index 745f700a..d0fe7452 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -11,6 +11,8 @@ use std::fmt; mod span; pub use span::Span; mod utils; +mod nodes; +pub use nodes::*; // Span は src/ast/span.rs へ分離(re-export で後方互換維持) diff --git a/src/ast/nodes.rs b/src/ast/nodes.rs new file mode 100644 index 00000000..6197bedf --- /dev/null +++ b/src/ast/nodes.rs @@ -0,0 +1,134 @@ +//! Lightweight wrapper structs around ASTNode variants (non-breaking). +//! +//! Purpose: provide a gentle path to work with structured nodes via +//! TryFrom/From without changing the canonical AST enum. This enables +//! gradual refactors in builders by converting once at the boundary and +//! then matching on small, typed wrappers. + +use super::{ASTNode, Span}; + +// ---------------- +// Statements +// ---------------- + +#[derive(Debug, Clone)] +pub struct AssignStmt { + pub target: Box, + pub value: Box, + pub span: Span, +} + +impl TryFrom for AssignStmt { + type Error = ASTNode; + fn try_from(node: ASTNode) -> Result { + match node { + ASTNode::Assignment { target, value, span } => Ok(AssignStmt { target, value, span }), + other => Err(other), + } + } +} + +impl From for ASTNode { + fn from(s: AssignStmt) -> Self { + ASTNode::Assignment { target: s.target, value: s.value, span: s.span } + } +} + +#[derive(Debug, Clone)] +pub struct ReturnStmt { + pub value: Option>, + pub span: Span, +} + +impl TryFrom for ReturnStmt { + type Error = ASTNode; + fn try_from(node: ASTNode) -> Result { + match node { + ASTNode::Return { value, span } => Ok(ReturnStmt { value, span }), + other => Err(other), + } + } +} + +impl From for ASTNode { + fn from(s: ReturnStmt) -> Self { + ASTNode::Return { value: s.value, span: s.span } + } +} + +#[derive(Debug, Clone)] +pub struct IfStmt { + pub condition: Box, + pub then_body: Vec, + pub else_body: Option>, + pub span: Span, +} + +impl TryFrom for IfStmt { + type Error = ASTNode; + fn try_from(node: ASTNode) -> Result { + match node { + ASTNode::If { condition, then_body, else_body, span } => Ok(IfStmt { condition, then_body, else_body, span }), + other => Err(other), + } + } +} + +impl From for ASTNode { + fn from(s: IfStmt) -> Self { + ASTNode::If { condition: s.condition, then_body: s.then_body, else_body: s.else_body, span: s.span } + } +} + +// ---------------- +// Expressions +// ---------------- + +#[derive(Debug, Clone)] +pub struct BinaryExpr { + pub operator: super::BinaryOperator, + pub left: Box, + pub right: Box, + pub span: Span, +} + +impl TryFrom for BinaryExpr { + type Error = ASTNode; + fn try_from(node: ASTNode) -> Result { + match node { + ASTNode::BinaryOp { operator, left, right, span } => + Ok(BinaryExpr { operator, left, right, span }), + other => Err(other), + } + } +} + +impl From for ASTNode { + fn from(e: BinaryExpr) -> Self { + ASTNode::BinaryOp { operator: e.operator, left: e.left, right: e.right, span: e.span } + } +} + +#[derive(Debug, Clone)] +pub struct CallExpr { + pub name: String, + pub arguments: Vec, + pub span: Span, +} + +impl TryFrom for CallExpr { + type Error = ASTNode; + fn try_from(node: ASTNode) -> Result { + match node { + ASTNode::FunctionCall { name, arguments, span } => Ok(CallExpr { name, arguments, span }), + other => Err(other), + } + } +} + +impl From for ASTNode { + fn from(c: CallExpr) -> Self { + ASTNode::FunctionCall { name: c.name, arguments: c.arguments, span: c.span } + } +} +