starting on field access in aiken

This commit is contained in:
Kasey White 2022-11-03 21:43:12 -04:00 committed by Lucas
parent 3cafb2bcbe
commit ad4a5e927d
3 changed files with 114 additions and 77 deletions

View File

@ -1,4 +1,4 @@
use std::{collections::HashMap, rc::Rc, sync::Arc}; use std::{collections::HashMap, fmt::format, rc::Rc, sync::Arc};
use uplc::{ use uplc::{
ast::{Constant, Name, Program, Term, Unique}, ast::{Constant, Name, Program, Term, Unique},
@ -242,49 +242,46 @@ impl<'a> CodeGenerator<'a> {
self.recurse_scope_level(&branch.body, scope_level.scope_increment_sequence(1)); self.recurse_scope_level(&branch.body, scope_level.scope_increment_sequence(1));
} }
} }
a @ TypedExpr::RecordAccess { a @ TypedExpr::RecordAccess { label, record, .. } => match &**record {
tipo, TypedExpr::Var {
label, constructor, name, ..
index, } => match (constructor.variant.clone(), (*constructor.tipo).clone()) {
record, (ValueConstructorVariant::LocalVariable { .. }, Type::App { module, .. }) => {
.. if let Some(val) = self.uplc_data_holder_lookup.get(&(
} => { module.clone(),
println!("tipo {tipo:#?}"); name.clone(),
println!("label {label:#?}"); label.clone(),
println!("index {index:#?}"); )) {
println!("record {record:#?}"); if scope_level.is_less_than(&val.0) {
match &**record {
TypedExpr::Var { constructor, .. } => {
match (constructor.variant.clone(), (*constructor.tipo).clone()) {
(
ValueConstructorVariant::LocalVariable { .. },
Type::App { module, name, .. },
) => {
self.uplc_data_holder_lookup.insert( self.uplc_data_holder_lookup.insert(
(module.clone(), name.clone(), label.to_string()), (module.clone(), name.clone(), label.clone()),
(scope_level.clone(), a.clone()), (scope_level.clone(), a.clone()),
); );
if let Some(val) = self
.uplc_data_usage_holder_lookup
.get(&(module.clone(), name.clone()))
{
if scope_level.is_less_than(val) {
self.uplc_data_usage_holder_lookup
.insert((module, name), scope_level);
}
} else {
self.uplc_data_usage_holder_lookup
.insert((module, name), scope_level);
}
} }
_ => todo!(), } else {
self.uplc_data_holder_lookup.insert(
(module.clone(), name.clone(), label.clone()),
(scope_level.clone(), a.clone()),
);
}
if let Some(val) = self
.uplc_data_usage_holder_lookup
.get(&(module.clone(), name.clone()))
{
if scope_level.is_less_than(val) {
self.uplc_data_usage_holder_lookup
.insert((module, name.clone()), scope_level);
}
} else {
self.uplc_data_usage_holder_lookup
.insert((module, name.clone()), scope_level);
} }
} }
_ => todo!(), _ => todo!(),
} },
} _ => todo!(),
},
a @ TypedExpr::ModuleSelect { a @ TypedExpr::ModuleSelect {
location, location,
tipo, tipo,
@ -392,7 +389,7 @@ impl<'a> CodeGenerator<'a> {
tipo, tipo,
} => { } => {
self.recurse_scope_level(value, scope_level); self.recurse_scope_level(value, scope_level);
todo!()
} }
} }
} }
@ -414,8 +411,8 @@ impl<'a> CodeGenerator<'a> {
let mut term = self let mut term = self
.recurse_code_gen(exp, scope_level.scope_increment_sequence(i as i32 + 1)); .recurse_code_gen(exp, scope_level.scope_increment_sequence(i as i32 + 1));
term = self term =
.maybe_insert_def(term, scope_level.scope_increment_sequence(i as i32 + 1)); self.maybe_insert_def(term, scope_level.scope_increment_sequence(i as i32));
self.uplc_function_holder self.uplc_function_holder
.push(("".to_string(), term.clone())); .push(("".to_string(), term.clone()));
@ -713,18 +710,17 @@ impl<'a> CodeGenerator<'a> {
index, index,
record, record,
} => match &**record { } => match &**record {
TypedExpr::Var { constructor, .. } => { TypedExpr::Var {
match (constructor.variant.clone(), (*constructor.tipo).clone()) { constructor, name, ..
( } => match (constructor.variant.clone(), (*constructor.tipo).clone()) {
ValueConstructorVariant::LocalVariable { .. }, (ValueConstructorVariant::LocalVariable { .. }, Type::App { module, .. }) => {
Type::App { module, name, .. }, Term::Var(Name {
) => Term::Var(Name { text: format!("{name}_field_{label}"),
text: format!("{module}_{name}.{label}"),
unique: 0.into(), unique: 0.into(),
}), })
_ => todo!(),
} }
} _ => todo!(),
},
_ => todo!(), _ => todo!(),
}, },
TypedExpr::ModuleSelect { TypedExpr::ModuleSelect {
@ -817,18 +813,65 @@ impl<'a> CodeGenerator<'a> {
} }
} }
for record_scope in self.uplc_data_usage_holder_lookup.keys() { for (key, (record_scope_level, expr)) in self.uplc_data_holder_lookup.clone().iter() {
if scope_level.is_less_than( if scope_level.is_less_than(record_scope_level) {
self.uplc_data_usage_holder_lookup let local_var_name = &key.1;
.get(record_scope) let field = &key.2;
.unwrap(), term = Term::Apply {
) { function: Term::Lambda {
for record in self.uplc_data_holder_lookup.keys() { parameter_name: Name {
if &(record.0.clone(), record.1.clone()) == record_scope { text: format!("{local_var_name}_field_{field}"),
let dt = self.data_types.get(record_scope).unwrap(); unique: 0.into(),
println!("DATA TYPE IS {dt:#?}") },
body: term.into(),
} }
} .into(),
argument: Term::Apply {
function: Term::Var(Name {
text: "constr_field_get_arg".to_string(),
unique: 0.into(),
})
.into(),
argument: Term::Var(Name {
text: format!("{local_var_name}_fields"),
unique: 0.into(),
})
.into(),
}
.into(),
};
self.uplc_data_holder_lookup.remove(key);
}
}
for (key, record_fields_scope) in self.uplc_data_usage_holder_lookup.clone().iter() {
if scope_level.is_less_than(record_fields_scope) {
let local_var_name = &key.1;
term = Term::Apply {
function: Term::Lambda {
parameter_name: Name {
text: format!("{local_var_name}_fields"),
unique: 0.into(),
},
body: term.into(),
}
.into(),
// TODO: Find proper scope for this function if at all.
argument: Term::Apply {
function: Term::Var(Name {
text: "constr_field_exposer".to_string(),
unique: 0.into(),
})
.into(),
argument: Term::Var(Name {
text: local_var_name.to_string(),
unique: 0.into(),
})
.into(),
}
.into(),
};
self.uplc_data_usage_holder_lookup.remove(key);
} }
} }

View File

@ -1,19 +1,17 @@
pub type ScriptContext { pub type ScriptContext {
thing: String thing: ByteArray
} }
pub type Datum { pub type Datum {
Datum2{ something: ByteArray,
something: String, fin: Int
fin: Int
}
None{}
} }
pub fn eqInt(a: Int, b: Int) { pub fn eqInt(a: Int, b: Int) {
a == b a == b
} }
pub fn eqString(a: String, b: String) { pub fn eqString(a: ByteArray, b: ByteArray) {
a == b a == b
} }

View File

@ -9,15 +9,11 @@ pub type Redeemer {
pub fn spend(datum: sample.Datum, rdmr: Redeemer, ctx: spend.ScriptContext) -> Bool { pub fn spend(datum: sample.Datum, rdmr: Redeemer, ctx: spend.ScriptContext) -> Bool {
let dat = sample.Datum{..}
let y = 2
let x = 1 let x = 1
let a = when datum is { let a = datum.something
sample.Datum2(first, rest) -> rest let e = dat.something
sample.None -> 0 let b = 2
}
let b = x
b == 1 b == 1
} }