ast/
expr.rs

1//! Expressions
2//!
3
4use lexer::token::TokenKind;
5use interner::Symbol;
6use span::{Span, Spanned};
7
8use crate::Path;
9use crate::{types::Type, Parenthesized};
10type Expr = Box<Expression>;
11
12#[derive(Debug)]
13pub enum UnaryExprOp {
14    Negation,
15    Plus,
16    Not,
17    Deref,
18    Ref,
19}
20
21impl TryFrom<TokenKind> for UnaryExprOp {
22    type Error = ();
23
24    fn try_from(value: TokenKind) -> Result<Self, Self::Error> {
25        Ok(match value {
26            TokenKind::Minus => Self::Negation,
27            TokenKind::Bang => Self::Not,
28            TokenKind::Plus => Self::Plus,
29            TokenKind::Ampersand => Self::Ref,
30            TokenKind::Star => Self::Deref,
31            _ => return Err(()),
32        })
33    }
34}
35
36#[derive(Debug)]
37pub enum BinaryExprOp {
38    Add,
39    Sub,
40    Mul,
41    Div,
42    Gt,
43    Ge,
44    Lt,
45    Le,
46    Eq,
47    Neq,
48    And,
49    Or,
50    Mod,
51    Assign,
52}
53
54impl TryFrom<TokenKind> for BinaryExprOp {
55    type Error = ();
56
57    fn try_from(value: TokenKind) -> Result<Self, Self::Error> {
58        Ok(match value {
59            TokenKind::Minus => Self::Sub,
60            TokenKind::Plus => Self::Add,
61            TokenKind::Slash => Self::Div,
62            TokenKind::Star => Self::Mul,
63            TokenKind::BangEqual => Self::Neq,
64            TokenKind::EqualEqual => Self::Eq,
65            TokenKind::Greater => Self::Gt,
66            TokenKind::GreaterEqual => Self::Ge,
67            TokenKind::Less => Self::Lt,
68            TokenKind::LessEqual => Self::Le,
69            TokenKind::And => Self::And,
70            TokenKind::Or => Self::Or,
71            TokenKind::Modulo => Self::Mod,
72            TokenKind::Equal => Self::Assign,
73            _ => return Err(()),
74        })
75    }
76}
77
78#[derive(Debug)]
79pub struct StructAccess {
80    pub st: Box<Expression>,
81    pub field: Spanned<Symbol>,
82}
83
84impl StructAccess {
85    pub fn new(st: impl Into<Box<Expression>>, field: Spanned<Symbol>) -> Self {
86        Self {
87            st: st.into(),
88            field,
89        }
90    }
91}
92
93#[derive(Debug)]
94pub enum ExpressionKind {
95    Unary {
96        op: Spanned<UnaryExprOp>,
97        expr: Expr,
98    },
99    Paren(Parenthesized<Expr>),
100    Binary {
101        op: Spanned<BinaryExprOp>,
102        left: Expr,
103        right: Expr,
104    },
105    Ternary {
106        cond: Expr,
107        if_true: Expr,
108        if_false: Expr,
109    },
110    Path(Path),
111    Literal(Spanned<LitValue>),
112    Cast {
113        expr: Box<Expression>,
114        kw_as: Span,
115        ty: Type,
116    },
117    Call {
118        callee: Expr,
119        args: Parenthesized<Box<[Expression]>>,
120    },
121    ArrayAccess {
122        arr: Expr,
123        index: Expr,
124        closing_bracket: Span,
125    },
126    StructAccess {
127        st: Expr,
128        field: Spanned<Symbol>,
129    },
130}
131
132#[derive(Debug)]
133pub struct Expression {
134    pub kind: ExpressionKind,
135    pub span: Span,
136}
137
138impl Expression {
139    pub fn new(kind: ExpressionKind, span: Span) -> Self { Expression { kind, span } }
140}
141
142#[derive(Clone, Debug)]
143pub enum LitValue {
144    Int(i32),
145    Float(f64),
146    Str(Symbol),
147    Bool(bool),
148    Char(char),
149}