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::{
|
||||
ast::{AssignmentKind, BinOp, Pattern, Span, TypedDataType, TypedFunction, TypedValidator},
|
||||
ast::{
|
||||
AssignmentKind, BinOp, Pattern, Span, TypedClause, TypedDataType, TypedFunction,
|
||||
TypedValidator,
|
||||
},
|
||||
builtins::{int, void},
|
||||
expr::TypedExpr,
|
||||
gen_uplc::{
|
||||
air::Air,
|
||||
builder::{self as build, AssignmentProperties, DataTypeKey, FunctionAccessKey},
|
||||
builder::{
|
||||
self as build, AssignmentProperties, ClauseProperties, DataTypeKey, FunctionAccessKey,
|
||||
},
|
||||
},
|
||||
tipo::{
|
||||
ModuleValueConstructor, PatternConstructor, Type, TypeInfo, ValueConstructor,
|
||||
|
@ -234,7 +239,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
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 {
|
||||
name,
|
||||
|
@ -303,14 +308,40 @@ impl<'a> CodeGenerator<'a> {
|
|||
AirTree::hoist_over(assignment, clause_then)
|
||||
} else {
|
||||
clauses = if subject.tipo().is_list() {
|
||||
build::rearrange_clauses(clauses.clone())
|
||||
build::rearrange_clauses(clauses)
|
||||
} else {
|
||||
clauses
|
||||
};
|
||||
|
||||
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!()
|
||||
}
|
||||
}
|
||||
|
||||
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>,
|
||||
count: usize,
|
||||
},
|
||||
Void {},
|
||||
Void,
|
||||
Var {
|
||||
constructor: ValueConstructor,
|
||||
name: String,
|
||||
|
@ -116,7 +116,7 @@ pub enum Air {
|
|||
next_tail_name: Option<String>,
|
||||
inverse: bool,
|
||||
},
|
||||
Finally {},
|
||||
Finally,
|
||||
// If
|
||||
If {
|
||||
tipo: Arc<Type>,
|
||||
|
@ -170,9 +170,9 @@ pub enum Air {
|
|||
Trace {
|
||||
tipo: Arc<Type>,
|
||||
},
|
||||
NoOp {},
|
||||
FieldsEmpty {},
|
||||
ListEmpty {},
|
||||
NoOp,
|
||||
FieldsEmpty,
|
||||
ListEmpty,
|
||||
}
|
||||
|
||||
impl Air {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use crate::{
|
||||
ast::{Constant, Pattern},
|
||||
gen_uplc::builder::AssignmentProperties,
|
||||
ast::{Constant, Pattern, TypedClause},
|
||||
gen_uplc::builder::{AssignmentProperties, ClauseProperties},
|
||||
tipo::{PatternConstructor, Type},
|
||||
};
|
||||
|
||||
|
@ -12,15 +12,6 @@ pub fn convert_opaque_type() -> Arc<Type> {
|
|||
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 {
|
||||
match literal {
|
||||
Constant::Int { value, .. } => AirTree::int(value),
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use indexmap::IndexSet;
|
||||
use std::sync::Arc;
|
||||
use std::{collections::VecDeque, sync::Arc};
|
||||
use uplc::builtins::DefaultFunction;
|
||||
|
||||
use crate::{
|
||||
|
@ -17,6 +17,42 @@ pub enum 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)]
|
||||
pub enum AirStatement {
|
||||
// Assignment
|
||||
|
@ -153,8 +189,7 @@ pub enum AirExpression {
|
|||
When {
|
||||
tipo: Arc<Type>,
|
||||
subject_name: String,
|
||||
clauses: Vec<AirTree>,
|
||||
final_clause: Box<AirTree>,
|
||||
clauses: Box<AirTree>,
|
||||
},
|
||||
Clause {
|
||||
tipo: Arc<Type>,
|
||||
|
@ -397,17 +432,11 @@ impl AirTree {
|
|||
hoisted_over: None,
|
||||
})
|
||||
}
|
||||
pub fn when(
|
||||
subject_name: impl ToString,
|
||||
tipo: Arc<Type>,
|
||||
clauses: Vec<AirTree>,
|
||||
final_clause: AirTree,
|
||||
) -> AirTree {
|
||||
pub fn when(subject_name: impl ToString, tipo: Arc<Type>, clauses: AirTree) -> AirTree {
|
||||
AirTree::Expression(AirExpression::When {
|
||||
tipo,
|
||||
subject_name: subject_name.to_string(),
|
||||
clauses,
|
||||
final_clause: final_clause.into(),
|
||||
clauses: clauses.into(),
|
||||
})
|
||||
}
|
||||
pub fn clause(
|
||||
|
@ -725,52 +754,89 @@ impl AirTree {
|
|||
// 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 {
|
||||
AirTree::Statement(st) => match st {
|
||||
AirStatement::Let {
|
||||
name,
|
||||
value,
|
||||
hoisted_over: Some(exp),
|
||||
} => {
|
||||
air_vec.push(Air::Let { name: name.clone() });
|
||||
value.to_air_vec(air_vec);
|
||||
exp.to_air_vec(air_vec);
|
||||
}
|
||||
} => Air::Let { name: name.clone() },
|
||||
AirStatement::DefineFunc { .. } => todo!(),
|
||||
AirStatement::AssertConstr {
|
||||
constr_index,
|
||||
constr,
|
||||
hoisted_over: Some(exp),
|
||||
} => {
|
||||
air_vec.push(Air::AssertConstr {
|
||||
} => Air::AssertConstr {
|
||||
constr_index: *constr_index,
|
||||
});
|
||||
constr.to_air_vec(air_vec);
|
||||
exp.to_air_vec(air_vec);
|
||||
}
|
||||
},
|
||||
AirStatement::AssertBool {
|
||||
is_true,
|
||||
value,
|
||||
hoisted_over: Some(exp),
|
||||
} => {
|
||||
air_vec.push(Air::AssertBool { is_true: *is_true });
|
||||
value.to_air_vec(air_vec);
|
||||
exp.to_air_vec(air_vec);
|
||||
}
|
||||
} => Air::AssertBool { is_true: *is_true },
|
||||
AirStatement::FieldsExpose {
|
||||
indices,
|
||||
check_last_item,
|
||||
record,
|
||||
hoisted_over: Some(exp),
|
||||
} => {
|
||||
air_vec.push(Air::FieldsExpose {
|
||||
} => Air::FieldsExpose {
|
||||
indices: indices.clone(),
|
||||
check_last_item: *check_last_item,
|
||||
});
|
||||
record.to_air_vec(air_vec);
|
||||
exp.to_air_vec(air_vec);
|
||||
}
|
||||
},
|
||||
AirStatement::ListAccessor {
|
||||
tipo,
|
||||
names,
|
||||
|
@ -778,65 +844,50 @@ impl AirTree {
|
|||
check_last_item,
|
||||
list,
|
||||
hoisted_over: Some(exp),
|
||||
} => {
|
||||
air_vec.push(Air::ListAccessor {
|
||||
} => Air::ListAccessor {
|
||||
tipo: tipo.clone(),
|
||||
names: names.clone(),
|
||||
tail: *tail,
|
||||
check_last_item: *check_last_item,
|
||||
});
|
||||
list.to_air_vec(air_vec);
|
||||
exp.to_air_vec(air_vec);
|
||||
}
|
||||
},
|
||||
AirStatement::ListExpose {
|
||||
tipo,
|
||||
tail_head_names,
|
||||
tail,
|
||||
list,
|
||||
hoisted_over: Some(exp),
|
||||
} => {
|
||||
air_vec.push(Air::ListExpose {
|
||||
} => Air::ListExpose {
|
||||
tipo: tipo.clone(),
|
||||
tail_head_names: tail_head_names.clone(),
|
||||
tail: tail.clone(),
|
||||
});
|
||||
list.to_air_vec(air_vec);
|
||||
exp.to_air_vec(air_vec);
|
||||
}
|
||||
},
|
||||
AirStatement::TupleAccessor {
|
||||
names,
|
||||
tipo,
|
||||
check_last_item,
|
||||
tuple,
|
||||
hoisted_over: Some(exp),
|
||||
} => {
|
||||
air_vec.push(Air::TupleAccessor {
|
||||
} => Air::TupleAccessor {
|
||||
names: names.clone(),
|
||||
tipo: tipo.clone(),
|
||||
check_last_item: *check_last_item,
|
||||
});
|
||||
tuple.to_air_vec(air_vec);
|
||||
exp.to_air_vec(air_vec);
|
||||
}
|
||||
},
|
||||
AirStatement::NoOp {
|
||||
hoisted_over: Some(exp),
|
||||
} => {
|
||||
// No need to push NoOp. It does nothing.
|
||||
exp.to_air_vec(air_vec);
|
||||
}
|
||||
} => Air::NoOp,
|
||||
_ => unreachable!("SHOULD NOT HAVE A HOISTED OVER RESOLVING TO NONE"),
|
||||
},
|
||||
AirTree::Expression(exp) => match exp {
|
||||
AirExpression::Int { value } => air_vec.push(Air::Int {
|
||||
AirExpression::Int { value } => Air::Int {
|
||||
value: value.clone(),
|
||||
}),
|
||||
AirExpression::String { value } => air_vec.push(Air::String {
|
||||
},
|
||||
AirExpression::String { value } => Air::String {
|
||||
value: value.clone(),
|
||||
}),
|
||||
AirExpression::ByteArray { bytes } => air_vec.push(Air::ByteArray {
|
||||
},
|
||||
AirExpression::ByteArray { bytes } => Air::ByteArray {
|
||||
bytes: bytes.clone(),
|
||||
}),
|
||||
AirExpression::Bool { value } => air_vec.push(Air::Bool { value: *value }),
|
||||
},
|
||||
AirExpression::Bool { value } => Air::Bool { value: *value },
|
||||
AirExpression::List { .. } => todo!(),
|
||||
AirExpression::Tuple { .. } => todo!(),
|
||||
AirExpression::Void => todo!(),
|
||||
|
|
Loading…
Reference in New Issue