1use crate::compiler::tokens::Span;
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct Program {
7 pub directives: Vec<Directive>,
8 pub items: Vec<Item>,
9 pub span: Span,
10}
11
12#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct Directive {
15 pub name: String,
16 pub value: Option<String>,
17 pub span: Span,
18}
19
20#[derive(Debug, Clone, Serialize, Deserialize)]
22pub enum Item {
23 Record(RecordDef),
24 Enum(EnumDef),
25 Cell(CellDef),
26 Agent(AgentDecl),
27 Process(ProcessDecl),
28 Effect(EffectDecl),
29 EffectBind(EffectBindDecl),
30 Handler(HandlerDecl),
31 Addon(AddonDecl),
32 UseTool(UseToolDecl),
33 Grant(GrantDecl),
34 TypeAlias(TypeAliasDef),
35 Trait(TraitDef),
36 Impl(ImplDef),
37 Import(ImportDecl),
38 ConstDecl(ConstDeclDef),
39 MacroDecl(MacroDeclDef),
40}
41
42impl Item {
43 pub fn span(&self) -> Span {
44 match self {
45 Item::Record(r) => r.span,
46 Item::Enum(e) => e.span,
47 Item::Cell(c) => c.span,
48 Item::Agent(a) => a.span,
49 Item::Process(p) => p.span,
50 Item::Effect(e) => e.span,
51 Item::EffectBind(b) => b.span,
52 Item::Handler(h) => h.span,
53 Item::Addon(a) => a.span,
54 Item::UseTool(u) => u.span,
55 Item::Grant(g) => g.span,
56 Item::TypeAlias(t) => t.span,
57 Item::Trait(t) => t.span,
58 Item::Impl(i) => i.span,
59 Item::Import(i) => i.span,
60 Item::ConstDecl(c) => c.span,
61 Item::MacroDecl(m) => m.span,
62 }
63 }
64}
65
66#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
70pub enum TypeExpr {
71 Named(String, Span),
73 List(Box<TypeExpr>, Span),
75 Map(Box<TypeExpr>, Box<TypeExpr>, Span),
77 Result(Box<TypeExpr>, Box<TypeExpr>, Span),
79 Union(Vec<TypeExpr>, Span),
81 Null(Span),
83 Tuple(Vec<TypeExpr>, Span),
85 Set(Box<TypeExpr>, Span),
87 Fn(Vec<TypeExpr>, Box<TypeExpr>, Vec<String>, Span),
89 Generic(String, Vec<TypeExpr>, Span),
91}
92
93impl TypeExpr {
94 pub fn span(&self) -> Span {
95 match self {
96 TypeExpr::Named(_, s) => *s,
97 TypeExpr::List(_, s) => *s,
98 TypeExpr::Map(_, _, s) => *s,
99 TypeExpr::Result(_, _, s) => *s,
100 TypeExpr::Union(_, s) => *s,
101 TypeExpr::Null(s) => *s,
102 TypeExpr::Tuple(_, s) => *s,
103 TypeExpr::Set(_, s) => *s,
104 TypeExpr::Fn(_, _, _, s) => *s,
105 TypeExpr::Generic(_, _, s) => *s,
106 }
107 }
108}
109
110#[derive(Debug, Clone, Serialize, Deserialize)]
113pub struct GenericParam {
114 pub name: String,
115 pub bounds: Vec<String>,
116 pub span: Span,
117}
118
119#[derive(Debug, Clone, Serialize, Deserialize)]
122pub struct RecordDef {
123 pub name: String,
124 pub generic_params: Vec<GenericParam>,
125 pub fields: Vec<FieldDef>,
126 pub is_pub: bool,
127 pub span: Span,
128}
129
130#[derive(Debug, Clone, Serialize, Deserialize)]
131pub struct FieldDef {
132 pub name: String,
133 pub ty: TypeExpr,
134 pub default_value: Option<Expr>,
135 pub constraint: Option<Expr>,
136 pub span: Span,
137}
138
139#[derive(Debug, Clone, Serialize, Deserialize)]
142pub struct EnumDef {
143 pub name: String,
144 pub generic_params: Vec<GenericParam>,
145 pub variants: Vec<EnumVariant>,
146 pub methods: Vec<CellDef>,
147 pub is_pub: bool,
148 pub span: Span,
149}
150
151#[derive(Debug, Clone, Serialize, Deserialize)]
152pub struct EnumVariant {
153 pub name: String,
154 pub payload: Option<TypeExpr>,
155 pub span: Span,
156}
157
158#[derive(Debug, Clone, Serialize, Deserialize)]
161pub struct CellDef {
162 pub name: String,
163 pub generic_params: Vec<GenericParam>,
164 pub params: Vec<Param>,
165 pub return_type: Option<TypeExpr>,
166 pub effects: Vec<String>,
167 pub body: Vec<Stmt>,
168 pub is_pub: bool,
169 pub is_async: bool,
170 pub where_clauses: Vec<Expr>,
171 pub span: Span,
172}
173
174#[derive(Debug, Clone, Serialize, Deserialize)]
175pub struct AgentDecl {
176 pub name: String,
177 pub cells: Vec<CellDef>,
178 pub grants: Vec<GrantDecl>,
179 pub span: Span,
180}
181
182#[derive(Debug, Clone, Serialize, Deserialize)]
183pub struct ProcessDecl {
184 pub kind: String,
185 pub name: String,
186 pub cells: Vec<CellDef>,
187 pub grants: Vec<GrantDecl>,
188 pub pipeline_stages: Vec<String>,
189 pub machine_initial: Option<String>,
190 pub machine_states: Vec<MachineStateDecl>,
191 pub span: Span,
192}
193
194#[derive(Debug, Clone, Serialize, Deserialize)]
195pub struct MachineStateDecl {
196 pub name: String,
197 pub params: Vec<Param>,
198 pub terminal: bool,
199 pub guard: Option<Expr>,
200 pub transition_to: Option<String>,
201 pub transition_args: Vec<Expr>,
202 pub span: Span,
203}
204
205#[derive(Debug, Clone, Serialize, Deserialize)]
206pub struct EffectDecl {
207 pub name: String,
208 pub operations: Vec<CellDef>,
209 pub span: Span,
210}
211
212#[derive(Debug, Clone, Serialize, Deserialize)]
213pub struct EffectBindDecl {
214 pub effect_path: String,
215 pub tool_alias: String,
216 pub span: Span,
217}
218
219#[derive(Debug, Clone, Serialize, Deserialize)]
220pub struct HandlerDecl {
221 pub name: String,
222 pub handles: Vec<CellDef>,
223 pub span: Span,
224}
225
226#[derive(Debug, Clone, Serialize, Deserialize)]
227pub struct AddonDecl {
228 pub kind: String,
229 pub name: Option<String>,
230 pub span: Span,
231}
232
233#[derive(Debug, Clone, Serialize, Deserialize)]
234pub struct Param {
235 pub name: String,
236 pub ty: TypeExpr,
237 pub default_value: Option<Expr>,
238 pub variadic: bool,
239 pub span: Span,
240}
241
242#[derive(Debug, Clone, Serialize, Deserialize)]
245pub struct TypeAliasDef {
246 pub name: String,
247 pub generic_params: Vec<GenericParam>,
248 pub type_expr: TypeExpr,
249 pub is_pub: bool,
250 pub span: Span,
251}
252
253#[derive(Debug, Clone, Serialize, Deserialize)]
254pub struct TraitDef {
255 pub name: String,
256 pub parent_traits: Vec<String>,
257 pub methods: Vec<CellDef>,
258 pub is_pub: bool,
259 pub span: Span,
260}
261
262#[derive(Debug, Clone, Serialize, Deserialize)]
263pub struct ImplDef {
264 pub trait_name: String,
265 pub generic_params: Vec<GenericParam>,
266 pub target_type: String,
267 pub cells: Vec<CellDef>,
268 pub span: Span,
269}
270
271#[derive(Debug, Clone, Serialize, Deserialize)]
272pub enum ImportList {
273 Names(Vec<ImportName>),
274 Wildcard,
275}
276
277#[derive(Debug, Clone, Serialize, Deserialize)]
278pub struct ImportName {
279 pub name: String,
280 pub alias: Option<String>,
281 pub span: Span,
282}
283
284#[derive(Debug, Clone, Serialize, Deserialize)]
285pub struct ImportDecl {
286 pub path: Vec<String>,
287 pub names: ImportList,
288 pub is_pub: bool,
289 pub span: Span,
290}
291
292#[derive(Debug, Clone, Serialize, Deserialize)]
293pub struct ConstDeclDef {
294 pub name: String,
295 pub type_ann: Option<TypeExpr>,
296 pub value: Expr,
297 pub span: Span,
298}
299
300#[derive(Debug, Clone, Serialize, Deserialize)]
301pub struct MacroDeclDef {
302 pub name: String,
303 pub params: Vec<String>,
304 pub body: Vec<Stmt>,
305 pub span: Span,
306}
307
308#[derive(Debug, Clone, Serialize, Deserialize)]
311pub enum CompoundOp {
312 AddAssign,
313 SubAssign,
314 MulAssign,
315 DivAssign,
316 FloorDivAssign,
317 ModAssign,
318 PowAssign,
319 BitAndAssign,
320 BitOrAssign,
321 BitXorAssign,
322}
323
324#[derive(Debug, Clone, Serialize, Deserialize)]
325pub enum Stmt {
326 Let(LetStmt),
327 If(IfStmt),
328 For(ForStmt),
329 Match(MatchStmt),
330 Return(ReturnStmt),
331 Halt(HaltStmt),
332 Assign(AssignStmt),
333 Expr(ExprStmt),
334 While(WhileStmt),
335 Loop(LoopStmt),
336 Break(BreakStmt),
337 Continue(ContinueStmt),
338 Emit(EmitStmt),
339 CompoundAssign(CompoundAssignStmt),
340 Defer(DeferStmt),
341}
342
343impl Stmt {
344 pub fn span(&self) -> Span {
345 match self {
346 Stmt::Let(s) => s.span,
347 Stmt::If(s) => s.span,
348 Stmt::For(s) => s.span,
349 Stmt::Match(s) => s.span,
350 Stmt::Return(s) => s.span,
351 Stmt::Halt(s) => s.span,
352 Stmt::Assign(s) => s.span,
353 Stmt::Expr(s) => s.span,
354 Stmt::While(s) => s.span,
355 Stmt::Loop(s) => s.span,
356 Stmt::Break(s) => s.span,
357 Stmt::Continue(s) => s.span,
358 Stmt::Emit(s) => s.span,
359 Stmt::CompoundAssign(s) => s.span,
360 Stmt::Defer(s) => s.span,
361 }
362 }
363}
364
365#[derive(Debug, Clone, Serialize, Deserialize)]
366pub struct LetStmt {
367 pub name: String,
368 pub mutable: bool,
369 pub pattern: Option<Pattern>,
370 pub ty: Option<TypeExpr>,
371 pub value: Expr,
372 pub span: Span,
373}
374
375#[derive(Debug, Clone, Serialize, Deserialize)]
376pub struct IfStmt {
377 pub condition: Expr,
378 pub then_body: Vec<Stmt>,
379 pub else_body: Option<Vec<Stmt>>,
380 pub span: Span,
381}
382
383#[derive(Debug, Clone, Serialize, Deserialize)]
384pub struct ForStmt {
385 pub label: Option<String>,
386 pub var: String,
387 pub pattern: Option<Pattern>,
388 pub iter: Expr,
389 pub filter: Option<Expr>,
390 pub body: Vec<Stmt>,
391 pub span: Span,
392}
393
394#[derive(Debug, Clone, Serialize, Deserialize)]
395pub struct MatchStmt {
396 pub subject: Expr,
397 pub arms: Vec<MatchArm>,
398 pub span: Span,
399}
400
401#[derive(Debug, Clone, Serialize, Deserialize)]
402pub struct MatchArm {
403 pub pattern: Pattern,
404 pub body: Vec<Stmt>,
405 pub span: Span,
406}
407
408#[derive(Debug, Clone, Serialize, Deserialize)]
409pub enum Pattern {
410 Literal(Expr),
412 Variant(String, Option<Box<Pattern>>, Span),
414 Wildcard(Span),
416 Ident(String, Span),
418 Guard {
420 inner: Box<Pattern>,
421 condition: Box<Expr>,
422 span: Span,
423 },
424 Or { patterns: Vec<Pattern>, span: Span },
426 ListDestructure {
428 elements: Vec<Pattern>,
429 rest: Option<String>,
430 span: Span,
431 },
432 TupleDestructure { elements: Vec<Pattern>, span: Span },
434 RecordDestructure {
436 type_name: String,
437 fields: Vec<(String, Option<Pattern>)>,
438 open: bool,
439 span: Span,
440 },
441 TypeCheck {
443 name: String,
444 type_expr: Box<TypeExpr>,
445 span: Span,
446 },
447}
448
449#[derive(Debug, Clone, Serialize, Deserialize)]
450pub struct ReturnStmt {
451 pub value: Expr,
452 pub span: Span,
453}
454
455#[derive(Debug, Clone, Serialize, Deserialize)]
456pub struct HaltStmt {
457 pub message: Expr,
458 pub span: Span,
459}
460
461#[derive(Debug, Clone, Serialize, Deserialize)]
462pub struct ExprStmt {
463 pub expr: Expr,
464 pub span: Span,
465}
466
467#[derive(Debug, Clone, Serialize, Deserialize)]
468pub struct AssignStmt {
469 pub target: String,
470 pub value: Expr,
471 pub span: Span,
472}
473
474#[derive(Debug, Clone, Serialize, Deserialize)]
475pub struct WhileStmt {
476 pub label: Option<String>,
477 pub condition: Expr,
478 pub body: Vec<Stmt>,
479 pub span: Span,
480}
481
482#[derive(Debug, Clone, Serialize, Deserialize)]
483pub struct LoopStmt {
484 pub label: Option<String>,
485 pub body: Vec<Stmt>,
486 pub span: Span,
487}
488
489#[derive(Debug, Clone, Serialize, Deserialize)]
490pub struct BreakStmt {
491 pub label: Option<String>,
492 pub value: Option<Expr>,
493 pub span: Span,
494}
495
496#[derive(Debug, Clone, Serialize, Deserialize)]
497pub struct ContinueStmt {
498 pub label: Option<String>,
499 pub span: Span,
500}
501
502#[derive(Debug, Clone, Serialize, Deserialize)]
503pub struct EmitStmt {
504 pub value: Expr,
505 pub span: Span,
506}
507
508#[derive(Debug, Clone, Serialize, Deserialize)]
509pub struct CompoundAssignStmt {
510 pub target: String,
511 pub op: CompoundOp,
512 pub value: Expr,
513 pub span: Span,
514}
515
516#[derive(Debug, Clone, Serialize, Deserialize)]
517pub struct DeferStmt {
518 pub body: Vec<Stmt>,
519 pub span: Span,
520}
521
522#[derive(Debug, Clone, Serialize, Deserialize)]
526pub enum LambdaBody {
527 Expr(Box<Expr>),
528 Block(Vec<Stmt>),
529}
530
531#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
533pub enum ComprehensionKind {
534 List,
535 Map,
536 Set,
537}
538
539#[derive(Debug, Clone, Serialize, Deserialize)]
540pub enum Expr {
541 IntLit(i64, Span),
543 FloatLit(f64, Span),
545 StringLit(String, Span),
547 StringInterp(Vec<StringSegment>, Span),
549 BoolLit(bool, Span),
551 NullLit(Span),
553 RawStringLit(String, Span),
555 BytesLit(Vec<u8>, Span),
557 Ident(String, Span),
559 ListLit(Vec<Expr>, Span),
561 MapLit(Vec<(Expr, Expr)>, Span),
563 RecordLit(String, Vec<(String, Expr)>, Span),
565 BinOp(Box<Expr>, BinOp, Box<Expr>, Span),
567 UnaryOp(UnaryOp, Box<Expr>, Span),
569 Call(Box<Expr>, Vec<CallArg>, Span),
571 ToolCall(Box<Expr>, Vec<CallArg>, Span),
573 DotAccess(Box<Expr>, String, Span),
575 IndexAccess(Box<Expr>, Box<Expr>, Span),
577 RoleBlock(String, Box<Expr>, Span),
579 ExpectSchema(Box<Expr>, String, Span),
581 Lambda {
583 params: Vec<Param>,
584 return_type: Option<Box<TypeExpr>>,
585 body: LambdaBody,
586 span: Span,
587 },
588 TupleLit(Vec<Expr>, Span),
590 SetLit(Vec<Expr>, Span),
592 RangeExpr {
594 start: Option<Box<Expr>>,
595 end: Option<Box<Expr>>,
596 inclusive: bool,
597 step: Option<Box<Expr>>,
598 span: Span,
599 },
600 TryExpr(Box<Expr>, Span),
602 NullCoalesce(Box<Expr>, Box<Expr>, Span),
604 NullSafeAccess(Box<Expr>, String, Span),
606 NullSafeIndex(Box<Expr>, Box<Expr>, Span),
608 NullAssert(Box<Expr>, Span),
610 SpreadExpr(Box<Expr>, Span),
612 IfExpr {
614 cond: Box<Expr>,
615 then_val: Box<Expr>,
616 else_val: Box<Expr>,
617 span: Span,
618 },
619 AwaitExpr(Box<Expr>, Span),
621 Comprehension {
623 body: Box<Expr>,
624 var: String,
625 iter: Box<Expr>,
626 condition: Option<Box<Expr>>,
627 kind: ComprehensionKind,
628 span: Span,
629 },
630 MatchExpr {
632 subject: Box<Expr>,
633 arms: Vec<MatchArm>,
634 span: Span,
635 },
636 BlockExpr(Vec<Stmt>, Span),
638 Pipe {
640 left: Box<Expr>,
641 right: Box<Expr>,
642 span: Span,
643 },
644 Illuminate {
646 input: Box<Expr>,
647 transform: Box<Expr>,
648 span: Span,
649 },
650 IsType {
652 expr: Box<Expr>,
653 type_name: String,
654 span: Span,
655 },
656 TypeCast {
658 expr: Box<Expr>,
659 target_type: String,
660 span: Span,
661 },
662}
663
664impl Expr {
665 pub fn span(&self) -> Span {
666 match self {
667 Expr::IntLit(_, s)
668 | Expr::FloatLit(_, s)
669 | Expr::StringLit(_, s)
670 | Expr::StringInterp(_, s)
671 | Expr::BoolLit(_, s)
672 | Expr::NullLit(s)
673 | Expr::RawStringLit(_, s)
674 | Expr::BytesLit(_, s)
675 | Expr::Ident(_, s)
676 | Expr::ListLit(_, s)
677 | Expr::MapLit(_, s)
678 | Expr::RecordLit(_, _, s)
679 | Expr::BinOp(_, _, _, s)
680 | Expr::UnaryOp(_, _, s)
681 | Expr::Call(_, _, s)
682 | Expr::ToolCall(_, _, s)
683 | Expr::DotAccess(_, _, s)
684 | Expr::IndexAccess(_, _, s)
685 | Expr::RoleBlock(_, _, s)
686 | Expr::ExpectSchema(_, _, s)
687 | Expr::TupleLit(_, s)
688 | Expr::SetLit(_, s)
689 | Expr::TryExpr(_, s)
690 | Expr::NullCoalesce(_, _, s)
691 | Expr::NullSafeAccess(_, _, s)
692 | Expr::NullSafeIndex(_, _, s)
693 | Expr::NullAssert(_, s)
694 | Expr::SpreadExpr(_, s)
695 | Expr::AwaitExpr(_, s)
696 | Expr::BlockExpr(_, s) => *s,
697 Expr::Lambda { span, .. } => *span,
698 Expr::RangeExpr { span, .. } => *span,
699 Expr::IfExpr { span, .. } => *span,
700 Expr::Comprehension { span, .. } => *span,
701 Expr::MatchExpr { span, .. } => *span,
702 Expr::Pipe { span, .. } => *span,
703 Expr::Illuminate { span, .. } => *span,
704 Expr::IsType { span, .. } => *span,
705 Expr::TypeCast { span, .. } => *span,
706 }
707 }
708}
709
710#[derive(Debug, Clone, Serialize, Deserialize)]
711pub enum StringSegment {
712 Literal(String),
713 Interpolation(Box<Expr>),
714}
715
716#[derive(Debug, Clone, Serialize, Deserialize)]
717pub enum CallArg {
718 Positional(Expr),
719 Named(String, Expr, Span),
720 Role(String, Expr, Span),
721}
722
723#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
724pub enum BinOp {
725 Add,
726 Sub,
727 Mul,
728 Div,
729 FloorDiv,
730 Mod,
731 Eq,
732 NotEq,
733 Lt,
734 LtEq,
735 Gt,
736 GtEq,
737 And,
738 Or,
739 Pow,
740 PipeForward,
741 Concat,
742 In,
743 BitAnd,
744 BitOr,
745 BitXor,
746 Shl,
747 Shr,
748}
749
750impl fmt::Display for BinOp {
751 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
752 match self {
753 BinOp::Add => write!(f, "+"),
754 BinOp::Sub => write!(f, "-"),
755 BinOp::Mul => write!(f, "*"),
756 BinOp::Div => write!(f, "/"),
757 BinOp::FloorDiv => write!(f, "//"),
758 BinOp::Mod => write!(f, "%"),
759 BinOp::Eq => write!(f, "=="),
760 BinOp::NotEq => write!(f, "!="),
761 BinOp::Lt => write!(f, "<"),
762 BinOp::LtEq => write!(f, "<="),
763 BinOp::Gt => write!(f, ">"),
764 BinOp::GtEq => write!(f, ">="),
765 BinOp::And => write!(f, "and"),
766 BinOp::Or => write!(f, "or"),
767 BinOp::Pow => write!(f, "**"),
768 BinOp::PipeForward => write!(f, "|>"),
769 BinOp::Concat => write!(f, "++"),
770 BinOp::In => write!(f, "in"),
771 BinOp::BitAnd => write!(f, "&"),
772 BinOp::BitOr => write!(f, "|"),
773 BinOp::BitXor => write!(f, "^"),
774 BinOp::Shl => write!(f, "<<"),
775 BinOp::Shr => write!(f, ">>"),
776 }
777 }
778}
779
780use std::fmt;
781
782#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
783pub enum UnaryOp {
784 Neg,
785 Not,
786 BitNot,
787}
788
789#[derive(Debug, Clone, Serialize, Deserialize)]
792pub struct UseToolDecl {
793 pub tool_path: String,
794 pub alias: String,
795 pub mcp_url: Option<String>,
796 pub span: Span,
797}
798
799#[derive(Debug, Clone, Serialize, Deserialize)]
800pub struct GrantDecl {
801 pub tool_alias: String,
802 pub constraints: Vec<GrantConstraint>,
803 pub span: Span,
804}
805
806#[derive(Debug, Clone, Serialize, Deserialize)]
807pub struct GrantConstraint {
808 pub key: String,
809 pub value: Expr,
810 pub span: Span,
811}