1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3
4#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
5#[serde(tag = "type", content = "value")]
6pub enum DurationValue {
7 Number(f32),
8 Identifier(String),
9 Beat(String),
10 Beats(f32),
11 Milliseconds(f32),
12 Auto,
13}
14
15#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
16#[serde(tag = "type", content = "value")]
17pub enum Value {
18 Boolean(bool),
19 Number(f32),
20 Duration(DurationValue),
21 Identifier(String),
22 String(String),
23 Array(Vec<Value>),
24 Map(HashMap<String, Value>),
25 Call { name: String, args: Vec<Value> },
26 Block(Vec<Statement>),
27 Sample(String),
28 Beat(String),
29 Statement(Box<Statement>),
30 StatementKind(Box<StatementKind>),
31 Midi(String),
32 Range { start: Box<Value>, end: Box<Value> },
33 Unknown,
34 Null,
35}
36
37impl Default for Value {
38 fn default() -> Self {
39 Value::Null
40 }
41}
42
43impl Value {
44 pub fn get(&self, key: &str) -> Option<&Value> {
45 if let Value::Map(map) = self {
46 map.get(key)
47 } else {
48 None
49 }
50 }
51}
52
53#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
54#[serde(tag = "kind")]
55pub enum StatementKind {
56 Tempo {
57 value: f32,
58 body: Option<Vec<Statement>>,
59 },
60 Print,
61 Pattern {
62 name: String,
63 target: Option<String>,
64 },
65 Trigger {
66 entity: String,
67 duration: DurationValue,
68 effects: Option<Value>,
69 },
70 Sleep,
71 Call {
72 name: String,
73 args: Vec<Value>,
74 },
75 Load {
76 source: String,
77 alias: String,
78 },
79 Use {
80 name: String,
81 alias: Option<String>,
82 },
83 UsePlugin {
84 author: String,
85 name: String,
86 alias: String,
87 },
88 Automate {
89 target: String,
90 },
91 ArrowCall {
92 target: String,
93 method: String,
94 args: Vec<Value>,
95 },
96 Function {
97 name: String,
98 parameters: Vec<String>,
99 body: Vec<Statement>,
100 },
101 Assign {
102 target: String,
103 property: String,
104 },
105 Synth,
106 Bank {
107 name: String,
108 alias: Option<String>,
109 },
110 Let {
111 name: String,
112 value: Option<Value>,
113 },
114 Var {
115 name: String,
116 value: Option<Value>,
117 },
118 Const {
119 name: String,
120 value: Option<Value>,
121 },
122 Group {
123 name: String,
124 body: Vec<Statement>,
125 duration: Option<DurationValue>, },
127 Spawn {
128 name: String,
129 args: Vec<Value>,
130 },
131 Loop {
132 count: Value,
133 body: Vec<Statement>,
134 },
135 For {
136 variable: String,
137 iterable: Value,
138 body: Vec<Statement>,
139 },
140 Routing {
141 body: Vec<Statement>,
142 },
143 RoutingNode {
144 name: String,
145 alias: Option<String>,
146 },
147 RoutingFx {
148 target: String,
149 effects: Value,
150 },
151 RoutingRoute {
152 source: String,
153 destination: String,
154 effects: Option<Value>,
155 },
156 RoutingDuck {
157 source: String,
158 destination: String,
159 effect: Value,
160 },
161 RoutingSidechain {
162 source: String,
163 destination: String,
164 effect: Value,
165 },
166 Bind {
167 source: String,
168 target: String,
169 },
170 FxPipeline {
171 effects: Vec<Value>,
172 subject: String,
173 },
174 Node {
175 name: String,
176 },
177 Sidechain {
178 source: String,
179 effect: Value,
180 target: Option<String>,
181 },
182 Include(String),
183 Export {
184 names: Vec<String>,
185 source: String,
186 },
187 Import {
188 names: Vec<String>,
189 source: String,
190 },
191 On {
192 event: String,
193 args: Option<Vec<Value>>,
194 body: Vec<Statement>,
195 },
196 Emit {
197 event: String,
198 payload: Option<Value>,
199 },
200 Fade {
201 direction: String, target: String, duration: DurationValue,
204 },
205 Section {
206 name: String,
207 duration: Option<DurationValue>, body: Vec<Statement>,
209 },
210 Timeline {
211 sections: Vec<(String, Option<DurationValue>)>, },
213 Schedule {
214 events: Vec<(DurationValue, Option<DurationValue>, Vec<Statement>)>, },
216 Stop {
217 target: Option<String>, after: Option<DurationValue>, },
220 If {
221 condition: Value,
222 body: Vec<Statement>,
223 else_body: Option<Vec<Statement>>, },
225 While {
226 condition: Value,
227 body: Vec<Statement>,
228 },
229 Return {
230 value: Option<Box<Value>>,
231 },
232 Break,
233 Comment,
234 Indent,
235 Dedent,
236 NewLine,
237 Unknown,
238 Error {
239 message: String,
240 },
241}
242
243impl Default for StatementKind {
244 fn default() -> Self {
245 StatementKind::Unknown
246 }
247}
248
249#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
250pub struct Statement {
251 pub kind: StatementKind,
252 #[serde(default)]
253 pub value: Value,
254 pub indent: usize,
255 pub line: usize,
256 pub column: usize,
257}
258
259impl Statement {
260 pub fn new(
261 kind: StatementKind,
262 value: Value,
263 indent: usize,
264 line: usize,
265 column: usize,
266 ) -> Self {
267 Self {
268 kind,
269 value,
270 indent,
271 line,
272 column,
273 }
274 }
275
276 pub fn tempo(value: f32, line: usize, column: usize) -> Self {
277 Self::new(
278 StatementKind::Tempo { value, body: None },
279 Value::Null,
280 0,
281 line,
282 column,
283 )
284 }
285
286 pub fn print(message: impl Into<String>, line: usize, column: usize) -> Self {
287 Self::new(
288 StatementKind::Print,
289 Value::String(message.into()),
290 0,
291 line,
292 column,
293 )
294 }
295
296 pub fn trigger(
297 entity: impl Into<String>,
298 duration: DurationValue,
299 effects: Option<Value>,
300 line: usize,
301 column: usize,
302 ) -> Self {
303 Self::new(
304 StatementKind::Trigger {
305 entity: entity.into(),
306 duration,
307 effects,
308 },
309 Value::Null,
310 0,
311 line,
312 column,
313 )
314 }
315
316 pub fn unknown() -> Self {
317 Self::default()
318 }
319
320 pub fn unknown_with_pos(indent: usize, line: usize, column: usize) -> Self {
321 Self::new(StatementKind::Unknown, Value::Null, indent, line, column)
322 }
323
324 pub fn error_with_pos(indent: usize, line: usize, column: usize, message: String) -> Self {
325 Self::new(
326 StatementKind::Error { message },
327 Value::Null,
328 indent,
329 line,
330 column,
331 )
332 }
333}