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 },
126 Spawn {
127 name: String,
128 args: Vec<Value>,
129 },
130 Loop {
131 count: Value,
132 body: Vec<Statement>,
133 },
134 For {
135 variable: String,
136 iterable: Value,
137 body: Vec<Statement>,
138 },
139 Routing {
140 body: Vec<Statement>,
141 },
142 RoutingNode {
143 name: String,
144 alias: Option<String>,
145 },
146 RoutingFx {
147 target: String,
148 effects: Value,
149 },
150 RoutingRoute {
151 source: String,
152 destination: String,
153 effects: Option<Value>,
154 },
155 RoutingDuck {
156 source: String,
157 destination: String,
158 effect: Value,
159 },
160 RoutingSidechain {
161 source: String,
162 destination: String,
163 effect: Value,
164 },
165 Bind {
166 source: String,
167 target: String,
168 },
169 FxPipeline {
170 effects: Vec<Value>,
171 subject: String,
172 },
173 Node {
174 name: String,
175 },
176 Sidechain {
177 source: String,
178 effect: Value,
179 target: Option<String>,
180 },
181 Include(String),
182 Export {
183 names: Vec<String>,
184 source: String,
185 },
186 Import {
187 names: Vec<String>,
188 source: String,
189 },
190 On {
191 event: String,
192 args: Option<Vec<Value>>,
193 body: Vec<Statement>,
194 },
195 Emit {
196 event: String,
197 payload: Option<Value>,
198 },
199 If {
200 condition: Value,
201 body: Vec<Statement>,
202 else_body: Option<Vec<Statement>>, },
204 Return {
205 value: Option<Box<Value>>,
206 },
207 Break,
208 Comment,
209 Indent,
210 Dedent,
211 NewLine,
212 Unknown,
213 Error {
214 message: String,
215 },
216}
217
218impl Default for StatementKind {
219 fn default() -> Self {
220 StatementKind::Unknown
221 }
222}
223
224#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
225pub struct Statement {
226 pub kind: StatementKind,
227 #[serde(default)]
228 pub value: Value,
229 pub indent: usize,
230 pub line: usize,
231 pub column: usize,
232}
233
234impl Statement {
235 pub fn new(
236 kind: StatementKind,
237 value: Value,
238 indent: usize,
239 line: usize,
240 column: usize,
241 ) -> Self {
242 Self {
243 kind,
244 value,
245 indent,
246 line,
247 column,
248 }
249 }
250
251 pub fn tempo(value: f32, line: usize, column: usize) -> Self {
252 Self::new(
253 StatementKind::Tempo { value, body: None },
254 Value::Null,
255 0,
256 line,
257 column,
258 )
259 }
260
261 pub fn print(message: impl Into<String>, line: usize, column: usize) -> Self {
262 Self::new(
263 StatementKind::Print,
264 Value::String(message.into()),
265 0,
266 line,
267 column,
268 )
269 }
270
271 pub fn trigger(
272 entity: impl Into<String>,
273 duration: DurationValue,
274 effects: Option<Value>,
275 line: usize,
276 column: usize,
277 ) -> Self {
278 Self::new(
279 StatementKind::Trigger {
280 entity: entity.into(),
281 duration,
282 effects,
283 },
284 Value::Null,
285 0,
286 line,
287 column,
288 )
289 }
290
291 pub fn unknown() -> Self {
292 Self::default()
293 }
294
295 pub fn unknown_with_pos(indent: usize, line: usize, column: usize) -> Self {
296 Self::new(StatementKind::Unknown, Value::Null, indent, line, column)
297 }
298
299 pub fn error_with_pos(indent: usize, line: usize, column: usize, message: String) -> Self {
300 Self::new(
301 StatementKind::Error { message },
302 Value::Null,
303 indent,
304 line,
305 column,
306 )
307 }
308}