#![allow(unused_assignments)]
use enum_as_inner::EnumAsInner;
use crate::Span;
use crate::pr::{BinOp, Literal, Ty, UnOp};
use super::{Path, TyParam};
#[derive(Debug, Clone, PartialEq)]
pub struct Expr {
pub kind: ExprKind,
pub span: Option<Span>,
pub ty: Option<Box<Ty>>,
pub ty_args: Vec<Ty>,
pub scope_id: Option<usize>,
pub target: Option<Ref>,
}
impl Expr {
pub fn new<K: Into<ExprKind>>(kind: K) -> Self {
Expr {
kind: kind.into(),
span: None,
ty: None,
ty_args: Vec::new(),
target: None,
scope_id: None,
}
}
pub fn new_with_span<K: Into<ExprKind>>(kind: K, span: Span) -> Expr {
Expr {
kind: kind.into(),
span: Some(span),
ty: None,
ty_args: Vec::new(),
target: None,
scope_id: None,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Ref {
Global(Path),
Local {
scope: usize,
offset: usize,
},
}
#[derive(Debug, EnumAsInner, PartialEq, Clone, strum::AsRefStr)]
pub enum ExprKind {
Ident(Path),
Lookup {
base: Box<Expr>,
lookup: Lookup,
},
Literal(Literal),
Nested(Box<Expr>),
TypeAnnotation(TypeAnnotation),
Tuple(Vec<TupleField>),
Array(Vec<Expr>),
Variant(Variant),
Range(Range),
Binary(BinaryExpr),
Unary(UnaryExpr),
Call(Call),
Func(Box<Func>),
FuncShort(Box<FuncShort>),
FString(Vec<InterpolateItem>),
Match(Match),
If(If),
VarBinding(VarBinding),
}
#[derive(Debug, EnumAsInner, PartialEq, Clone)]
pub enum Lookup {
Name(String),
Position(i64),
}
#[derive(Debug, PartialEq, Clone)]
pub struct BinaryExpr {
pub left: Box<Expr>,
pub op: BinOp,
pub right: Box<Expr>,
}
#[derive(Debug, PartialEq, Clone)]
pub struct UnaryExpr {
pub op: UnOp,
pub expr: Box<Expr>,
}
#[derive(Debug, PartialEq, Clone)]
pub struct Call {
pub subject: Box<Expr>,
pub args: Vec<CallArg>,
}
#[derive(Debug, PartialEq, Clone)]
pub struct CallArg {
pub label: Option<String>,
pub expr: Expr,
pub span: Option<Span>,
}
impl CallArg {
pub fn simple(expr: Expr) -> Self {
CallArg {
label: None,
span: expr.span,
expr,
}
}
}
#[derive(Debug, PartialEq, Clone)]
pub struct Func {
pub params: Vec<FuncParam>,
pub return_ty: Option<Ty>,
pub body: Box<Expr>,
pub ty_params: Vec<TyParam>,
}
#[derive(Debug, PartialEq, Clone)]
pub struct FuncShort {
pub param: FuncParam,
pub body: Box<Expr>,
}
#[derive(Debug, PartialEq, Clone)]
pub struct FuncParam {
pub constant: bool,
pub label: Option<String>,
pub name: String,
pub ty: Option<Ty>,
pub span: Span,
}
#[derive(Debug, PartialEq, Clone)]
pub struct Pipeline {
pub exprs: Vec<Expr>,
}
#[derive(Debug, PartialEq, Clone)]
pub struct TypeAnnotation {
pub expr: Box<Expr>,
pub ty: Box<Ty>,
}
#[derive(Debug, PartialEq, Clone)]
pub struct TupleField {
pub name: Option<String>,
pub unpack: bool,
pub expr: Expr,
}
#[derive(Debug, PartialEq, Clone)]
pub struct Variant {
pub name: String,
pub inner: Option<Box<Expr>>,
}
#[derive(Debug, Clone, Default, PartialEq)]
pub struct Range {
pub start: Option<Box<Expr>>,
pub end: Option<Box<Expr>>,
}
impl Range {
pub const fn unbounded() -> Self {
Range {
start: None,
end: None,
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum InterpolateItem {
String(String),
Expr {
expr: Box<Expr>,
format: Option<String>,
},
}
#[derive(Debug, Clone, PartialEq)]
pub struct Match {
pub subject: Box<Expr>,
pub branches: Vec<MatchBranch>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct MatchBranch {
pub scope_id: Option<usize>,
pub pattern: Pattern,
pub value: Box<Expr>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Pattern {
pub kind: PatternKind,
pub span: Span,
pub variant_tag: Option<usize>,
}
#[derive(Debug, Clone, PartialEq, strum::AsRefStr)]
pub enum PatternKind {
Enum(String, Option<Box<Pattern>>),
Literal(Literal),
AnyOf(Vec<Pattern>),
Bind(String),
}
impl Pattern {
pub fn new_with_span(kind: PatternKind, span: Span) -> Self {
Self {
kind,
span,
variant_tag: None,
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct If {
pub condition: Box<Expr>,
pub then: Box<Expr>,
pub els: Box<Expr>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct VarBinding {
pub name: String,
pub name_span: Span,
pub bound: Box<Expr>,
pub main: Box<Expr>,
}
impl From<Literal> for ExprKind {
fn from(value: Literal) -> Self {
ExprKind::Literal(value)
}
}
impl From<Func> for ExprKind {
fn from(value: Func) -> Self {
ExprKind::Func(Box::new(value))
}
}
impl From<Path> for ExprKind {
fn from(value: Path) -> Self {
ExprKind::Ident(value)
}
}
impl From<Range> for ExprKind {
fn from(value: Range) -> Self {
ExprKind::Range(value)
}
}
impl From<Call> for ExprKind {
fn from(value: Call) -> Self {
ExprKind::Call(value)
}
}
impl From<Variant> for ExprKind {
fn from(value: Variant) -> Self {
ExprKind::Variant(value)
}
}
impl From<TypeAnnotation> for ExprKind {
fn from(value: TypeAnnotation) -> Self {
ExprKind::TypeAnnotation(value)
}
}