create struct Air Env

refactor out some to_strings
This commit is contained in:
Kasey White 2023-03-21 16:02:52 -04:00 committed by Lucas
parent 0060d29265
commit 32d34d5fd3
6 changed files with 118 additions and 139 deletions

View File

@ -1,13 +1,11 @@
use std::sync::Arc;
use indexmap::IndexSet;
use uplc::builtins::DefaultFunction;
use crate::{
ast::{BinOp, UnOp},
tipo::{Type, ValueConstructor},
IdGenerator,
};
use indexmap::IndexSet;
use std::sync::Arc;
use uplc::builtins::DefaultFunction;
#[derive(Debug, Clone)]
pub enum Air {
// Primitives
@ -15,53 +13,44 @@ pub enum Air {
scope: Vec<u64>,
value: String,
},
String {
scope: Vec<u64>,
value: String,
},
ByteArray {
scope: Vec<u64>,
bytes: Vec<u8>,
},
Bool {
scope: Vec<u64>,
value: bool,
},
List {
scope: Vec<u64>,
count: usize,
tipo: Arc<Type>,
tail: bool,
},
Tuple {
scope: Vec<u64>,
tipo: Arc<Type>,
count: usize,
},
Void {
scope: Vec<u64>,
},
Var {
scope: Vec<u64>,
constructor: ValueConstructor,
name: String,
variant_name: String,
},
// Functions
Call {
scope: Vec<u64>,
count: usize,
tipo: Arc<Type>,
},
DefineFunc {
scope: Vec<u64>,
func_name: String,
@ -70,19 +59,16 @@ pub enum Air {
recursive: bool,
variant_name: String,
},
Fn {
scope: Vec<u64>,
params: Vec<String>,
},
Builtin {
scope: Vec<u64>,
count: usize,
func: DefaultFunction,
tipo: Arc<Type>,
},
// Operators
BinOp {
scope: Vec<u64>,
@ -90,52 +76,43 @@ pub enum Air {
count: usize,
tipo: Arc<Type>,
},
UnOp {
scope: Vec<u64>,
op: UnOp,
},
// Assignment
Let {
scope: Vec<u64>,
name: String,
},
UnWrapData {
scope: Vec<u64>,
tipo: Arc<Type>,
},
WrapData {
scope: Vec<u64>,
tipo: Arc<Type>,
},
AssertConstr {
scope: Vec<u64>,
constr_index: usize,
},
AssertBool {
scope: Vec<u64>,
is_true: bool,
},
// When
When {
scope: Vec<u64>,
tipo: Arc<Type>,
subject_name: String,
},
Clause {
scope: Vec<u64>,
tipo: Arc<Type>,
subject_name: String,
complex_clause: bool,
},
ListClause {
scope: Vec<u64>,
tipo: Arc<Type>,
@ -143,11 +120,9 @@ pub enum Air {
next_tail_name: Option<String>,
complex_clause: bool,
},
WrapClause {
scope: Vec<u64>,
},
TupleClause {
scope: Vec<u64>,
tipo: Arc<Type>,
@ -157,13 +132,11 @@ pub enum Air {
count: usize,
complex_clause: bool,
},
ClauseGuard {
scope: Vec<u64>,
subject_name: String,
tipo: Arc<Type>,
},
ListClauseGuard {
scope: Vec<u64>,
tipo: Arc<Type>,
@ -171,17 +144,14 @@ pub enum Air {
next_tail_name: Option<String>,
inverse: bool,
},
Finally {
scope: Vec<u64>,
},
// If
If {
scope: Vec<u64>,
tipo: Arc<Type>,
},
// Record Creation
Record {
scope: Vec<u64>,
@ -189,27 +159,23 @@ pub enum Air {
tipo: Arc<Type>,
count: usize,
},
RecordUpdate {
scope: Vec<u64>,
highest_index: usize,
indices: Vec<(usize, Arc<Type>)>,
tipo: Arc<Type>,
},
// Field Access
RecordAccess {
scope: Vec<u64>,
record_index: u64,
tipo: Arc<Type>,
},
FieldsExpose {
scope: Vec<u64>,
indices: Vec<(usize, String, Arc<Type>)>,
check_last_item: bool,
},
// ListAccess
ListAccessor {
scope: Vec<u64>,
@ -218,14 +184,12 @@ pub enum Air {
tail: bool,
check_last_item: bool,
},
ListExpose {
scope: Vec<u64>,
tipo: Arc<Type>,
tail_head_names: Vec<(String, String)>,
tail: Option<(String, String)>,
},
// Tuple Access
TupleAccessor {
scope: Vec<u64>,
@ -233,19 +197,16 @@ pub enum Air {
tipo: Arc<Type>,
check_last_item: bool,
},
TupleIndex {
scope: Vec<u64>,
tipo: Arc<Type>,
tuple_index: usize,
},
// Misc.
ErrorTerm {
scope: Vec<u64>,
tipo: Arc<Type>,
},
Trace {
scope: Vec<u64>,
tipo: Arc<Type>,
@ -295,7 +256,6 @@ impl Air {
| Air::Trace { scope, .. } => scope.clone(),
}
}
pub fn scope_mut(&mut self) -> &mut Vec<u64> {
match self {
Air::Int { scope, .. }
@ -338,7 +298,6 @@ impl Air {
| Air::Trace { scope, .. } => scope,
}
}
pub fn tipo(&self) -> Option<Arc<Type>> {
match self {
Air::Int { .. } => Some(
@ -418,7 +377,6 @@ impl Air {
| Air::TupleIndex { tipo, .. }
| Air::ErrorTerm { tipo, .. }
| Air::Trace { tipo, .. } => Some(tipo.clone()),
Air::DefineFunc { .. }
| Air::Fn { .. }
| Air::Let { .. }
@ -427,7 +385,6 @@ impl Air {
| Air::AssertBool { .. }
| Air::Finally { .. }
| Air::FieldsExpose { .. } => None,
Air::UnOp { op, .. } => match op {
UnOp::Not => Some(
Type::App {
@ -451,3 +408,55 @@ impl Air {
}
}
}
pub struct AirEnv<'a> {
pub id_gen: &'a mut IdGenerator,
pub scope: Vec<u64>,
pub air: Vec<Air>,
}
impl<'a> AirEnv<'a> {
pub fn new(id_gen: &'a mut IdGenerator) -> Self {
AirEnv {
id_gen,
scope: vec![0],
air: vec![],
}
}
pub fn new_with_scope(id_gen: &'a mut IdGenerator, scope: Vec<u64>) -> Self {
AirEnv {
id_gen,
scope,
air: vec![],
}
}
pub fn int(mut self, value: String) -> Self {
self.air.push(Air::Int {
scope: self.scope.clone(),
value,
});
self
}
pub fn string(mut self, value: String) -> Self {
self.air.push(Air::String {
scope: self.scope.clone(),
value,
});
self
}
pub fn byte_array(mut self, bytes: Vec<u8>) -> Self {
self.air.push(Air::ByteArray {
scope: self.scope.clone(),
bytes,
});
self
}
// pub fn sequence(mut self, expressions: AirEnv) -> Self{
// }
}

View File

@ -208,14 +208,14 @@ pub fn convert_type_to_data(term: Term<Name>, field_type: &Arc<Type>) -> Term<Na
Term::list_data()
.apply(
Term::mk_cons()
.apply(Term::fst_pair().apply(Term::var("__pair".to_string())))
.apply(Term::fst_pair().apply(Term::var("__pair")))
.apply(
Term::mk_cons()
.apply(Term::snd_pair().apply(Term::var("__pair".to_string())))
.apply(Term::snd_pair().apply(Term::var("__pair")))
.apply(Term::empty_list()),
),
)
.lambda("__pair".to_string())
.lambda("__pair")
.apply(term)
} else if field_type.is_list() || field_type.is_tuple() {
Term::list_data().apply(term)
@ -260,8 +260,8 @@ pub fn convert_data_to_type(term: Term<Name>, field_type: &Arc<Type>) -> Term<Na
} else if field_type.is_tuple() && matches!(field_type.get_uplc_type(), UplcType::Pair(_, _)) {
Term::mk_pair_data()
.apply(Term::head_list().apply(Term::var("__list_data")))
.apply(Term::head_list().apply(Term::var("__tail".to_string())))
.lambda("__tail".to_string())
.apply(Term::head_list().apply(Term::var("__tail")))
.lambda("__tail")
.apply(Term::tail_list().apply(Term::var("__list_data")))
.lambda("__list_data")
.apply(Term::unlist_data().apply(term))
@ -470,7 +470,7 @@ pub fn list_access_to_uplc(
if names.len() == 1 && tail {
if first == "_" && names[0] == "_" {
term.lambda("_".to_string())
term.lambda("_")
} else if first == "_" {
term.lambda(names[0].clone())
.apply(Term::tail_list().apply(Term::var(format!(
@ -580,7 +580,7 @@ pub fn list_access_to_uplc(
match &list_access_inner {
Term::Lambda { .. } => list_access_inner,
_ => list_access_inner.lambda("_".to_string()),
_ => list_access_inner.lambda("_"),
}
} else {
let mut list_access_inner = list_access_to_uplc(
@ -978,14 +978,14 @@ pub fn wrap_validator_args(term: Term<Name>, arguments: &[TypedArg]) -> Term<Nam
for arg in arguments.iter().rev() {
if !matches!(arg.tipo.get_uplc_type(), UplcType::Data) {
term = term
.lambda(arg.arg_name.get_variable_name().unwrap_or("_").to_string())
.lambda(arg.arg_name.get_variable_name().unwrap_or("_"))
.apply(convert_data_to_type(
Term::var(arg.arg_name.get_variable_name().unwrap_or("_").to_string()),
Term::var(arg.arg_name.get_variable_name().unwrap_or("_")),
&arg.tipo,
));
}
term = term.lambda(arg.arg_name.get_variable_name().unwrap_or("_").to_string())
term = term.lambda(arg.arg_name.get_variable_name().unwrap_or("_"))
}
term
}

View File

@ -4615,7 +4615,7 @@ impl<'a> CodeGenerator<'a> {
term = Term::equals_integer()
.apply(Term::integer(constr_index.into()))
.apply(Term::var(CONSTR_INDEX_EXPOSER.to_string()).apply(constr))
.apply(Term::var(CONSTR_INDEX_EXPOSER).apply(constr))
.delayed_if_else(term, error_term);
arg_stack.push(term);
@ -4675,7 +4675,7 @@ impl<'a> CodeGenerator<'a> {
if tipo.is_bool() {
let other_clauses = if complex_clause {
Term::var("__other_clauses_delayed".to_string())
Term::var("__other_clauses_delayed")
} else {
term.clone()
};
@ -4692,9 +4692,7 @@ impl<'a> CodeGenerator<'a> {
}
if complex_clause {
term = body
.lambda("__other_clauses_delayed".to_string())
.apply(term.delay());
term = body.lambda("__other_clauses_delayed").apply(term.delay());
}
} else {
let condition = if tipo.is_int() {
@ -4719,12 +4717,9 @@ impl<'a> CodeGenerator<'a> {
if complex_clause {
term = condition
.if_else(
body.delay(),
Term::var("__other_clauses_delayed".to_string()),
)
.if_else(body.delay(), Term::var("__other_clauses_delayed"))
.force()
.lambda("__other_clauses_delayed".to_string())
.lambda("__other_clauses_delayed")
.apply(term.delay());
} else {
term = condition.delayed_if_else(body, term);
@ -4754,12 +4749,9 @@ impl<'a> CodeGenerator<'a> {
if complex_clause {
term = Term::var(tail_name)
.choose_list(
body.delay(),
Term::var("__other_clauses_delayed".to_string()),
)
.choose_list(body.delay(), Term::var("__other_clauses_delayed"))
.force()
.lambda("__other_clauses_delayed".to_string())
.lambda("__other_clauses_delayed")
.apply(arg.delay());
} else {
term = Term::var(tail_name).delayed_choose_list(body, arg);
@ -4773,9 +4765,7 @@ impl<'a> CodeGenerator<'a> {
let mut term = arg_stack.pop().unwrap();
let arg = arg_stack.pop().unwrap();
term = term
.lambda("__other_clauses_delayed".to_string())
.apply(arg.delay());
term = term.lambda("__other_clauses_delayed").apply(arg.delay());
arg_stack.push(term);
}
@ -4787,7 +4777,7 @@ impl<'a> CodeGenerator<'a> {
let then = arg_stack.pop().unwrap();
if tipo.is_bool() {
let mut term = Term::var("__other_clauses_delayed".to_string());
let mut term = Term::var("__other_clauses_delayed");
if matches!(checker, Term::Constant(boolean) if matches!(boolean.as_ref(), UplcConstant::Bool(true)))
{
term = Term::var(subject_name).if_else(then.delay(), term).force();
@ -4817,10 +4807,7 @@ impl<'a> CodeGenerator<'a> {
};
let term = condition
.if_else(
then.delay(),
Term::var("__other_clauses_delayed".to_string()),
)
.if_else(then.delay(), Term::var("__other_clauses_delayed"))
.force();
arg_stack.push(term);
}
@ -4847,17 +4834,11 @@ impl<'a> CodeGenerator<'a> {
if !inverse {
term = Term::var(tail_name)
.choose_list(
term.delay(),
Term::var("__other_clauses_delayed".to_string()),
)
.choose_list(term.delay(), Term::var("__other_clauses_delayed"))
.force();
} else {
term = Term::var(tail_name)
.choose_list(
Term::var("__other_clauses_delayed".to_string()),
term.delay(),
)
.choose_list(Term::var("__other_clauses_delayed"), term.delay())
.force();
}
@ -4925,8 +4906,8 @@ impl<'a> CodeGenerator<'a> {
self.needs_field_access = true;
let constr = arg_stack.pop().unwrap();
let mut term = Term::var(CONSTR_GET_FIELD.to_string())
.apply(Term::var(CONSTR_FIELDS_EXPOSER.to_string()).apply(constr))
let mut term = Term::var(CONSTR_GET_FIELD)
.apply(Term::var(CONSTR_FIELDS_EXPOSER).apply(constr))
.apply(Term::integer(record_index.into()));
term = convert_data_to_type(term, &tipo);
@ -4970,7 +4951,7 @@ impl<'a> CodeGenerator<'a> {
term
};
term = term.apply(Term::var(CONSTR_FIELDS_EXPOSER.to_string()).apply(value));
term = term.apply(Term::var(CONSTR_FIELDS_EXPOSER).apply(value));
arg_stack.push(term);
}
@ -5032,7 +5013,7 @@ impl<'a> CodeGenerator<'a> {
..
} => {
self.needs_field_access = true;
let tail_name_prefix = "__tail_index".to_string();
let tail_name_prefix = "__tail_index";
let record = arg_stack.pop().unwrap();
@ -5108,7 +5089,7 @@ impl<'a> CodeGenerator<'a> {
term = term
.lambda(prev_tail_name)
.apply(Term::var(CONSTR_FIELDS_EXPOSER.to_string()).apply(record));
.apply(Term::var(CONSTR_FIELDS_EXPOSER).apply(record));
arg_stack.push(term);
}
@ -5144,7 +5125,7 @@ impl<'a> CodeGenerator<'a> {
} else {
self.needs_field_access = true;
term = convert_data_to_type(
Term::var(CONSTR_GET_FIELD.to_string())
Term::var(CONSTR_GET_FIELD)
.apply(term)
.apply(Term::integer(tuple_index.into())),
&tipo.get_inner_types()[tuple_index],
@ -5226,7 +5207,7 @@ impl<'a> CodeGenerator<'a> {
let next_clause = arg_stack.pop().unwrap();
term = term
.lambda("__other_clauses_delayed".to_string())
.lambda("__other_clauses_delayed")
.apply(next_clause.delay());
}

View File

@ -45,3 +45,36 @@ test foo_4() {
False
}
}
// type Seasons {
// Winter
// Spring
// Summer
// Fall
// }
// fn is_cold(season, hour) {
// when season is {
// Winter | Fall ->
// True
// _ if hour >= 18 ->
// True
// _ ->
// False
// }
// }
// test foo_5() {
// !is_cold(Spring, 15) && is_cold(Summer, 22)
// }
fn when_tuple(a: (Int, Int)) -> Int {
when a is {
(a, _b) ->
a
}
}
test spend() {
when_tuple((4, 1)) == 4
}

View File

@ -1,32 +0,0 @@
{
"preamble": {
"title": "aiken-lang/acceptance_test_048",
"version": "0.0.0",
"plutusVersion": "v2"
},
"validators": [
{
"title": "foo.spend",
"datum": {
"title": "a",
"schema": {
"$ref": "#/definitions/Data"
}
},
"redeemer": {
"title": "b",
"schema": {
"$ref": "#/definitions/Data"
}
},
"compiledCode": "586001000032323232323232323222253330063370e6464640046eb4c02c008dd69804800a5ef6c6010104000101010048020526163001001222533300800214984cc014c004c024008ccc00c00cc0280080055cd2b9b5573aaae7955cfaba157441",
"hash": "7ecbfc3ae91c4d5ba3799b4d283e385d457c860cd22034d825379ae2"
}
],
"definitions": {
"Data": {
"title": "Data",
"description": "Any Plutus data."
}
}
}

View File

@ -1,12 +0,0 @@
fn when_tuple(a: (Int, Int)) -> Int {
when a is {
(a, b) ->
a
}
}
validator {
fn spend(a: Data, b: Data, c) -> Bool {
when_tuple((4, 1)) == 4
}
}