use tl_errors::Span;
#[derive(Debug, Clone)]
pub struct Program {
pub statements: Vec<Stmt>,
pub module_doc: Option<String>,
}
#[derive(Debug, Clone)]
pub struct Stmt {
pub kind: StmtKind,
pub span: Span,
pub doc_comment: Option<String>,
}
#[derive(Debug, Clone)]
pub enum UseItem {
Single(Vec<String>),
Group(Vec<String>, Vec<String>),
Wildcard(Vec<String>),
Aliased(Vec<String>, String),
}
#[derive(Debug, Clone)]
pub struct TraitBound {
pub type_param: String,
pub traits: Vec<String>,
}
#[derive(Debug, Clone)]
pub struct TraitMethod {
pub name: String,
pub params: Vec<Param>,
pub return_type: Option<TypeExpr>,
}
#[derive(Debug, Clone)]
pub enum StmtKind {
Let {
name: String,
mutable: bool,
type_ann: Option<TypeExpr>,
value: Expr,
is_public: bool,
},
FnDecl {
name: String,
type_params: Vec<String>,
params: Vec<Param>,
return_type: Option<TypeExpr>,
bounds: Vec<TraitBound>,
body: Vec<Stmt>,
is_generator: bool,
is_public: bool,
is_async: bool,
},
Expr(Expr),
Return(Option<Expr>),
If {
condition: Expr,
then_body: Vec<Stmt>,
else_ifs: Vec<(Expr, Vec<Stmt>)>,
else_body: Option<Vec<Stmt>>,
},
While { condition: Expr, body: Vec<Stmt> },
For {
name: String,
iter: Expr,
body: Vec<Stmt>,
},
ParallelFor {
name: String,
iter: Expr,
body: Vec<Stmt>,
},
Schema {
name: String,
fields: Vec<SchemaField>,
is_public: bool,
version: Option<i64>,
parent_version: Option<i64>,
},
Migrate {
schema_name: String,
from_version: i64,
to_version: i64,
operations: Vec<MigrateOp>,
},
Train {
name: String,
algorithm: String,
config: Vec<(String, Expr)>,
},
Pipeline {
name: String,
extract: Vec<Stmt>,
transform: Vec<Stmt>,
load: Vec<Stmt>,
schedule: Option<String>,
timeout: Option<String>,
retries: Option<i64>,
on_failure: Option<Vec<Stmt>>,
on_success: Option<Vec<Stmt>>,
},
StreamDecl {
name: String,
source: Expr,
transform: Vec<Stmt>,
sink: Option<Expr>,
window: Option<WindowSpec>,
watermark: Option<String>,
},
SourceDecl {
name: String,
connector_type: String,
config: Vec<(String, Expr)>,
},
SinkDecl {
name: String,
connector_type: String,
config: Vec<(String, Expr)>,
},
StructDecl {
name: String,
type_params: Vec<String>,
fields: Vec<SchemaField>,
is_public: bool,
},
EnumDecl {
name: String,
type_params: Vec<String>,
variants: Vec<EnumVariant>,
is_public: bool,
},
ImplBlock {
type_name: String,
type_params: Vec<String>,
methods: Vec<Stmt>,
},
TryCatch {
try_body: Vec<Stmt>,
catch_var: String,
catch_body: Vec<Stmt>,
finally_body: Option<Vec<Stmt>>,
},
Throw(Expr),
Import { path: String, alias: Option<String> },
Test { name: String, body: Vec<Stmt> },
Use { item: UseItem, is_public: bool },
ModDecl { name: String, is_public: bool },
TraitDef {
name: String,
type_params: Vec<String>,
methods: Vec<TraitMethod>,
is_public: bool,
},
TraitImpl {
trait_name: String,
type_name: String,
type_params: Vec<String>,
methods: Vec<Stmt>,
},
LetDestructure {
pattern: Pattern,
mutable: bool,
value: Expr,
is_public: bool,
},
TypeAlias {
name: String,
type_params: Vec<String>,
value: TypeExpr,
is_public: bool,
},
Agent {
name: String,
model: String,
system_prompt: Option<String>,
tools: Vec<(String, Expr)>,
max_turns: Option<i64>,
temperature: Option<f64>,
max_tokens: Option<i64>,
base_url: Option<String>,
api_key: Option<String>,
output_format: Option<String>,
on_tool_call: Option<Vec<Stmt>>,
on_complete: Option<Vec<Stmt>>,
mcp_servers: Vec<Expr>,
},
Break,
Continue,
}
#[derive(Debug, Clone)]
pub struct EnumVariant {
pub name: String,
pub fields: Vec<TypeExpr>,
}
#[derive(Debug, Clone)]
pub enum WindowSpec {
Tumbling(String),
Sliding(String, String),
Session(String),
}
#[derive(Debug, Clone)]
pub enum Pattern {
Wildcard,
Literal(Expr),
Binding(String),
Enum {
type_name: String,
variant: String,
args: Vec<Pattern>,
},
Struct {
name: Option<String>,
fields: Vec<StructPatternField>,
},
List {
elements: Vec<Pattern>,
rest: Option<String>,
},
Or(Vec<Pattern>),
}
#[derive(Debug, Clone)]
pub struct StructPatternField {
pub name: String,
pub pattern: Option<Pattern>,
}
#[derive(Debug, Clone)]
pub struct MatchArm {
pub pattern: Pattern,
pub guard: Option<Expr>,
pub body: Expr,
}
#[derive(Debug, Clone)]
pub enum MigrateOp {
AddColumn {
name: String,
type_ann: TypeExpr,
default: Option<Expr>,
},
DropColumn { name: String },
RenameColumn { from: String, to: String },
AlterType { column: String, new_type: TypeExpr },
AddConstraint { column: String, constraint: String },
DropConstraint { column: String, constraint: String },
}
#[derive(Debug, Clone)]
pub enum ClosureBody {
Expr(Box<Expr>),
Block {
stmts: Vec<Stmt>,
expr: Option<Box<Expr>>,
},
}
#[derive(Debug, Clone)]
pub enum Expr {
Int(i64),
Float(f64),
String(String),
Bool(bool),
None,
Decimal(String),
Ident(String),
BinOp {
left: Box<Expr>,
op: BinOp,
right: Box<Expr>,
},
UnaryOp {
op: UnaryOp,
expr: Box<Expr>,
},
Call {
function: Box<Expr>,
args: Vec<Expr>,
},
NamedArg {
name: String,
value: Box<Expr>,
},
Pipe {
left: Box<Expr>,
right: Box<Expr>,
},
Member {
object: Box<Expr>,
field: String,
},
Index {
object: Box<Expr>,
index: Box<Expr>,
},
List(Vec<Expr>),
Map(Vec<(Expr, Expr)>),
Block {
stmts: Vec<Stmt>,
expr: Option<Box<Expr>>,
},
Case {
arms: Vec<MatchArm>,
},
Match {
subject: Box<Expr>,
arms: Vec<MatchArm>,
},
Closure {
params: Vec<Param>,
return_type: Option<TypeExpr>,
body: ClosureBody,
},
Range {
start: Box<Expr>,
end: Box<Expr>,
},
NullCoalesce {
expr: Box<Expr>,
default: Box<Expr>,
},
Assign {
target: Box<Expr>,
value: Box<Expr>,
},
StructInit {
name: String,
fields: Vec<(String, Expr)>,
},
EnumVariant {
enum_name: String,
variant: String,
args: Vec<Expr>,
},
Await(Box<Expr>),
Yield(Option<Box<Expr>>),
Try(Box<Expr>),
}
#[derive(Debug, Clone, PartialEq)]
pub enum BinOp {
Add,
Sub,
Mul,
Div,
Mod,
Pow,
Eq,
Neq,
Lt,
Gt,
Lte,
Gte,
And,
Or,
}
impl std::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::Mod => write!(f, "%"),
BinOp::Pow => write!(f, "**"),
BinOp::Eq => write!(f, "=="),
BinOp::Neq => write!(f, "!="),
BinOp::Lt => write!(f, "<"),
BinOp::Gt => write!(f, ">"),
BinOp::Lte => write!(f, "<="),
BinOp::Gte => write!(f, ">="),
BinOp::And => write!(f, "and"),
BinOp::Or => write!(f, "or"),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum UnaryOp {
Neg,
Not,
Ref,
}
#[derive(Debug, Clone)]
pub struct Param {
pub name: String,
pub type_ann: Option<TypeExpr>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Annotation {
Sensitive,
Redact,
Pii,
Custom(String),
}
#[derive(Debug, Clone)]
pub struct SchemaField {
pub name: String,
pub type_ann: TypeExpr,
pub doc_comment: Option<String>,
pub default_value: Option<Expr>,
pub annotations: Vec<Annotation>,
}
#[derive(Debug, Clone)]
pub enum TypeExpr {
Named(String),
Generic { name: String, args: Vec<TypeExpr> },
Optional(Box<TypeExpr>),
Function {
params: Vec<TypeExpr>,
return_type: Box<TypeExpr>,
},
}