1use serde::{Deserialize, Serialize};
2use std::fmt;
3
4#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
6pub struct Span {
7 pub start_line: usize,
8 pub start_col: usize,
9 pub end_line: usize,
10 pub end_col: usize,
11}
12
13impl Span {
14 pub fn new(start_line: usize, start_col: usize, end_line: usize, end_col: usize) -> Self {
15 Self {
16 start_line,
17 start_col,
18 end_line,
19 end_col,
20 }
21 }
22}
23
24impl fmt::Display for Span {
25 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26 write!(
27 f,
28 "{}:{}-{}:{}",
29 self.start_line, self.start_col, self.end_line, self.end_col
30 )
31 }
32}
33
34#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
36pub enum Type {
37 I8,
38 I16,
39 I32,
40 I64,
41 U8,
42 U16,
43 U32,
44 U64,
45 F32,
46 F64,
47 Bool,
48 String,
49 Void,
50 Pin, Bus, Duration, Custom(String),
54 Array(Box<Type>, usize),
55}
56
57impl fmt::Display for Type {
58 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
59 match self {
60 Type::I8 => write!(f, "i8"),
61 Type::I16 => write!(f, "i16"),
62 Type::I32 => write!(f, "i32"),
63 Type::I64 => write!(f, "i64"),
64 Type::U8 => write!(f, "u8"),
65 Type::U16 => write!(f, "u16"),
66 Type::U32 => write!(f, "u32"),
67 Type::U64 => write!(f, "u64"),
68 Type::F32 => write!(f, "f32"),
69 Type::F64 => write!(f, "f64"),
70 Type::Bool => write!(f, "bool"),
71 Type::String => write!(f, "string"),
72 Type::Void => write!(f, "void"),
73 Type::Pin => write!(f, "pin"),
74 Type::Bus => write!(f, "bus"),
75 Type::Duration => write!(f, "duration"),
76 Type::Custom(name) => write!(f, "{}", name),
77 Type::Array(inner, size) => write!(f, "[{}; {}]", inner, size),
78 }
79 }
80}
81
82#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
84pub enum PinMode {
85 In,
86 Out,
87 Alt,
88 Pwm,
89 Analog,
90}
91
92#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
94pub enum PinPull {
95 None,
96 Up,
97 Down,
98}
99
100#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
102pub enum TaskPriority {
103 Low,
104 Normal,
105 High,
106 Critical,
107 Realtime,
108}
109
110#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
112pub enum BusType {
113 I2C,
114 SPI,
115 UART,
116 CAN,
117}
118
119#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
121pub struct Program {
122 pub imports: Vec<ImportDecl>,
123 pub items: Vec<Item>,
124}
125
126#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
127pub struct ImportDecl {
128 pub path: Vec<String>,
129 pub span: Span,
130}
131
132#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
133pub enum Item {
134 Pin(PinDecl),
135 Bus(BusDecl),
136 Robot(RobotDecl),
137 Task(TaskDecl),
138 Function(FnDecl),
139 Struct(StructDecl),
140 Enum(EnumDecl),
141 StateMachine(StateMachineDecl),
142 TopicHandler(TopicHandlerDecl),
143 EventHandler(EventHandlerDecl),
144 InterruptHandler(InterruptHandlerDecl),
145 ServiceHandler(ServiceHandlerDecl),
146 ActionHandler(ActionHandlerDecl),
147 Watchdog(WatchdogDecl),
148 SensorPipeline(SensorPipelineDecl),
149 SafetyInvariant(SafetyInvariantDecl),
150}
151
152#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
154pub struct WatchdogDecl {
155 pub name: String,
156 pub timeout_ms: u32,
157 pub priority: TaskPriority,
158 pub span: Span,
159}
160
161#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
163pub struct SensorPipelineDecl {
164 pub name: String,
165 pub source: String,
166 pub filter: String,
167 pub output_type: Type,
168 pub span: Span,
169}
170
171#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
173pub struct SafetyInvariantDecl {
174 pub condition: Expr,
175 pub panic_msg: String,
176 pub span: Span,
177}
178
179#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
181pub struct StateMachineDecl {
182 pub name: String,
183 pub initial_state: String,
184 pub states: Vec<StateBlock>,
185 pub transitions: Vec<StateTransition>,
186 pub span: Span,
187}
188
189#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
190pub struct StateBlock {
191 pub name: String,
192 pub on_enter: Block,
193 pub on_update: Block,
194 pub span: Span,
195}
196
197#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
198pub struct StateTransition {
199 pub from_state: String,
200 pub to_state: String,
201 pub condition: String,
202 pub span: Span,
203}
204
205#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
207pub struct InterruptHandlerDecl {
208 pub pin_num: u32,
209 pub edge: String,
210 pub handler_name: String,
211 pub body: Block,
212 pub span: Span,
213}
214
215#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
217pub struct ServiceHandlerDecl {
218 pub service: String,
219 pub req_name: String,
220 pub req_type: Type,
221 pub ret_type: Type,
222 pub body: Block,
223 pub span: Span,
224}
225
226#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
228pub struct ActionHandlerDecl {
229 pub action: String,
230 pub goal_name: String,
231 pub goal_type: Type,
232 pub body: Block,
233 pub span: Span,
234}
235
236#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
238pub struct PinDecl {
239 pub name: String,
240 pub pin_num: u32,
241 pub mode: PinMode,
242 pub pull: PinPull,
243 pub span: Span,
244}
245
246#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
248pub struct BusDecl {
249 pub name: String,
250 pub bus_type: BusType,
251 pub bus_id: u32,
252 pub pins: Vec<String>,
253 pub baudrate: u32,
254 pub span: Span,
255}
256
257#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
259pub struct RobotDecl {
260 pub name: String,
261 pub pins: Vec<PinDecl>,
262 pub buses: Vec<BusDecl>,
263 pub fields: Vec<StructField>,
264 pub methods: Vec<FnDecl>,
265 pub tasks: Vec<TaskDecl>,
266 pub topic_handlers: Vec<TopicHandlerDecl>,
267 pub event_handlers: Vec<EventHandlerDecl>,
268 pub state_machines: Vec<StateMachineDecl>,
269 pub interrupt_handlers: Vec<InterruptHandlerDecl>,
270 pub service_handlers: Vec<ServiceHandlerDecl>,
271 pub action_handlers: Vec<ActionHandlerDecl>,
272 pub watchdogs: Vec<WatchdogDecl>,
273 pub sensor_pipelines: Vec<SensorPipelineDecl>,
274 pub safety_invariants: Vec<SafetyInvariantDecl>,
275 pub span: Span,
276}
277
278#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
280pub struct TaskDecl {
281 pub name: String,
282 pub deadline_ms: u32,
283 pub priority: TaskPriority,
284 pub body: Block,
285 pub span: Span,
286}
287
288#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
290pub struct TopicHandlerDecl {
291 pub topic: String,
292 pub param_name: String,
293 pub param_type: Type,
294 pub body: Block,
295 pub span: Span,
296}
297
298#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
300pub struct EventHandlerDecl {
301 pub event_type: String,
302 pub target_id: u32,
303 pub condition: String,
304 pub body: Block,
305 pub span: Span,
306}
307
308#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
309pub struct FnDecl {
310 pub name: String,
311 pub params: Vec<Param>,
312 pub ret_type: Type,
313 pub body: Block,
314 pub is_test: bool,
315 pub span: Span,
316}
317
318#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
319pub struct Param {
320 pub name: String,
321 pub ty: Type,
322 pub span: Span,
323}
324
325#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
326pub struct StructDecl {
327 pub name: String,
328 pub fields: Vec<StructField>,
329 pub span: Span,
330}
331
332#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
333pub struct StructField {
334 pub name: String,
335 pub ty: Type,
336 pub span: Span,
337}
338
339#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
340pub struct EnumDecl {
341 pub name: String,
342 pub variants: Vec<String>,
343 pub span: Span,
344}
345
346#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
347pub struct Block {
348 pub statements: Vec<Stmt>,
349 pub span: Span,
350}
351
352#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
353pub enum Stmt {
354 Let {
355 name: String,
356 mutability: bool,
357 ty: Option<Type>,
358 init: Expr,
359 span: Span,
360 },
361 Assign {
362 target: Expr,
363 value: Expr,
364 span: Span,
365 },
366 If {
367 cond: Expr,
368 then_block: Block,
369 else_block: Option<Block>,
370 span: Span,
371 },
372 While {
373 cond: Expr,
374 body: Block,
375 span: Span,
376 },
377 For {
378 var: String,
379 start: Expr,
380 end: Expr,
381 body: Block,
382 span: Span,
383 },
384 Loop {
385 body: Block,
386 span: Span,
387 },
388 Match {
389 target: Expr,
390 arms: Vec<MatchArm>,
391 span: Span,
392 },
393 Return {
394 value: Option<Expr>,
395 span: Span,
396 },
397 Emit {
398 topic: String,
399 payload: Expr,
400 span: Span,
401 },
402 Break(Span),
403 Continue(Span),
404 Expr(Expr),
405}
406
407#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
408pub struct MatchArm {
409 pub pattern: Pattern,
410 pub body: Block,
411 pub span: Span,
412}
413
414#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
415pub enum Pattern {
416 Literal(Literal),
417 EnumVariant { enum_name: String, variant: String },
418 Wildcard,
419}
420
421#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
422pub enum Expr {
423 Literal(Literal, Span),
424 Variable(String, Span),
425 FieldAccess(Box<Expr>, String, Span),
426 Index(Box<Expr>, Box<Expr>, Span),
427 Binary {
428 op: BinaryOp,
429 left: Box<Expr>,
430 right: Box<Expr>,
431 span: Span,
432 },
433 Unary {
434 op: UnaryOp,
435 operand: Box<Expr>,
436 span: Span,
437 },
438 Call {
439 func: String,
440 args: Vec<Expr>,
441 span: Span,
442 },
443 MethodCall {
444 receiver: Box<Expr>,
445 method: String,
446 args: Vec<Expr>,
447 span: Span,
448 },
449 StructInit {
450 name: String,
451 fields: Vec<(String, Expr)>,
452 span: Span,
453 },
454 ArrayInit(Vec<Expr>, Span),
455}
456
457#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
458pub enum Literal {
459 Int(i64),
460 Float(f64),
461 Bool(bool),
462 String(String),
463 DurationMs(u32),
464 HardwareConstant(String), }
466
467impl Eq for Literal {}
468
469#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
470pub enum BinaryOp {
471 Add,
472 Sub,
473 Mul,
474 Div,
475 Mod,
476 Eq,
477 NotEq,
478 Lt,
479 LtEq,
480 Gt,
481 GtEq,
482 And,
483 Or,
484 BitAnd,
485 BitOr,
486 BitXor,
487 Shl,
488 Shr,
489}
490
491#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
492pub enum UnaryOp {
493 Neg,
494 Not,
495 BitNot,
496}