use std::{collections::HashSet, sync::Arc}; use uplc::builtins::DefaultFunction; use crate::{ ast::{BinOp, UnOp}, tipo::{Type, ValueConstructor}, }; #[derive(Debug, Clone)] pub enum Air { Int { scope: Vec, value: String, }, String { scope: Vec, value: String, }, ByteArray { scope: Vec, bytes: Vec, }, Bool { scope: Vec, value: bool, }, Var { scope: Vec, constructor: ValueConstructor, name: String, variant_name: String, }, Fn { scope: Vec, params: Vec, }, List { scope: Vec, count: usize, tipo: Arc, tail: bool, }, ListAccessor { scope: Vec, tipo: Arc, names: Vec, tail: bool, }, ListExpose { scope: Vec, tipo: Arc, tail_head_names: Vec<(String, String)>, tail: Option<(String, String)>, }, Call { scope: Vec, count: usize, }, Builtin { scope: Vec, func: DefaultFunction, tipo: Arc, }, BinOp { scope: Vec, name: BinOp, count: usize, tipo: Arc, }, Assignment { scope: Vec, name: String, }, Assert { scope: Vec, constr_index: usize, }, DefineFunc { scope: Vec, func_name: String, module_name: String, params: Vec, recursive: bool, variant_name: String, }, Lam { scope: Vec, name: String, }, When { scope: Vec, tipo: Arc, subject_name: String, }, Clause { scope: Vec, tipo: Arc, subject_name: String, complex_clause: bool, }, ListClause { scope: Vec, tipo: Arc, tail_name: String, next_tail_name: Option, complex_clause: bool, }, TupleClause { scope: Vec, tipo: Arc, indices: HashSet<(usize, String)>, predefined_indices: HashSet<(usize, String)>, subject_name: String, count: usize, complex_clause: bool, }, ClauseGuard { scope: Vec, subject_name: String, tipo: Arc, }, ListClauseGuard { scope: Vec, tipo: Arc, tail_name: String, next_tail_name: Option, inverse: bool, }, Discard { scope: Vec, }, Finally { scope: Vec, }, If { scope: Vec, }, Record { scope: Vec, constr_index: usize, tipo: Arc, count: usize, }, RecordAccess { scope: Vec, record_index: u64, tipo: Arc, }, FieldsExpose { scope: Vec, count: usize, indices: Vec<(usize, String, Arc)>, }, Tuple { scope: Vec, tipo: Arc, count: usize, }, TupleIndex { scope: Vec, tipo: Arc, tuple_index: usize, }, Todo { scope: Vec, label: Option, tipo: Arc, }, ErrorTerm { scope: Vec, tipo: Arc, label: Option, }, Trace { scope: Vec, text: Option, tipo: Arc, }, RecordUpdate { scope: Vec, highest_index: usize, indices: Vec<(usize, Arc)>, }, UnOp { scope: Vec, op: UnOp, }, TupleAccessor { scope: Vec, names: Vec, tipo: Arc, }, } impl Air { pub fn scope(&self) -> Vec { match self { Air::Int { scope, .. } | Air::String { scope, .. } | Air::ByteArray { scope, .. } | Air::Bool { scope, .. } | Air::Var { scope, .. } | Air::List { scope, .. } | Air::ListAccessor { scope, .. } | Air::ListExpose { scope, .. } | Air::Fn { scope, .. } | Air::Call { scope, .. } | Air::Builtin { scope, .. } | Air::BinOp { scope, .. } | Air::Assignment { scope, .. } | Air::Assert { scope, .. } | Air::DefineFunc { scope, .. } | Air::Lam { scope, .. } | Air::When { scope, .. } | Air::Clause { scope, .. } | Air::ListClause { scope, .. } | Air::ClauseGuard { scope, .. } | Air::ListClauseGuard { scope, .. } | Air::Discard { scope } | Air::Finally { scope } | Air::If { scope, .. } | Air::Record { scope, .. } | Air::RecordAccess { scope, .. } | Air::FieldsExpose { scope, .. } | Air::Tuple { scope, .. } | Air::Todo { scope, .. } | Air::ErrorTerm { scope, .. } | Air::RecordUpdate { scope, .. } | Air::UnOp { scope, .. } | Air::Trace { scope, .. } | Air::TupleAccessor { scope, .. } | Air::TupleIndex { scope, .. } | Air::TupleClause { scope, .. } => scope.to_vec(), } } pub fn tipo(&self) -> Option> { match self { Air::List { tipo, .. } | Air::ListAccessor { tipo, .. } | Air::ListExpose { tipo, .. } | Air::Builtin { tipo, .. } | Air::BinOp { tipo, .. } | Air::When { tipo, .. } | Air::Clause { tipo, .. } | Air::ListClause { tipo, .. } | Air::TupleClause { tipo, .. } | Air::ClauseGuard { tipo, .. } | Air::ListClauseGuard { tipo, .. } | Air::Record { tipo, .. } | Air::RecordAccess { tipo, .. } | Air::Tuple { tipo, .. } | Air::TupleIndex { tipo, .. } | Air::Todo { tipo, .. } | Air::ErrorTerm { tipo, .. } | Air::Trace { tipo, .. } | Air::TupleAccessor { tipo, .. } | Air::Var { constructor: ValueConstructor { tipo, .. }, .. } => Some(tipo.clone()), _ => None, } } }