checkpoint commit
This commit is contained in:
parent
d8f3ada13e
commit
3cafb2bcbe
|
@ -602,9 +602,9 @@ checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
|
|||
|
||||
[[package]]
|
||||
name = "pallas-addresses"
|
||||
version = "0.14.0-alpha.4"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1188a2434037b74129f8d209a37a1d09721b900e6e378255db1a91abc37199bc"
|
||||
checksum = "c82eb1d0c40048cdfcbb06f68eca9b0bb96d0aea621a29f9aa4d8f000803ee34"
|
||||
dependencies = [
|
||||
"base58",
|
||||
"bech32",
|
||||
|
@ -616,9 +616,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pallas-codec"
|
||||
version = "0.14.0-alpha.4"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "65c035a772aa84e858e53b7c98e6036eaa216d8a699bb9c826787722bde13d05"
|
||||
checksum = "32560b75dcbab63b26bd3f529f00d39720118e79506b29b24d746007df71dc9b"
|
||||
dependencies = [
|
||||
"hex",
|
||||
"minicbor",
|
||||
|
@ -627,9 +627,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pallas-crypto"
|
||||
version = "0.14.0-alpha.4"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2841f9225dcd6a78c6f386d4d5e76bcdbecd7b4489455b2d2485b105bf4c0499"
|
||||
checksum = "2280ac7df1ef64ba253846e83d4a0e7dfdae7507a7ab3cb31c7292a40f17976c"
|
||||
dependencies = [
|
||||
"cryptoxide",
|
||||
"hex",
|
||||
|
@ -641,9 +641,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pallas-primitives"
|
||||
version = "0.14.0-alpha.4"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e51824547f7a1e1a6574ecec4bf8557f3819f435132873c0bae97acba81cbb1"
|
||||
checksum = "0f2fc36d67a90cedafd0e120608ebf004464be462506fdd8fab96c4540a03f71"
|
||||
dependencies = [
|
||||
"base58",
|
||||
"bech32",
|
||||
|
@ -657,9 +657,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pallas-traverse"
|
||||
version = "0.14.0-alpha.4"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3291d1ae31cd803b9142fb32e1fcb0a58fc1d65b3bbe1d527d14b322db6eb019"
|
||||
checksum = "c48e218019e6ff9dd368642db9bbe4c87382846932470b20643198b7df377769"
|
||||
dependencies = [
|
||||
"hex",
|
||||
"pallas-addresses",
|
||||
|
|
|
@ -10,6 +10,8 @@ pub mod format;
|
|||
pub mod parser;
|
||||
pub mod pretty;
|
||||
pub mod tipo;
|
||||
pub mod token;
|
||||
pub mod uplc;
|
||||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct IdGenerator {
|
||||
|
|
|
@ -0,0 +1,837 @@
|
|||
use std::{collections::HashMap, rc::Rc, sync::Arc};
|
||||
|
||||
use uplc::{
|
||||
ast::{Constant, Name, Program, Term, Unique},
|
||||
builtins::DefaultFunction,
|
||||
parser::interner::Interner,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
ast::{self, DataType, Function, ModuleConstant, Pattern, TypeAlias, TypedArg, Use},
|
||||
expr::TypedExpr,
|
||||
tipo::{self, ModuleValueConstructor, Type, ValueConstructorVariant},
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct ScopeLevels {
|
||||
scope_tracker: Vec<i32>,
|
||||
}
|
||||
|
||||
impl ScopeLevels {
|
||||
pub fn new() -> Self {
|
||||
ScopeLevels {
|
||||
scope_tracker: vec![0],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_less_than(&self, other: &ScopeLevels) -> bool {
|
||||
if self.scope_tracker.is_empty() && !other.scope_tracker.is_empty() {
|
||||
return true;
|
||||
} else if other.scope_tracker.is_empty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
let mut result = self.scope_tracker.len() < other.scope_tracker.len();
|
||||
|
||||
for (scope_self, scope_other) in self.scope_tracker.iter().zip(other.scope_tracker.iter()) {
|
||||
match scope_self.cmp(scope_other) {
|
||||
std::cmp::Ordering::Less => {
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
std::cmp::Ordering::Equal => {}
|
||||
std::cmp::Ordering::Greater => {
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
pub fn scope_increment_sequence(&self, inc: i32) -> ScopeLevels {
|
||||
let mut new_scope = self.clone();
|
||||
*new_scope.scope_tracker.last_mut().unwrap() += inc;
|
||||
new_scope.scope_tracker.push(0);
|
||||
new_scope
|
||||
}
|
||||
|
||||
pub fn scope_increment(&self, inc: i32) -> ScopeLevels {
|
||||
let mut new_scope = self.clone();
|
||||
*new_scope.scope_tracker.last_mut().unwrap() += inc;
|
||||
new_scope
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ScopeLevels {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CodeGenerator<'a> {
|
||||
uplc_function_holder: Vec<(String, Term<Name>)>,
|
||||
uplc_function_holder_lookup: HashMap<(String, String), (ScopeLevels, TypedExpr)>,
|
||||
uplc_data_holder_lookup: HashMap<(String, String, String), (ScopeLevels, TypedExpr)>,
|
||||
uplc_data_usage_holder_lookup: HashMap<(String, String), ScopeLevels>,
|
||||
functions: &'a HashMap<(String, String), &'a Function<Arc<tipo::Type>, TypedExpr>>,
|
||||
type_aliases: &'a HashMap<(String, String), &'a TypeAlias<Arc<tipo::Type>>>,
|
||||
data_types: &'a HashMap<(String, String), &'a DataType<Arc<tipo::Type>>>,
|
||||
imports: &'a HashMap<(String, String), &'a Use<String>>,
|
||||
constants: &'a HashMap<(String, String), &'a ModuleConstant<Arc<tipo::Type>, String>>,
|
||||
}
|
||||
|
||||
impl<'a> CodeGenerator<'a> {
|
||||
pub fn new(
|
||||
functions: &'a HashMap<(String, String), &'a Function<Arc<tipo::Type>, TypedExpr>>,
|
||||
type_aliases: &'a HashMap<(String, String), &'a TypeAlias<Arc<tipo::Type>>>,
|
||||
data_types: &'a HashMap<(String, String), &'a DataType<Arc<tipo::Type>>>,
|
||||
imports: &'a HashMap<(String, String), &'a Use<String>>,
|
||||
constants: &'a HashMap<(String, String), &'a ModuleConstant<Arc<tipo::Type>, String>>,
|
||||
) -> Self {
|
||||
CodeGenerator {
|
||||
uplc_function_holder: Vec::new(),
|
||||
uplc_function_holder_lookup: HashMap::new(),
|
||||
uplc_data_holder_lookup: HashMap::new(),
|
||||
uplc_data_usage_holder_lookup: HashMap::new(),
|
||||
functions,
|
||||
type_aliases,
|
||||
data_types,
|
||||
imports,
|
||||
constants,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate(&mut self, body: TypedExpr, arguments: Vec<TypedArg>) -> Program<Name> {
|
||||
self.recurse_scope_level(&body, ScopeLevels::new());
|
||||
|
||||
let mut term = self.recurse_code_gen(&body, ScopeLevels::new());
|
||||
|
||||
for arg in arguments.iter().rev() {
|
||||
term = Term::Lambda {
|
||||
parameter_name: uplc::ast::Name {
|
||||
text: arg.arg_name.get_variable_name().unwrap_or("_").to_string(),
|
||||
unique: Unique::new(0),
|
||||
},
|
||||
body: Rc::new(term),
|
||||
}
|
||||
}
|
||||
|
||||
let mut program = Program {
|
||||
version: (1, 0, 0),
|
||||
term,
|
||||
};
|
||||
|
||||
let mut interner = Interner::new();
|
||||
|
||||
interner.program(&mut program);
|
||||
|
||||
println!("{}", program.to_pretty());
|
||||
|
||||
program
|
||||
}
|
||||
|
||||
pub(crate) fn recurse_scope_level(&mut self, body: &TypedExpr, scope_level: ScopeLevels) {
|
||||
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,
|
||||
scope_level.scope_increment_sequence(i as i32 + 1),
|
||||
);
|
||||
}
|
||||
}
|
||||
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,
|
||||
} => {
|
||||
self.recurse_scope_level(fun, scope_level.scope_increment(args.len() as i32 + 1));
|
||||
|
||||
for (i, arg) in args.iter().enumerate() {
|
||||
self.recurse_scope_level(&arg.value, scope_level.scope_increment(i as i32 + 1));
|
||||
}
|
||||
}
|
||||
TypedExpr::BinOp {
|
||||
location,
|
||||
tipo,
|
||||
name,
|
||||
left,
|
||||
right,
|
||||
} => {
|
||||
self.recurse_scope_level(left, scope_level.clone());
|
||||
self.recurse_scope_level(right, scope_level);
|
||||
}
|
||||
TypedExpr::Assignment {
|
||||
location,
|
||||
tipo,
|
||||
value,
|
||||
pattern,
|
||||
kind,
|
||||
} => self.recurse_scope_level_pattern(pattern, value, scope_level),
|
||||
TypedExpr::Try {
|
||||
location,
|
||||
tipo,
|
||||
value,
|
||||
then,
|
||||
pattern,
|
||||
} => todo!(),
|
||||
TypedExpr::When {
|
||||
location,
|
||||
tipo,
|
||||
subjects,
|
||||
clauses,
|
||||
} => {
|
||||
for clause in clauses {
|
||||
for pattern in clause.pattern.iter() {
|
||||
self.recurse_scope_level_pattern(
|
||||
pattern,
|
||||
&clause.then,
|
||||
scope_level.scope_increment_sequence(1),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
//if statements increase scope due to branching.
|
||||
TypedExpr::If {
|
||||
branches,
|
||||
final_else,
|
||||
..
|
||||
} => {
|
||||
self.recurse_scope_level(final_else, scope_level.scope_increment_sequence(1));
|
||||
|
||||
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
|
||||
self.recurse_scope_level(
|
||||
&branch.condition,
|
||||
scope_level.scope_increment_sequence(1), // Since this happens before branching. Maybe not increase scope level
|
||||
);
|
||||
|
||||
self.recurse_scope_level(&branch.body, scope_level.scope_increment_sequence(1));
|
||||
}
|
||||
}
|
||||
a @ TypedExpr::RecordAccess {
|
||||
tipo,
|
||||
label,
|
||||
index,
|
||||
record,
|
||||
..
|
||||
} => {
|
||||
println!("tipo {tipo:#?}");
|
||||
println!("label {label:#?}");
|
||||
println!("index {index:#?}");
|
||||
println!("record {record:#?}");
|
||||
|
||||
match &**record {
|
||||
TypedExpr::Var { constructor, .. } => {
|
||||
match (constructor.variant.clone(), (*constructor.tipo).clone()) {
|
||||
(
|
||||
ValueConstructorVariant::LocalVariable { .. },
|
||||
Type::App { module, name, .. },
|
||||
) => {
|
||||
self.uplc_data_holder_lookup.insert(
|
||||
(module.clone(), name.clone(), label.to_string()),
|
||||
(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!(),
|
||||
}
|
||||
}
|
||||
_ => 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 !self
|
||||
.uplc_function_holder_lookup
|
||||
.contains_key(&(module.to_string(), name.to_string()))
|
||||
{
|
||||
let func_def = self
|
||||
.functions
|
||||
.get(&(module.to_string(), name.to_string()))
|
||||
.unwrap();
|
||||
|
||||
self.recurse_scope_level(
|
||||
&func_def.body,
|
||||
scope_level.scope_increment(func_def.arguments.len() as i32 + 1),
|
||||
);
|
||||
|
||||
self.uplc_function_holder_lookup.insert(
|
||||
(module.to_string(), name.to_string()),
|
||||
(scope_level.clone(), a.clone()),
|
||||
);
|
||||
}
|
||||
|
||||
if scope_level.is_less_than(
|
||||
&self
|
||||
.uplc_function_holder_lookup
|
||||
.get(&(module.to_string(), name.to_string()))
|
||||
.unwrap()
|
||||
.0,
|
||||
) {
|
||||
self.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_scope_level_pattern<Constructor, Type>(
|
||||
&mut self,
|
||||
pattern: &Pattern<Constructor, Type>,
|
||||
value: &TypedExpr,
|
||||
scope_level: ScopeLevels,
|
||||
) {
|
||||
match pattern {
|
||||
Pattern::Int { .. } | Pattern::String { .. } | Pattern::Var { .. } => {
|
||||
self.recurse_scope_level(value, scope_level);
|
||||
}
|
||||
|
||||
Pattern::VarUsage {
|
||||
location,
|
||||
name,
|
||||
tipo,
|
||||
} => todo!(),
|
||||
Pattern::Assign {
|
||||
name,
|
||||
location,
|
||||
pattern,
|
||||
} => todo!(),
|
||||
Pattern::Discard { name, location } => todo!(),
|
||||
Pattern::List {
|
||||
location,
|
||||
elements,
|
||||
tail,
|
||||
} => todo!(),
|
||||
Pattern::Constructor {
|
||||
location,
|
||||
name,
|
||||
arguments,
|
||||
module,
|
||||
constructor,
|
||||
with_spread,
|
||||
tipo,
|
||||
} => {
|
||||
self.recurse_scope_level(value, scope_level);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn recurse_code_gen(&mut self, body: &TypedExpr, scope_level: ScopeLevels) -> Term<Name> {
|
||||
match dbg!(body) {
|
||||
TypedExpr::Int { value, .. } => {
|
||||
Term::Constant(Constant::Integer(value.parse::<i128>().unwrap()))
|
||||
}
|
||||
TypedExpr::String { value, .. } => Term::Constant(Constant::String(value.clone())),
|
||||
TypedExpr::ByteArray { bytes, .. } => {
|
||||
Term::Constant(Constant::ByteString(bytes.clone()))
|
||||
}
|
||||
TypedExpr::Sequence {
|
||||
location,
|
||||
expressions,
|
||||
} => {
|
||||
for (i, exp) in expressions.iter().enumerate().rev() {
|
||||
let mut term = self
|
||||
.recurse_code_gen(exp, scope_level.scope_increment_sequence(i as i32 + 1));
|
||||
|
||||
term = self
|
||||
.maybe_insert_def(term, scope_level.scope_increment_sequence(i as i32 + 1));
|
||||
|
||||
self.uplc_function_holder
|
||||
.push(("".to_string(), term.clone()));
|
||||
}
|
||||
|
||||
self.uplc_function_holder.pop().unwrap().1
|
||||
}
|
||||
TypedExpr::Pipeline {
|
||||
location,
|
||||
expressions,
|
||||
} => todo!(),
|
||||
TypedExpr::Var {
|
||||
location,
|
||||
constructor,
|
||||
name,
|
||||
} => {
|
||||
if name == "True" || name == "False" {
|
||||
Term::Constant(Constant::Bool(name == "True"))
|
||||
} else {
|
||||
match constructor.variant.clone() {
|
||||
ValueConstructorVariant::LocalVariable { location } => Term::Var(Name {
|
||||
text: name.to_string(),
|
||||
unique: 0.into(),
|
||||
}),
|
||||
ValueConstructorVariant::ModuleConstant {
|
||||
location,
|
||||
module,
|
||||
literal,
|
||||
} => todo!(),
|
||||
ValueConstructorVariant::ModuleFn {
|
||||
name,
|
||||
field_map,
|
||||
module,
|
||||
arity,
|
||||
location,
|
||||
builtin,
|
||||
} => todo!(),
|
||||
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,
|
||||
} => {
|
||||
let mut term =
|
||||
self.recurse_code_gen(fun, scope_level.scope_increment(args.len() as i32 + 1));
|
||||
|
||||
for (i, arg) in args.iter().enumerate() {
|
||||
term = Term::Apply {
|
||||
function: term.into(),
|
||||
argument: self
|
||||
.recurse_code_gen(&arg.value, scope_level.scope_increment(i as i32 + 1))
|
||||
.into(),
|
||||
};
|
||||
}
|
||||
|
||||
term
|
||||
}
|
||||
TypedExpr::BinOp {
|
||||
location,
|
||||
tipo,
|
||||
name,
|
||||
left,
|
||||
right,
|
||||
} => {
|
||||
let left_term = self.recurse_code_gen(left, scope_level.clone());
|
||||
|
||||
let right_term = self.recurse_code_gen(right, scope_level);
|
||||
println!("NAME IS {name:#?}");
|
||||
match name {
|
||||
Eq => match &*left.tipo() {
|
||||
Type::App {
|
||||
public,
|
||||
module,
|
||||
name,
|
||||
args,
|
||||
} => match name.as_str() {
|
||||
"Int" => Term::Apply {
|
||||
function: Term::Apply {
|
||||
function: Term::Builtin(DefaultFunction::EqualsInteger).into(),
|
||||
argument: left_term.into(),
|
||||
}
|
||||
.into(),
|
||||
argument: right_term.into(),
|
||||
},
|
||||
|
||||
"String" => Term::Apply {
|
||||
function: Term::Apply {
|
||||
function: Term::Builtin(DefaultFunction::EqualsString).into(),
|
||||
argument: left_term.into(),
|
||||
}
|
||||
.into(),
|
||||
argument: right_term.into(),
|
||||
},
|
||||
|
||||
_ => todo!(),
|
||||
},
|
||||
Type::Fn { args, ret } => todo!(),
|
||||
Type::Var { tipo } => todo!(),
|
||||
},
|
||||
And => todo!(),
|
||||
Or => todo!(),
|
||||
NotEq => todo!(),
|
||||
LtInt => todo!(),
|
||||
LtEqInt => todo!(),
|
||||
GtEqInt => todo!(),
|
||||
GtInt => todo!(),
|
||||
AddInt => todo!(),
|
||||
SubInt => todo!(),
|
||||
MultInt => todo!(),
|
||||
DivInt => todo!(),
|
||||
ModInt => todo!(),
|
||||
}
|
||||
}
|
||||
TypedExpr::Assignment {
|
||||
location,
|
||||
tipo,
|
||||
value,
|
||||
pattern,
|
||||
kind,
|
||||
} => match pattern {
|
||||
Pattern::Int { location, value } => todo!(),
|
||||
Pattern::String { location, value } => todo!(),
|
||||
Pattern::Var { location, name } => Term::Apply {
|
||||
function: Term::Lambda {
|
||||
parameter_name: Name {
|
||||
text: name.to_string(),
|
||||
unique: 0.into(),
|
||||
},
|
||||
body: self.uplc_function_holder.pop().unwrap().1.into(),
|
||||
}
|
||||
.into(),
|
||||
argument: self
|
||||
.recurse_code_gen(value, scope_level.scope_increment(1))
|
||||
.into(),
|
||||
},
|
||||
|
||||
Pattern::VarUsage {
|
||||
location,
|
||||
name,
|
||||
tipo,
|
||||
} => todo!(),
|
||||
Pattern::Assign {
|
||||
name,
|
||||
location,
|
||||
pattern,
|
||||
} => todo!(),
|
||||
Pattern::Discard { name, location } => todo!(),
|
||||
Pattern::List {
|
||||
location,
|
||||
elements,
|
||||
tail,
|
||||
} => todo!(),
|
||||
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_code_gen(final_else, scope_level.scope_increment_sequence(1));
|
||||
|
||||
if branches.len() == 1 {
|
||||
let condition_term = self.recurse_code_gen(
|
||||
&branches[0].condition,
|
||||
scope_level.scope_increment_sequence(1),
|
||||
);
|
||||
|
||||
let branch_term = self.recurse_code_gen(
|
||||
&branches[0].body,
|
||||
scope_level.scope_increment_sequence(1),
|
||||
);
|
||||
|
||||
match (final_if_term.clone(), branch_term.clone()) {
|
||||
(
|
||||
Term::Var(..) | Term::Constant(..),
|
||||
Term::Var(..) | Term::Constant(..),
|
||||
) => {
|
||||
final_if_term = Term::Apply {
|
||||
function: Rc::new(Term::Apply {
|
||||
function: Rc::new(Term::Apply {
|
||||
function: Rc::new(Term::Force(Rc::new(Term::Builtin(
|
||||
DefaultFunction::IfThenElse,
|
||||
)))),
|
||||
argument: Rc::new(condition_term),
|
||||
}),
|
||||
//If this is just a var then don't include delay
|
||||
argument: Rc::new(branch_term),
|
||||
}),
|
||||
//If this is just a var then don't include delay
|
||||
argument: Rc::new(final_if_term.clone()),
|
||||
};
|
||||
}
|
||||
_ => {
|
||||
final_if_term = Term::Force(
|
||||
Term::Apply {
|
||||
function: Rc::new(Term::Apply {
|
||||
function: Rc::new(Term::Apply {
|
||||
function: Rc::new(Term::Force(Rc::new(Term::Builtin(
|
||||
DefaultFunction::IfThenElse,
|
||||
)))),
|
||||
argument: Rc::new(condition_term),
|
||||
}),
|
||||
argument: Rc::new(Term::Delay(Rc::new(branch_term))),
|
||||
}),
|
||||
argument: Rc::new(Term::Delay(Rc::new(final_if_term.clone()))),
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//TODO: for multi branch if statements we can insert function definitions between branches
|
||||
for branch in branches {
|
||||
let condition_term = self.recurse_code_gen(
|
||||
&branch.condition,
|
||||
scope_level.scope_increment_sequence(1),
|
||||
);
|
||||
|
||||
let branch_term = self.recurse_code_gen(
|
||||
&branch.body,
|
||||
scope_level.scope_increment_sequence(1),
|
||||
);
|
||||
|
||||
final_if_term = Term::Force(
|
||||
Term::Apply {
|
||||
function: Rc::new(Term::Apply {
|
||||
function: Rc::new(Term::Apply {
|
||||
function: Rc::new(Term::Force(Rc::new(Term::Builtin(
|
||||
DefaultFunction::IfThenElse,
|
||||
)))),
|
||||
argument: Rc::new(condition_term),
|
||||
}),
|
||||
argument: Rc::new(Term::Delay(Rc::new(branch_term))),
|
||||
}),
|
||||
argument: Rc::new(Term::Delay(Rc::new(final_if_term.clone()))),
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
self.maybe_insert_def(final_if_term, scope_level)
|
||||
}
|
||||
TypedExpr::RecordAccess {
|
||||
location,
|
||||
tipo,
|
||||
label,
|
||||
index,
|
||||
record,
|
||||
} => match &**record {
|
||||
TypedExpr::Var { constructor, .. } => {
|
||||
match (constructor.variant.clone(), (*constructor.tipo).clone()) {
|
||||
(
|
||||
ValueConstructorVariant::LocalVariable { .. },
|
||||
Type::App { module, name, .. },
|
||||
) => Term::Var(Name {
|
||||
text: format!("{module}_{name}.{label}"),
|
||||
unique: 0.into(),
|
||||
}),
|
||||
_ => todo!(),
|
||||
}
|
||||
}
|
||||
_ => todo!(),
|
||||
},
|
||||
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,
|
||||
} => Term::Var(Name {
|
||||
text: format!("{module}_{name}"),
|
||||
unique: 0.into(),
|
||||
}),
|
||||
ModuleValueConstructor::Constant { literal, location } => todo!(),
|
||||
},
|
||||
TypedExpr::Todo {
|
||||
location,
|
||||
label,
|
||||
tipo,
|
||||
} => todo!(),
|
||||
TypedExpr::RecordUpdate {
|
||||
location,
|
||||
tipo,
|
||||
spread,
|
||||
args,
|
||||
} => todo!(),
|
||||
TypedExpr::Negate { location, value } => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn maybe_insert_def(
|
||||
&mut self,
|
||||
current_term: Term<Name>,
|
||||
scope_level: ScopeLevels,
|
||||
) -> Term<Name> {
|
||||
let mut term = current_term;
|
||||
for func in self.uplc_function_holder_lookup.clone().keys() {
|
||||
if scope_level.is_less_than(
|
||||
&self
|
||||
.uplc_function_holder_lookup
|
||||
.clone()
|
||||
.get(func)
|
||||
.unwrap()
|
||||
.0,
|
||||
) {
|
||||
let func_def = self
|
||||
.functions
|
||||
.get(&(func.0.to_string(), func.1.to_string()))
|
||||
.unwrap();
|
||||
|
||||
let mut function_body = self.recurse_code_gen(
|
||||
&func_def.body,
|
||||
scope_level.scope_increment_sequence(func_def.arguments.len() as i32),
|
||||
);
|
||||
|
||||
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: format!("{}_{}", func.0, func.1),
|
||||
unique: 0.into(),
|
||||
},
|
||||
body: term.into(),
|
||||
}
|
||||
.into(),
|
||||
argument: function_body.into(),
|
||||
};
|
||||
self.uplc_function_holder_lookup.remove(func);
|
||||
}
|
||||
}
|
||||
|
||||
for record_scope in self.uplc_data_usage_holder_lookup.keys() {
|
||||
if scope_level.is_less_than(
|
||||
self.uplc_data_usage_holder_lookup
|
||||
.get(record_scope)
|
||||
.unwrap(),
|
||||
) {
|
||||
for record in self.uplc_data_holder_lookup.keys() {
|
||||
if &(record.0.clone(), record.1.clone()) == record_scope {
|
||||
let dt = self.data_types.get(record_scope).unwrap();
|
||||
println!("DATA TYPE IS {dt:#?}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
term
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -16,11 +16,11 @@ exclude = ["test_data/*"]
|
|||
cryptoxide = "0.4.2"
|
||||
flat-rs = { path = "../flat", version = "0.0.21" }
|
||||
hex = "0.4.3"
|
||||
pallas-addresses = "0.14.0-alpha.3"
|
||||
pallas-codec = "0.14.0-alpha.3"
|
||||
pallas-crypto = "0.14.0-alpha.3"
|
||||
pallas-primitives = "0.14.0-alpha.3"
|
||||
pallas-traverse = "0.14.0-alpha.3"
|
||||
pallas-addresses = "0.14.0"
|
||||
pallas-codec = "0.14.0"
|
||||
pallas-crypto = "0.14.0"
|
||||
pallas-primitives = "0.14.0"
|
||||
pallas-traverse = "0.14.0"
|
||||
peg = "0.8.0"
|
||||
pretty = "0.11.3"
|
||||
thiserror = "1.0.31"
|
||||
|
|
|
@ -3,7 +3,11 @@ pub type ScriptContext {
|
|||
}
|
||||
|
||||
pub type Datum {
|
||||
something: String,
|
||||
Datum2{
|
||||
something: String,
|
||||
fin: Int
|
||||
}
|
||||
None{}
|
||||
}
|
||||
|
||||
pub fn eqInt(a: Int, b: Int) {
|
||||
|
|
|
@ -10,17 +10,14 @@ pub type Redeemer {
|
|||
|
||||
pub fn spend(datum: sample.Datum, rdmr: Redeemer, ctx: spend.ScriptContext) -> Bool {
|
||||
|
||||
let x = "x"
|
||||
let a = "y"
|
||||
let b = sample.eqString(x, a)
|
||||
let c = 1
|
||||
let y = 1
|
||||
let d = sample.eqInt(y, c)
|
||||
|
||||
if b {
|
||||
c == 1
|
||||
} else{
|
||||
d
|
||||
let x = 1
|
||||
let a = when datum is {
|
||||
sample.Datum2(first, rest) -> rest
|
||||
sample.None -> 0
|
||||
}
|
||||
let b = x
|
||||
b == 1
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue