use crate::compiler::tokens::Span;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Program {
pub directives: Vec<Directive>,
pub items: Vec<Item>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Directive {
pub name: String,
pub value: Option<String>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Item {
Record(RecordDef),
Enum(EnumDef),
Cell(CellDef),
Agent(AgentDecl),
Process(ProcessDecl),
Effect(EffectDecl),
EffectBind(EffectBindDecl),
Handler(HandlerDecl),
Addon(AddonDecl),
UseTool(UseToolDecl),
Grant(GrantDecl),
TypeAlias(TypeAliasDef),
Trait(TraitDef),
Impl(ImplDef),
Import(ImportDecl),
ConstDecl(ConstDeclDef),
MacroDecl(MacroDeclDef),
}
impl Item {
pub fn span(&self) -> Span {
match self {
Item::Record(r) => r.span,
Item::Enum(e) => e.span,
Item::Cell(c) => c.span,
Item::Agent(a) => a.span,
Item::Process(p) => p.span,
Item::Effect(e) => e.span,
Item::EffectBind(b) => b.span,
Item::Handler(h) => h.span,
Item::Addon(a) => a.span,
Item::UseTool(u) => u.span,
Item::Grant(g) => g.span,
Item::TypeAlias(t) => t.span,
Item::Trait(t) => t.span,
Item::Impl(i) => i.span,
Item::Import(i) => i.span,
Item::ConstDecl(c) => c.span,
Item::MacroDecl(m) => m.span,
}
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum TypeExpr {
Named(String, Span),
List(Box<TypeExpr>, Span),
Map(Box<TypeExpr>, Box<TypeExpr>, Span),
Result(Box<TypeExpr>, Box<TypeExpr>, Span),
Union(Vec<TypeExpr>, Span),
Null(Span),
Tuple(Vec<TypeExpr>, Span),
Set(Box<TypeExpr>, Span),
Fn(Vec<TypeExpr>, Box<TypeExpr>, Vec<String>, Span),
Generic(String, Vec<TypeExpr>, Span),
}
impl TypeExpr {
pub fn span(&self) -> Span {
match self {
TypeExpr::Named(_, s) => *s,
TypeExpr::List(_, s) => *s,
TypeExpr::Map(_, _, s) => *s,
TypeExpr::Result(_, _, s) => *s,
TypeExpr::Union(_, s) => *s,
TypeExpr::Null(s) => *s,
TypeExpr::Tuple(_, s) => *s,
TypeExpr::Set(_, s) => *s,
TypeExpr::Fn(_, _, _, s) => *s,
TypeExpr::Generic(_, _, s) => *s,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GenericParam {
pub name: String,
pub bounds: Vec<String>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RecordDef {
pub name: String,
pub generic_params: Vec<GenericParam>,
pub fields: Vec<FieldDef>,
pub is_pub: bool,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FieldDef {
pub name: String,
pub ty: TypeExpr,
pub default_value: Option<Expr>,
pub constraint: Option<Expr>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EnumDef {
pub name: String,
pub generic_params: Vec<GenericParam>,
pub variants: Vec<EnumVariant>,
pub methods: Vec<CellDef>,
pub is_pub: bool,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EnumVariant {
pub name: String,
pub payload: Option<TypeExpr>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CellDef {
pub name: String,
pub generic_params: Vec<GenericParam>,
pub params: Vec<Param>,
pub return_type: Option<TypeExpr>,
pub effects: Vec<String>,
pub body: Vec<Stmt>,
pub is_pub: bool,
pub is_async: bool,
pub where_clauses: Vec<Expr>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AgentDecl {
pub name: String,
pub cells: Vec<CellDef>,
pub grants: Vec<GrantDecl>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProcessDecl {
pub kind: String,
pub name: String,
pub cells: Vec<CellDef>,
pub grants: Vec<GrantDecl>,
pub pipeline_stages: Vec<String>,
pub machine_initial: Option<String>,
pub machine_states: Vec<MachineStateDecl>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MachineStateDecl {
pub name: String,
pub params: Vec<Param>,
pub terminal: bool,
pub guard: Option<Expr>,
pub transition_to: Option<String>,
pub transition_args: Vec<Expr>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EffectDecl {
pub name: String,
pub operations: Vec<CellDef>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EffectBindDecl {
pub effect_path: String,
pub tool_alias: String,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HandlerDecl {
pub name: String,
pub handles: Vec<CellDef>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AddonDecl {
pub kind: String,
pub name: Option<String>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Param {
pub name: String,
pub ty: TypeExpr,
pub default_value: Option<Expr>,
pub variadic: bool,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TypeAliasDef {
pub name: String,
pub generic_params: Vec<GenericParam>,
pub type_expr: TypeExpr,
pub is_pub: bool,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TraitDef {
pub name: String,
pub parent_traits: Vec<String>,
pub methods: Vec<CellDef>,
pub is_pub: bool,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ImplDef {
pub trait_name: String,
pub generic_params: Vec<GenericParam>,
pub target_type: String,
pub cells: Vec<CellDef>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ImportList {
Names(Vec<ImportName>),
Wildcard,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ImportName {
pub name: String,
pub alias: Option<String>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ImportDecl {
pub path: Vec<String>,
pub names: ImportList,
pub is_pub: bool,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConstDeclDef {
pub name: String,
pub type_ann: Option<TypeExpr>,
pub value: Expr,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MacroDeclDef {
pub name: String,
pub params: Vec<String>,
pub body: Vec<Stmt>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum CompoundOp {
AddAssign,
SubAssign,
MulAssign,
DivAssign,
FloorDivAssign,
ModAssign,
PowAssign,
BitAndAssign,
BitOrAssign,
BitXorAssign,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Stmt {
Let(LetStmt),
If(IfStmt),
For(ForStmt),
Match(MatchStmt),
Return(ReturnStmt),
Halt(HaltStmt),
Assign(AssignStmt),
Expr(ExprStmt),
While(WhileStmt),
Loop(LoopStmt),
Break(BreakStmt),
Continue(ContinueStmt),
Emit(EmitStmt),
CompoundAssign(CompoundAssignStmt),
Defer(DeferStmt),
}
impl Stmt {
pub fn span(&self) -> Span {
match self {
Stmt::Let(s) => s.span,
Stmt::If(s) => s.span,
Stmt::For(s) => s.span,
Stmt::Match(s) => s.span,
Stmt::Return(s) => s.span,
Stmt::Halt(s) => s.span,
Stmt::Assign(s) => s.span,
Stmt::Expr(s) => s.span,
Stmt::While(s) => s.span,
Stmt::Loop(s) => s.span,
Stmt::Break(s) => s.span,
Stmt::Continue(s) => s.span,
Stmt::Emit(s) => s.span,
Stmt::CompoundAssign(s) => s.span,
Stmt::Defer(s) => s.span,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LetStmt {
pub name: String,
pub mutable: bool,
pub pattern: Option<Pattern>,
pub ty: Option<TypeExpr>,
pub value: Expr,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IfStmt {
pub condition: Expr,
pub then_body: Vec<Stmt>,
pub else_body: Option<Vec<Stmt>>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ForStmt {
pub label: Option<String>,
pub var: String,
pub pattern: Option<Pattern>,
pub iter: Expr,
pub filter: Option<Expr>,
pub body: Vec<Stmt>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MatchStmt {
pub subject: Expr,
pub arms: Vec<MatchArm>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MatchArm {
pub pattern: Pattern,
pub body: Vec<Stmt>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Pattern {
Literal(Expr),
Variant(String, Option<Box<Pattern>>, Span),
Wildcard(Span),
Ident(String, Span),
Guard {
inner: Box<Pattern>,
condition: Box<Expr>,
span: Span,
},
Or { patterns: Vec<Pattern>, span: Span },
ListDestructure {
elements: Vec<Pattern>,
rest: Option<String>,
span: Span,
},
TupleDestructure { elements: Vec<Pattern>, span: Span },
RecordDestructure {
type_name: String,
fields: Vec<(String, Option<Pattern>)>,
open: bool,
span: Span,
},
TypeCheck {
name: String,
type_expr: Box<TypeExpr>,
span: Span,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ReturnStmt {
pub value: Expr,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HaltStmt {
pub message: Expr,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExprStmt {
pub expr: Expr,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AssignStmt {
pub target: String,
pub value: Expr,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WhileStmt {
pub label: Option<String>,
pub condition: Expr,
pub body: Vec<Stmt>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LoopStmt {
pub label: Option<String>,
pub body: Vec<Stmt>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BreakStmt {
pub label: Option<String>,
pub value: Option<Expr>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ContinueStmt {
pub label: Option<String>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EmitStmt {
pub value: Expr,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompoundAssignStmt {
pub target: String,
pub op: CompoundOp,
pub value: Expr,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DeferStmt {
pub body: Vec<Stmt>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum LambdaBody {
Expr(Box<Expr>),
Block(Vec<Stmt>),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum ComprehensionKind {
List,
Map,
Set,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Expr {
IntLit(i64, Span),
FloatLit(f64, Span),
StringLit(String, Span),
StringInterp(Vec<StringSegment>, Span),
BoolLit(bool, Span),
NullLit(Span),
RawStringLit(String, Span),
BytesLit(Vec<u8>, Span),
Ident(String, Span),
ListLit(Vec<Expr>, Span),
MapLit(Vec<(Expr, Expr)>, Span),
RecordLit(String, Vec<(String, Expr)>, Span),
BinOp(Box<Expr>, BinOp, Box<Expr>, Span),
UnaryOp(UnaryOp, Box<Expr>, Span),
Call(Box<Expr>, Vec<CallArg>, Span),
ToolCall(Box<Expr>, Vec<CallArg>, Span),
DotAccess(Box<Expr>, String, Span),
IndexAccess(Box<Expr>, Box<Expr>, Span),
RoleBlock(String, Box<Expr>, Span),
ExpectSchema(Box<Expr>, String, Span),
Lambda {
params: Vec<Param>,
return_type: Option<Box<TypeExpr>>,
body: LambdaBody,
span: Span,
},
TupleLit(Vec<Expr>, Span),
SetLit(Vec<Expr>, Span),
RangeExpr {
start: Option<Box<Expr>>,
end: Option<Box<Expr>>,
inclusive: bool,
step: Option<Box<Expr>>,
span: Span,
},
TryExpr(Box<Expr>, Span),
NullCoalesce(Box<Expr>, Box<Expr>, Span),
NullSafeAccess(Box<Expr>, String, Span),
NullSafeIndex(Box<Expr>, Box<Expr>, Span),
NullAssert(Box<Expr>, Span),
SpreadExpr(Box<Expr>, Span),
IfExpr {
cond: Box<Expr>,
then_val: Box<Expr>,
else_val: Box<Expr>,
span: Span,
},
AwaitExpr(Box<Expr>, Span),
Comprehension {
body: Box<Expr>,
var: String,
iter: Box<Expr>,
condition: Option<Box<Expr>>,
kind: ComprehensionKind,
span: Span,
},
MatchExpr {
subject: Box<Expr>,
arms: Vec<MatchArm>,
span: Span,
},
BlockExpr(Vec<Stmt>, Span),
Pipe {
left: Box<Expr>,
right: Box<Expr>,
span: Span,
},
Illuminate {
input: Box<Expr>,
transform: Box<Expr>,
span: Span,
},
IsType {
expr: Box<Expr>,
type_name: String,
span: Span,
},
TypeCast {
expr: Box<Expr>,
target_type: String,
span: Span,
},
}
impl Expr {
pub fn span(&self) -> Span {
match self {
Expr::IntLit(_, s)
| Expr::FloatLit(_, s)
| Expr::StringLit(_, s)
| Expr::StringInterp(_, s)
| Expr::BoolLit(_, s)
| Expr::NullLit(s)
| Expr::RawStringLit(_, s)
| Expr::BytesLit(_, s)
| Expr::Ident(_, s)
| Expr::ListLit(_, s)
| Expr::MapLit(_, s)
| Expr::RecordLit(_, _, s)
| Expr::BinOp(_, _, _, s)
| Expr::UnaryOp(_, _, s)
| Expr::Call(_, _, s)
| Expr::ToolCall(_, _, s)
| Expr::DotAccess(_, _, s)
| Expr::IndexAccess(_, _, s)
| Expr::RoleBlock(_, _, s)
| Expr::ExpectSchema(_, _, s)
| Expr::TupleLit(_, s)
| Expr::SetLit(_, s)
| Expr::TryExpr(_, s)
| Expr::NullCoalesce(_, _, s)
| Expr::NullSafeAccess(_, _, s)
| Expr::NullSafeIndex(_, _, s)
| Expr::NullAssert(_, s)
| Expr::SpreadExpr(_, s)
| Expr::AwaitExpr(_, s)
| Expr::BlockExpr(_, s) => *s,
Expr::Lambda { span, .. } => *span,
Expr::RangeExpr { span, .. } => *span,
Expr::IfExpr { span, .. } => *span,
Expr::Comprehension { span, .. } => *span,
Expr::MatchExpr { span, .. } => *span,
Expr::Pipe { span, .. } => *span,
Expr::Illuminate { span, .. } => *span,
Expr::IsType { span, .. } => *span,
Expr::TypeCast { span, .. } => *span,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum StringSegment {
Literal(String),
Interpolation(Box<Expr>),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum CallArg {
Positional(Expr),
Named(String, Expr, Span),
Role(String, Expr, Span),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum BinOp {
Add,
Sub,
Mul,
Div,
FloorDiv,
Mod,
Eq,
NotEq,
Lt,
LtEq,
Gt,
GtEq,
And,
Or,
Pow,
PipeForward,
Concat,
In,
BitAnd,
BitOr,
BitXor,
Shl,
Shr,
}
impl fmt::Display for BinOp {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
BinOp::Add => write!(f, "+"),
BinOp::Sub => write!(f, "-"),
BinOp::Mul => write!(f, "*"),
BinOp::Div => write!(f, "/"),
BinOp::FloorDiv => write!(f, "//"),
BinOp::Mod => write!(f, "%"),
BinOp::Eq => write!(f, "=="),
BinOp::NotEq => write!(f, "!="),
BinOp::Lt => write!(f, "<"),
BinOp::LtEq => write!(f, "<="),
BinOp::Gt => write!(f, ">"),
BinOp::GtEq => write!(f, ">="),
BinOp::And => write!(f, "and"),
BinOp::Or => write!(f, "or"),
BinOp::Pow => write!(f, "**"),
BinOp::PipeForward => write!(f, "|>"),
BinOp::Concat => write!(f, "++"),
BinOp::In => write!(f, "in"),
BinOp::BitAnd => write!(f, "&"),
BinOp::BitOr => write!(f, "|"),
BinOp::BitXor => write!(f, "^"),
BinOp::Shl => write!(f, "<<"),
BinOp::Shr => write!(f, ">>"),
}
}
}
use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum UnaryOp {
Neg,
Not,
BitNot,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UseToolDecl {
pub tool_path: String,
pub alias: String,
pub mcp_url: Option<String>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GrantDecl {
pub tool_alias: String,
pub constraints: Vec<GrantConstraint>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GrantConstraint {
pub key: String,
pub value: Expr,
pub span: Span,
}