did hacky way for scope level, but now i know how it works and how to fix

This commit is contained in:
Kasey White 2022-10-29 04:02:44 -04:00 committed by Lucas
parent f7276df355
commit f6a72cc7f9
4 changed files with 390 additions and 298 deletions

View File

@ -370,6 +370,20 @@ impl Project {
let mut lookup_map = HashMap::new();
self.recurse_scope_level(
body,
scripts,
0,
&mut lookup_map,
&functions,
&type_aliases,
&data_types,
&imports,
&constants,
);
println!("Look up map is {:#?}", lookup_map);
let mut term = self.recurse_code_gen(
body,
scripts,
@ -417,195 +431,295 @@ impl Project {
Ok(programs)
}
// fn recurse_simplifier(
// &self,
// body: &TypedExpr,
// scripts: &[CheckedModule],
// scope_level: i32,
// lookup_map: &mut HashMap<_, _>,
// functions: &HashMap<
// (String, String),
// &Function<std::sync::Arc<aiken_lang::tipo::Type>, TypedExpr>,
// >,
// type_aliases: &HashMap<
// (String, String),
// &aiken_lang::ast::TypeAlias<std::sync::Arc<aiken_lang::tipo::Type>>,
// >,
// data_types: &HashMap<
// (String, String),
// &aiken_lang::ast::DataType<std::sync::Arc<aiken_lang::tipo::Type>>,
// >,
// imports: &HashMap<(String, String), &aiken_lang::ast::Use<String>>,
// constants: &HashMap<
// (String, String),
// &aiken_lang::ast::ModuleConstant<std::sync::Arc<aiken_lang::tipo::Type>, String>,
// >,
// ) {
// match body {
// TypedExpr::Int {
// location,
// tipo,
// value,
// } => {}
// TypedExpr::String {
// location,
// tipo,
// value,
// } => {}
// TypedExpr::ByteArray {
// location,
// tipo,
// bytes,
// } => {}
// TypedExpr::Sequence {
// location,
// expressions,
// } => {
// for expression in expressions {
// self.recurse_simplifier(
// expression,
// scripts,
// scope_level,
// lookup_map,
// functions,
// type_aliases,
// data_types,
// imports,
// constants,
// );
// }
// }
// TypedExpr::Pipeline {
// location,
// expressions,
// } => {
// for expression in expressions {
// self.recurse_simplifier(
// expression,
// scripts,
// scope_level,
// lookup_map,
// functions,
// type_aliases,
// data_types,
// imports,
// constants,
// );
// }
// }
// TypedExpr::Var {
// location,
// constructor,
// name,
// } => match constructor.variant {
// aiken_lang::tipo::ValueConstructorVariant::LocalVariable { location } => {}
// aiken_lang::tipo::ValueConstructorVariant::ModuleConstant {
// location,
// module,
// literal,
// } => {}
// aiken_lang::tipo::ValueConstructorVariant::ModuleFn {
// name,
// field_map,
// module,
// arity,
// location,
// builtin,
// } => {
pub(crate) fn recurse_scope_level(
&self,
body: &TypedExpr,
scripts: &[CheckedModule],
scope_level: i32,
uplc_function_holder_lookup: &mut HashMap<(String, String), (i32, TypedExpr)>,
functions: &HashMap<(String, String), &Function<std::sync::Arc<tipo::Type>, TypedExpr>>,
type_aliases: &HashMap<(String, String), &ast::TypeAlias<std::sync::Arc<tipo::Type>>>,
data_types: &HashMap<(String, String), &ast::DataType<std::sync::Arc<tipo::Type>>>,
imports: &HashMap<(String, String), &ast::Use<String>>,
constants: &HashMap<
(String, String),
&ast::ModuleConstant<std::sync::Arc<tipo::Type>, String>,
>,
) {
match dbg!(body) {
TypedExpr::Int { value, .. } => {}
TypedExpr::String { value, .. } => {}
TypedExpr::ByteArray { bytes, .. } => {}
TypedExpr::Sequence {
location,
expressions,
} => {
// let mut terms = Vec::new();
for (i, exp) in expressions.iter().enumerate().rev() {
self.recurse_scope_level(
exp,
scripts,
scope_level + i as i32 * 100 + 1,
uplc_function_holder_lookup,
functions,
type_aliases,
data_types,
imports,
constants,
);
}
}
TypedExpr::Pipeline {
location,
expressions,
} => todo!(),
TypedExpr::Var {
location,
constructor,
name,
} => {}
TypedExpr::Fn {
location,
tipo,
is_capture,
args,
body,
return_annotation,
} => todo!(),
TypedExpr::List {
location,
tipo,
elements,
tail,
} => todo!(),
TypedExpr::Call {
location,
tipo,
fun,
args,
} => {
let mut term = self.recurse_scope_level(
fun,
scripts,
scope_level + args.len() as i32,
uplc_function_holder_lookup,
functions,
type_aliases,
data_types,
imports,
constants,
);
// self.recurse_simplifier(&functions.get(&(module, name)).unwrap().body, scripts, scope_level, lookup_map, functions, type_aliases, data_types, imports, constants)
// }
// aiken_lang::tipo::ValueConstructorVariant::Record {
// name,
// arity,
// field_map,
// location,
// module,
// constructors_count,
// } => todo!(),
// },
// TypedExpr::Fn {
// location,
// tipo,
// is_capture,
// args,
// body,
// return_annotation,
// } => todo!(),
// TypedExpr::List {
// location,
// tipo,
// elements,
// tail,
// } => todo!(),
// TypedExpr::Call {
// location,
// tipo,
// fun,
// args,
// } => todo!(),
// TypedExpr::BinOp {
// location,
// tipo,
// name,
// left,
// right,
// } => todo!(),
// TypedExpr::Assignment {
// location,
// tipo,
// value,
// pattern,
// kind,
// } => todo!(),
// TypedExpr::Try {
// location,
// tipo,
// value,
// then,
// pattern,
// } => todo!(),
// TypedExpr::When {
// location,
// tipo,
// subjects,
// clauses,
// } => todo!(),
// TypedExpr::If {
// location,
// branches,
// final_else,
// tipo,
// } => todo!(),
// TypedExpr::RecordAccess {
// location,
// tipo,
// label,
// index,
// record,
// } => todo!(),
// TypedExpr::ModuleSelect {
// location,
// tipo,
// label,
// module_name,
// module_alias,
// constructor,
// } => todo!(),
// TypedExpr::Todo {
// location,
// label,
// tipo,
// } => todo!(),
// TypedExpr::RecordUpdate {
// location,
// tipo,
// spread,
// args,
// } => todo!(),
// TypedExpr::Negate { location, value } => todo!(),
// }
// }
for (i, arg) in args.iter().enumerate() {
self.recurse_scope_level(
&arg.value,
scripts,
scope_level + i as i32,
uplc_function_holder_lookup,
functions,
type_aliases,
data_types,
imports,
constants,
);
}
}
TypedExpr::BinOp {
location,
tipo,
name,
left,
right,
} => {
todo!()
}
TypedExpr::Assignment {
location,
tipo,
value,
pattern,
kind,
} => match pattern {
ast::Pattern::Int { location, value } => todo!(),
ast::Pattern::String { location, value } => todo!(),
ast::Pattern::Var { location, name } => {
self.recurse_scope_level(
value,
scripts,
scope_level + 1,
uplc_function_holder_lookup,
functions,
type_aliases,
data_types,
imports,
constants,
);
}
ast::Pattern::VarUsage {
location,
name,
tipo,
} => todo!(),
ast::Pattern::Assign {
name,
location,
pattern,
} => todo!(),
ast::Pattern::Discard { name, location } => todo!(),
ast::Pattern::List {
location,
elements,
tail,
} => todo!(),
ast::Pattern::Constructor {
location,
name,
arguments,
module,
constructor,
with_spread,
tipo,
} => todo!(),
},
TypedExpr::Try {
location,
tipo,
value,
then,
pattern,
} => todo!(),
TypedExpr::When {
location,
tipo,
subjects,
clauses,
} => todo!(),
//if statements increase scope due to branching.
TypedExpr::If {
branches,
final_else,
..
} => {
let mut final_if_term = self.recurse_scope_level(
final_else,
scripts,
scope_level + 1,
uplc_function_holder_lookup,
functions,
type_aliases,
data_types,
imports,
constants,
);
for branch in branches {
// Need some scoping count to potentially replace condition with var since we should assume a condition
// may be repeated 3 + times or be large enough series of binops to warrant var replacement
let condition_term = self.recurse_scope_level(
&branch.condition,
scripts,
scope_level + 1, // Since this happens before branching. Maybe not increase scope level
uplc_function_holder_lookup,
functions,
type_aliases,
data_types,
imports,
constants,
);
let branch_term = self.recurse_scope_level(
&branch.body,
scripts,
scope_level + 1,
uplc_function_holder_lookup,
functions,
type_aliases,
data_types,
imports,
constants,
);
}
}
TypedExpr::RecordAccess {
location,
tipo,
label,
index,
record,
} => todo!(),
a @ TypedExpr::ModuleSelect {
location,
tipo,
label,
module_name,
module_alias,
constructor,
} => match constructor {
ModuleValueConstructor::Record {
name,
arity,
tipo,
field_map,
location,
} => todo!(),
ModuleValueConstructor::Fn {
location,
module,
name,
} => {
if !uplc_function_holder_lookup
.contains_key(&(module.to_string(), name.to_string()))
{
let func_def = functions
.get(&(module.to_string(), name.to_string()))
.unwrap();
let mut term = self.recurse_scope_level(
&func_def.body,
scripts,
scope_level + func_def.arguments.len() as i32,
uplc_function_holder_lookup,
functions,
type_aliases,
data_types,
imports,
constants,
);
uplc_function_holder_lookup.insert(
(module.to_string(), name.to_string()),
(scope_level, a.clone()),
);
}
if uplc_function_holder_lookup
.get(&(module.to_string(), name.to_string()))
.unwrap()
.0
> scope_level
{
uplc_function_holder_lookup.insert(
(module.to_string(), name.to_string()),
(scope_level, a.clone()),
);
}
}
ModuleValueConstructor::Constant { literal, location } => todo!(),
},
TypedExpr::Todo {
location,
label,
tipo,
} => todo!(),
TypedExpr::RecordUpdate {
location,
tipo,
spread,
args,
} => todo!(),
TypedExpr::Negate { location, value } => todo!(),
}
}
fn recurse_code_gen(
&self,
@ -613,10 +727,10 @@ impl Project {
scripts: &[CheckedModule],
scope_level: i32,
uplc_function_holder: &mut Vec<(String, Term<Name>)>,
uplc_function_holder_lookup: &mut HashMap<(String, String), i32>,
uplc_function_holder_lookup: &mut HashMap<(String, String), (i32, TypedExpr)>,
functions: &HashMap<
(String, String),
&Function<std::sync::Arc<aiken_lang::tipo::Type>, aiken_lang::expr::TypedExpr>,
&Function<std::sync::Arc<aiken_lang::tipo::Type>, TypedExpr>,
>,
type_aliases: &HashMap<
(String, String),
@ -644,18 +758,17 @@ impl Project {
location,
expressions,
} => {
// let mut terms = Vec::new();
for (i, exp) in expressions.iter().enumerate().rev() {
println!(
"The index is {} and the scope level is {} and next scope is {}",
i,
scope_level,
scope_level + i as i32 + 1
scope_level + i as i32 * 100 + 1,
);
let mut term = self.recurse_code_gen(
exp,
scripts,
scope_level + i as i32 + 1,
scope_level + i as i32 * 100 + 1,
uplc_function_holder,
uplc_function_holder_lookup,
functions,
@ -665,50 +778,57 @@ impl Project {
constants,
);
let mut above_scope = Vec::new();
for func in uplc_function_holder.clone() {
let mut split_name = func.0.split('_');
let mut split_name2 = func.0.split('_');
println!("This is scope level {}", scope_level + i as i32 + 1);
println!(
"This is uplc_function_holder_lookup scope {} and func is {}",
uplc_function_holder_lookup
.get(&(
split_name2.next().unwrap().to_string(),
split_name2.next().unwrap().to_string(),
))
.unwrap(),
func.0
);
if uplc_function_holder_lookup
.get(&(
split_name.next().unwrap().to_string(),
split_name.next().unwrap().to_string(),
))
.unwrap()
< &(scope_level + i as i32 + 1)
for func in uplc_function_holder_lookup.clone().keys() {
if uplc_function_holder_lookup.clone().get(func).unwrap().0
> scope_level + i as i32 * 100
{
println!("Scope level -1 is {}", scope_level + i as i32);
let func_def = functions
.get(&(func.0.to_string(), func.1.to_string()))
.unwrap();
let mut function_body = self.recurse_code_gen(
&func_def.body,
scripts,
scope_level + func_def.arguments.len() as i32,
uplc_function_holder,
uplc_function_holder_lookup,
functions,
type_aliases,
data_types,
imports,
constants,
);
for arg in func_def.arguments.iter().rev() {
function_body = Term::Lambda {
parameter_name: Name {
text: arg
.arg_name
.get_variable_name()
.unwrap_or("_")
.to_string(),
unique: Unique::new(0),
},
body: Rc::new(function_body),
}
}
term = Term::Apply {
function: Term::Lambda {
parameter_name: Name {
text: func.0.clone(),
text: format!("{}_{}", func.0, func.1),
unique: 0.into(),
},
body: term.into(),
}
.into(),
argument: func.1.clone().into(),
argument: function_body.into(),
};
} else {
above_scope.push(func);
uplc_function_holder_lookup.remove(func);
}
uplc_function_holder.drain(0..);
uplc_function_holder.append(&mut above_scope);
}
uplc_function_holder.push(("".to_string(), term.clone()));
}
@ -777,7 +897,11 @@ impl Project {
fun,
args,
} => {
println!("Scope is {} and Scope with args is {}", scope_level, scope_level + args.len() as i32);
println!(
"Scope is {} and Scope with args is {}",
scope_level,
scope_level + args.len() as i32
);
let mut term = self.recurse_code_gen(
fun,
scripts,
@ -846,13 +970,14 @@ impl Project {
ast::Pattern::Int { location, value } => todo!(),
ast::Pattern::String { location, value } => todo!(),
ast::Pattern::Var { location, name } => Term::Apply {
function: Rc::new(Term::Lambda {
function: Term::Lambda {
parameter_name: Name {
text: name.to_string(),
unique: 0.into(),
},
body: uplc_function_holder.pop().unwrap().1.into(),
}),
}
.into(),
argument: self
.recurse_code_gen(
value,
@ -868,6 +993,7 @@ impl Project {
)
.into(),
},
ast::Pattern::VarUsage {
location,
name,
@ -998,66 +1124,10 @@ impl Project {
location,
module,
name,
} => {
if !uplc_function_holder_lookup
.contains_key(&(module.to_string(), name.to_string()))
{
let func_def = functions
.get(&(module.to_string(), name.to_string()))
.unwrap();
let mut term = self.recurse_code_gen(
&func_def.body,
scripts,
scope_level + func_def.arguments.len() as i32,
uplc_function_holder,
uplc_function_holder_lookup,
functions,
type_aliases,
data_types,
imports,
constants,
);
for arg in func_def.arguments.iter().rev() {
term = Term::Lambda {
parameter_name: Name {
text: arg
.arg_name
.get_variable_name()
.unwrap_or("_")
.to_string(),
unique: Unique::new(0),
},
body: Rc::new(term),
}
}
uplc_function_holder.push((format!("{module}_{name}"), term));
uplc_function_holder_lookup
.insert((module.to_string(), name.to_string()), scope_level);
}
if uplc_function_holder_lookup
.get(&(module.to_string(), name.to_string()))
.unwrap()
> &scope_level
{
println!(
"This is scope level in module select {} and func is {}_{}",
scope_level,
module.to_string(),
name.to_string()
);
uplc_function_holder_lookup
.insert((module.to_string(), name.to_string()), scope_level);
}
Term::Var(Name {
text: format!("{module}_{name}"),
unique: 0.into(),
})
}
} => Term::Var(Name {
text: format!("{module}_{name}"),
unique: 0.into(),
}),
ModuleValueConstructor::Constant { literal, location } => todo!(),
},
TypedExpr::Todo {

View File

@ -6,6 +6,7 @@ pub type Datum {
something: String,
}
pub fn thing(a: Datum, b){
a.something == b
pub fn thing(a: Bool) {
a
}

View File

@ -7,12 +7,11 @@ pub type Redeemer {
Sell(Int)
}
pub fn spend(datum: Datum, rdmr: Redeemer, ctx: spend.ScriptContext) -> Bool {
if datum.something == "Aiken" {
True
} else if datum.something == "Wow" {
True
} else {
False
}
pub fn spend(datum: sample.Datum, rdmr: Redeemer, ctx: spend.ScriptContext) -> Bool {
let a = True
let b = sample.thing(a)
let c = sample.thing(b)
c
}

22
thing.uplc Normal file
View File

@ -0,0 +1,22 @@
(program
1.0.0
(lam
datum
(lam
rdmr
(lam
ctx
[
(lam
a
[
(lam b [ [ (lam sample_thing sample_thing) (lam a a) ] a ])
(con bool False)
]
)
(con bool True)
]
)
)
)
)