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(); 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( let mut term = self.recurse_code_gen(
body, body,
scripts, scripts,
@ -417,195 +431,295 @@ impl Project {
Ok(programs) Ok(programs)
} }
// fn recurse_simplifier( pub(crate) fn recurse_scope_level(
// &self, &self,
// body: &TypedExpr, body: &TypedExpr,
// scripts: &[CheckedModule], scripts: &[CheckedModule],
// scope_level: i32, scope_level: i32,
// lookup_map: &mut HashMap<_, _>, uplc_function_holder_lookup: &mut HashMap<(String, String), (i32, TypedExpr)>,
// functions: &HashMap< functions: &HashMap<(String, String), &Function<std::sync::Arc<tipo::Type>, TypedExpr>>,
// (String, String), type_aliases: &HashMap<(String, String), &ast::TypeAlias<std::sync::Arc<tipo::Type>>>,
// &Function<std::sync::Arc<aiken_lang::tipo::Type>, TypedExpr>, data_types: &HashMap<(String, String), &ast::DataType<std::sync::Arc<tipo::Type>>>,
// >, imports: &HashMap<(String, String), &ast::Use<String>>,
// type_aliases: &HashMap< constants: &HashMap<
// (String, String), (String, String),
// &aiken_lang::ast::TypeAlias<std::sync::Arc<aiken_lang::tipo::Type>>, &ast::ModuleConstant<std::sync::Arc<tipo::Type>, String>,
// >, >,
// data_types: &HashMap< ) {
// (String, String), match dbg!(body) {
// &aiken_lang::ast::DataType<std::sync::Arc<aiken_lang::tipo::Type>>, TypedExpr::Int { value, .. } => {}
// >, TypedExpr::String { value, .. } => {}
// imports: &HashMap<(String, String), &aiken_lang::ast::Use<String>>, TypedExpr::ByteArray { bytes, .. } => {}
// constants: &HashMap< TypedExpr::Sequence {
// (String, String), location,
// &aiken_lang::ast::ModuleConstant<std::sync::Arc<aiken_lang::tipo::Type>, String>, expressions,
// >, } => {
// ) { // let mut terms = Vec::new();
// match body { for (i, exp) in expressions.iter().enumerate().rev() {
// TypedExpr::Int { self.recurse_scope_level(
// location, exp,
// tipo, scripts,
// value, scope_level + i as i32 * 100 + 1,
// } => {} uplc_function_holder_lookup,
// TypedExpr::String { functions,
// location, type_aliases,
// tipo, data_types,
// value, imports,
// } => {} constants,
// TypedExpr::ByteArray { );
// location, }
// tipo, }
// bytes, TypedExpr::Pipeline {
// } => {} location,
// TypedExpr::Sequence { expressions,
// location, } => todo!(),
// expressions, TypedExpr::Var {
// } => { location,
// for expression in expressions { constructor,
// self.recurse_simplifier( name,
// expression, } => {}
// scripts, TypedExpr::Fn {
// scope_level, location,
// lookup_map, tipo,
// functions, is_capture,
// type_aliases, args,
// data_types, body,
// imports, return_annotation,
// constants, } => todo!(),
// ); TypedExpr::List {
// } location,
// } tipo,
// TypedExpr::Pipeline { elements,
// location, tail,
// expressions, } => todo!(),
// } => { TypedExpr::Call {
// for expression in expressions { location,
// self.recurse_simplifier( tipo,
// expression, fun,
// scripts, args,
// scope_level, } => {
// lookup_map, let mut term = self.recurse_scope_level(
// functions, fun,
// type_aliases, scripts,
// data_types, scope_level + args.len() as i32,
// imports, uplc_function_holder_lookup,
// constants, functions,
// ); type_aliases,
// } data_types,
// } imports,
// TypedExpr::Var { constants,
// 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,
// } => {
// self.recurse_simplifier(&functions.get(&(module, name)).unwrap().body, scripts, scope_level, lookup_map, functions, type_aliases, data_types, imports, constants) for (i, arg) in args.iter().enumerate() {
// } self.recurse_scope_level(
// aiken_lang::tipo::ValueConstructorVariant::Record { &arg.value,
// name, scripts,
// arity, scope_level + i as i32,
// field_map, uplc_function_holder_lookup,
// location, functions,
// module, type_aliases,
// constructors_count, data_types,
// } => todo!(), imports,
// }, constants,
// TypedExpr::Fn { );
// location, }
// tipo, }
// is_capture, TypedExpr::BinOp {
// args, location,
// body, tipo,
// return_annotation, name,
// } => todo!(), left,
// TypedExpr::List { right,
// location, } => {
// tipo, todo!()
// elements, }
// tail, TypedExpr::Assignment {
// } => todo!(), location,
// TypedExpr::Call { tipo,
// location, value,
// tipo, pattern,
// fun, kind,
// args, } => match pattern {
// } => todo!(), ast::Pattern::Int { location, value } => todo!(),
// TypedExpr::BinOp { ast::Pattern::String { location, value } => todo!(),
// location, ast::Pattern::Var { location, name } => {
// tipo, self.recurse_scope_level(
// name, value,
// left, scripts,
// right, scope_level + 1,
// } => todo!(), uplc_function_holder_lookup,
// TypedExpr::Assignment { functions,
// location, type_aliases,
// tipo, data_types,
// value, imports,
// pattern, constants,
// kind, );
// } => todo!(), }
// TypedExpr::Try { ast::Pattern::VarUsage {
// location, location,
// tipo, name,
// value, tipo,
// then, } => todo!(),
// pattern, ast::Pattern::Assign {
// } => todo!(), name,
// TypedExpr::When { location,
// location, pattern,
// tipo, } => todo!(),
// subjects, ast::Pattern::Discard { name, location } => todo!(),
// clauses, ast::Pattern::List {
// } => todo!(), location,
// TypedExpr::If { elements,
// location, tail,
// branches, } => todo!(),
// final_else, ast::Pattern::Constructor {
// tipo, location,
// } => todo!(), name,
// TypedExpr::RecordAccess { arguments,
// location, module,
// tipo, constructor,
// label, with_spread,
// index, tipo,
// record, } => todo!(),
// } => todo!(), },
// TypedExpr::ModuleSelect { TypedExpr::Try {
// location, location,
// tipo, tipo,
// label, value,
// module_name, then,
// module_alias, pattern,
// constructor, } => todo!(),
// } => todo!(), TypedExpr::When {
// TypedExpr::Todo { location,
// location, tipo,
// label, subjects,
// tipo, clauses,
// } => todo!(), } => todo!(),
// TypedExpr::RecordUpdate { //if statements increase scope due to branching.
// location, TypedExpr::If {
// tipo, branches,
// spread, final_else,
// args, ..
// } => todo!(), } => {
// TypedExpr::Negate { location, value } => todo!(), 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( fn recurse_code_gen(
&self, &self,
@ -613,10 +727,10 @@ impl Project {
scripts: &[CheckedModule], scripts: &[CheckedModule],
scope_level: i32, scope_level: i32,
uplc_function_holder: &mut Vec<(String, Term<Name>)>, 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< functions: &HashMap<
(String, String), (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< type_aliases: &HashMap<
(String, String), (String, String),
@ -644,18 +758,17 @@ impl Project {
location, location,
expressions, expressions,
} => { } => {
// let mut terms = Vec::new();
for (i, exp) in expressions.iter().enumerate().rev() { for (i, exp) in expressions.iter().enumerate().rev() {
println!( println!(
"The index is {} and the scope level is {} and next scope is {}", "The index is {} and the scope level is {} and next scope is {}",
i, i,
scope_level, scope_level,
scope_level + i as i32 + 1 scope_level + i as i32 * 100 + 1,
); );
let mut term = self.recurse_code_gen( let mut term = self.recurse_code_gen(
exp, exp,
scripts, scripts,
scope_level + i as i32 + 1, scope_level + i as i32 * 100 + 1,
uplc_function_holder, uplc_function_holder,
uplc_function_holder_lookup, uplc_function_holder_lookup,
functions, functions,
@ -665,50 +778,57 @@ impl Project {
constants, constants,
); );
let mut above_scope = Vec::new(); for func in uplc_function_holder_lookup.clone().keys() {
for func in uplc_function_holder.clone() { if uplc_function_holder_lookup.clone().get(func).unwrap().0
let mut split_name = func.0.split('_'); > scope_level + i as i32 * 100
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)
{ {
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 { term = Term::Apply {
function: Term::Lambda { function: Term::Lambda {
parameter_name: Name { parameter_name: Name {
text: func.0.clone(), text: format!("{}_{}", func.0, func.1),
unique: 0.into(), unique: 0.into(),
}, },
body: term.into(), body: term.into(),
} }
.into(), .into(),
argument: func.1.clone().into(), argument: function_body.into(),
}; };
} else { uplc_function_holder_lookup.remove(func);
above_scope.push(func);
} }
uplc_function_holder.drain(0..);
uplc_function_holder.append(&mut above_scope);
} }
uplc_function_holder.push(("".to_string(), term.clone())); uplc_function_holder.push(("".to_string(), term.clone()));
} }
@ -777,7 +897,11 @@ impl Project {
fun, fun,
args, 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( let mut term = self.recurse_code_gen(
fun, fun,
scripts, scripts,
@ -846,13 +970,14 @@ impl Project {
ast::Pattern::Int { location, value } => todo!(), ast::Pattern::Int { location, value } => todo!(),
ast::Pattern::String { location, value } => todo!(), ast::Pattern::String { location, value } => todo!(),
ast::Pattern::Var { location, name } => Term::Apply { ast::Pattern::Var { location, name } => Term::Apply {
function: Rc::new(Term::Lambda { function: Term::Lambda {
parameter_name: Name { parameter_name: Name {
text: name.to_string(), text: name.to_string(),
unique: 0.into(), unique: 0.into(),
}, },
body: uplc_function_holder.pop().unwrap().1.into(), body: uplc_function_holder.pop().unwrap().1.into(),
}), }
.into(),
argument: self argument: self
.recurse_code_gen( .recurse_code_gen(
value, value,
@ -868,6 +993,7 @@ impl Project {
) )
.into(), .into(),
}, },
ast::Pattern::VarUsage { ast::Pattern::VarUsage {
location, location,
name, name,
@ -998,66 +1124,10 @@ impl Project {
location, location,
module, module,
name, name,
} => { } => Term::Var(Name {
if !uplc_function_holder_lookup text: format!("{module}_{name}"),
.contains_key(&(module.to_string(), name.to_string())) unique: 0.into(),
{ }),
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(),
})
}
ModuleValueConstructor::Constant { literal, location } => todo!(), ModuleValueConstructor::Constant { literal, location } => todo!(),
}, },
TypedExpr::Todo { TypedExpr::Todo {

View File

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

View File

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