nexus_lib/parser/
ast.rs

1use std::fmt::Display;
2
3use crate::lexer::tokens::Literal;
4
5#[derive(Debug, PartialEq, Clone)]
6pub enum Statement {
7    Variable(VarStmt),
8    Return(ReturnStmt),
9    Break(BreakStmt),
10    Local(LocalStmt),
11    Use(UseStmt),
12    Expression(Expression),
13}
14
15#[derive(Debug, PartialEq, Clone)]
16pub enum Expression {
17    Ident(Ident),
18    Literal(Literal),
19    Prefix(PrefixExpr),
20    Infix(InfixExpr),
21    Index(IndexExpr),
22    Call(CallExpr),
23    List(ListExpr),
24    None,
25
26    If(IfExpr),
27    Loop(LoopExpr),
28    When(WhenExpr),
29    Func(FuncExpr),
30    Annotation(AnnotationExpr),
31    Struct(StructExpr),
32    Enum(EnumExpr),
33}
34
35#[derive(Debug, PartialEq, Clone)]
36pub struct Ident(pub String);
37
38#[derive(Debug, PartialEq, Clone)]
39pub struct OptionallyTypedIdent {
40    pub ident: Ident,
41    pub _type: Option<Ident>,
42}
43
44#[derive(Debug, PartialEq, Clone)]
45pub struct VarStmt {
46    pub name: OptionallyTypedIdent,
47    pub val: Expression,
48    pub is_const: bool,
49}
50
51#[derive(Debug, PartialEq, Clone)]
52pub struct ReturnStmt {
53    pub val: Option<Expression>,
54}
55
56#[derive(Debug, PartialEq, Clone)]
57pub struct BreakStmt {
58    pub label: Option<Ident>,
59}
60
61#[derive(Debug, PartialEq, Clone)]
62pub struct LocalStmt {
63    pub val: Box<Statement>,
64}
65
66#[derive(Debug, PartialEq, Clone)]
67pub struct UseStmt {
68    // TODO: Import paths
69    pub import: Ident,
70}
71
72#[derive(Debug, PartialEq, Clone)]
73pub struct PrefixExpr {
74    pub op: PrefixOp,
75    pub val: Box<Expression>,
76}
77
78#[derive(Debug, PartialEq, Clone)]
79pub struct InfixExpr {
80    pub op: InfixOp,
81    pub left: Box<Expression>,
82    pub right: Box<Expression>,
83}
84
85#[derive(Debug, PartialEq, Clone)]
86pub struct IndexExpr {
87    pub list: Box<Expression>,
88    pub pos: usize,
89}
90
91#[derive(Debug, PartialEq, Clone)]
92pub struct CallExpr {
93    // needs to be an expression
94    // because of weird infix parsing
95    pub ident: Box<Expression>,
96    pub args: Vec<Expression>,
97}
98
99#[derive(Debug, PartialEq, Clone)]
100pub struct ListExpr {
101    pub list: Vec<Expression>,
102}
103
104#[derive(Debug, PartialEq, Clone)]
105pub struct IfExpr {
106    pub _type: IfType,
107    pub cond: Option<Box<Expression>>,
108    pub block: BlockStmt,
109    pub alt: Option<Box<IfExpr>>,
110}
111
112#[derive(Debug, PartialEq, Clone)]
113pub struct LoopExpr {
114    pub _type: LoopType,
115    pub cond: Option<Box<Expression>>,
116    pub block: BlockStmt,
117    pub alt: Option<Box<LoopExpr>>,
118}
119
120#[derive(Debug, PartialEq, Clone)]
121pub struct WhenExpr {
122    pub comp_val: Option<Box<Expression>>,
123    pub cases: Vec<CaseStmt>,
124}
125
126#[derive(Debug, PartialEq, Clone)]
127pub struct FuncExpr {
128    pub ret_type: Option<Ident>,
129    pub args: Vec<OptionallyTypedIdent>,
130    pub block: BlockStmt,
131}
132
133// TODO: Finish this
134#[derive(Debug, PartialEq, Clone)]
135pub struct AnnotationExpr {
136    pub name: Ident,
137}
138
139#[derive(Debug, PartialEq, Clone)]
140pub struct StructExpr {
141    pub fields: Vec<OptionallyTypedIdent>,
142}
143
144#[derive(Debug, PartialEq, Clone)]
145pub struct EnumExpr {
146    pub consts: Ident,
147}
148
149#[derive(Debug, PartialEq, Clone)]
150pub struct BlockStmt {
151    pub stmts: Vec<Statement>,
152}
153
154#[derive(Debug, PartialEq, Clone)]
155pub struct CaseStmt {
156    pub _type: CaseType,
157    /// This should be Some(...) if the _type is Regular and
158    /// the WhenExpr.comp_val is Some(...) as well
159    pub comp_cond: Option<Box<Expression>>,
160    /// This should be None unless the WhenExpr.comp_val is None
161    pub comp_val: Option<Box<Expression>>,
162}
163
164#[derive(Debug, PartialEq, Clone, Copy)]
165pub enum PrefixOp {
166    Pos,
167    Neg,
168    Not,
169}
170
171#[derive(Debug, PartialEq, Clone, Copy)]
172pub enum InfixOp {
173    Add,
174    Sub,
175    Mul,
176    Div,
177    Eq,
178    NEq,
179    GT,
180    LT,
181    GTEq,
182    LTEq,
183    As,
184    In,
185    Range,
186    Assign,
187}
188
189#[derive(Debug, PartialEq, Clone, Copy)]
190pub enum IfType {
191    If,
192    Else,
193    ElseIf,
194}
195
196#[derive(Debug, PartialEq, Clone, Copy)]
197pub enum LoopType {
198    For,
199    While,
200    ElseFor,
201    ElseWhile,
202    Else,
203}
204
205#[derive(Debug, PartialEq, Clone)]
206pub enum CaseType {
207    Regular,
208    Else,
209}
210
211impl Display for Ident {
212    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
213        write!(f, "{}", self.0)
214    }
215}
216
217impl Display for Statement {
218    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
219        write!(
220            f,
221            "{}",
222            match self {
223                Statement::Variable(var) => format!(
224                    "{} {} = {}",
225                    match var.is_const {
226                        true => "const",
227                        false => "var",
228                    },
229                    todo!(), //var.name,
230                    var.val,
231                ),
232                Statement::Return(ret) => todo!(),
233                Statement::Break(br) => todo!(),
234                Statement::Local(lcl) => todo!(),
235                Statement::Use(_use) => todo!(),
236                Statement::Expression(expr) => expr.to_string(),
237            }
238        )
239    }
240}
241
242impl Display for Expression {
243    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
244        write!(
245            f,
246            "{}",
247            match self {
248                Expression::Ident(ident) => ident.to_string(),
249                Expression::Literal(lit) => lit.to_string(),
250                Expression::Prefix(prefix) => prefix.to_string(),
251                Expression::Infix(infix) => infix.to_string(),
252                Expression::Index(_) => todo!(),
253                //Expression::Call(call) => call.to_string(),
254                Expression::List(_) => todo!(),
255                Expression::None => "none".into(),
256                //Expression::If(_if) => _if.to_string(),
257                //Expression::Loop(_loop) => _loop.to_string(),
258                Expression::When(_) => todo!(),
259                //Expression::Func(func) => func.to_string(),
260                Expression::Annotation(_) => todo!(),
261                Expression::Struct(_) => todo!(),
262                Expression::Enum(_) => todo!(),
263                _ => todo!(),
264            }
265        )
266    }
267}
268
269impl Display for PrefixExpr {
270    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
271        write!(
272            f,
273            "{}{}",
274            match self.op {
275                PrefixOp::Pos => "+",
276                PrefixOp::Neg => "-",
277                PrefixOp::Not => "!",
278            },
279            self.to_string()
280        )
281    }
282}
283
284impl Display for InfixExpr {
285    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
286        write!(
287            f,
288            "{} {} {}",
289            self.left.to_string(),
290            match self.op {
291                InfixOp::Add => "+",
292                InfixOp::Sub => "-",
293                InfixOp::Mul => "*",
294                InfixOp::Div => "/",
295                InfixOp::Eq => "==",
296                InfixOp::NEq => "!=",
297                InfixOp::GT => ">",
298                InfixOp::LT => "<",
299                InfixOp::GTEq => ">=",
300                InfixOp::LTEq => "<=",
301                InfixOp::As => "as",
302                InfixOp::In => "in",
303                InfixOp::Range =>
304                    return write!(f, "{}..{}", self.left.to_string(), self.right.to_string()),
305                InfixOp::Assign => "=",
306            },
307            self.right.to_string()
308        )
309    }
310}