compose_syntax/ast/
expr.rs

1use crate::SyntaxNode;
2use crate::ast::atomics::Unit;
3use crate::ast::control_flow::Conditional;
4use crate::ast::map::MapLiteral;
5use crate::ast::range::Range;
6use crate::ast::unary::Unary;
7use crate::ast::{Array, AstNode, Binary, ForLoop, Ident, Int, Lambda, Parenthesized, WhileLoop};
8use crate::ast::{Bool, CodeBlock, FieldAccess, FuncCall, LetBinding, PathAccess, Str};
9use crate::kind::SyntaxKind;
10
11/// An expression. The base of Compose. Any "statement" is an expression.
12///
13/// # Examples:
14///
15/// ```compose
16/// 1 + 2
17/// foobar()
18/// foo.bar()[0]
19/// let a = (2 / 5) + (7 - 2) * foobar()
20/// ```
21#[derive(Debug, Clone, Copy)]
22pub enum Expr<'a> {
23    Unary(Unary<'a>),
24    Unit(Unit<'a>),
25    Ident(Ident<'a>),
26    Binary(Binary<'a>),
27    Int(Int<'a>),
28    LetBinding(LetBinding<'a>),
29    CodeBlock(CodeBlock<'a>),
30    Str(Str<'a>),
31    Bool(Bool<'a>),
32    FuncCall(FuncCall<'a>),
33    FieldAccess(FieldAccess<'a>),
34    PathAccess(PathAccess<'a>),
35    Parenthesized(Parenthesized<'a>),
36    Conditional(Conditional<'a>),
37    WhileLoop(WhileLoop<'a>),
38    ForLoop(ForLoop<'a>),
39    Array(Array<'a>),
40    Range(Range<'a>),
41    Map(MapLiteral<'a>),
42    Lambda(Lambda<'a>),
43}
44
45impl<'a> AstNode<'a> for Expr<'a> {
46    fn from_untyped(node: &'a SyntaxNode) -> Option<Self> {
47        match node.kind() {
48            SyntaxKind::Unary => Some(Self::Unary(Unary::from_untyped(node)?)),
49            SyntaxKind::Unit => Some(Self::Unit(Unit::from_untyped(node)?)),
50            SyntaxKind::Ident => Some(Self::Ident(Ident::from_untyped(node)?)),
51            SyntaxKind::Binary => Some(Self::Binary(Binary::from_untyped(node)?)),
52            SyntaxKind::Int => Some(Self::Int(Int::from_untyped(node)?)),
53            SyntaxKind::LetBinding => Some(Self::LetBinding(LetBinding::from_untyped(node)?)),
54            SyntaxKind::CodeBlock => Some(Self::CodeBlock(CodeBlock::from_untyped(node)?)),
55            SyntaxKind::Str => Some(Self::Str(Str::from_untyped(node)?)),
56            SyntaxKind::Bool => Some(Self::Bool(Bool::from_untyped(node)?)),
57            SyntaxKind::FuncCall => Some(Self::FuncCall(FuncCall::from_untyped(node)?)),
58            SyntaxKind::FieldAccess => Some(Self::FieldAccess(FieldAccess::from_untyped(node)?)),
59            SyntaxKind::PathAccess => Some(Self::PathAccess(PathAccess::from_untyped(node)?)),
60            SyntaxKind::Parenthesized => {
61                Some(Self::Parenthesized(Parenthesized::from_untyped(node)?))
62            }
63            SyntaxKind::Conditional => Some(Self::Conditional(Conditional::from_untyped(node)?)),
64            SyntaxKind::WhileLoop => Some(Self::WhileLoop(WhileLoop::from_untyped(node)?)),
65            SyntaxKind::ForLoop => Some(Self::ForLoop(ForLoop::from_untyped(node)?)),
66            SyntaxKind::Array => Some(Self::Array(Array::from_untyped(node)?)),
67            SyntaxKind::Range => Some(Self::Range(Range::from_untyped(node)?)),
68            SyntaxKind::MapLiteral => Some(Self::Map(MapLiteral::from_untyped(node)?)),
69            SyntaxKind::Lambda => Some(Self::Lambda(Lambda::from_untyped(node)?)),
70            _ => None,
71        }
72    }
73
74    fn to_untyped(&self) -> &'a SyntaxNode {
75        match self {
76            Self::Unary(unary) => unary.to_untyped(),
77            Self::Unit(unit) => unit.to_untyped(),
78            Self::Ident(ident) => ident.to_untyped(),
79            Self::Binary(binary) => binary.to_untyped(),
80            Self::Int(int) => int.to_untyped(),
81            Self::LetBinding(let_binding) => let_binding.to_untyped(),
82            Self::CodeBlock(code_block) => code_block.to_untyped(),
83            Self::Str(str) => str.to_untyped(),
84            Self::Bool(bool) => bool.to_untyped(),
85            Self::FuncCall(func_call) => func_call.to_untyped(),
86            Self::FieldAccess(field_access) => field_access.to_untyped(),
87            Self::PathAccess(path_access) => path_access.to_untyped(),
88            Self::Parenthesized(parenthesized) => parenthesized.to_untyped(),
89            Self::Conditional(conditional) => conditional.to_untyped(),
90            Self::WhileLoop(while_loop) => while_loop.to_untyped(),
91            Self::ForLoop(for_loop) => for_loop.to_untyped(),
92            Self::Array(array) => array.to_untyped(),
93            Self::Range(range) => range.to_untyped(),
94            Self::Map(map) => map.to_untyped(),
95            Self::Lambda(lambda) => lambda.to_untyped(),
96        }
97    }
98}
99
100impl Default for Expr<'_> {
101    fn default() -> Self {
102        Self::Unit(Unit::default())
103    }
104}