1use crate::{
2 StringHandle, Token,
3 frontend::{ast_node_arena::NodeId, node_array_arena::NodeArrayId},
4};
5use std::convert::TryFrom;
6
7#[derive(Debug, Clone, PartialEq, Default, Copy)]
8pub struct SourceSpan {
9 pub start: usize,
10 pub end: usize,
11}
12
13impl SourceSpan {
14 pub fn new(start: usize, end: usize) -> Self {
15 Self { start, end }
16 }
17
18 pub fn from_token(token: &Token) -> Self {
19 Self {
20 start: token.start,
21 end: token.end,
22 }
23 }
24
25 pub fn combine(start: SourceSpan, end: SourceSpan) -> Self {
26 Self {
27 start: start.start,
28 end: end.end,
29 }
30 }
31}
32
33#[derive(Debug, Clone, PartialEq, Copy)]
35pub enum AssignmentOperator {
36 Assign, AddAssign, SubtractAssign, MultiplyAssign, DivideAssign, ModuloAssign, }
43
44#[derive(Debug, Clone, PartialEq, Copy)]
45pub enum ComparisonOperator {
46 Greater, GreaterEqual, Less, LessEqual, }
51
52#[derive(Debug, Clone, PartialEq, Copy)]
53pub enum EqualityOperator {
54 Equal, NotEqual, Is, }
58
59#[derive(Debug, Clone, PartialEq, Copy)]
60pub enum FactorOperator {
61 Divide, Multiply, Modulo, }
65
66#[derive(Debug, Clone, PartialEq, Copy)]
67pub enum TermOperator {
68 Add, Subtract, }
71
72#[derive(Debug, Clone, PartialEq, Copy)]
73pub enum UnaryOperator {
74 Minus, Not, }
77
78#[derive(Debug, Clone, PartialEq, Copy)]
79pub enum AstNode {
80 Module(Module),
81 Class(ClassDeclNode),
82 Function(FunctionDeclNode),
83 Identifier(IdentifierNode),
84 FieldDecl(FieldDeclNode),
85 FunctionDecl(FunctionDeclNode),
86 FunctionExpr(FunctionExprNode),
87 NumberLiteral(NumberLiteralNode),
88 StringLiteral(StringLiteralNode),
89 BooleanLiteral(BooleanLiteralNode),
90 NilLiteral(NilLiteralNode),
91 ThisExpr(ThisExprNode),
92 SuperExpr(SuperExprNode),
93 AssignmentExpr(AssignmentExprNode),
94 PipeExpr(PipeExprNode),
95 TernaryExpr(TernaryExprNode),
96 LogicalOrExpr(LogicalOrExprNode),
97 LogicalAndExpr(LogicalAndExprNode),
98 EqualityExpr(EqualityExprNode),
99 ComparisonExpr(ComparisonExprNode),
100 TermExpr(TermExprNode),
101 FactorExpr(FactorExprNode),
102 UnaryExpr(UnaryExprNode),
103 CallExpr(CallExprNode),
104 CallOperation(CallNode),
105 PropertyAccess(PropertyNode),
106 PropertyAssignment(PropertyAssignmentNode),
107 OptionalPropertyAccess(OptionalPropertyNode),
108 IndexAccess(IndexNode),
109 IndexAssignment(IndexAssignmentNode),
110 ArrayLiteralExpr(ArrayLiteralExprNode),
111 ObjectLiteralExpr(ObjectLiteralExprNode),
112 ObjectEntry(ObjectEntryNode),
113 MapExpr(MapExprNode),
114 OptionalMapExpr(OptionalMapExprNode),
115 WhenExpr(WhenExprNode),
116 WhenBranch(WhenBranchNode),
117 ExprStmt(ExprStmtNode),
118 GroupingExpr(GroupingExprNode),
119 LambdaDecl(LambdaDeclNode),
120 LambdaExpr(LambdaExprNode),
121 ReturnStmt(ReturnStmtNode),
122 BreakStmt(BreakStmtNode),
123 ContinueStmt(ContinueStmtNode),
124 BlockStmt(BlockStmtNode),
125 IfStmt(IfStmtNode),
126 WhileStmt(WhileStmtNode),
127 ForStmt(ForStmtNode),
128 VariableDecl(VariableDeclNode),
129 ImportModuleDecl(ImportModuleDeclNode),
130}
131
132impl AstNode {
133 pub fn span(&self) -> SourceSpan {
134 match self {
135 AstNode::Module(node) => node.span,
136 AstNode::Class(node) => node.span,
137 AstNode::Function(node) => node.span,
138 AstNode::Identifier(node) => node.span,
139 AstNode::FieldDecl(node) => node.span,
140 AstNode::FunctionDecl(node) => node.span,
141 AstNode::FunctionExpr(node) => node.span,
142 AstNode::NumberLiteral(node) => node.span,
143 AstNode::StringLiteral(node) => node.span,
144 AstNode::BooleanLiteral(node) => node.span,
145 AstNode::NilLiteral(node) => node.span,
146 AstNode::ThisExpr(node) => node.span,
147 AstNode::SuperExpr(node) => node.span,
148 AstNode::AssignmentExpr(node) => node.span,
149 AstNode::PipeExpr(node) => node.span,
150 AstNode::TernaryExpr(node) => node.span,
151 AstNode::LogicalOrExpr(node) => node.span,
152 AstNode::LogicalAndExpr(node) => node.span,
153 AstNode::EqualityExpr(node) => node.span,
154 AstNode::ComparisonExpr(node) => node.span,
155 AstNode::TermExpr(node) => node.span,
156 AstNode::FactorExpr(node) => node.span,
157 AstNode::UnaryExpr(node) => node.span,
158 AstNode::CallExpr(node) => node.span,
159 AstNode::CallOperation(node) => node.span,
160 AstNode::PropertyAccess(node) => node.span,
161 AstNode::PropertyAssignment(node) => node.span,
162 AstNode::OptionalPropertyAccess(node) => node.span,
163 AstNode::IndexAccess(node) => node.span,
164 AstNode::IndexAssignment(node) => node.span,
165 AstNode::ArrayLiteralExpr(node) => node.span,
166 AstNode::ObjectLiteralExpr(node) => node.span,
167 AstNode::ObjectEntry(node) => node.span,
168 AstNode::MapExpr(node) => node.span,
169 AstNode::OptionalMapExpr(node) => node.span,
170 AstNode::WhenExpr(node) => node.span,
171 AstNode::WhenBranch(node) => node.span,
172 AstNode::ExprStmt(node) => node.span,
173 AstNode::GroupingExpr(node) => node.span,
174 AstNode::LambdaDecl(node) => node.span,
175 AstNode::LambdaExpr(node) => node.span,
176 AstNode::ReturnStmt(node) => node.span,
177 AstNode::BreakStmt(node) => node.span,
178 AstNode::ContinueStmt(node) => node.span,
179 AstNode::BlockStmt(node) => node.span,
180 AstNode::IfStmt(node) => node.span,
181 AstNode::WhileStmt(node) => node.span,
182 AstNode::ForStmt(node) => node.span,
183 AstNode::VariableDecl(node) => node.span,
184 AstNode::ImportModuleDecl(node) => node.span,
185 }
186 }
187}
188
189#[derive(Debug, Clone, PartialEq, Copy)]
191pub struct Module {
192 pub decls: NodeArrayId, pub span: SourceSpan,
194}
195
196#[derive(Debug, Clone, PartialEq, Copy)]
197pub struct IdentifierNode {
198 pub name: StringHandle,
199 pub span: SourceSpan,
200}
201
202#[derive(Debug, Clone, PartialEq, Copy)]
204pub struct NumberLiteralNode {
205 pub value: f64,
206 pub span: SourceSpan,
207}
208
209#[derive(Debug, Clone, PartialEq, Copy)]
211pub struct StringLiteralNode {
212 pub value: StringHandle,
213 pub span: SourceSpan,
214}
215
216#[derive(Debug, Clone, PartialEq, Copy)]
218pub struct BooleanLiteralNode {
219 pub value: bool,
220 pub span: SourceSpan,
221}
222
223#[derive(Debug, Clone, PartialEq, Copy)]
225pub struct NilLiteralNode {
226 pub span: SourceSpan,
227}
228
229#[derive(Debug, Clone, PartialEq, Copy)]
231pub struct ThisExprNode {
232 pub span: SourceSpan,
233}
234
235#[derive(Debug, Clone, PartialEq, Copy)]
237pub struct SuperExprNode {
238 pub method: NodeId, pub span: SourceSpan,
240}
241
242#[derive(Debug, Clone, PartialEq, Copy)]
244pub struct GroupingExprNode {
245 pub expr: NodeId, pub span: SourceSpan,
247}
248
249#[derive(Debug, Clone, PartialEq, Copy)]
251pub struct ArrayLiteralExprNode {
252 pub elements: NodeArrayId, pub span: SourceSpan,
254}
255
256#[derive(Debug, Clone, PartialEq, Copy)]
257pub struct ObjectLiteralExprNode {
258 pub entries: NodeArrayId, pub span: SourceSpan,
260}
261
262#[derive(Debug, Clone, PartialEq, Copy)]
263pub struct ObjectEntryNode {
264 pub key: NodeId, pub value: NodeId, pub span: SourceSpan,
267}
268
269#[derive(Debug, Clone, PartialEq, Copy)]
270pub struct ImportModuleDeclNode {
271 pub path: StringHandle,
272 pub name: NodeId, pub path_literal_span: SourceSpan, pub span: SourceSpan,
275}
276
277#[derive(Debug, Clone, PartialEq, Copy)]
279pub struct ClassDeclNode {
280 pub name: NodeId, pub superclass: Option<NodeId>, pub members: NodeArrayId, pub span: SourceSpan,
284}
285
286#[derive(Debug, Clone, PartialEq, Copy)]
288pub struct FieldDeclNode {
289 pub name: NodeId, pub initializer: Option<NodeId>, pub span: SourceSpan,
292}
293
294#[derive(Debug, Clone, PartialEq, Copy)]
296pub struct FunctionDeclNode {
297 pub function: NodeId, pub span: SourceSpan,
299}
300
301#[derive(Debug, Clone, PartialEq, Copy)]
303pub struct FunctionExprNode {
304 pub name: NodeId, pub parameters: NodeArrayId, pub body: NodeId, pub span: SourceSpan,
308}
309
310#[derive(Debug, Clone, PartialEq, Copy)]
312pub struct AssignmentExprNode {
313 pub target: NodeId, pub operator: AssignmentOperator,
315 pub value: NodeId, pub span: SourceSpan,
317}
318
319#[derive(Debug, Clone, PartialEq, Copy)]
321pub struct PropertyAssignmentNode {
322 pub property: NodeId, pub object: NodeId, pub span: SourceSpan,
325}
326
327#[derive(Debug, Clone, PartialEq, Copy)]
329pub struct IndexAssignmentNode {
330 pub object: NodeId, pub index: NodeId, pub span: SourceSpan,
333}
334
335#[derive(Debug, Clone, PartialEq, Copy)]
337pub struct PipeExprNode {
338 pub left: NodeId, pub right: NodeId, pub span: SourceSpan,
341}
342
343#[derive(Debug, Clone, PartialEq, Copy)]
345pub struct TernaryExprNode {
346 pub condition: NodeId, pub then_expr: NodeId, pub else_expr: NodeId, pub span: SourceSpan,
350}
351
352#[derive(Debug, Clone, PartialEq, Copy)]
354pub struct LogicalOrExprNode {
355 pub left: NodeId, pub right: NodeId, pub span: SourceSpan,
358}
359
360#[derive(Debug, Clone, PartialEq, Copy)]
362pub struct LogicalAndExprNode {
363 pub left: NodeId, pub right: NodeId, pub span: SourceSpan,
366}
367
368#[derive(Debug, Clone, PartialEq, Copy)]
370pub struct EqualityExprNode {
371 pub left: NodeId, pub operator: EqualityOperator,
373 pub right: NodeId, pub span: SourceSpan,
375}
376
377#[derive(Debug, Clone, PartialEq, Copy)]
379pub struct ComparisonExprNode {
380 pub left: NodeId, pub operator: ComparisonOperator,
382 pub right: NodeId, pub span: SourceSpan,
384}
385
386#[derive(Debug, Clone, PartialEq, Copy)]
387pub struct TermExprNode {
388 pub left: NodeId, pub operator: TermOperator,
390 pub right: NodeId, pub span: SourceSpan,
392}
393
394#[derive(Debug, Clone, PartialEq, Copy)]
395pub struct FactorExprNode {
396 pub left: NodeId, pub operator: FactorOperator,
398 pub right: NodeId, pub span: SourceSpan,
400}
401
402#[derive(Debug, Clone, PartialEq, Copy)]
403pub struct UnaryExprNode {
404 pub operator: UnaryOperator,
405 pub operand: NodeId, pub span: SourceSpan,
407}
408
409#[derive(Debug, Clone, PartialEq, Copy)]
411pub struct CallExprNode {
412 pub callee: NodeId, pub operation: NodeId, pub span: SourceSpan,
415}
416
417#[derive(Debug, Clone, PartialEq, Copy)]
418pub struct CallNode {
419 pub args: NodeArrayId, pub span: SourceSpan,
421}
422
423#[derive(Debug, Clone, PartialEq, Copy)]
424pub struct PropertyNode {
425 pub identifier: NodeId, pub span: SourceSpan,
427}
428
429#[derive(Debug, Clone, PartialEq, Copy)]
430pub struct OptionalPropertyNode {
431 pub identifier: NodeId, pub span: SourceSpan,
433}
434
435#[derive(Debug, Clone, PartialEq, Copy)]
436pub struct IndexNode {
437 pub index: NodeId, pub span: SourceSpan,
439}
440
441#[derive(Debug, Clone, PartialEq, Copy)]
443pub struct MapExprNode {
444 pub parameter: NodeId, pub body: NodeId, pub span: SourceSpan,
447}
448
449#[derive(Debug, Clone, PartialEq, Copy)]
451pub struct OptionalMapExprNode {
452 pub parameter: NodeId, pub body: NodeId, pub span: SourceSpan,
455}
456
457#[derive(Debug, Clone, PartialEq, Copy)]
459pub struct WhenExprNode {
460 pub value: Option<NodeId>, pub branches: NodeArrayId, pub else_branch: Option<NodeId>, pub span: SourceSpan,
464}
465
466#[derive(Debug, Clone, PartialEq, Copy)]
468pub struct WhenBranchNode {
469 pub condition: NodeId, pub is_type_check: bool, pub body: NodeId, pub span: SourceSpan,
473}
474
475#[derive(Debug, Clone, PartialEq, Copy)]
477pub struct LambdaDeclNode {
478 pub name: NodeId, pub lambda: NodeId, pub span: SourceSpan,
481}
482
483#[derive(Debug, Clone, PartialEq, Copy)]
485pub struct LambdaExprNode {
486 pub parameters: NodeArrayId, pub body: NodeId, pub span: SourceSpan,
489}
490
491#[derive(Debug, Clone, PartialEq, Copy)]
493pub struct VariableDeclNode {
494 pub target: NodeId, pub initializer: Option<NodeId>, pub span: SourceSpan,
497}
498
499#[derive(Debug, Clone, PartialEq, Copy)]
501pub struct ExprStmtNode {
502 pub expr: NodeId, pub span: SourceSpan,
504}
505
506#[derive(Debug, Clone, PartialEq, Copy)]
508pub struct BlockStmtNode {
509 pub decls: NodeArrayId, pub span: SourceSpan,
511}
512
513#[derive(Debug, Clone, PartialEq, Copy)]
515pub struct IfStmtNode {
516 pub condition: NodeId, pub then_branch: NodeId, pub else_branch: Option<NodeId>, pub span: SourceSpan,
520}
521
522#[derive(Debug, Clone, PartialEq, Copy)]
524pub struct WhileStmtNode {
525 pub condition: NodeId, pub body: NodeId, pub span: SourceSpan,
528}
529
530#[derive(Debug, Clone, PartialEq, Copy)]
532pub struct ForStmtNode {
533 pub initializer: Option<NodeId>, pub condition: Option<NodeId>, pub afterthought: Option<NodeId>, pub body: NodeId, pub span: SourceSpan,
538}
539
540#[derive(Debug, Clone, PartialEq, Copy)]
542pub struct BreakStmtNode {
543 pub span: SourceSpan,
544}
545
546#[derive(Debug, Clone, PartialEq, Copy)]
548pub struct ContinueStmtNode {
549 pub span: SourceSpan,
550}
551
552#[derive(Debug, Clone, PartialEq, Copy)]
554pub struct ReturnStmtNode {
555 pub value: Option<NodeId>, pub span: SourceSpan,
557}
558
559#[derive(Debug, Clone, PartialEq)]
560pub struct NodeConversionError(String);
561
562#[derive(Debug, Clone, PartialEq, Copy)]
563
564pub enum DeclNode {
565 Class(ClassDeclNode),
566 Function(FunctionDeclNode),
567 Lambda(LambdaDeclNode),
568 Variable(VariableDeclNode),
569 Stmt(StmtNode),
570 Module(ImportModuleDeclNode),
571}
572
573impl DeclNode {
574 pub fn span(&self) -> SourceSpan {
575 match self {
576 Self::Class(class_decl) => class_decl.span,
577 Self::Function(func_decl) => func_decl.span,
578 Self::Lambda(lambda_decl) => lambda_decl.span,
579 Self::Variable(variable_decl) => variable_decl.span,
580 Self::Stmt(stmt) => stmt.span(),
581 Self::Module(import_decl) => import_decl.span,
582 }
583 }
584}
585
586impl TryFrom<AstNode> for DeclNode {
587 type Error = NodeConversionError;
588
589 fn try_from(value: AstNode) -> Result<Self, Self::Error> {
590 match value {
591 AstNode::Class(class_decl) => Ok(DeclNode::Class(class_decl)),
592 AstNode::FunctionDecl(func_decl) => Ok(DeclNode::Function(func_decl)),
593 AstNode::LambdaDecl(lambda_decl) => Ok(DeclNode::Lambda(lambda_decl)),
594 AstNode::VariableDecl(var_decl) => Ok(DeclNode::Variable(var_decl)),
595 AstNode::ImportModuleDecl(imprt_decl) => Ok(DeclNode::Module(imprt_decl)),
596 _ => Ok(DeclNode::Stmt(StmtNode::try_from(value)?)),
597 }
598 }
599}
600
601#[derive(Debug, Clone, PartialEq, Copy)]
602
603pub enum StmtNode {
604 Expr(ExprStmtNode),
605 Block(BlockStmtNode),
606 If(IfStmtNode),
607 While(WhileStmtNode),
608 For(ForStmtNode),
609 Break(BreakStmtNode),
610 Continue(ContinueStmtNode),
611 Return(ReturnStmtNode),
612}
613
614impl StmtNode {
615 pub fn span(&self) -> SourceSpan {
616 match self {
617 Self::Expr(expr_stmt) => expr_stmt.span,
618 Self::Block(block_stmt) => block_stmt.span,
619 Self::If(if_stmt) => if_stmt.span,
620 Self::While(while_stmt) => while_stmt.span,
621 Self::For(for_stmt) => for_stmt.span,
622 Self::Break(break_stmt) => break_stmt.span,
623 Self::Continue(continue_stmt) => continue_stmt.span,
624 Self::Return(return_stmt) => return_stmt.span,
625 }
626 }
627}
628
629impl TryFrom<AstNode> for StmtNode {
630 type Error = NodeConversionError;
631
632 fn try_from(value: AstNode) -> Result<Self, Self::Error> {
633 match value {
634 AstNode::ExprStmt(expr_stmt) => Ok(StmtNode::Expr(expr_stmt)),
635 AstNode::BlockStmt(block_stmt) => Ok(StmtNode::Block(block_stmt)),
636 AstNode::IfStmt(if_stmt) => Ok(StmtNode::If(if_stmt)),
637 AstNode::WhileStmt(while_stmt) => Ok(StmtNode::While(while_stmt)),
638 AstNode::ForStmt(for_stmt) => Ok(StmtNode::For(for_stmt)),
639 AstNode::BreakStmt(break_stmt) => Ok(StmtNode::Break(break_stmt)),
640 AstNode::ContinueStmt(continue_stmt) => Ok(StmtNode::Continue(continue_stmt)),
641 AstNode::ReturnStmt(return_stmt) => Ok(StmtNode::Return(return_stmt)),
642 _ => Err(NodeConversionError(format!(
643 "Cannot convert {:?} to StmtNode",
644 value
645 ))),
646 }
647 }
648}
649
650#[derive(Debug, Clone, PartialEq, Copy)]
651pub enum ExprNode {
652 Assignment(AssignmentExprNode),
653 Pipe(PipeExprNode),
654 Ternary(TernaryExprNode),
655 LogicalOr(LogicalOrExprNode),
656 LogicalAnd(LogicalAndExprNode),
657 Equality(EqualityExprNode),
658 Comparison(ComparisonExprNode),
659 Term(TermExprNode),
660 Factor(FactorExprNode),
661 Unary(UnaryExprNode),
662 Call(CallExprNode),
663 Primary(PrimaryNode),
664}
665
666impl ExprNode {
667 pub fn span(&self) -> SourceSpan {
668 match self {
669 Self::Assignment(assignment_expr) => assignment_expr.span,
670 Self::Pipe(pipe_expr) => pipe_expr.span,
671 Self::Ternary(ternary_expr) => ternary_expr.span,
672 Self::LogicalOr(logical_or_expr) => logical_or_expr.span,
673 Self::LogicalAnd(logical_and_expr) => logical_and_expr.span,
674 Self::Equality(equality_expr) => equality_expr.span,
675 Self::Comparison(comparison_expr) => comparison_expr.span,
676 Self::Term(term_expr) => term_expr.span,
677 Self::Factor(factor_expr) => factor_expr.span,
678 Self::Unary(unary_expr) => unary_expr.span,
679 Self::Call(call_expr) => call_expr.span,
680 Self::Primary(primary) => primary.span(),
681 }
682 }
683}
684
685impl TryFrom<AstNode> for ExprNode {
686 type Error = NodeConversionError;
687
688 fn try_from(value: AstNode) -> Result<Self, Self::Error> {
689 match value {
690 AstNode::AssignmentExpr(assignment_expr) => Ok(ExprNode::Assignment(assignment_expr)),
691 AstNode::PipeExpr(pipe_expr) => Ok(ExprNode::Pipe(pipe_expr)),
692 AstNode::TernaryExpr(ternary_expr) => Ok(ExprNode::Ternary(ternary_expr)),
693 AstNode::LogicalOrExpr(logical_or_expr) => Ok(ExprNode::LogicalOr(logical_or_expr)),
694 AstNode::LogicalAndExpr(logical_and_expr) => Ok(ExprNode::LogicalAnd(logical_and_expr)),
695 AstNode::EqualityExpr(equality_expr) => Ok(ExprNode::Equality(equality_expr)),
696 AstNode::ComparisonExpr(comparison_expr) => Ok(ExprNode::Comparison(comparison_expr)),
697 AstNode::TermExpr(term_expr) => Ok(ExprNode::Term(term_expr)),
698 AstNode::FactorExpr(factor_expr) => Ok(ExprNode::Factor(factor_expr)),
699 AstNode::UnaryExpr(unary_expr) => Ok(ExprNode::Unary(unary_expr)),
700 AstNode::CallExpr(call_expr) => Ok(ExprNode::Call(call_expr)),
701 _ => Ok(ExprNode::Primary(PrimaryNode::try_from(value)?)),
702 }
703 }
704}
705
706#[derive(Debug, Clone, PartialEq, Copy)]
707pub enum CallOperationNode {
708 Call(CallNode),
709 Property(PropertyNode),
710 OptionalProperty(OptionalPropertyNode),
711 Index(IndexNode),
712 Map(MapExprNode),
713 OptionalMap(OptionalMapExprNode),
714}
715
716impl CallOperationNode {
717 pub fn span(&self) -> SourceSpan {
718 match self {
719 Self::Call(call) => call.span,
720 Self::Property(property) => property.span,
721 Self::OptionalProperty(optional_property) => optional_property.span,
722 Self::Index(index) => index.span,
723 Self::Map(map_expr) => map_expr.span,
724 Self::OptionalMap(optional_map_expr) => optional_map_expr.span,
725 }
726 }
727}
728
729impl TryFrom<AstNode> for CallOperationNode {
730 type Error = NodeConversionError;
731
732 fn try_from(value: AstNode) -> Result<Self, Self::Error> {
733 match value {
734 AstNode::CallOperation(call) => Ok(CallOperationNode::Call(call)),
735 AstNode::PropertyAccess(property) => Ok(CallOperationNode::Property(property)),
736 AstNode::OptionalPropertyAccess(optional_property) => {
737 Ok(CallOperationNode::OptionalProperty(optional_property))
738 }
739 AstNode::IndexAccess(index_access) => Ok(CallOperationNode::Index(index_access)),
740 AstNode::MapExpr(map_expr) => Ok(CallOperationNode::Map(map_expr)),
741 AstNode::OptionalMapExpr(optional_map_expr) => {
742 Ok(CallOperationNode::OptionalMap(optional_map_expr))
743 }
744 _ => Err(NodeConversionError(format!(
745 "Cannot convert {:?} to CallOperationNode",
746 value
747 ))),
748 }
749 }
750}
751
752#[derive(Debug, Clone, PartialEq, Copy)]
753pub enum AssignmentTargetNode {
754 Identifier(IdentifierNode),
755 Property(PropertyAssignmentNode),
756 Index(IndexAssignmentNode),
757}
758
759impl AssignmentTargetNode {
760 pub fn span(&self) -> SourceSpan {
761 match self {
762 Self::Identifier(identifier) => identifier.span,
763 Self::Property(property) => property.span,
764 Self::Index(index) => index.span,
765 }
766 }
767}
768
769impl TryFrom<AstNode> for AssignmentTargetNode {
770 type Error = NodeConversionError;
771
772 fn try_from(value: AstNode) -> Result<Self, Self::Error> {
773 match value {
774 AstNode::PropertyAssignment(property) => Ok(AssignmentTargetNode::Property(property)),
775 AstNode::IndexAssignment(index) => Ok(AssignmentTargetNode::Index(index)),
776 AstNode::Identifier(identifier) => Ok(AssignmentTargetNode::Identifier(identifier)),
777 _ => Err(NodeConversionError(format!(
778 "Cannot convert {:?} to AssignmentTargetNode",
779 value
780 ))),
781 }
782 }
783}
784
785#[derive(Debug, Clone, PartialEq, Copy)]
786pub enum PrimaryNode {
787 Number(NumberLiteralNode),
788 String(StringLiteralNode),
789 Boolean(BooleanLiteralNode),
790 Nil(NilLiteralNode),
791 Identifier(IdentifierNode),
792 This(ThisExprNode),
793 Super(SuperExprNode),
794 Grouping(GroupingExprNode),
795 Lambda(LambdaExprNode),
796 Array(ArrayLiteralExprNode),
797 Object(ObjectLiteralExprNode),
798 When(WhenExprNode),
799}
800
801impl PrimaryNode {
802 pub fn span(&self) -> SourceSpan {
803 match self {
804 Self::Array(array_literal) => array_literal.span,
805 Self::Boolean(boolean_literal) => boolean_literal.span,
806 Self::Grouping(grouping_expr) => grouping_expr.span,
807 Self::Identifier(identifier) => identifier.span,
808 Self::Lambda(lambda_expr) => lambda_expr.span,
809 Self::Nil(nil_literal) => nil_literal.span,
810 Self::Number(number_literal) => number_literal.span,
811 Self::Object(object_literal) => object_literal.span,
812 Self::String(string_literal) => string_literal.span,
813 Self::Super(super_expr) => super_expr.span,
814 Self::This(this_expr) => this_expr.span,
815 Self::When(when_expr) => when_expr.span,
816 }
817 }
818}
819
820impl TryFrom<AstNode> for PrimaryNode {
821 type Error = NodeConversionError;
822
823 fn try_from(value: AstNode) -> Result<Self, Self::Error> {
824 match value {
825 AstNode::NumberLiteral(number_literal) => Ok(PrimaryNode::Number(number_literal)),
826 AstNode::StringLiteral(string_literal) => Ok(PrimaryNode::String(string_literal)),
827 AstNode::BooleanLiteral(boolean_literal) => Ok(PrimaryNode::Boolean(boolean_literal)),
828 AstNode::NilLiteral(nil_literal) => Ok(PrimaryNode::Nil(nil_literal)),
829 AstNode::Identifier(identifier_literal) => {
830 Ok(PrimaryNode::Identifier(identifier_literal))
831 }
832 AstNode::ThisExpr(this_expr) => Ok(PrimaryNode::This(this_expr)),
833 AstNode::SuperExpr(super_expr) => Ok(PrimaryNode::Super(super_expr)),
834 AstNode::GroupingExpr(grouping_expr) => Ok(PrimaryNode::Grouping(grouping_expr)),
835 AstNode::LambdaExpr(lambda_expr) => Ok(PrimaryNode::Lambda(lambda_expr)),
836 AstNode::ArrayLiteralExpr(array_expr) => Ok(PrimaryNode::Array(array_expr)),
837 AstNode::ObjectLiteralExpr(object_expr) => Ok(PrimaryNode::Object(object_expr)),
838 AstNode::WhenExpr(when_expr) => Ok(PrimaryNode::When(when_expr)),
839 _ => Err(NodeConversionError(format!(
840 "Cannot convert {:?} to PrimaryNode",
841 value
842 ))),
843 }
844 }
845}
846
847#[derive(Debug, Clone, PartialEq, Copy)]
848pub enum ClassMemberNode {
849 Method(FunctionExprNode),
850 Field(FieldDeclNode),
851}
852
853impl ClassMemberNode {
854 pub fn span(&self) -> SourceSpan {
855 match self {
856 Self::Method(method) => method.span,
857 Self::Field(field) => field.span,
858 }
859 }
860}
861
862impl TryFrom<AstNode> for ClassMemberNode {
863 type Error = NodeConversionError;
864
865 fn try_from(value: AstNode) -> Result<Self, Self::Error> {
866 match value {
867 AstNode::FieldDecl(field) => Ok(ClassMemberNode::Field(field)),
868 AstNode::FunctionExpr(method) => Ok(ClassMemberNode::Method(method)),
869 _ => Err(NodeConversionError(format!(
870 "Cannot convert {:?} to ClassMember",
871 value
872 ))),
873 }
874 }
875}
876
877#[derive(Debug, Clone, PartialEq, Copy)]
878pub enum LambdaBodyNode {
879 Block(BlockStmtNode),
880 Expr(ExprNode),
881}
882
883impl LambdaBodyNode {
884 pub fn span(&self) -> SourceSpan {
885 match self {
886 Self::Block(block) => block.span,
887 Self::Expr(expr) => expr.span(),
888 }
889 }
890}
891
892impl TryFrom<AstNode> for LambdaBodyNode {
893 type Error = NodeConversionError;
894
895 fn try_from(value: AstNode) -> Result<Self, Self::Error> {
896 match value {
897 AstNode::BlockStmt(block) => Ok(LambdaBodyNode::Block(block)),
898 _ => Ok(LambdaBodyNode::Expr(value.try_into()?)),
899 }
900 }
901}
902
903#[derive(Debug, Clone, PartialEq, Copy)]
904pub enum ForInitializerNode {
905 VarDecl(VariableDeclNode),
906 Expr(ExprNode),
907}
908
909impl ForInitializerNode {
910 pub fn span(&self) -> SourceSpan {
911 match self {
912 Self::VarDecl(var_decl) => var_decl.span,
913 Self::Expr(expr) => expr.span(),
914 }
915 }
916}
917
918impl TryFrom<AstNode> for ForInitializerNode {
919 type Error = NodeConversionError;
920
921 fn try_from(value: AstNode) -> Result<Self, Self::Error> {
922 match value {
923 AstNode::VariableDecl(var_decl) => Ok(ForInitializerNode::VarDecl(var_decl)),
924 _ => Ok(ForInitializerNode::Expr(value.try_into()?)),
925 }
926 }
927}