roost_lang/
nodes.rs

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>;