use crate::diagnostic::Span;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Module {
pub name: String,
pub items: Vec<Item>,
}
impl Module {
pub fn new(name: impl Into<String>, items: Vec<Item>) -> Self {
Self {
name: name.into(),
items,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Item {
Type(TypeDecl),
Const(Const),
Function(Function),
Validator(Validator),
Test(Test),
}
impl Item {
pub fn name(&self) -> &str {
match self {
Item::Type(type_decl) => &type_decl.name,
Item::Const(constant) => &constant.name,
Item::Function(function) => &function.name,
Item::Validator(validator) => &validator.name,
Item::Test(test) => &test.name,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TypeDecl {
pub name: String,
pub variants: Vec<Variant>,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Variant {
pub name: String,
pub fields: Vec<VariantField>,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct VariantField {
pub name: Option<String>,
pub ty: TypeRef,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Const {
pub name: String,
pub ty: TypeRef,
pub value: Expr,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Function {
pub name: String,
pub params: Vec<Param>,
pub return_type: TypeRef,
pub body: Block,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Validator {
pub name: String,
pub params: Vec<Param>,
pub body: Block,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Test {
pub name: String,
pub should_fail: bool,
pub body: Block,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Param {
pub name: String,
pub ty: TypeRef,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TypeRef {
pub name: String,
pub args: Vec<TypeRef>,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Block {
pub statements: Vec<Statement>,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Statement {
Let {
name: String,
ty: Option<TypeRef>,
value: Expr,
span: Span,
},
Require {
condition: Expr,
span: Span,
},
Trace {
message: Expr,
span: Span,
},
Return {
value: Expr,
span: Span,
},
Expr {
value: Expr,
trailing_semicolon: bool,
span: Span,
},
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Expr {
pub kind: ExprKind,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ExprKind {
Bool(bool),
Int(i64),
String(String),
ByteArray(String),
Unit,
List(Vec<Expr>),
Fail,
Variable(String),
Unary {
op: UnaryOp,
expr: Box<Expr>,
},
Binary {
left: Box<Expr>,
op: BinaryOp,
right: Box<Expr>,
},
Call {
callee: String,
args: Vec<Expr>,
},
If {
condition: Box<Expr>,
then_branch: Block,
else_branch: Block,
},
Match {
subject: Box<Expr>,
arms: Vec<MatchArm>,
},
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MatchArm {
pub pattern: Pattern,
pub body: Block,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Pattern {
Wildcard {
span: Span,
},
Variable {
name: String,
span: Span,
},
Constructor {
name: String,
bindings: Vec<PatternBinding>,
span: Span,
},
Bool {
value: bool,
span: Span,
},
Int {
value: i64,
span: Span,
},
ByteArray {
hex: String,
span: Span,
},
String {
value: String,
span: Span,
},
Unit {
span: Span,
},
}
impl Pattern {
pub fn span(&self) -> Span {
match self {
Pattern::Wildcard { span }
| Pattern::Variable { span, .. }
| Pattern::Constructor { span, .. }
| Pattern::Bool { span, .. }
| Pattern::Int { span, .. }
| Pattern::ByteArray { span, .. }
| Pattern::String { span, .. }
| Pattern::Unit { span } => *span,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PatternBinding {
pub name: Option<String>,
pub span: Span,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum UnaryOp {
Not,
Negate,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BinaryOp {
Or,
And,
Equal,
NotEqual,
Less,
LessEqual,
Greater,
GreaterEqual,
Add,
Subtract,
Multiply,
Divide,
Remainder,
}