feat: finish up build. just have helper methods
feat: Create an air and AirTree iterator. This allows us to iterate forwards or backwards over the tree as a vec. chore: moved around some functions
This commit is contained in:
parent
ba3265054c
commit
96959011e9
|
@ -12,12 +12,17 @@ use uplc::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{AssignmentKind, BinOp, Pattern, Span, TypedDataType, TypedFunction, TypedValidator},
|
ast::{
|
||||||
|
AssignmentKind, BinOp, Pattern, Span, TypedClause, TypedDataType, TypedFunction,
|
||||||
|
TypedValidator,
|
||||||
|
},
|
||||||
builtins::{int, void},
|
builtins::{int, void},
|
||||||
expr::TypedExpr,
|
expr::TypedExpr,
|
||||||
gen_uplc::{
|
gen_uplc::{
|
||||||
air::Air,
|
air::Air,
|
||||||
builder::{self as build, AssignmentProperties, DataTypeKey, FunctionAccessKey},
|
builder::{
|
||||||
|
self as build, AssignmentProperties, ClauseProperties, DataTypeKey, FunctionAccessKey,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
tipo::{
|
tipo::{
|
||||||
ModuleValueConstructor, PatternConstructor, Type, TypeInfo, ValueConstructor,
|
ModuleValueConstructor, PatternConstructor, Type, TypeInfo, ValueConstructor,
|
||||||
|
@ -234,7 +239,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
AirTree::call(self.build(fun.as_ref()), tipo.clone(), func_args)
|
AirTree::call(self.build(fun.as_ref()), tipo.clone(), func_args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => todo!("IS THIS REACHABLE?"),
|
_ => unreachable!("IS THIS REACHABLE? Well you reached it with {:#?}", body),
|
||||||
},
|
},
|
||||||
TypedExpr::BinOp {
|
TypedExpr::BinOp {
|
||||||
name,
|
name,
|
||||||
|
@ -303,14 +308,40 @@ impl<'a> CodeGenerator<'a> {
|
||||||
AirTree::hoist_over(assignment, clause_then)
|
AirTree::hoist_over(assignment, clause_then)
|
||||||
} else {
|
} else {
|
||||||
clauses = if subject.tipo().is_list() {
|
clauses = if subject.tipo().is_list() {
|
||||||
build::rearrange_clauses(clauses.clone())
|
build::rearrange_clauses(clauses)
|
||||||
} else {
|
} else {
|
||||||
clauses
|
clauses
|
||||||
};
|
};
|
||||||
|
|
||||||
let last_clause = clauses.pop().unwrap();
|
let last_clause = clauses.pop().unwrap();
|
||||||
|
|
||||||
todo!()
|
let constr_var = format!(
|
||||||
|
"__when_var_span_{}_{}",
|
||||||
|
subject.location().start,
|
||||||
|
subject.location().end
|
||||||
|
);
|
||||||
|
|
||||||
|
let subject_name = format!(
|
||||||
|
"__subject_var_span_{}_{}",
|
||||||
|
subject.location().start,
|
||||||
|
subject.location().end
|
||||||
|
);
|
||||||
|
|
||||||
|
let clauses = self.handle_each_clause(
|
||||||
|
&clauses,
|
||||||
|
last_clause,
|
||||||
|
&subject.tipo(),
|
||||||
|
&mut ClauseProperties::init(
|
||||||
|
&subject.tipo(),
|
||||||
|
constr_var.clone(),
|
||||||
|
subject_name.clone(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
let constr_assign = AirTree::let_assignment(&constr_var, self.build(subject));
|
||||||
|
let when_assign = AirTree::when(subject_name, subject.tipo(), clauses);
|
||||||
|
|
||||||
|
AirTree::hoist_over(constr_assign, when_assign)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -952,4 +983,34 @@ impl<'a> CodeGenerator<'a> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn handle_each_clause(
|
||||||
|
&mut self,
|
||||||
|
clauses: &[TypedClause],
|
||||||
|
final_clause: TypedClause,
|
||||||
|
subject_tipo: &Arc<Type>,
|
||||||
|
props: &mut ClauseProperties,
|
||||||
|
) -> AirTree {
|
||||||
|
assert!(!clauses.is_empty());
|
||||||
|
*props.is_complex_clause() = false;
|
||||||
|
|
||||||
|
if let Some((clause, rest_clauses)) = clauses.split_first() {
|
||||||
|
todo!()
|
||||||
|
} else {
|
||||||
|
// handle final_clause
|
||||||
|
|
||||||
|
*props.is_final_clause() = true;
|
||||||
|
assert!(final_clause.guard.is_none());
|
||||||
|
let clause_then = self.build(&final_clause.then);
|
||||||
|
self.clause_pattern(&final_clause.pattern, clause_then)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clause_pattern(
|
||||||
|
&mut self,
|
||||||
|
pattern: &Pattern<PatternConstructor, Arc<Type>>,
|
||||||
|
clause_then: AirTree,
|
||||||
|
) -> AirTree {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ pub enum Air {
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
count: usize,
|
count: usize,
|
||||||
},
|
},
|
||||||
Void {},
|
Void,
|
||||||
Var {
|
Var {
|
||||||
constructor: ValueConstructor,
|
constructor: ValueConstructor,
|
||||||
name: String,
|
name: String,
|
||||||
|
@ -116,7 +116,7 @@ pub enum Air {
|
||||||
next_tail_name: Option<String>,
|
next_tail_name: Option<String>,
|
||||||
inverse: bool,
|
inverse: bool,
|
||||||
},
|
},
|
||||||
Finally {},
|
Finally,
|
||||||
// If
|
// If
|
||||||
If {
|
If {
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
|
@ -170,9 +170,9 @@ pub enum Air {
|
||||||
Trace {
|
Trace {
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
},
|
},
|
||||||
NoOp {},
|
NoOp,
|
||||||
FieldsEmpty {},
|
FieldsEmpty,
|
||||||
ListEmpty {},
|
ListEmpty,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Air {
|
impl Air {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{Constant, Pattern},
|
ast::{Constant, Pattern, TypedClause},
|
||||||
gen_uplc::builder::AssignmentProperties,
|
gen_uplc::builder::{AssignmentProperties, ClauseProperties},
|
||||||
tipo::{PatternConstructor, Type},
|
tipo::{PatternConstructor, Type},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -12,15 +12,6 @@ pub fn convert_opaque_type() -> Arc<Type> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_each_clause(
|
|
||||||
pattern: &Pattern<PatternConstructor, Arc<Type>>,
|
|
||||||
value: AirTree,
|
|
||||||
tipo: &Arc<Type>,
|
|
||||||
props: AssignmentProperties,
|
|
||||||
) -> AirTree {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn constants_ir(literal: &Constant) -> AirTree {
|
pub fn constants_ir(literal: &Constant) -> AirTree {
|
||||||
match literal {
|
match literal {
|
||||||
Constant::Int { value, .. } => AirTree::int(value),
|
Constant::Int { value, .. } => AirTree::int(value),
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use indexmap::IndexSet;
|
use indexmap::IndexSet;
|
||||||
use std::sync::Arc;
|
use std::{collections::VecDeque, sync::Arc};
|
||||||
use uplc::builtins::DefaultFunction;
|
use uplc::builtins::DefaultFunction;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -17,6 +17,42 @@ pub enum AirTree {
|
||||||
UnhoistedSequence(Vec<AirTree>),
|
UnhoistedSequence(Vec<AirTree>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct AirIterator<'a> {
|
||||||
|
deque_pointer: VecDeque<&'a AirTree>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Iterator for AirIterator<'_> {
|
||||||
|
type Item = Air;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DoubleEndedIterator for AirIterator<'_> {
|
||||||
|
fn next_back(&mut self) -> Option<Self::Item> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct AirTreeIterator<'a> {
|
||||||
|
deque_pointer: VecDeque<&'a AirTree>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for AirTreeIterator<'a> {
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
self.deque_pointer.pop_front()
|
||||||
|
}
|
||||||
|
|
||||||
|
type Item = &'a AirTree;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DoubleEndedIterator for AirTreeIterator<'_> {
|
||||||
|
fn next_back(&mut self) -> Option<Self::Item> {
|
||||||
|
self.deque_pointer.pop_back()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum AirStatement {
|
pub enum AirStatement {
|
||||||
// Assignment
|
// Assignment
|
||||||
|
@ -153,8 +189,7 @@ pub enum AirExpression {
|
||||||
When {
|
When {
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
subject_name: String,
|
subject_name: String,
|
||||||
clauses: Vec<AirTree>,
|
clauses: Box<AirTree>,
|
||||||
final_clause: Box<AirTree>,
|
|
||||||
},
|
},
|
||||||
Clause {
|
Clause {
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
|
@ -397,17 +432,11 @@ impl AirTree {
|
||||||
hoisted_over: None,
|
hoisted_over: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
pub fn when(
|
pub fn when(subject_name: impl ToString, tipo: Arc<Type>, clauses: AirTree) -> AirTree {
|
||||||
subject_name: impl ToString,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
clauses: Vec<AirTree>,
|
|
||||||
final_clause: AirTree,
|
|
||||||
) -> AirTree {
|
|
||||||
AirTree::Expression(AirExpression::When {
|
AirTree::Expression(AirExpression::When {
|
||||||
tipo,
|
tipo,
|
||||||
subject_name: subject_name.to_string(),
|
subject_name: subject_name.to_string(),
|
||||||
clauses,
|
clauses: clauses.into(),
|
||||||
final_clause: final_clause.into(),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
pub fn clause(
|
pub fn clause(
|
||||||
|
@ -725,52 +754,89 @@ impl AirTree {
|
||||||
// self.call(void(), expect_stack, vec![tail_stack, arg_stack2])
|
// self.call(void(), expect_stack, vec![tail_stack, arg_stack2])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_air_vec(&self, air_vec: &mut Vec<Air>) {
|
pub fn iter(&self) -> AirTreeIterator {
|
||||||
|
let mut new_vec = vec![];
|
||||||
|
self.create_iter(&mut new_vec);
|
||||||
|
AirTreeIterator {
|
||||||
|
deque_pointer: new_vec.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn air_iter(&self) -> AirIterator {
|
||||||
|
let mut new_vec = vec![];
|
||||||
|
self.create_iter(&mut new_vec);
|
||||||
|
AirIterator {
|
||||||
|
deque_pointer: new_vec.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_iter<'a>(&'a self, pointer_vec: &mut Vec<&'a AirTree>) {
|
||||||
|
match self {
|
||||||
|
AirTree::Statement(st) => match st {
|
||||||
|
AirStatement::Let {
|
||||||
|
value,
|
||||||
|
hoisted_over: Some(exp),
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
pointer_vec.push(self);
|
||||||
|
value.create_iter(pointer_vec);
|
||||||
|
exp.create_iter(pointer_vec);
|
||||||
|
}
|
||||||
|
AirStatement::DefineFunc { .. } => todo!(),
|
||||||
|
AirStatement::AssertConstr {
|
||||||
|
constr,
|
||||||
|
hoisted_over: Some(exp),
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
pointer_vec.push(self);
|
||||||
|
constr.create_iter(pointer_vec);
|
||||||
|
exp.create_iter(pointer_vec);
|
||||||
|
}
|
||||||
|
AirStatement::AssertBool { .. } => todo!(),
|
||||||
|
AirStatement::FieldsExpose { .. } => todo!(),
|
||||||
|
AirStatement::ListAccessor { .. } => todo!(),
|
||||||
|
AirStatement::ListExpose { .. } => todo!(),
|
||||||
|
AirStatement::TupleAccessor { .. } => todo!(),
|
||||||
|
AirStatement::NoOp { .. } => todo!(),
|
||||||
|
_ => unreachable!("FOUND UNHOISTED STATEMENT"),
|
||||||
|
},
|
||||||
|
AirTree::Expression(_) => todo!(),
|
||||||
|
AirTree::UnhoistedSequence(_) => {
|
||||||
|
unreachable!("SHOULD FIRST RESOLVE ALL UNHOISTED SEQUENCES")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn convert_to_air(&self) -> Air {
|
||||||
match self {
|
match self {
|
||||||
AirTree::Statement(st) => match st {
|
AirTree::Statement(st) => match st {
|
||||||
AirStatement::Let {
|
AirStatement::Let {
|
||||||
name,
|
name,
|
||||||
value,
|
value,
|
||||||
hoisted_over: Some(exp),
|
hoisted_over: Some(exp),
|
||||||
} => {
|
} => Air::Let { name: name.clone() },
|
||||||
air_vec.push(Air::Let { name: name.clone() });
|
|
||||||
value.to_air_vec(air_vec);
|
|
||||||
exp.to_air_vec(air_vec);
|
|
||||||
}
|
|
||||||
AirStatement::DefineFunc { .. } => todo!(),
|
AirStatement::DefineFunc { .. } => todo!(),
|
||||||
AirStatement::AssertConstr {
|
AirStatement::AssertConstr {
|
||||||
constr_index,
|
constr_index,
|
||||||
constr,
|
constr,
|
||||||
hoisted_over: Some(exp),
|
hoisted_over: Some(exp),
|
||||||
} => {
|
} => Air::AssertConstr {
|
||||||
air_vec.push(Air::AssertConstr {
|
constr_index: *constr_index,
|
||||||
constr_index: *constr_index,
|
},
|
||||||
});
|
|
||||||
constr.to_air_vec(air_vec);
|
|
||||||
exp.to_air_vec(air_vec);
|
|
||||||
}
|
|
||||||
AirStatement::AssertBool {
|
AirStatement::AssertBool {
|
||||||
is_true,
|
is_true,
|
||||||
value,
|
value,
|
||||||
hoisted_over: Some(exp),
|
hoisted_over: Some(exp),
|
||||||
} => {
|
} => Air::AssertBool { is_true: *is_true },
|
||||||
air_vec.push(Air::AssertBool { is_true: *is_true });
|
|
||||||
value.to_air_vec(air_vec);
|
|
||||||
exp.to_air_vec(air_vec);
|
|
||||||
}
|
|
||||||
AirStatement::FieldsExpose {
|
AirStatement::FieldsExpose {
|
||||||
indices,
|
indices,
|
||||||
check_last_item,
|
check_last_item,
|
||||||
record,
|
record,
|
||||||
hoisted_over: Some(exp),
|
hoisted_over: Some(exp),
|
||||||
} => {
|
} => Air::FieldsExpose {
|
||||||
air_vec.push(Air::FieldsExpose {
|
indices: indices.clone(),
|
||||||
indices: indices.clone(),
|
check_last_item: *check_last_item,
|
||||||
check_last_item: *check_last_item,
|
},
|
||||||
});
|
|
||||||
record.to_air_vec(air_vec);
|
|
||||||
exp.to_air_vec(air_vec);
|
|
||||||
}
|
|
||||||
AirStatement::ListAccessor {
|
AirStatement::ListAccessor {
|
||||||
tipo,
|
tipo,
|
||||||
names,
|
names,
|
||||||
|
@ -778,65 +844,50 @@ impl AirTree {
|
||||||
check_last_item,
|
check_last_item,
|
||||||
list,
|
list,
|
||||||
hoisted_over: Some(exp),
|
hoisted_over: Some(exp),
|
||||||
} => {
|
} => Air::ListAccessor {
|
||||||
air_vec.push(Air::ListAccessor {
|
tipo: tipo.clone(),
|
||||||
tipo: tipo.clone(),
|
names: names.clone(),
|
||||||
names: names.clone(),
|
tail: *tail,
|
||||||
tail: *tail,
|
check_last_item: *check_last_item,
|
||||||
check_last_item: *check_last_item,
|
},
|
||||||
});
|
|
||||||
list.to_air_vec(air_vec);
|
|
||||||
exp.to_air_vec(air_vec);
|
|
||||||
}
|
|
||||||
AirStatement::ListExpose {
|
AirStatement::ListExpose {
|
||||||
tipo,
|
tipo,
|
||||||
tail_head_names,
|
tail_head_names,
|
||||||
tail,
|
tail,
|
||||||
list,
|
list,
|
||||||
hoisted_over: Some(exp),
|
hoisted_over: Some(exp),
|
||||||
} => {
|
} => Air::ListExpose {
|
||||||
air_vec.push(Air::ListExpose {
|
tipo: tipo.clone(),
|
||||||
tipo: tipo.clone(),
|
tail_head_names: tail_head_names.clone(),
|
||||||
tail_head_names: tail_head_names.clone(),
|
tail: tail.clone(),
|
||||||
tail: tail.clone(),
|
},
|
||||||
});
|
|
||||||
list.to_air_vec(air_vec);
|
|
||||||
exp.to_air_vec(air_vec);
|
|
||||||
}
|
|
||||||
AirStatement::TupleAccessor {
|
AirStatement::TupleAccessor {
|
||||||
names,
|
names,
|
||||||
tipo,
|
tipo,
|
||||||
check_last_item,
|
check_last_item,
|
||||||
tuple,
|
tuple,
|
||||||
hoisted_over: Some(exp),
|
hoisted_over: Some(exp),
|
||||||
} => {
|
} => Air::TupleAccessor {
|
||||||
air_vec.push(Air::TupleAccessor {
|
names: names.clone(),
|
||||||
names: names.clone(),
|
tipo: tipo.clone(),
|
||||||
tipo: tipo.clone(),
|
check_last_item: *check_last_item,
|
||||||
check_last_item: *check_last_item,
|
},
|
||||||
});
|
|
||||||
tuple.to_air_vec(air_vec);
|
|
||||||
exp.to_air_vec(air_vec);
|
|
||||||
}
|
|
||||||
AirStatement::NoOp {
|
AirStatement::NoOp {
|
||||||
hoisted_over: Some(exp),
|
hoisted_over: Some(exp),
|
||||||
} => {
|
} => Air::NoOp,
|
||||||
// No need to push NoOp. It does nothing.
|
|
||||||
exp.to_air_vec(air_vec);
|
|
||||||
}
|
|
||||||
_ => unreachable!("SHOULD NOT HAVE A HOISTED OVER RESOLVING TO NONE"),
|
_ => unreachable!("SHOULD NOT HAVE A HOISTED OVER RESOLVING TO NONE"),
|
||||||
},
|
},
|
||||||
AirTree::Expression(exp) => match exp {
|
AirTree::Expression(exp) => match exp {
|
||||||
AirExpression::Int { value } => air_vec.push(Air::Int {
|
AirExpression::Int { value } => Air::Int {
|
||||||
value: value.clone(),
|
value: value.clone(),
|
||||||
}),
|
},
|
||||||
AirExpression::String { value } => air_vec.push(Air::String {
|
AirExpression::String { value } => Air::String {
|
||||||
value: value.clone(),
|
value: value.clone(),
|
||||||
}),
|
},
|
||||||
AirExpression::ByteArray { bytes } => air_vec.push(Air::ByteArray {
|
AirExpression::ByteArray { bytes } => Air::ByteArray {
|
||||||
bytes: bytes.clone(),
|
bytes: bytes.clone(),
|
||||||
}),
|
},
|
||||||
AirExpression::Bool { value } => air_vec.push(Air::Bool { value: *value }),
|
AirExpression::Bool { value } => Air::Bool { value: *value },
|
||||||
AirExpression::List { .. } => todo!(),
|
AirExpression::List { .. } => todo!(),
|
||||||
AirExpression::Tuple { .. } => todo!(),
|
AirExpression::Tuple { .. } => todo!(),
|
||||||
AirExpression::Void => todo!(),
|
AirExpression::Void => todo!(),
|
||||||
|
|
Loading…
Reference in New Issue