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}