1use std::fmt::Debug;
2
3use crate::{error::Span, tokens::TokenKind};
4use rust_decimal::Decimal;
5
6macro_rules! node {
7 ($name:ident; $($field:ident : $type:ty),* $(,)?) => {
8 #[derive(Debug, PartialEq, Clone)]
9 pub struct $name {
10 pub span: Span,
11 $(pub $field: $type,)*
12 }
13 };
14}
15
16pub type Program = Statements;
17pub type Statements = Vec<Statement>;
18pub type Block = Statements;
19
20#[derive(Debug, PartialEq, Clone)]
21pub enum Statement {
22 Var(VarStmt),
23 Function(FunctionDecl),
24 Class(ClassDecl),
25 Break(BreakStmt),
26 Continue(ContinueStmt),
27 Return(ReturnStmt),
28 Expr(Expression),
29}
30node! { VarStmt; ident: String, expr: Option<Expression> }
31node! { FunctionDecl; ident: String, args: Params, block: Block }
32node! { ClassDecl; ident: String, block: MemberBlock }
33node! { BreakStmt; expr: Option<Expression> }
34node! { ContinueStmt; }
35node! { ReturnStmt; expr: Option<Expression> }
36
37node! { Member; is_static: bool, kind: MemberKind }
38#[derive(Debug, PartialEq, Clone)]
39pub enum MemberKind {
40 Attribute(VarStmt),
41 Method(FunctionDecl),
42}
43node! { MemberBlock; members: Vec<Member> }
44
45pub type Expression = RangeExpr;
46#[derive(Debug, PartialEq, Clone)]
47pub enum RangeExpr {
48 None(Box<OrExpr>),
49 Closed(Box<OrExpr>, TokenKind, Box<OrExpr>, Span),
50 OpenEnd(Box<OrExpr>, Span),
51 OpenStart(TokenKind, Box<OrExpr>, Span),
52 Open,
53}
54node! { OrExpr; base: AndExpr, following: Vec<AndExpr> }
55node! { AndExpr; base: BitOrExpr, following: Vec<BitOrExpr> }
56node! { BitOrExpr; base: BitXorExpr, following: Vec<BitXorExpr> }
57node! { BitXorExpr; base: BitAndExpr, following: Vec<BitAndExpr> }
58node! { BitAndExpr; base: EqExpr, following: Vec<EqExpr> }
59node! { EqExpr; left: RelExpr, right: Option<(TokenKind, RelExpr)> }
60node! { RelExpr; left: ShiftExpr, right: Option<(TokenKind, ShiftExpr)> }
61node! { ShiftExpr; base: AddExpr, following: Vec<(TokenKind, AddExpr)> }
62node! { AddExpr; base: MulExpr, following: Vec<(TokenKind, MulExpr)> }
63node! { MulExpr; base: UnaryExpr, following: Vec<(TokenKind, UnaryExpr)> }
64#[derive(Debug, PartialEq, Clone)]
65pub enum UnaryExpr {
66 Unary {
67 span: Span,
68 operator: TokenKind,
69 expr: Box<UnaryExpr>,
70 },
71 Done(Box<ExpExpr>),
72}
73node! { ExpExpr; base: AssignExpr, exponent: Option<UnaryExpr> }
74node! { AssignExpr; left: CallExpr, right: Option<(TokenKind, Expression)> }
75node! { CallExpr; base: MemberExpr, following: Vec<CallPart> }
76node! { MemberExpr; base: Atom, following: Vec<MemberPart> }
77#[derive(Debug, PartialEq, Clone)]
78pub enum Atom {
79 Number(Decimal),
80 Bool(bool),
81 String(String),
82 Null,
83 Identifier { span: Span, name: String },
84 Expr(Expression),
85 List(ListLiteral),
86 IfExpr(IfExpr),
87 ForExpr(ForExpr),
88 WhileExpr(WhileExpr),
89 LoopExpr(LoopExpr),
90 FunExpr(FunExpr),
91 ClassExpr(ClassExpr),
92 TryExpr(TryExpr),
93 BlockExpr(BlockExpr),
94}
95pub type ListLiteral = Vec<Expression>;
96node! { IfExpr; cond: Expression, block: Block, else_block: Option<Block> }
97node! { ForExpr; ident: String, iter: Expression, block: Block }
98node! { WhileExpr; cond: Expression, block: Block }
99node! { LoopExpr; block: Block }
100node! { FunExpr; args: Params, block: Block }
101node! { ClassExpr; block: MemberBlock }
102node! { TryExpr; try_block: Block, ident: String, catch_block: Block }
103pub type BlockExpr = Block;
104
105#[derive(Debug, PartialEq, Clone)]
106pub enum MemberPart {
107 Field(String),
108 Index(Expression),
109}
110#[derive(Debug, PartialEq, Clone)]
111pub enum CallPart {
112 Member(MemberPart),
113 Args(Args),
114}
115pub type Args = Vec<Expression>;
116pub type Params = Vec<String>;