1use 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}