out with the old code and in with the air tree
This commit is contained in:
parent
02ce3761ae
commit
55dd1a1a56
File diff suppressed because it is too large
Load Diff
|
@ -7,55 +7,42 @@ use crate::{
|
||||||
tipo::{Type, ValueConstructor},
|
tipo::{Type, ValueConstructor},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::scope::Scope;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum Air {
|
pub enum Air {
|
||||||
// Primitives
|
// Primitives
|
||||||
Int {
|
Int {
|
||||||
scope: Scope,
|
|
||||||
value: String,
|
value: String,
|
||||||
},
|
},
|
||||||
String {
|
String {
|
||||||
scope: Scope,
|
|
||||||
value: String,
|
value: String,
|
||||||
},
|
},
|
||||||
ByteArray {
|
ByteArray {
|
||||||
scope: Scope,
|
|
||||||
bytes: Vec<u8>,
|
bytes: Vec<u8>,
|
||||||
},
|
},
|
||||||
Bool {
|
Bool {
|
||||||
scope: Scope,
|
|
||||||
value: bool,
|
value: bool,
|
||||||
},
|
},
|
||||||
List {
|
List {
|
||||||
scope: Scope,
|
|
||||||
count: usize,
|
count: usize,
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
tail: bool,
|
tail: bool,
|
||||||
},
|
},
|
||||||
Tuple {
|
Tuple {
|
||||||
scope: Scope,
|
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
count: usize,
|
count: usize,
|
||||||
},
|
},
|
||||||
Void {
|
Void,
|
||||||
scope: Scope,
|
|
||||||
},
|
|
||||||
Var {
|
Var {
|
||||||
scope: Scope,
|
|
||||||
constructor: ValueConstructor,
|
constructor: ValueConstructor,
|
||||||
name: String,
|
name: String,
|
||||||
variant_name: String,
|
variant_name: String,
|
||||||
},
|
},
|
||||||
// Functions
|
// Functions
|
||||||
Call {
|
Call {
|
||||||
scope: Scope,
|
|
||||||
count: usize,
|
count: usize,
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
},
|
},
|
||||||
DefineFunc {
|
DefineFunc {
|
||||||
scope: Scope,
|
|
||||||
func_name: String,
|
func_name: String,
|
||||||
module_name: String,
|
module_name: String,
|
||||||
params: Vec<String>,
|
params: Vec<String>,
|
||||||
|
@ -63,71 +50,58 @@ pub enum Air {
|
||||||
variant_name: String,
|
variant_name: String,
|
||||||
},
|
},
|
||||||
Fn {
|
Fn {
|
||||||
scope: Scope,
|
|
||||||
params: Vec<String>,
|
params: Vec<String>,
|
||||||
},
|
},
|
||||||
Builtin {
|
Builtin {
|
||||||
scope: Scope,
|
|
||||||
count: usize,
|
count: usize,
|
||||||
func: DefaultFunction,
|
func: DefaultFunction,
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
},
|
},
|
||||||
// Operators
|
// Operators
|
||||||
BinOp {
|
BinOp {
|
||||||
scope: Scope,
|
|
||||||
name: BinOp,
|
name: BinOp,
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
|
argument_tipo: Arc<Type>,
|
||||||
},
|
},
|
||||||
UnOp {
|
UnOp {
|
||||||
scope: Scope,
|
|
||||||
op: UnOp,
|
op: UnOp,
|
||||||
},
|
},
|
||||||
// Assignment
|
// Assignment
|
||||||
Let {
|
Let {
|
||||||
scope: Scope,
|
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
UnWrapData {
|
UnWrapData {
|
||||||
scope: Scope,
|
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
},
|
},
|
||||||
WrapData {
|
WrapData {
|
||||||
scope: Scope,
|
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
},
|
},
|
||||||
AssertConstr {
|
AssertConstr {
|
||||||
scope: Scope,
|
|
||||||
constr_index: usize,
|
constr_index: usize,
|
||||||
},
|
},
|
||||||
AssertBool {
|
AssertBool {
|
||||||
scope: Scope,
|
|
||||||
is_true: bool,
|
is_true: bool,
|
||||||
},
|
},
|
||||||
// When
|
// When
|
||||||
When {
|
When {
|
||||||
scope: Scope,
|
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
subject_name: String,
|
subject_name: String,
|
||||||
|
subject_tipo: Arc<Type>,
|
||||||
},
|
},
|
||||||
Clause {
|
Clause {
|
||||||
scope: Scope,
|
subject_tipo: Arc<Type>,
|
||||||
tipo: Arc<Type>,
|
|
||||||
subject_name: String,
|
subject_name: String,
|
||||||
complex_clause: bool,
|
complex_clause: bool,
|
||||||
},
|
},
|
||||||
ListClause {
|
ListClause {
|
||||||
scope: Scope,
|
subject_tipo: Arc<Type>,
|
||||||
tipo: Arc<Type>,
|
|
||||||
tail_name: String,
|
tail_name: String,
|
||||||
next_tail_name: Option<String>,
|
next_tail_name: Option<String>,
|
||||||
complex_clause: bool,
|
complex_clause: bool,
|
||||||
},
|
},
|
||||||
WrapClause {
|
WrapClause,
|
||||||
scope: Scope,
|
|
||||||
},
|
|
||||||
TupleClause {
|
TupleClause {
|
||||||
scope: Scope,
|
subject_tipo: Arc<Type>,
|
||||||
tipo: Arc<Type>,
|
|
||||||
indices: IndexSet<(usize, String)>,
|
indices: IndexSet<(usize, String)>,
|
||||||
predefined_indices: IndexSet<(usize, String)>,
|
predefined_indices: IndexSet<(usize, String)>,
|
||||||
subject_name: String,
|
subject_name: String,
|
||||||
|
@ -135,296 +109,76 @@ pub enum Air {
|
||||||
complex_clause: bool,
|
complex_clause: bool,
|
||||||
},
|
},
|
||||||
ClauseGuard {
|
ClauseGuard {
|
||||||
scope: Scope,
|
|
||||||
subject_name: String,
|
subject_name: String,
|
||||||
tipo: Arc<Type>,
|
subject_tipo: Arc<Type>,
|
||||||
},
|
},
|
||||||
ListClauseGuard {
|
ListClauseGuard {
|
||||||
scope: Scope,
|
subject_tipo: Arc<Type>,
|
||||||
tipo: Arc<Type>,
|
|
||||||
tail_name: String,
|
tail_name: String,
|
||||||
next_tail_name: Option<String>,
|
next_tail_name: Option<String>,
|
||||||
inverse: bool,
|
inverse: bool,
|
||||||
},
|
},
|
||||||
Finally {
|
TupleGuard {
|
||||||
scope: Scope,
|
subject_tipo: Arc<Type>,
|
||||||
|
indices: IndexSet<(usize, String)>,
|
||||||
|
subject_name: String,
|
||||||
|
type_count: usize,
|
||||||
},
|
},
|
||||||
|
Finally,
|
||||||
// If
|
// If
|
||||||
If {
|
If {
|
||||||
scope: Scope,
|
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
},
|
},
|
||||||
// Record Creation
|
// Record Creation
|
||||||
Record {
|
Constr {
|
||||||
scope: Scope,
|
|
||||||
tag: usize,
|
tag: usize,
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
count: usize,
|
count: usize,
|
||||||
},
|
},
|
||||||
RecordUpdate {
|
RecordUpdate {
|
||||||
scope: Scope,
|
|
||||||
highest_index: usize,
|
highest_index: usize,
|
||||||
indices: Vec<(usize, Arc<Type>)>,
|
indices: Vec<(usize, Arc<Type>)>,
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
},
|
},
|
||||||
// Field Access
|
// Field Access
|
||||||
RecordAccess {
|
RecordAccess {
|
||||||
scope: Scope,
|
|
||||||
record_index: u64,
|
record_index: u64,
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
},
|
},
|
||||||
FieldsExpose {
|
FieldsExpose {
|
||||||
scope: Scope,
|
|
||||||
indices: Vec<(usize, String, Arc<Type>)>,
|
indices: Vec<(usize, String, Arc<Type>)>,
|
||||||
check_last_item: bool,
|
check_last_item: bool,
|
||||||
},
|
},
|
||||||
// ListAccess
|
// ListAccess
|
||||||
ListAccessor {
|
ListAccessor {
|
||||||
scope: Scope,
|
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
names: Vec<String>,
|
names: Vec<String>,
|
||||||
tail: bool,
|
tail: bool,
|
||||||
check_last_item: bool,
|
check_last_item: bool,
|
||||||
},
|
},
|
||||||
ListExpose {
|
ListExpose {
|
||||||
scope: Scope,
|
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
tail_head_names: Vec<(String, String)>,
|
tail_head_names: Vec<(String, String)>,
|
||||||
tail: Option<(String, String)>,
|
tail: Option<(String, String)>,
|
||||||
},
|
},
|
||||||
// Tuple Access
|
// Tuple Access
|
||||||
TupleAccessor {
|
TupleAccessor {
|
||||||
scope: Scope,
|
|
||||||
names: Vec<String>,
|
names: Vec<String>,
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
check_last_item: bool,
|
check_last_item: bool,
|
||||||
},
|
},
|
||||||
TupleIndex {
|
TupleIndex {
|
||||||
scope: Scope,
|
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
tuple_index: usize,
|
tuple_index: usize,
|
||||||
},
|
},
|
||||||
// Misc.
|
// Misc.
|
||||||
ErrorTerm {
|
ErrorTerm {
|
||||||
scope: Scope,
|
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
},
|
},
|
||||||
Trace {
|
Trace {
|
||||||
scope: Scope,
|
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
},
|
},
|
||||||
NoOp {
|
NoOp,
|
||||||
scope: Scope,
|
FieldsEmpty,
|
||||||
},
|
ListEmpty,
|
||||||
FieldsEmpty {
|
|
||||||
scope: Scope,
|
|
||||||
},
|
|
||||||
ListEmpty {
|
|
||||||
scope: Scope,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Air {
|
|
||||||
pub fn scope(&self) -> Scope {
|
|
||||||
match self {
|
|
||||||
Air::Int { scope, .. }
|
|
||||||
| Air::String { scope, .. }
|
|
||||||
| Air::ByteArray { scope, .. }
|
|
||||||
| Air::Bool { scope, .. }
|
|
||||||
| Air::List { scope, .. }
|
|
||||||
| Air::Tuple { scope, .. }
|
|
||||||
| Air::Void { scope }
|
|
||||||
| Air::Var { scope, .. }
|
|
||||||
| Air::Call { scope, .. }
|
|
||||||
| Air::DefineFunc { scope, .. }
|
|
||||||
| Air::Fn { scope, .. }
|
|
||||||
| Air::Builtin { scope, .. }
|
|
||||||
| Air::BinOp { scope, .. }
|
|
||||||
| Air::UnOp { scope, .. }
|
|
||||||
| Air::Let { scope, .. }
|
|
||||||
| Air::UnWrapData { scope, .. }
|
|
||||||
| Air::WrapData { scope, .. }
|
|
||||||
| Air::AssertConstr { scope, .. }
|
|
||||||
| Air::AssertBool { scope, .. }
|
|
||||||
| Air::When { scope, .. }
|
|
||||||
| Air::Clause { scope, .. }
|
|
||||||
| Air::ListClause { scope, .. }
|
|
||||||
| Air::WrapClause { scope }
|
|
||||||
| Air::TupleClause { scope, .. }
|
|
||||||
| Air::ClauseGuard { scope, .. }
|
|
||||||
| Air::ListClauseGuard { scope, .. }
|
|
||||||
| Air::Finally { scope }
|
|
||||||
| Air::If { scope, .. }
|
|
||||||
| Air::Record { scope, .. }
|
|
||||||
| Air::RecordUpdate { scope, .. }
|
|
||||||
| Air::RecordAccess { scope, .. }
|
|
||||||
| Air::FieldsExpose { scope, .. }
|
|
||||||
| Air::FieldsEmpty { scope }
|
|
||||||
| Air::ListEmpty { scope }
|
|
||||||
| Air::ListAccessor { scope, .. }
|
|
||||||
| Air::ListExpose { scope, .. }
|
|
||||||
| Air::TupleAccessor { scope, .. }
|
|
||||||
| Air::TupleIndex { scope, .. }
|
|
||||||
| Air::ErrorTerm { scope, .. }
|
|
||||||
| Air::Trace { scope, .. }
|
|
||||||
| Air::NoOp { scope, .. } => scope.clone(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn scope_mut(&mut self) -> &mut Scope {
|
|
||||||
match self {
|
|
||||||
Air::Int { scope, .. }
|
|
||||||
| Air::String { scope, .. }
|
|
||||||
| Air::ByteArray { scope, .. }
|
|
||||||
| Air::Bool { scope, .. }
|
|
||||||
| Air::List { scope, .. }
|
|
||||||
| Air::Tuple { scope, .. }
|
|
||||||
| Air::Void { scope }
|
|
||||||
| Air::Var { scope, .. }
|
|
||||||
| Air::Call { scope, .. }
|
|
||||||
| Air::DefineFunc { scope, .. }
|
|
||||||
| Air::Fn { scope, .. }
|
|
||||||
| Air::Builtin { scope, .. }
|
|
||||||
| Air::BinOp { scope, .. }
|
|
||||||
| Air::UnOp { scope, .. }
|
|
||||||
| Air::Let { scope, .. }
|
|
||||||
| Air::UnWrapData { scope, .. }
|
|
||||||
| Air::WrapData { scope, .. }
|
|
||||||
| Air::AssertConstr { scope, .. }
|
|
||||||
| Air::AssertBool { scope, .. }
|
|
||||||
| Air::When { scope, .. }
|
|
||||||
| Air::Clause { scope, .. }
|
|
||||||
| Air::ListClause { scope, .. }
|
|
||||||
| Air::WrapClause { scope }
|
|
||||||
| Air::TupleClause { scope, .. }
|
|
||||||
| Air::ClauseGuard { scope, .. }
|
|
||||||
| Air::ListClauseGuard { scope, .. }
|
|
||||||
| Air::Finally { scope }
|
|
||||||
| Air::If { scope, .. }
|
|
||||||
| Air::Record { scope, .. }
|
|
||||||
| Air::RecordUpdate { scope, .. }
|
|
||||||
| Air::RecordAccess { scope, .. }
|
|
||||||
| Air::FieldsExpose { scope, .. }
|
|
||||||
| Air::FieldsEmpty { scope }
|
|
||||||
| Air::ListEmpty { scope }
|
|
||||||
| Air::ListAccessor { scope, .. }
|
|
||||||
| Air::ListExpose { scope, .. }
|
|
||||||
| Air::TupleAccessor { scope, .. }
|
|
||||||
| Air::TupleIndex { scope, .. }
|
|
||||||
| Air::ErrorTerm { scope, .. }
|
|
||||||
| Air::Trace { scope, .. }
|
|
||||||
| Air::NoOp { scope, .. } => scope,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn tipo(&self) -> Option<Arc<Type>> {
|
|
||||||
match self {
|
|
||||||
Air::Int { .. } => Some(
|
|
||||||
Type::App {
|
|
||||||
public: true,
|
|
||||||
module: String::new(),
|
|
||||||
name: "Int".to_string(),
|
|
||||||
args: vec![],
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
),
|
|
||||||
Air::String { .. } => Some(
|
|
||||||
Type::App {
|
|
||||||
public: true,
|
|
||||||
module: String::new(),
|
|
||||||
name: "String".to_string(),
|
|
||||||
args: vec![],
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
),
|
|
||||||
Air::ByteArray { .. } => Some(
|
|
||||||
Type::App {
|
|
||||||
public: true,
|
|
||||||
module: String::new(),
|
|
||||||
name: "ByteArray".to_string(),
|
|
||||||
args: vec![],
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
),
|
|
||||||
Air::Bool { .. } => Some(
|
|
||||||
Type::App {
|
|
||||||
public: true,
|
|
||||||
module: String::new(),
|
|
||||||
name: "Bool".to_string(),
|
|
||||||
args: vec![],
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
),
|
|
||||||
Air::Void { .. } => Some(
|
|
||||||
Type::App {
|
|
||||||
public: true,
|
|
||||||
module: String::new(),
|
|
||||||
name: "Void".to_string(),
|
|
||||||
args: vec![],
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
),
|
|
||||||
Air::WrapData { .. } => Some(
|
|
||||||
Type::App {
|
|
||||||
public: true,
|
|
||||||
module: String::new(),
|
|
||||||
name: "Data".to_string(),
|
|
||||||
args: vec![],
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
),
|
|
||||||
Air::Var { constructor, .. } => Some(constructor.tipo.clone()),
|
|
||||||
Air::List { tipo, .. }
|
|
||||||
| Air::Tuple { tipo, .. }
|
|
||||||
| Air::Call { tipo, .. }
|
|
||||||
| Air::Builtin { tipo, .. }
|
|
||||||
| Air::BinOp { tipo, .. }
|
|
||||||
| Air::UnWrapData { tipo, .. }
|
|
||||||
| Air::When { tipo, .. }
|
|
||||||
| Air::Clause { tipo, .. }
|
|
||||||
| Air::ListClause { tipo, .. }
|
|
||||||
| Air::TupleClause { tipo, .. }
|
|
||||||
| Air::ClauseGuard { tipo, .. }
|
|
||||||
| Air::If { tipo, .. }
|
|
||||||
| Air::ListClauseGuard { tipo, .. }
|
|
||||||
| Air::Record { tipo, .. }
|
|
||||||
| Air::RecordUpdate { tipo, .. }
|
|
||||||
| Air::RecordAccess { tipo, .. }
|
|
||||||
| Air::ListAccessor { tipo, .. }
|
|
||||||
| Air::ListExpose { tipo, .. }
|
|
||||||
| Air::TupleAccessor { tipo, .. }
|
|
||||||
| Air::TupleIndex { tipo, .. }
|
|
||||||
| Air::ErrorTerm { tipo, .. }
|
|
||||||
| Air::Trace { tipo, .. } => Some(tipo.clone()),
|
|
||||||
Air::DefineFunc { .. }
|
|
||||||
| Air::Fn { .. }
|
|
||||||
| Air::Let { .. }
|
|
||||||
| Air::WrapClause { .. }
|
|
||||||
| Air::AssertConstr { .. }
|
|
||||||
| Air::AssertBool { .. }
|
|
||||||
| Air::Finally { .. }
|
|
||||||
| Air::FieldsExpose { .. }
|
|
||||||
| Air::FieldsEmpty { .. }
|
|
||||||
| Air::ListEmpty { .. }
|
|
||||||
| Air::NoOp { .. } => None,
|
|
||||||
Air::UnOp { op, .. } => match op {
|
|
||||||
UnOp::Not => Some(
|
|
||||||
Type::App {
|
|
||||||
public: true,
|
|
||||||
module: String::new(),
|
|
||||||
name: "Bool".to_string(),
|
|
||||||
args: vec![],
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
),
|
|
||||||
UnOp::Negate => Some(
|
|
||||||
Type::App {
|
|
||||||
public: true,
|
|
||||||
module: String::new(),
|
|
||||||
name: "Int".to_string(),
|
|
||||||
args: vec![],
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,184 +0,0 @@
|
||||||
use indexmap::IndexSet;
|
|
||||||
use std::sync::Arc;
|
|
||||||
use uplc::builtins::DefaultFunction;
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
ast::{BinOp, UnOp},
|
|
||||||
tipo::{Type, ValueConstructor},
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
|
||||||
pub enum Air {
|
|
||||||
// Primitives
|
|
||||||
Int {
|
|
||||||
value: String,
|
|
||||||
},
|
|
||||||
String {
|
|
||||||
value: String,
|
|
||||||
},
|
|
||||||
ByteArray {
|
|
||||||
bytes: Vec<u8>,
|
|
||||||
},
|
|
||||||
Bool {
|
|
||||||
value: bool,
|
|
||||||
},
|
|
||||||
List {
|
|
||||||
count: usize,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
tail: bool,
|
|
||||||
},
|
|
||||||
Tuple {
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
count: usize,
|
|
||||||
},
|
|
||||||
Void,
|
|
||||||
Var {
|
|
||||||
constructor: ValueConstructor,
|
|
||||||
name: String,
|
|
||||||
variant_name: String,
|
|
||||||
},
|
|
||||||
// Functions
|
|
||||||
Call {
|
|
||||||
count: usize,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
},
|
|
||||||
DefineFunc {
|
|
||||||
func_name: String,
|
|
||||||
module_name: String,
|
|
||||||
params: Vec<String>,
|
|
||||||
recursive: bool,
|
|
||||||
variant_name: String,
|
|
||||||
},
|
|
||||||
Fn {
|
|
||||||
params: Vec<String>,
|
|
||||||
},
|
|
||||||
Builtin {
|
|
||||||
count: usize,
|
|
||||||
func: DefaultFunction,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
},
|
|
||||||
// Operators
|
|
||||||
BinOp {
|
|
||||||
name: BinOp,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
argument_tipo: Arc<Type>,
|
|
||||||
},
|
|
||||||
UnOp {
|
|
||||||
op: UnOp,
|
|
||||||
},
|
|
||||||
// Assignment
|
|
||||||
Let {
|
|
||||||
name: String,
|
|
||||||
},
|
|
||||||
UnWrapData {
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
},
|
|
||||||
WrapData {
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
},
|
|
||||||
AssertConstr {
|
|
||||||
constr_index: usize,
|
|
||||||
},
|
|
||||||
AssertBool {
|
|
||||||
is_true: bool,
|
|
||||||
},
|
|
||||||
// When
|
|
||||||
When {
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
subject_name: String,
|
|
||||||
subject_tipo: Arc<Type>,
|
|
||||||
},
|
|
||||||
Clause {
|
|
||||||
subject_tipo: Arc<Type>,
|
|
||||||
subject_name: String,
|
|
||||||
complex_clause: bool,
|
|
||||||
},
|
|
||||||
ListClause {
|
|
||||||
subject_tipo: Arc<Type>,
|
|
||||||
tail_name: String,
|
|
||||||
next_tail_name: Option<String>,
|
|
||||||
complex_clause: bool,
|
|
||||||
},
|
|
||||||
WrapClause,
|
|
||||||
TupleClause {
|
|
||||||
subject_tipo: Arc<Type>,
|
|
||||||
indices: IndexSet<(usize, String)>,
|
|
||||||
predefined_indices: IndexSet<(usize, String)>,
|
|
||||||
subject_name: String,
|
|
||||||
count: usize,
|
|
||||||
complex_clause: bool,
|
|
||||||
},
|
|
||||||
ClauseGuard {
|
|
||||||
subject_name: String,
|
|
||||||
subject_tipo: Arc<Type>,
|
|
||||||
},
|
|
||||||
ListClauseGuard {
|
|
||||||
subject_tipo: Arc<Type>,
|
|
||||||
tail_name: String,
|
|
||||||
next_tail_name: Option<String>,
|
|
||||||
inverse: bool,
|
|
||||||
},
|
|
||||||
TupleGuard {
|
|
||||||
subject_tipo: Arc<Type>,
|
|
||||||
indices: IndexSet<(usize, String)>,
|
|
||||||
subject_name: String,
|
|
||||||
type_count: usize,
|
|
||||||
},
|
|
||||||
Finally,
|
|
||||||
// If
|
|
||||||
If {
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
},
|
|
||||||
// Record Creation
|
|
||||||
Constr {
|
|
||||||
tag: usize,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
count: usize,
|
|
||||||
},
|
|
||||||
RecordUpdate {
|
|
||||||
highest_index: usize,
|
|
||||||
indices: Vec<(usize, Arc<Type>)>,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
},
|
|
||||||
// Field Access
|
|
||||||
RecordAccess {
|
|
||||||
record_index: u64,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
},
|
|
||||||
FieldsExpose {
|
|
||||||
indices: Vec<(usize, String, Arc<Type>)>,
|
|
||||||
check_last_item: bool,
|
|
||||||
},
|
|
||||||
// ListAccess
|
|
||||||
ListAccessor {
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
names: Vec<String>,
|
|
||||||
tail: bool,
|
|
||||||
check_last_item: bool,
|
|
||||||
},
|
|
||||||
ListExpose {
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
tail_head_names: Vec<(String, String)>,
|
|
||||||
tail: Option<(String, String)>,
|
|
||||||
},
|
|
||||||
// Tuple Access
|
|
||||||
TupleAccessor {
|
|
||||||
names: Vec<String>,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
check_last_item: bool,
|
|
||||||
},
|
|
||||||
TupleIndex {
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
tuple_index: usize,
|
|
||||||
},
|
|
||||||
// Misc.
|
|
||||||
ErrorTerm {
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
},
|
|
||||||
Trace {
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
},
|
|
||||||
NoOp,
|
|
||||||
FieldsEmpty,
|
|
||||||
ListEmpty,
|
|
||||||
}
|
|
|
@ -1,366 +0,0 @@
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use indexmap::IndexMap;
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
ast::TypedDataType,
|
|
||||||
builtins::bool,
|
|
||||||
gen_uplc::builder::{lookup_data_type_by_tipo, DataTypeKey, FunctionAccessKey},
|
|
||||||
tipo::TypeVar,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
ast::{BinOp, ClauseGuard, Constant, UnOp},
|
|
||||||
tipo::Type,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::tree::{AirExpression, AirStatement, AirTree};
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub enum CodeGenFunction {
|
|
||||||
Function { body: AirTree, params: Vec<String> },
|
|
||||||
Link(String),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub enum UserFunction {
|
|
||||||
Function(AirTree, Vec<(FunctionAccessKey, String)>),
|
|
||||||
Link(String),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_generic_id_and_type(tipo: &Type, param: &Type) -> Vec<(u64, Arc<Type>)> {
|
|
||||||
let mut generics_ids = vec![];
|
|
||||||
|
|
||||||
if let Some(id) = tipo.get_generic() {
|
|
||||||
generics_ids.push((id, param.clone().into()));
|
|
||||||
return generics_ids;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (tipo, param_type) in tipo
|
|
||||||
.get_inner_types()
|
|
||||||
.iter()
|
|
||||||
.zip(param.get_inner_types().iter())
|
|
||||||
{
|
|
||||||
generics_ids.append(&mut get_generic_id_and_type(tipo, param_type));
|
|
||||||
}
|
|
||||||
generics_ids
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn convert_opaque_type(
|
|
||||||
t: &Arc<Type>,
|
|
||||||
data_types: &IndexMap<DataTypeKey, &TypedDataType>,
|
|
||||||
) -> Arc<Type> {
|
|
||||||
if check_replaceable_opaque_type(t, data_types) && matches!(t.as_ref(), Type::App { .. }) {
|
|
||||||
let data_type = lookup_data_type_by_tipo(data_types, t).unwrap();
|
|
||||||
let new_type_fields = data_type.typed_parameters;
|
|
||||||
|
|
||||||
let mono_types: IndexMap<u64, Arc<Type>>;
|
|
||||||
let mut mono_type_vec = vec![];
|
|
||||||
|
|
||||||
for (tipo, param) in new_type_fields.iter().zip(t.arg_types().unwrap()) {
|
|
||||||
mono_type_vec.append(&mut get_generic_id_and_type(tipo, ¶m));
|
|
||||||
}
|
|
||||||
mono_types = mono_type_vec.into_iter().collect();
|
|
||||||
|
|
||||||
let generic_type = &data_type.constructors[0].arguments[0].tipo;
|
|
||||||
|
|
||||||
let mono_type = find_and_replace_generics(generic_type, &mono_types);
|
|
||||||
|
|
||||||
convert_opaque_type(&mono_type, data_types)
|
|
||||||
} else {
|
|
||||||
match t.as_ref() {
|
|
||||||
Type::App {
|
|
||||||
public,
|
|
||||||
module,
|
|
||||||
name,
|
|
||||||
args,
|
|
||||||
} => {
|
|
||||||
let mut new_args = vec![];
|
|
||||||
for arg in args {
|
|
||||||
let arg = convert_opaque_type(arg, data_types);
|
|
||||||
new_args.push(arg);
|
|
||||||
}
|
|
||||||
Type::App {
|
|
||||||
public: *public,
|
|
||||||
module: module.clone(),
|
|
||||||
name: name.clone(),
|
|
||||||
args: new_args,
|
|
||||||
}
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
Type::Fn { args, ret } => {
|
|
||||||
let mut new_args = vec![];
|
|
||||||
for arg in args {
|
|
||||||
let arg = convert_opaque_type(arg, data_types);
|
|
||||||
new_args.push(arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
let ret = convert_opaque_type(ret, data_types);
|
|
||||||
|
|
||||||
Type::Fn {
|
|
||||||
args: new_args,
|
|
||||||
ret,
|
|
||||||
}
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
Type::Var { tipo: var_tipo } => {
|
|
||||||
if let TypeVar::Link { tipo } = &var_tipo.borrow().clone() {
|
|
||||||
convert_opaque_type(tipo, data_types)
|
|
||||||
} else {
|
|
||||||
t.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Type::Tuple { elems } => {
|
|
||||||
let mut new_elems = vec![];
|
|
||||||
for arg in elems {
|
|
||||||
let arg = convert_opaque_type(arg, data_types);
|
|
||||||
new_elems.push(arg);
|
|
||||||
}
|
|
||||||
Type::Tuple { elems: new_elems }.into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn check_replaceable_opaque_type(
|
|
||||||
t: &Arc<Type>,
|
|
||||||
data_types: &IndexMap<DataTypeKey, &TypedDataType>,
|
|
||||||
) -> bool {
|
|
||||||
let data_type = lookup_data_type_by_tipo(data_types, t);
|
|
||||||
|
|
||||||
if let Some(data_type) = data_type {
|
|
||||||
let data_type_args = &data_type.constructors[0].arguments;
|
|
||||||
data_type_args.len() == 1 && data_type.opaque && data_type.constructors.len() == 1
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn find_and_replace_generics(
|
|
||||||
tipo: &Arc<Type>,
|
|
||||||
mono_types: &IndexMap<u64, Arc<Type>>,
|
|
||||||
) -> Arc<Type> {
|
|
||||||
if let Some(id) = tipo.get_generic() {
|
|
||||||
// If a generic does not have a type we know of
|
|
||||||
// like a None in option then just use same type
|
|
||||||
mono_types.get(&id).unwrap_or(tipo).clone()
|
|
||||||
} else if tipo.is_generic() {
|
|
||||||
match &**tipo {
|
|
||||||
Type::App {
|
|
||||||
args,
|
|
||||||
public,
|
|
||||||
module,
|
|
||||||
name,
|
|
||||||
} => {
|
|
||||||
let mut new_args = vec![];
|
|
||||||
for arg in args {
|
|
||||||
let arg = find_and_replace_generics(arg, mono_types);
|
|
||||||
new_args.push(arg);
|
|
||||||
}
|
|
||||||
let t = Type::App {
|
|
||||||
args: new_args,
|
|
||||||
public: *public,
|
|
||||||
module: module.clone(),
|
|
||||||
name: name.clone(),
|
|
||||||
};
|
|
||||||
t.into()
|
|
||||||
}
|
|
||||||
Type::Fn { args, ret } => {
|
|
||||||
let mut new_args = vec![];
|
|
||||||
for arg in args {
|
|
||||||
let arg = find_and_replace_generics(arg, mono_types);
|
|
||||||
new_args.push(arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
let ret = find_and_replace_generics(ret, mono_types);
|
|
||||||
|
|
||||||
let t = Type::Fn {
|
|
||||||
args: new_args,
|
|
||||||
ret,
|
|
||||||
};
|
|
||||||
|
|
||||||
t.into()
|
|
||||||
}
|
|
||||||
Type::Tuple { elems } => {
|
|
||||||
let mut new_elems = vec![];
|
|
||||||
for elem in elems {
|
|
||||||
let elem = find_and_replace_generics(elem, mono_types);
|
|
||||||
new_elems.push(elem);
|
|
||||||
}
|
|
||||||
let t = Type::Tuple { elems: new_elems };
|
|
||||||
t.into()
|
|
||||||
}
|
|
||||||
Type::Var { tipo: var_tipo } => {
|
|
||||||
let var_type = var_tipo.as_ref().borrow().clone();
|
|
||||||
|
|
||||||
match var_type {
|
|
||||||
TypeVar::Link { tipo } => find_and_replace_generics(&tipo, mono_types),
|
|
||||||
TypeVar::Generic { .. } | TypeVar::Unbound { .. } => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
tipo.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn constants_ir(literal: &Constant) -> AirTree {
|
|
||||||
match literal {
|
|
||||||
Constant::Int { value, .. } => AirTree::int(value),
|
|
||||||
Constant::String { value, .. } => AirTree::string(value),
|
|
||||||
Constant::ByteArray { bytes, .. } => AirTree::byte_array(bytes.clone()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn handle_clause_guard(clause_guard: &ClauseGuard<Arc<Type>>) -> AirTree {
|
|
||||||
match clause_guard {
|
|
||||||
ClauseGuard::Not { value, .. } => {
|
|
||||||
let val = handle_clause_guard(value);
|
|
||||||
|
|
||||||
AirTree::unop(UnOp::Not, val)
|
|
||||||
}
|
|
||||||
ClauseGuard::Equals { left, right, .. } => {
|
|
||||||
let left_child = handle_clause_guard(left);
|
|
||||||
let right_child = handle_clause_guard(right);
|
|
||||||
|
|
||||||
AirTree::binop(BinOp::Eq, bool(), left_child, right_child, left.tipo())
|
|
||||||
}
|
|
||||||
ClauseGuard::NotEquals { left, right, .. } => {
|
|
||||||
let left_child = handle_clause_guard(left);
|
|
||||||
let right_child = handle_clause_guard(right);
|
|
||||||
|
|
||||||
AirTree::binop(BinOp::NotEq, bool(), left_child, right_child, left.tipo())
|
|
||||||
}
|
|
||||||
ClauseGuard::GtInt { left, right, .. } => {
|
|
||||||
let left_child = handle_clause_guard(left);
|
|
||||||
let right_child = handle_clause_guard(right);
|
|
||||||
|
|
||||||
AirTree::binop(BinOp::GtInt, bool(), left_child, right_child, left.tipo())
|
|
||||||
}
|
|
||||||
ClauseGuard::GtEqInt { left, right, .. } => {
|
|
||||||
let left_child = handle_clause_guard(left);
|
|
||||||
let right_child = handle_clause_guard(right);
|
|
||||||
|
|
||||||
AirTree::binop(BinOp::GtEqInt, bool(), left_child, right_child, left.tipo())
|
|
||||||
}
|
|
||||||
ClauseGuard::LtInt { left, right, .. } => {
|
|
||||||
let left_child = handle_clause_guard(left);
|
|
||||||
let right_child = handle_clause_guard(right);
|
|
||||||
|
|
||||||
AirTree::binop(BinOp::LtInt, bool(), left_child, right_child, left.tipo())
|
|
||||||
}
|
|
||||||
ClauseGuard::LtEqInt { left, right, .. } => {
|
|
||||||
let left_child = handle_clause_guard(left);
|
|
||||||
let right_child = handle_clause_guard(right);
|
|
||||||
|
|
||||||
AirTree::binop(BinOp::LtEqInt, bool(), left_child, right_child, left.tipo())
|
|
||||||
}
|
|
||||||
ClauseGuard::Or { left, right, .. } => {
|
|
||||||
let left_child = handle_clause_guard(left);
|
|
||||||
let right_child = handle_clause_guard(right);
|
|
||||||
|
|
||||||
AirTree::binop(BinOp::Or, bool(), left_child, right_child, left.tipo())
|
|
||||||
}
|
|
||||||
ClauseGuard::And { left, right, .. } => {
|
|
||||||
let left_child = handle_clause_guard(left);
|
|
||||||
let right_child = handle_clause_guard(right);
|
|
||||||
|
|
||||||
AirTree::binop(BinOp::And, bool(), left_child, right_child, left.tipo())
|
|
||||||
}
|
|
||||||
ClauseGuard::Var { tipo, name, .. } => AirTree::local_var(name, tipo.clone()),
|
|
||||||
ClauseGuard::Constant(constant) => constants_ir(constant),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_variant_name(t: &Arc<Type>) -> String {
|
|
||||||
if t.is_string() {
|
|
||||||
"_string".to_string()
|
|
||||||
} else if t.is_int() {
|
|
||||||
"_int".to_string()
|
|
||||||
} else if t.is_bool() {
|
|
||||||
"_bool".to_string()
|
|
||||||
} else if t.is_bytearray() {
|
|
||||||
"_bytearray".to_string()
|
|
||||||
} else if t.is_map() {
|
|
||||||
let mut full_type = vec!["_map".to_string()];
|
|
||||||
let pair_type = &t.get_inner_types()[0];
|
|
||||||
let fst_type = &pair_type.get_inner_types()[0];
|
|
||||||
let snd_type = &pair_type.get_inner_types()[1];
|
|
||||||
full_type.push(get_variant_name(fst_type));
|
|
||||||
full_type.push(get_variant_name(snd_type));
|
|
||||||
full_type.join("")
|
|
||||||
} else if t.is_list() {
|
|
||||||
let full_type = "_list".to_string();
|
|
||||||
let list_type = &t.get_inner_types()[0];
|
|
||||||
|
|
||||||
format!("{}{}", full_type, get_variant_name(list_type))
|
|
||||||
} else if t.is_tuple() {
|
|
||||||
let mut full_type = vec!["_tuple".to_string()];
|
|
||||||
|
|
||||||
let inner_types = t.get_inner_types();
|
|
||||||
|
|
||||||
for arg_type in inner_types {
|
|
||||||
full_type.push(get_variant_name(&arg_type));
|
|
||||||
}
|
|
||||||
full_type.join("")
|
|
||||||
} else if t.is_unbound() {
|
|
||||||
"_unbound".to_string()
|
|
||||||
} else {
|
|
||||||
let full_type = "_data".to_string();
|
|
||||||
|
|
||||||
if t.is_generic() {
|
|
||||||
println!("FULL TYPE: {:#?}", t);
|
|
||||||
panic!("FOUND A POLYMORPHIC TYPE. EXPECTED MONOMORPHIC TYPE");
|
|
||||||
}
|
|
||||||
|
|
||||||
full_type
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn monomorphize(air_tree: &mut AirTree, mono_types: &IndexMap<u64, Arc<Type>>) {
|
|
||||||
let mut held_types = air_tree.mut_held_types();
|
|
||||||
|
|
||||||
while let Some(tipo) = held_types.pop() {
|
|
||||||
*tipo = find_and_replace_generics(tipo, mono_types);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn erase_opaque_type_operations(
|
|
||||||
air_tree: &mut AirTree,
|
|
||||||
data_types: &IndexMap<DataTypeKey, &TypedDataType>,
|
|
||||||
) {
|
|
||||||
if let AirTree::Expression(e) = air_tree {
|
|
||||||
match e {
|
|
||||||
AirExpression::Constr { tipo, args, .. } => {
|
|
||||||
if check_replaceable_opaque_type(tipo, data_types) {
|
|
||||||
*air_tree = args.pop().unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AirExpression::RecordAccess { tipo, record, .. } => {
|
|
||||||
if check_replaceable_opaque_type(tipo, data_types) {
|
|
||||||
*air_tree = (**record).clone();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
} else if let AirTree::Statement {
|
|
||||||
statement: AirStatement::FieldsExpose {
|
|
||||||
record, indices, ..
|
|
||||||
},
|
|
||||||
hoisted_over: Some(hoisted_over),
|
|
||||||
} = air_tree
|
|
||||||
{
|
|
||||||
if check_replaceable_opaque_type(&record.return_type(), data_types) {
|
|
||||||
let name = indices[0].1.clone();
|
|
||||||
*air_tree = AirTree::let_assignment(name, (**record).clone())
|
|
||||||
.hoist_over((**hoisted_over).clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut held_types = air_tree.mut_held_types();
|
|
||||||
|
|
||||||
while let Some(tipo) = held_types.pop() {
|
|
||||||
*tipo = convert_opaque_type(tipo, data_types);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,430 @@
|
||||||
|
use indexmap::IndexSet;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use uplc::builtins::DefaultFunction;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
ast::{BinOp, UnOp},
|
||||||
|
tipo::{Type, ValueConstructor},
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::scope::Scope;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub enum Air {
|
||||||
|
// Primitives
|
||||||
|
Int {
|
||||||
|
scope: Scope,
|
||||||
|
value: String,
|
||||||
|
},
|
||||||
|
String {
|
||||||
|
scope: Scope,
|
||||||
|
value: String,
|
||||||
|
},
|
||||||
|
ByteArray {
|
||||||
|
scope: Scope,
|
||||||
|
bytes: Vec<u8>,
|
||||||
|
},
|
||||||
|
Bool {
|
||||||
|
scope: Scope,
|
||||||
|
value: bool,
|
||||||
|
},
|
||||||
|
List {
|
||||||
|
scope: Scope,
|
||||||
|
count: usize,
|
||||||
|
tipo: Arc<Type>,
|
||||||
|
tail: bool,
|
||||||
|
},
|
||||||
|
Tuple {
|
||||||
|
scope: Scope,
|
||||||
|
tipo: Arc<Type>,
|
||||||
|
count: usize,
|
||||||
|
},
|
||||||
|
Void {
|
||||||
|
scope: Scope,
|
||||||
|
},
|
||||||
|
Var {
|
||||||
|
scope: Scope,
|
||||||
|
constructor: ValueConstructor,
|
||||||
|
name: String,
|
||||||
|
variant_name: String,
|
||||||
|
},
|
||||||
|
// Functions
|
||||||
|
Call {
|
||||||
|
scope: Scope,
|
||||||
|
count: usize,
|
||||||
|
tipo: Arc<Type>,
|
||||||
|
},
|
||||||
|
DefineFunc {
|
||||||
|
scope: Scope,
|
||||||
|
func_name: String,
|
||||||
|
module_name: String,
|
||||||
|
params: Vec<String>,
|
||||||
|
recursive: bool,
|
||||||
|
variant_name: String,
|
||||||
|
},
|
||||||
|
Fn {
|
||||||
|
scope: Scope,
|
||||||
|
params: Vec<String>,
|
||||||
|
},
|
||||||
|
Builtin {
|
||||||
|
scope: Scope,
|
||||||
|
count: usize,
|
||||||
|
func: DefaultFunction,
|
||||||
|
tipo: Arc<Type>,
|
||||||
|
},
|
||||||
|
// Operators
|
||||||
|
BinOp {
|
||||||
|
scope: Scope,
|
||||||
|
name: BinOp,
|
||||||
|
tipo: Arc<Type>,
|
||||||
|
},
|
||||||
|
UnOp {
|
||||||
|
scope: Scope,
|
||||||
|
op: UnOp,
|
||||||
|
},
|
||||||
|
// Assignment
|
||||||
|
Let {
|
||||||
|
scope: Scope,
|
||||||
|
name: String,
|
||||||
|
},
|
||||||
|
UnWrapData {
|
||||||
|
scope: Scope,
|
||||||
|
tipo: Arc<Type>,
|
||||||
|
},
|
||||||
|
WrapData {
|
||||||
|
scope: Scope,
|
||||||
|
tipo: Arc<Type>,
|
||||||
|
},
|
||||||
|
AssertConstr {
|
||||||
|
scope: Scope,
|
||||||
|
constr_index: usize,
|
||||||
|
},
|
||||||
|
AssertBool {
|
||||||
|
scope: Scope,
|
||||||
|
is_true: bool,
|
||||||
|
},
|
||||||
|
// When
|
||||||
|
When {
|
||||||
|
scope: Scope,
|
||||||
|
tipo: Arc<Type>,
|
||||||
|
subject_name: String,
|
||||||
|
},
|
||||||
|
Clause {
|
||||||
|
scope: Scope,
|
||||||
|
tipo: Arc<Type>,
|
||||||
|
subject_name: String,
|
||||||
|
complex_clause: bool,
|
||||||
|
},
|
||||||
|
ListClause {
|
||||||
|
scope: Scope,
|
||||||
|
tipo: Arc<Type>,
|
||||||
|
tail_name: String,
|
||||||
|
next_tail_name: Option<String>,
|
||||||
|
complex_clause: bool,
|
||||||
|
},
|
||||||
|
WrapClause {
|
||||||
|
scope: Scope,
|
||||||
|
},
|
||||||
|
TupleClause {
|
||||||
|
scope: Scope,
|
||||||
|
tipo: Arc<Type>,
|
||||||
|
indices: IndexSet<(usize, String)>,
|
||||||
|
predefined_indices: IndexSet<(usize, String)>,
|
||||||
|
subject_name: String,
|
||||||
|
count: usize,
|
||||||
|
complex_clause: bool,
|
||||||
|
},
|
||||||
|
ClauseGuard {
|
||||||
|
scope: Scope,
|
||||||
|
subject_name: String,
|
||||||
|
tipo: Arc<Type>,
|
||||||
|
},
|
||||||
|
ListClauseGuard {
|
||||||
|
scope: Scope,
|
||||||
|
tipo: Arc<Type>,
|
||||||
|
tail_name: String,
|
||||||
|
next_tail_name: Option<String>,
|
||||||
|
inverse: bool,
|
||||||
|
},
|
||||||
|
Finally {
|
||||||
|
scope: Scope,
|
||||||
|
},
|
||||||
|
// If
|
||||||
|
If {
|
||||||
|
scope: Scope,
|
||||||
|
tipo: Arc<Type>,
|
||||||
|
},
|
||||||
|
// Record Creation
|
||||||
|
Record {
|
||||||
|
scope: Scope,
|
||||||
|
tag: usize,
|
||||||
|
tipo: Arc<Type>,
|
||||||
|
count: usize,
|
||||||
|
},
|
||||||
|
RecordUpdate {
|
||||||
|
scope: Scope,
|
||||||
|
highest_index: usize,
|
||||||
|
indices: Vec<(usize, Arc<Type>)>,
|
||||||
|
tipo: Arc<Type>,
|
||||||
|
},
|
||||||
|
// Field Access
|
||||||
|
RecordAccess {
|
||||||
|
scope: Scope,
|
||||||
|
record_index: u64,
|
||||||
|
tipo: Arc<Type>,
|
||||||
|
},
|
||||||
|
FieldsExpose {
|
||||||
|
scope: Scope,
|
||||||
|
indices: Vec<(usize, String, Arc<Type>)>,
|
||||||
|
check_last_item: bool,
|
||||||
|
},
|
||||||
|
// ListAccess
|
||||||
|
ListAccessor {
|
||||||
|
scope: Scope,
|
||||||
|
tipo: Arc<Type>,
|
||||||
|
names: Vec<String>,
|
||||||
|
tail: bool,
|
||||||
|
check_last_item: bool,
|
||||||
|
},
|
||||||
|
ListExpose {
|
||||||
|
scope: Scope,
|
||||||
|
tipo: Arc<Type>,
|
||||||
|
tail_head_names: Vec<(String, String)>,
|
||||||
|
tail: Option<(String, String)>,
|
||||||
|
},
|
||||||
|
// Tuple Access
|
||||||
|
TupleAccessor {
|
||||||
|
scope: Scope,
|
||||||
|
names: Vec<String>,
|
||||||
|
tipo: Arc<Type>,
|
||||||
|
check_last_item: bool,
|
||||||
|
},
|
||||||
|
TupleIndex {
|
||||||
|
scope: Scope,
|
||||||
|
tipo: Arc<Type>,
|
||||||
|
tuple_index: usize,
|
||||||
|
},
|
||||||
|
// Misc.
|
||||||
|
ErrorTerm {
|
||||||
|
scope: Scope,
|
||||||
|
tipo: Arc<Type>,
|
||||||
|
},
|
||||||
|
Trace {
|
||||||
|
scope: Scope,
|
||||||
|
tipo: Arc<Type>,
|
||||||
|
},
|
||||||
|
NoOp {
|
||||||
|
scope: Scope,
|
||||||
|
},
|
||||||
|
FieldsEmpty {
|
||||||
|
scope: Scope,
|
||||||
|
},
|
||||||
|
ListEmpty {
|
||||||
|
scope: Scope,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Air {
|
||||||
|
pub fn scope(&self) -> Scope {
|
||||||
|
match self {
|
||||||
|
Air::Int { scope, .. }
|
||||||
|
| Air::String { scope, .. }
|
||||||
|
| Air::ByteArray { scope, .. }
|
||||||
|
| Air::Bool { scope, .. }
|
||||||
|
| Air::List { scope, .. }
|
||||||
|
| Air::Tuple { scope, .. }
|
||||||
|
| Air::Void { scope }
|
||||||
|
| Air::Var { scope, .. }
|
||||||
|
| Air::Call { scope, .. }
|
||||||
|
| Air::DefineFunc { scope, .. }
|
||||||
|
| Air::Fn { scope, .. }
|
||||||
|
| Air::Builtin { scope, .. }
|
||||||
|
| Air::BinOp { scope, .. }
|
||||||
|
| Air::UnOp { scope, .. }
|
||||||
|
| Air::Let { scope, .. }
|
||||||
|
| Air::UnWrapData { scope, .. }
|
||||||
|
| Air::WrapData { scope, .. }
|
||||||
|
| Air::AssertConstr { scope, .. }
|
||||||
|
| Air::AssertBool { scope, .. }
|
||||||
|
| Air::When { scope, .. }
|
||||||
|
| Air::Clause { scope, .. }
|
||||||
|
| Air::ListClause { scope, .. }
|
||||||
|
| Air::WrapClause { scope }
|
||||||
|
| Air::TupleClause { scope, .. }
|
||||||
|
| Air::ClauseGuard { scope, .. }
|
||||||
|
| Air::ListClauseGuard { scope, .. }
|
||||||
|
| Air::Finally { scope }
|
||||||
|
| Air::If { scope, .. }
|
||||||
|
| Air::Record { scope, .. }
|
||||||
|
| Air::RecordUpdate { scope, .. }
|
||||||
|
| Air::RecordAccess { scope, .. }
|
||||||
|
| Air::FieldsExpose { scope, .. }
|
||||||
|
| Air::FieldsEmpty { scope }
|
||||||
|
| Air::ListEmpty { scope }
|
||||||
|
| Air::ListAccessor { scope, .. }
|
||||||
|
| Air::ListExpose { scope, .. }
|
||||||
|
| Air::TupleAccessor { scope, .. }
|
||||||
|
| Air::TupleIndex { scope, .. }
|
||||||
|
| Air::ErrorTerm { scope, .. }
|
||||||
|
| Air::Trace { scope, .. }
|
||||||
|
| Air::NoOp { scope, .. } => scope.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn scope_mut(&mut self) -> &mut Scope {
|
||||||
|
match self {
|
||||||
|
Air::Int { scope, .. }
|
||||||
|
| Air::String { scope, .. }
|
||||||
|
| Air::ByteArray { scope, .. }
|
||||||
|
| Air::Bool { scope, .. }
|
||||||
|
| Air::List { scope, .. }
|
||||||
|
| Air::Tuple { scope, .. }
|
||||||
|
| Air::Void { scope }
|
||||||
|
| Air::Var { scope, .. }
|
||||||
|
| Air::Call { scope, .. }
|
||||||
|
| Air::DefineFunc { scope, .. }
|
||||||
|
| Air::Fn { scope, .. }
|
||||||
|
| Air::Builtin { scope, .. }
|
||||||
|
| Air::BinOp { scope, .. }
|
||||||
|
| Air::UnOp { scope, .. }
|
||||||
|
| Air::Let { scope, .. }
|
||||||
|
| Air::UnWrapData { scope, .. }
|
||||||
|
| Air::WrapData { scope, .. }
|
||||||
|
| Air::AssertConstr { scope, .. }
|
||||||
|
| Air::AssertBool { scope, .. }
|
||||||
|
| Air::When { scope, .. }
|
||||||
|
| Air::Clause { scope, .. }
|
||||||
|
| Air::ListClause { scope, .. }
|
||||||
|
| Air::WrapClause { scope }
|
||||||
|
| Air::TupleClause { scope, .. }
|
||||||
|
| Air::ClauseGuard { scope, .. }
|
||||||
|
| Air::ListClauseGuard { scope, .. }
|
||||||
|
| Air::Finally { scope }
|
||||||
|
| Air::If { scope, .. }
|
||||||
|
| Air::Record { scope, .. }
|
||||||
|
| Air::RecordUpdate { scope, .. }
|
||||||
|
| Air::RecordAccess { scope, .. }
|
||||||
|
| Air::FieldsExpose { scope, .. }
|
||||||
|
| Air::FieldsEmpty { scope }
|
||||||
|
| Air::ListEmpty { scope }
|
||||||
|
| Air::ListAccessor { scope, .. }
|
||||||
|
| Air::ListExpose { scope, .. }
|
||||||
|
| Air::TupleAccessor { scope, .. }
|
||||||
|
| Air::TupleIndex { scope, .. }
|
||||||
|
| Air::ErrorTerm { scope, .. }
|
||||||
|
| Air::Trace { scope, .. }
|
||||||
|
| Air::NoOp { scope, .. } => scope,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn tipo(&self) -> Option<Arc<Type>> {
|
||||||
|
match self {
|
||||||
|
Air::Int { .. } => Some(
|
||||||
|
Type::App {
|
||||||
|
public: true,
|
||||||
|
module: String::new(),
|
||||||
|
name: "Int".to_string(),
|
||||||
|
args: vec![],
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
),
|
||||||
|
Air::String { .. } => Some(
|
||||||
|
Type::App {
|
||||||
|
public: true,
|
||||||
|
module: String::new(),
|
||||||
|
name: "String".to_string(),
|
||||||
|
args: vec![],
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
),
|
||||||
|
Air::ByteArray { .. } => Some(
|
||||||
|
Type::App {
|
||||||
|
public: true,
|
||||||
|
module: String::new(),
|
||||||
|
name: "ByteArray".to_string(),
|
||||||
|
args: vec![],
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
),
|
||||||
|
Air::Bool { .. } => Some(
|
||||||
|
Type::App {
|
||||||
|
public: true,
|
||||||
|
module: String::new(),
|
||||||
|
name: "Bool".to_string(),
|
||||||
|
args: vec![],
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
),
|
||||||
|
Air::Void { .. } => Some(
|
||||||
|
Type::App {
|
||||||
|
public: true,
|
||||||
|
module: String::new(),
|
||||||
|
name: "Void".to_string(),
|
||||||
|
args: vec![],
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
),
|
||||||
|
Air::WrapData { .. } => Some(
|
||||||
|
Type::App {
|
||||||
|
public: true,
|
||||||
|
module: String::new(),
|
||||||
|
name: "Data".to_string(),
|
||||||
|
args: vec![],
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
),
|
||||||
|
Air::Var { constructor, .. } => Some(constructor.tipo.clone()),
|
||||||
|
Air::List { tipo, .. }
|
||||||
|
| Air::Tuple { tipo, .. }
|
||||||
|
| Air::Call { tipo, .. }
|
||||||
|
| Air::Builtin { tipo, .. }
|
||||||
|
| Air::BinOp { tipo, .. }
|
||||||
|
| Air::UnWrapData { tipo, .. }
|
||||||
|
| Air::When { tipo, .. }
|
||||||
|
| Air::Clause { tipo, .. }
|
||||||
|
| Air::ListClause { tipo, .. }
|
||||||
|
| Air::TupleClause { tipo, .. }
|
||||||
|
| Air::ClauseGuard { tipo, .. }
|
||||||
|
| Air::If { tipo, .. }
|
||||||
|
| Air::ListClauseGuard { tipo, .. }
|
||||||
|
| Air::Record { tipo, .. }
|
||||||
|
| Air::RecordUpdate { tipo, .. }
|
||||||
|
| Air::RecordAccess { tipo, .. }
|
||||||
|
| Air::ListAccessor { tipo, .. }
|
||||||
|
| Air::ListExpose { tipo, .. }
|
||||||
|
| Air::TupleAccessor { tipo, .. }
|
||||||
|
| Air::TupleIndex { tipo, .. }
|
||||||
|
| Air::ErrorTerm { tipo, .. }
|
||||||
|
| Air::Trace { tipo, .. } => Some(tipo.clone()),
|
||||||
|
Air::DefineFunc { .. }
|
||||||
|
| Air::Fn { .. }
|
||||||
|
| Air::Let { .. }
|
||||||
|
| Air::WrapClause { .. }
|
||||||
|
| Air::AssertConstr { .. }
|
||||||
|
| Air::AssertBool { .. }
|
||||||
|
| Air::Finally { .. }
|
||||||
|
| Air::FieldsExpose { .. }
|
||||||
|
| Air::FieldsEmpty { .. }
|
||||||
|
| Air::ListEmpty { .. }
|
||||||
|
| Air::NoOp { .. } => None,
|
||||||
|
Air::UnOp { op, .. } => match op {
|
||||||
|
UnOp::Not => Some(
|
||||||
|
Type::App {
|
||||||
|
public: true,
|
||||||
|
module: String::new(),
|
||||||
|
name: "Bool".to_string(),
|
||||||
|
args: vec![],
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
),
|
||||||
|
UnOp::Negate => Some(
|
||||||
|
Type::App {
|
||||||
|
public: true,
|
||||||
|
module: String::new(),
|
||||||
|
name: "Int".to_string(),
|
||||||
|
args: vec![],
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
|
|
@ -8,7 +8,6 @@ pub mod builtins;
|
||||||
pub mod expr;
|
pub mod expr;
|
||||||
pub mod format;
|
pub mod format;
|
||||||
pub mod gen_uplc;
|
pub mod gen_uplc;
|
||||||
pub mod gen_uplc2;
|
|
||||||
pub mod levenshtein;
|
pub mod levenshtein;
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
pub mod pretty;
|
pub mod pretty;
|
||||||
|
|
|
@ -317,7 +317,6 @@ impl CheckedModules {
|
||||||
FunctionAccessKey {
|
FunctionAccessKey {
|
||||||
module_name: module.name.clone(),
|
module_name: module.name.clone(),
|
||||||
function_name: func.name.clone(),
|
function_name: func.name.clone(),
|
||||||
variant_name: String::new(),
|
|
||||||
},
|
},
|
||||||
func,
|
func,
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue