Skip to main content

rill_lang/
ast.rs

1//! Abstract syntax tree produced by the parser.
2
3use crate::error::Span;
4
5#[cfg(feature = "serde")]
6use serde::{Deserialize, Serialize};
7
8/// Binary block-diagram combinators and arithmetic operators.
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11pub enum BinOp {
12    /// `:` sequential composition.
13    Seq,
14    /// `,` parallel composition.
15    Par,
16    /// `<:` split / fan-out.
17    Split,
18    /// `:>` merge / fan-in.
19    Merge,
20    /// `~` feedback (implicit 1-sample delay).
21    Feedback,
22    /// `@` integer delay.
23    Delay,
24    /// `+`
25    Add,
26    /// `-`
27    Sub,
28    /// `*`
29    Mul,
30    /// `/`
31    Div,
32    /// `%`
33    Rem,
34}
35
36/// A rill-lang expression node.
37#[derive(Debug, Clone, PartialEq)]
38#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
39pub enum Expr {
40    /// Integer literal.
41    Int(i64, Span),
42    /// Float literal.
43    Float(f64, Span),
44    /// Imaginary literal, e.g. `3i`, `2.5i`.
45    Imag(f64, Span),
46    /// Identity wire `_` (arity 1→1).
47    Wire(Span),
48    /// Cut `!` (arity 1→0).
49    Cut(Span),
50    /// String literal, e.g. `"cutoff"`.
51    Str(String, Span),
52    /// A reference to a definition or a bound parameter.
53    Ref(String, Span),
54    /// Application `name(arg, ...)` or juxtaposed `name arg1 arg2`.
55    Apply {
56        /// Function name.
57        name: String,
58        /// Argument expressions.
59        args: Vec<Expr>,
60        /// Full span of the application.
61        span: Span,
62    },
63    /// Unary negation `-expr`.
64    Neg(Box<Expr>, Span),
65    /// A binary combinator/operator.
66    Bin {
67        /// The operator.
68        op: BinOp,
69        /// Left operand.
70        lhs: Box<Expr>,
71        /// Right operand.
72        rhs: Box<Expr>,
73        /// Full span.
74        span: Span,
75    },
76    /// `let defs in body` — expression-level mutually-recursive bindings.
77    Let {
78        /// Definitions (may contain Anchors and Locals).
79        defs: Vec<Def>,
80        /// The expression these bindings are visible in.
81        body: Box<Expr>,
82        /// Full span.
83        span: Span,
84    },
85    /// Record literal, e.g. `{ channels: 3, gain: 0.8 }`.
86    Record(Vec<(String, Expr)>, Span),
87    /// Late-binding actor parameter: `?name` or `?name=default`.
88    ActorParam {
89        /// Parameter name (without `?` prefix).
90        name: String,
91        /// Optional default value expression.
92        default: Option<Box<Expr>>,
93        /// Source span.
94        span: Span,
95    },
96}
97
98impl Expr {
99    /// The source span of this node.
100    pub fn span(&self) -> Span {
101        match self {
102            Expr::Int(_, s)
103            | Expr::Float(_, s)
104            | Expr::Imag(_, s)
105            | Expr::Wire(s)
106            | Expr::Cut(s)
107            | Expr::Str(_, s)
108            | Expr::Ref(_, s)
109            | Expr::Neg(_, s) => *s,
110            Expr::Apply { span, .. }
111            | Expr::Bin { span, .. }
112            | Expr::Let { span, .. }
113            | Expr::Record(_, span)
114            | Expr::ActorParam { span, .. } => *span,
115        }
116    }
117}
118
119/// A parameter declaration.
120#[derive(Debug, Clone, PartialEq)]
121#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
122pub struct Param {
123    /// Parameter name.
124    pub name: String,
125    /// Source span.
126    pub span: Span,
127}
128
129/// A definition — top-level, `where`-block, or `let`-block.
130#[derive(Debug, Clone, PartialEq)]
131#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
132pub enum Def {
133    /// `name p1 p2 = body` — an anchor with parameters.
134    Anchor {
135        /// Definition name.
136        name: String,
137        /// Formal parameters.
138        params: Vec<Param>,
139        /// Right-hand side.
140        body: Expr,
141        /// Optional where-block definitions.
142        where_defs: Vec<Def>,
143        /// Span of the whole definition.
144        span: Span,
145    },
146    /// `name = body` — a local binding (no params).
147    Local {
148        /// Definition name.
149        name: String,
150        /// Right-hand side.
151        body: Expr,
152        /// Optional where-block definitions.
153        where_defs: Vec<Def>,
154        /// Span of the whole definition.
155        span: Span,
156    },
157}
158
159impl Def {
160    /// Returns the identifier name of this definition.
161    pub fn name(&self) -> &str {
162        match self {
163            Def::Anchor { name, .. } => name,
164            Def::Local { name, .. } => name,
165        }
166    }
167
168    /// Returns the body expression of this definition.
169    pub fn body(&self) -> &Expr {
170        match self {
171            Def::Anchor { body, .. } => body,
172            Def::Local { body, .. } => body,
173        }
174    }
175
176    /// Returns the parameters of this definition (empty for Local).
177    pub fn params(&self) -> &[Param] {
178        match self {
179            Def::Anchor { params, .. } => params,
180            Def::Local { .. } => &[],
181        }
182    }
183
184    /// Returns the where-block definitions of this definition.
185    pub fn where_defs(&self) -> &[Def] {
186        match self {
187            Def::Anchor { where_defs, .. } => where_defs,
188            Def::Local { where_defs, .. } => where_defs,
189        }
190    }
191}
192
193/// A whole program: a list of mutually-recursive definitions.
194/// Exactly one must be named `main`.
195#[derive(Debug, Clone, PartialEq)]
196#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
197pub struct Program {
198    /// Top-level definitions.
199    pub defs: Vec<Def>,
200}
201
202impl Program {
203    /// Returns the `main` definition, if present.
204    pub fn main_def(&self) -> Option<&Def> {
205        self.defs.iter().find(|d| d.name() == "main")
206    }
207}