feat: function insertion IR done, code gen will be easy
This commit is contained in:
parent
4129cf92c9
commit
02ee129615
|
@ -12,23 +12,28 @@ use crate::{
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum IR {
|
pub enum IR {
|
||||||
Int {
|
Int {
|
||||||
|
scope: Vec<u64>,
|
||||||
value: String,
|
value: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
String {
|
String {
|
||||||
|
scope: Vec<u64>,
|
||||||
value: String,
|
value: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
ByteArray {
|
ByteArray {
|
||||||
|
scope: Vec<u64>,
|
||||||
bytes: Vec<u8>,
|
bytes: Vec<u8>,
|
||||||
},
|
},
|
||||||
|
|
||||||
Var {
|
Var {
|
||||||
|
scope: Vec<u64>,
|
||||||
constructor: ValueConstructor,
|
constructor: ValueConstructor,
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
// Fn {
|
// Fn {
|
||||||
|
// scope: Vec<u64>,
|
||||||
// tipo: Arc<Type>,
|
// tipo: Arc<Type>,
|
||||||
// is_capture: bool,
|
// is_capture: bool,
|
||||||
// args: Vec<Arg<Arc<Type>>>,
|
// args: Vec<Arg<Arc<Type>>>,
|
||||||
|
@ -36,16 +41,19 @@ pub enum IR {
|
||||||
// return_annotation: Option<Annotation>,
|
// return_annotation: Option<Annotation>,
|
||||||
// },
|
// },
|
||||||
List {
|
List {
|
||||||
|
scope: Vec<u64>,
|
||||||
count: usize,
|
count: usize,
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
tail: bool,
|
tail: bool,
|
||||||
},
|
},
|
||||||
|
|
||||||
Tail {
|
Tail {
|
||||||
|
scope: Vec<u64>,
|
||||||
count: usize,
|
count: usize,
|
||||||
},
|
},
|
||||||
|
|
||||||
ListAccessor {
|
ListAccessor {
|
||||||
|
scope: Vec<u64>,
|
||||||
names: Vec<String>,
|
names: Vec<String>,
|
||||||
tail: bool,
|
tail: bool,
|
||||||
},
|
},
|
||||||
|
@ -55,96 +63,120 @@ pub enum IR {
|
||||||
|
|
||||||
// [y_varCall other_var Call Call x_defCall func_var ]
|
// [y_varCall other_var Call Call x_defCall func_var ]
|
||||||
Call {
|
Call {
|
||||||
|
scope: Vec<u64>,
|
||||||
count: usize,
|
count: usize,
|
||||||
},
|
},
|
||||||
|
|
||||||
Builtin {
|
Builtin {
|
||||||
|
scope: Vec<u64>,
|
||||||
func: DefaultFunction,
|
func: DefaultFunction,
|
||||||
},
|
},
|
||||||
|
|
||||||
BinOp {
|
BinOp {
|
||||||
|
scope: Vec<u64>,
|
||||||
name: BinOp,
|
name: BinOp,
|
||||||
count: usize,
|
count: usize,
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
},
|
},
|
||||||
|
|
||||||
Assignment {
|
Assignment {
|
||||||
|
scope: Vec<u64>,
|
||||||
name: String,
|
name: String,
|
||||||
kind: AssignmentKind,
|
kind: AssignmentKind,
|
||||||
},
|
},
|
||||||
|
|
||||||
DefineFunc {
|
DefineFunc {
|
||||||
|
scope: Vec<u64>,
|
||||||
func_name: String,
|
func_name: String,
|
||||||
module_name: String,
|
module_name: String,
|
||||||
|
params: Vec<String>,
|
||||||
|
recursive: bool,
|
||||||
},
|
},
|
||||||
|
|
||||||
DefineConst {
|
DefineConst {
|
||||||
|
scope: Vec<u64>,
|
||||||
func_name: String,
|
func_name: String,
|
||||||
module_name: String,
|
module_name: String,
|
||||||
count: usize,
|
count: usize,
|
||||||
},
|
},
|
||||||
|
|
||||||
DefineConstrFields {
|
DefineConstrFields {
|
||||||
|
scope: Vec<u64>,
|
||||||
func_name: String,
|
func_name: String,
|
||||||
module_name: String,
|
module_name: String,
|
||||||
count: usize,
|
count: usize,
|
||||||
},
|
},
|
||||||
|
|
||||||
DefineConstrFieldAccess {
|
DefineConstrFieldAccess {
|
||||||
|
scope: Vec<u64>,
|
||||||
func_name: String,
|
func_name: String,
|
||||||
module_name: String,
|
module_name: String,
|
||||||
count: usize,
|
count: usize,
|
||||||
},
|
},
|
||||||
|
|
||||||
Lam {
|
Lam {
|
||||||
|
scope: Vec<u64>,
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
// Try {
|
// Try {
|
||||||
|
// scope: Vec<u64>,
|
||||||
// tipo: Arc<Type>,
|
// tipo: Arc<Type>,
|
||||||
// value: Box<Self>,
|
// value: Box<Self>,
|
||||||
// then: Box<Self>,
|
// then: Box<Self>,
|
||||||
// pattern: Pattern<PatternConstructor, Arc<Type>>,
|
// pattern: Pattern<PatternConstructor, Arc<Type>>,
|
||||||
// },
|
// },
|
||||||
When {
|
When {
|
||||||
|
scope: Vec<u64>,
|
||||||
count: usize,
|
count: usize,
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
subject_name: String,
|
subject_name: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
Clause {
|
Clause {
|
||||||
|
scope: Vec<u64>,
|
||||||
count: usize,
|
count: usize,
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
subject_name: String,
|
subject_name: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
Discard,
|
Discard {
|
||||||
|
scope: Vec<u64>,
|
||||||
|
},
|
||||||
|
|
||||||
Finally,
|
Finally {
|
||||||
|
scope: Vec<u64>,
|
||||||
|
},
|
||||||
|
|
||||||
If {
|
If {
|
||||||
|
scope: Vec<u64>,
|
||||||
count: usize,
|
count: usize,
|
||||||
},
|
},
|
||||||
|
|
||||||
Constr {
|
Constr {
|
||||||
|
scope: Vec<u64>,
|
||||||
count: usize,
|
count: usize,
|
||||||
},
|
},
|
||||||
|
|
||||||
Fields {
|
Fields {
|
||||||
|
scope: Vec<u64>,
|
||||||
count: usize,
|
count: usize,
|
||||||
},
|
},
|
||||||
|
|
||||||
RecordAccess {
|
RecordAccess {
|
||||||
|
scope: Vec<u64>,
|
||||||
index: u64,
|
index: u64,
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
},
|
},
|
||||||
|
|
||||||
FieldsExpose {
|
FieldsExpose {
|
||||||
|
scope: Vec<u64>,
|
||||||
count: usize,
|
count: usize,
|
||||||
indices: Vec<(usize, String, Arc<Type>)>,
|
indices: Vec<(usize, String, Arc<Type>)>,
|
||||||
},
|
},
|
||||||
|
|
||||||
// ModuleSelect {
|
// ModuleSelect {
|
||||||
|
// scope: Vec<u64>,
|
||||||
// tipo: Arc<Type>,
|
// tipo: Arc<Type>,
|
||||||
// label: String,
|
// label: String,
|
||||||
// module_name: String,
|
// module_name: String,
|
||||||
|
@ -153,33 +185,72 @@ pub enum IR {
|
||||||
// },
|
// },
|
||||||
|
|
||||||
// Tuple {
|
// Tuple {
|
||||||
|
// scope: Vec<u64>,
|
||||||
//
|
//
|
||||||
// tipo: Arc<Type>,
|
// tipo: Arc<Type>,
|
||||||
// elems: Vec<Self>,
|
// elems: Vec<Self>,
|
||||||
// },
|
// },
|
||||||
|
|
||||||
// TupleIndex {
|
// TupleIndex {
|
||||||
|
// scope: Vec<u64>,
|
||||||
//
|
//
|
||||||
// tipo: Arc<Type>,
|
// tipo: Arc<Type>,
|
||||||
// index: u64,
|
// index: u64,
|
||||||
// tuple: Box<Self>,
|
// tuple: Box<Self>,
|
||||||
// },
|
// },
|
||||||
Todo {
|
Todo {
|
||||||
|
scope: Vec<u64>,
|
||||||
label: Option<String>,
|
label: Option<String>,
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
},
|
},
|
||||||
|
|
||||||
RecordUpdate {
|
RecordUpdate {
|
||||||
|
scope: Vec<u64>,
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
spread: Box<Self>,
|
spread: Box<Self>,
|
||||||
args: Vec<TypedRecordUpdateArg>,
|
args: Vec<TypedRecordUpdateArg>,
|
||||||
},
|
},
|
||||||
|
|
||||||
Negate {
|
Negate {
|
||||||
|
scope: Vec<u64>,
|
||||||
value: Box<Self>,
|
value: Box<Self>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl IR {
|
||||||
|
pub fn scope(&self) -> Vec<u64> {
|
||||||
|
match self {
|
||||||
|
IR::Int { scope, .. }
|
||||||
|
| IR::String { scope, .. }
|
||||||
|
| IR::ByteArray { scope, .. }
|
||||||
|
| IR::Var { scope, .. }
|
||||||
|
| IR::List { scope, .. }
|
||||||
|
| IR::Tail { scope, .. }
|
||||||
|
| IR::ListAccessor { scope, .. }
|
||||||
|
| IR::Call { scope, .. }
|
||||||
|
| IR::Builtin { scope, .. }
|
||||||
|
| IR::BinOp { scope, .. }
|
||||||
|
| IR::Assignment { scope, .. }
|
||||||
|
| IR::DefineFunc { scope, .. }
|
||||||
|
| IR::DefineConst { scope, .. }
|
||||||
|
| IR::DefineConstrFields { scope, .. }
|
||||||
|
| IR::DefineConstrFieldAccess { scope, .. }
|
||||||
|
| IR::Lam { scope, .. }
|
||||||
|
| IR::When { scope, .. }
|
||||||
|
| IR::Clause { scope, .. }
|
||||||
|
| IR::Discard { scope }
|
||||||
|
| IR::Finally { scope }
|
||||||
|
| IR::If { scope, .. }
|
||||||
|
| IR::Constr { scope, .. }
|
||||||
|
| IR::Fields { scope, .. }
|
||||||
|
| IR::RecordAccess { scope, .. }
|
||||||
|
| IR::FieldsExpose { scope, .. }
|
||||||
|
| IR::Todo { scope, .. }
|
||||||
|
| IR::RecordUpdate { scope, .. }
|
||||||
|
| IR::Negate { scope, .. } => scope.to_vec(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// pub fn get(r: Int) -> This{g: Int}{
|
// pub fn get(r: Int) -> This{g: Int}{
|
||||||
// This{ g: r }
|
// This{ g: r }
|
||||||
// }
|
// }
|
||||||
|
|
|
@ -97,7 +97,7 @@ pub struct DataTypeKey {
|
||||||
|
|
||||||
pub type ConstrUsageKey = String;
|
pub type ConstrUsageKey = String;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
|
#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
|
||||||
pub struct FunctionAccessKey {
|
pub struct FunctionAccessKey {
|
||||||
pub module_name: String,
|
pub module_name: String,
|
||||||
pub function_name: String,
|
pub function_name: String,
|
||||||
|
@ -353,8 +353,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
TypedExpr::Assignment { value, pattern, .. } => {
|
TypedExpr::Assignment { value, pattern, .. } => {
|
||||||
self.recurse_scope_level_pattern(pattern, value, scope_level, &[])
|
self.recurse_scope_level_pattern(pattern, value, scope_level, &[])
|
||||||
}
|
}
|
||||||
TypedExpr::Trace {..} => todo!(),
|
TypedExpr::Trace { .. } => todo!(),
|
||||||
TypedExpr::Try { .. } => todo!(),
|
|
||||||
TypedExpr::When {
|
TypedExpr::When {
|
||||||
subjects, clauses, ..
|
subjects, clauses, ..
|
||||||
} => {
|
} => {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use std::{collections::HashMap, ops::Deref, sync::Arc, vec};
|
use std::{collections::HashMap, ops::Deref, sync::Arc, vec};
|
||||||
|
|
||||||
|
use indexmap::IndexMap;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use uplc::{
|
use uplc::{
|
||||||
ast::{
|
ast::{
|
||||||
|
@ -12,7 +13,7 @@ use uplc::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{AssignmentKind, BinOp, DataType, Function, Pattern, Span, TypedArg},
|
ast::{ArgName, AssignmentKind, BinOp, DataType, Function, Pattern, Span, TypedArg},
|
||||||
expr::TypedExpr,
|
expr::TypedExpr,
|
||||||
ir::IR,
|
ir::IR,
|
||||||
tipo::{self, Type, TypeInfo, ValueConstructor, ValueConstructorVariant},
|
tipo::{self, Type, TypeInfo, ValueConstructor, ValueConstructorVariant},
|
||||||
|
@ -20,6 +21,14 @@ use crate::{
|
||||||
IdGenerator,
|
IdGenerator,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct FuncComponents {
|
||||||
|
ir: Vec<IR>,
|
||||||
|
dependencies: Vec<FunctionAccessKey>,
|
||||||
|
args: Vec<String>,
|
||||||
|
recursive: bool,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct CodeGenerator<'a> {
|
pub struct CodeGenerator<'a> {
|
||||||
defined_functions: HashMap<FunctionAccessKey, ()>,
|
defined_functions: HashMap<FunctionAccessKey, ()>,
|
||||||
functions: &'a HashMap<FunctionAccessKey, &'a Function<Arc<tipo::Type>, TypedExpr>>,
|
functions: &'a HashMap<FunctionAccessKey, &'a Function<Arc<tipo::Type>, TypedExpr>>,
|
||||||
|
@ -56,8 +65,13 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
pub fn generate(&mut self, body: TypedExpr, arguments: Vec<TypedArg>) -> Program<Name> {
|
pub fn generate(&mut self, body: TypedExpr, arguments: Vec<TypedArg>) -> Program<Name> {
|
||||||
let mut ir_stack = vec![];
|
let mut ir_stack = vec![];
|
||||||
|
let scope = vec![self.id_gen.next()];
|
||||||
|
|
||||||
self.build_ir(&body, &mut ir_stack);
|
self.build_ir(&body, &mut ir_stack, scope);
|
||||||
|
|
||||||
|
println!("{ir_stack:#?}");
|
||||||
|
|
||||||
|
self.define_ir(&mut ir_stack);
|
||||||
|
|
||||||
println!("{ir_stack:#?}");
|
println!("{ir_stack:#?}");
|
||||||
|
|
||||||
|
@ -96,31 +110,39 @@ impl<'a> CodeGenerator<'a> {
|
||||||
program
|
program
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn build_ir(&mut self, body: &TypedExpr, ir_stack: &mut Vec<IR>) {
|
pub(crate) fn build_ir(&mut self, body: &TypedExpr, ir_stack: &mut Vec<IR>, scope: Vec<u64>) {
|
||||||
match dbg!(body) {
|
match dbg!(body) {
|
||||||
TypedExpr::Int { value, .. } => ir_stack.push(IR::Int {
|
TypedExpr::Int { value, .. } => ir_stack.push(IR::Int {
|
||||||
|
scope,
|
||||||
value: value.to_string(),
|
value: value.to_string(),
|
||||||
}),
|
}),
|
||||||
TypedExpr::String { value, .. } => ir_stack.push(IR::String {
|
TypedExpr::String { value, .. } => ir_stack.push(IR::String {
|
||||||
|
scope,
|
||||||
value: value.to_string(),
|
value: value.to_string(),
|
||||||
}),
|
}),
|
||||||
TypedExpr::ByteArray { bytes, .. } => ir_stack.push(IR::ByteArray {
|
TypedExpr::ByteArray { bytes, .. } => ir_stack.push(IR::ByteArray {
|
||||||
|
scope,
|
||||||
bytes: bytes.to_vec(),
|
bytes: bytes.to_vec(),
|
||||||
}),
|
}),
|
||||||
TypedExpr::Sequence { expressions, .. } => {
|
TypedExpr::Sequence { expressions, .. } => {
|
||||||
for expr in expressions {
|
for expr in expressions {
|
||||||
self.build_ir(expr, ir_stack);
|
let mut scope = scope.clone();
|
||||||
|
scope.push(self.id_gen.next());
|
||||||
|
self.build_ir(expr, ir_stack, scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TypedExpr::Pipeline { expressions, .. } => {
|
TypedExpr::Pipeline { expressions, .. } => {
|
||||||
for expr in expressions {
|
for expr in expressions {
|
||||||
self.build_ir(expr, ir_stack);
|
let mut scope = scope.clone();
|
||||||
|
scope.push(self.id_gen.next());
|
||||||
|
self.build_ir(expr, ir_stack, scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TypedExpr::Var {
|
TypedExpr::Var {
|
||||||
constructor, name, ..
|
constructor, name, ..
|
||||||
} => {
|
} => {
|
||||||
ir_stack.push(IR::Var {
|
ir_stack.push(IR::Var {
|
||||||
|
scope,
|
||||||
constructor: constructor.clone(),
|
constructor: constructor.clone(),
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
});
|
});
|
||||||
|
@ -133,6 +155,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
ir_stack.push(IR::List {
|
ir_stack.push(IR::List {
|
||||||
|
scope: scope.clone(),
|
||||||
count: if tail.is_some() {
|
count: if tail.is_some() {
|
||||||
elements.len() + 1
|
elements.len() + 1
|
||||||
} else {
|
} else {
|
||||||
|
@ -143,34 +166,53 @@ impl<'a> CodeGenerator<'a> {
|
||||||
});
|
});
|
||||||
|
|
||||||
for element in elements {
|
for element in elements {
|
||||||
self.build_ir(element, ir_stack)
|
let mut scope = scope.clone();
|
||||||
|
scope.push(self.id_gen.next());
|
||||||
|
self.build_ir(element, ir_stack, scope.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(tail) = tail {
|
if let Some(tail) = tail {
|
||||||
ir_stack.push(IR::Tail { count: 1 });
|
let mut scope = scope;
|
||||||
self.build_ir(tail, ir_stack);
|
scope.push(self.id_gen.next());
|
||||||
|
ir_stack.push(IR::Tail {
|
||||||
|
scope: scope.clone(),
|
||||||
|
count: 1,
|
||||||
|
});
|
||||||
|
self.build_ir(tail, ir_stack, scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TypedExpr::Call { fun, args, .. } => {
|
TypedExpr::Call { fun, args, .. } => {
|
||||||
ir_stack.push(IR::Call {
|
ir_stack.push(IR::Call {
|
||||||
|
scope: scope.clone(),
|
||||||
count: args.len() + 1,
|
count: args.len() + 1,
|
||||||
});
|
});
|
||||||
self.build_ir(fun, ir_stack);
|
let mut scope_fun = scope.clone();
|
||||||
|
scope_fun.push(self.id_gen.next());
|
||||||
|
self.build_ir(fun, ir_stack, scope_fun);
|
||||||
|
|
||||||
for arg in args {
|
for arg in args {
|
||||||
self.build_ir(&arg.value, ir_stack);
|
let mut scope = scope.clone();
|
||||||
|
scope.push(self.id_gen.next());
|
||||||
|
self.build_ir(&arg.value, ir_stack, scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TypedExpr::BinOp {
|
TypedExpr::BinOp {
|
||||||
name, left, right, ..
|
name, left, right, ..
|
||||||
} => {
|
} => {
|
||||||
ir_stack.push(IR::BinOp {
|
ir_stack.push(IR::BinOp {
|
||||||
|
scope: scope.clone(),
|
||||||
name: *name,
|
name: *name,
|
||||||
count: 2,
|
count: 2,
|
||||||
tipo: left.tipo(),
|
tipo: left.tipo(),
|
||||||
});
|
});
|
||||||
self.build_ir(left, ir_stack);
|
let mut scope_left = scope.clone();
|
||||||
self.build_ir(right, ir_stack);
|
scope_left.push(self.id_gen.next());
|
||||||
|
|
||||||
|
let mut scope_right = scope;
|
||||||
|
scope_right.push(self.id_gen.next());
|
||||||
|
|
||||||
|
self.build_ir(left, ir_stack, scope_left);
|
||||||
|
self.build_ir(right, ir_stack, scope_right);
|
||||||
}
|
}
|
||||||
TypedExpr::Assignment {
|
TypedExpr::Assignment {
|
||||||
value,
|
value,
|
||||||
|
@ -182,15 +224,25 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let mut define_vec: Vec<IR> = vec![];
|
let mut define_vec: Vec<IR> = vec![];
|
||||||
let mut value_vec: Vec<IR> = vec![];
|
let mut value_vec: Vec<IR> = vec![];
|
||||||
let mut pattern_vec: Vec<IR> = vec![];
|
let mut pattern_vec: Vec<IR> = vec![];
|
||||||
self.build_ir(value, &mut value_vec);
|
|
||||||
self.define_ir(&value_vec, &mut define_vec);
|
|
||||||
|
|
||||||
self.assignment_ir(pattern, &mut pattern_vec, &mut value_vec, tipo, *kind);
|
let mut value_scope = scope.clone();
|
||||||
|
value_scope.push(self.id_gen.next());
|
||||||
|
|
||||||
|
self.build_ir(value, &mut value_vec, value_scope);
|
||||||
|
|
||||||
|
self.assignment_ir(
|
||||||
|
pattern,
|
||||||
|
&mut pattern_vec,
|
||||||
|
&mut value_vec,
|
||||||
|
tipo,
|
||||||
|
*kind,
|
||||||
|
scope,
|
||||||
|
);
|
||||||
|
|
||||||
ir_stack.append(&mut define_vec);
|
ir_stack.append(&mut define_vec);
|
||||||
ir_stack.append(&mut pattern_vec);
|
ir_stack.append(&mut pattern_vec);
|
||||||
}
|
}
|
||||||
TypedExpr::Try { .. } => todo!(),
|
TypedExpr::Trace { .. } => todo!(),
|
||||||
TypedExpr::When {
|
TypedExpr::When {
|
||||||
subjects, clauses, ..
|
subjects, clauses, ..
|
||||||
} => {
|
} => {
|
||||||
|
@ -206,13 +258,17 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let mut pattern_vec = vec![];
|
let mut pattern_vec = vec![];
|
||||||
|
|
||||||
for clause in clauses {
|
for clause in clauses {
|
||||||
|
let mut scope = scope.clone();
|
||||||
|
scope.push(self.id_gen.next());
|
||||||
|
|
||||||
pattern_vec.push(IR::Clause {
|
pattern_vec.push(IR::Clause {
|
||||||
|
scope: scope.clone(),
|
||||||
count: 2,
|
count: 2,
|
||||||
tipo: subject.tipo().clone(),
|
tipo: subject.tipo().clone(),
|
||||||
subject_name: subject_name.clone(),
|
subject_name: subject_name.clone(),
|
||||||
});
|
});
|
||||||
|
|
||||||
self.build_ir(&clause.then, &mut clauses_vec);
|
self.build_ir(&clause.then, &mut clauses_vec, scope.clone());
|
||||||
self.when_ir(
|
self.when_ir(
|
||||||
&clause.pattern[0],
|
&clause.pattern[0],
|
||||||
&mut pattern_vec,
|
&mut pattern_vec,
|
||||||
|
@ -220,13 +276,19 @@ impl<'a> CodeGenerator<'a> {
|
||||||
&subject.tipo(),
|
&subject.tipo(),
|
||||||
constr_var.clone(),
|
constr_var.clone(),
|
||||||
&mut needs_constr_var,
|
&mut needs_constr_var,
|
||||||
|
scope,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let last_pattern = &last_clause.pattern[0];
|
let last_pattern = &last_clause.pattern[0];
|
||||||
pattern_vec.push(IR::Finally);
|
|
||||||
|
|
||||||
self.build_ir(&last_clause.then, &mut clauses_vec);
|
let mut final_scope = scope.clone();
|
||||||
|
final_scope.push(self.id_gen.next());
|
||||||
|
pattern_vec.push(IR::Finally {
|
||||||
|
scope: final_scope.clone(),
|
||||||
|
});
|
||||||
|
|
||||||
|
self.build_ir(&last_clause.then, &mut clauses_vec, final_scope);
|
||||||
self.when_ir(
|
self.when_ir(
|
||||||
last_pattern,
|
last_pattern,
|
||||||
&mut pattern_vec,
|
&mut pattern_vec,
|
||||||
|
@ -234,22 +296,29 @@ impl<'a> CodeGenerator<'a> {
|
||||||
&subject.tipo(),
|
&subject.tipo(),
|
||||||
constr_var.clone(),
|
constr_var.clone(),
|
||||||
&mut needs_constr_var,
|
&mut needs_constr_var,
|
||||||
|
scope.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
if needs_constr_var {
|
if needs_constr_var {
|
||||||
ir_stack.push(IR::Lam {
|
ir_stack.push(IR::Lam {
|
||||||
|
scope: scope.clone(),
|
||||||
name: constr_var.clone(),
|
name: constr_var.clone(),
|
||||||
});
|
});
|
||||||
|
|
||||||
self.build_ir(&subject, ir_stack);
|
self.build_ir(&subject, ir_stack, scope.clone());
|
||||||
|
|
||||||
ir_stack.push(IR::When {
|
ir_stack.push(IR::When {
|
||||||
|
scope: scope.clone(),
|
||||||
count: clauses.len() + 1,
|
count: clauses.len() + 1,
|
||||||
subject_name,
|
subject_name,
|
||||||
tipo: subject.tipo(),
|
tipo: subject.tipo(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let mut scope = scope;
|
||||||
|
scope.push(self.id_gen.next());
|
||||||
|
|
||||||
ir_stack.push(IR::Var {
|
ir_stack.push(IR::Var {
|
||||||
|
scope,
|
||||||
constructor: ValueConstructor::public(
|
constructor: ValueConstructor::public(
|
||||||
subject.tipo(),
|
subject.tipo(),
|
||||||
ValueConstructorVariant::LocalVariable {
|
ValueConstructorVariant::LocalVariable {
|
||||||
|
@ -260,12 +329,16 @@ impl<'a> CodeGenerator<'a> {
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
ir_stack.push(IR::When {
|
ir_stack.push(IR::When {
|
||||||
|
scope: scope.clone(),
|
||||||
count: clauses.len() + 1,
|
count: clauses.len() + 1,
|
||||||
subject_name,
|
subject_name,
|
||||||
tipo: subject.tipo(),
|
tipo: subject.tipo(),
|
||||||
});
|
});
|
||||||
|
|
||||||
self.build_ir(&subject, ir_stack);
|
let mut scope = scope;
|
||||||
|
scope.push(self.id_gen.next());
|
||||||
|
|
||||||
|
self.build_ir(&subject, ir_stack, scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
ir_stack.append(&mut pattern_vec);
|
ir_stack.append(&mut pattern_vec);
|
||||||
|
@ -281,11 +354,12 @@ impl<'a> CodeGenerator<'a> {
|
||||||
self.needs_field_access = true;
|
self.needs_field_access = true;
|
||||||
|
|
||||||
ir_stack.push(IR::RecordAccess {
|
ir_stack.push(IR::RecordAccess {
|
||||||
|
scope: scope.clone(),
|
||||||
index: *index,
|
index: *index,
|
||||||
tipo: tipo.clone(),
|
tipo: tipo.clone(),
|
||||||
});
|
});
|
||||||
|
|
||||||
self.build_ir(record, ir_stack);
|
self.build_ir(record, ir_stack, scope);
|
||||||
}
|
}
|
||||||
TypedExpr::ModuleSelect {
|
TypedExpr::ModuleSelect {
|
||||||
constructor,
|
constructor,
|
||||||
|
@ -308,7 +382,10 @@ impl<'a> CodeGenerator<'a> {
|
||||||
ValueConstructorVariant::ModuleFn { builtin, .. } => {
|
ValueConstructorVariant::ModuleFn { builtin, .. } => {
|
||||||
let builtin = builtin.unwrap();
|
let builtin = builtin.unwrap();
|
||||||
|
|
||||||
ir_stack.push(IR::Builtin { func: builtin });
|
ir_stack.push(IR::Builtin {
|
||||||
|
func: builtin,
|
||||||
|
scope,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
@ -319,37 +396,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
TypedExpr::Todo { .. } => todo!(),
|
TypedExpr::Todo { .. } => todo!(),
|
||||||
TypedExpr::RecordUpdate { .. } => todo!(),
|
TypedExpr::RecordUpdate { .. } => todo!(),
|
||||||
TypedExpr::Negate { .. } => todo!(),
|
TypedExpr::Negate { .. } => todo!(),
|
||||||
}
|
TypedExpr::Tuple { .. } => todo!(),
|
||||||
}
|
|
||||||
|
|
||||||
fn define_ir(&self, value_vec: &Vec<IR>, _define_vec: &mut [IR]) {
|
|
||||||
// get value item
|
|
||||||
for value in value_vec {
|
|
||||||
match dbg!(value) {
|
|
||||||
IR::Int { .. } => {}
|
|
||||||
IR::Var { constructor, .. } => match constructor.variant {
|
|
||||||
ValueConstructorVariant::LocalVariable { .. } => {}
|
|
||||||
ValueConstructorVariant::ModuleConstant { .. } => todo!(),
|
|
||||||
ValueConstructorVariant::ModuleFn { .. } => todo!(),
|
|
||||||
ValueConstructorVariant::Record { .. } => {}
|
|
||||||
},
|
|
||||||
IR::Call { .. } => {}
|
|
||||||
IR::BinOp { .. } => {}
|
|
||||||
IR::When { .. } => todo!(),
|
|
||||||
IR::Clause { .. } => todo!(),
|
|
||||||
IR::Finally { .. } => todo!(),
|
|
||||||
IR::If { .. } => todo!(),
|
|
||||||
IR::Constr { .. } => todo!(),
|
|
||||||
IR::Fields { .. } => todo!(),
|
|
||||||
IR::RecordAccess { .. } => todo!(),
|
|
||||||
IR::FieldsExpose { .. } => todo!(),
|
|
||||||
IR::Todo { .. } => todo!(),
|
|
||||||
IR::RecordUpdate { .. } => todo!(),
|
|
||||||
IR::Negate { .. } => todo!(),
|
|
||||||
IR::Builtin { .. } => {}
|
|
||||||
IR::List { .. } => {}
|
|
||||||
_ => todo!(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,6 +407,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
value_vec: &mut Vec<IR>,
|
value_vec: &mut Vec<IR>,
|
||||||
_tipo: &Type,
|
_tipo: &Type,
|
||||||
kind: AssignmentKind,
|
kind: AssignmentKind,
|
||||||
|
scope: Vec<u64>,
|
||||||
) {
|
) {
|
||||||
match pattern {
|
match pattern {
|
||||||
Pattern::Int { .. } => todo!(),
|
Pattern::Int { .. } => todo!(),
|
||||||
|
@ -368,6 +416,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
pattern_vec.push(IR::Assignment {
|
pattern_vec.push(IR::Assignment {
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
kind,
|
kind,
|
||||||
|
scope,
|
||||||
});
|
});
|
||||||
|
|
||||||
pattern_vec.append(value_vec);
|
pattern_vec.append(value_vec);
|
||||||
|
@ -376,9 +425,10 @@ impl<'a> CodeGenerator<'a> {
|
||||||
Pattern::Assign { .. } => todo!(),
|
Pattern::Assign { .. } => todo!(),
|
||||||
Pattern::Discard { .. } => todo!(),
|
Pattern::Discard { .. } => todo!(),
|
||||||
list @ Pattern::List { .. } => {
|
list @ Pattern::List { .. } => {
|
||||||
self.pattern_ir(list, pattern_vec, value_vec);
|
self.pattern_ir(list, pattern_vec, value_vec, scope);
|
||||||
}
|
}
|
||||||
Pattern::Constructor { .. } => todo!(),
|
Pattern::Constructor { .. } => todo!(),
|
||||||
|
Pattern::Tuple { .. } => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -390,10 +440,12 @@ impl<'a> CodeGenerator<'a> {
|
||||||
tipo: &Type,
|
tipo: &Type,
|
||||||
constr_var: String,
|
constr_var: String,
|
||||||
needs_constr_var: &mut bool,
|
needs_constr_var: &mut bool,
|
||||||
|
scope: Vec<u64>,
|
||||||
) {
|
) {
|
||||||
match pattern {
|
match pattern {
|
||||||
Pattern::Int { value, .. } => {
|
Pattern::Int { value, .. } => {
|
||||||
pattern_vec.push(IR::Int {
|
pattern_vec.push(IR::Int {
|
||||||
|
scope,
|
||||||
value: value.clone(),
|
value: value.clone(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -426,17 +478,19 @@ impl<'a> CodeGenerator<'a> {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
name: constr_var,
|
name: constr_var,
|
||||||
|
scope: scope.clone(),
|
||||||
}];
|
}];
|
||||||
|
|
||||||
if needs_access_to_constr_var {
|
if needs_access_to_constr_var {
|
||||||
*needs_constr_var = true;
|
*needs_constr_var = true;
|
||||||
new_vec.append(values);
|
new_vec.append(values);
|
||||||
|
|
||||||
self.pattern_ir(pattern, pattern_vec, &mut new_vec);
|
self.pattern_ir(pattern, pattern_vec, &mut new_vec, scope);
|
||||||
} else {
|
} else {
|
||||||
self.pattern_ir(pattern, pattern_vec, values);
|
self.pattern_ir(pattern, pattern_vec, values, scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Pattern::Tuple { .. } => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,6 +499,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
pattern: &Pattern<tipo::PatternConstructor, Arc<tipo::Type>>,
|
pattern: &Pattern<tipo::PatternConstructor, Arc<tipo::Type>>,
|
||||||
pattern_vec: &mut Vec<IR>,
|
pattern_vec: &mut Vec<IR>,
|
||||||
values: &mut Vec<IR>,
|
values: &mut Vec<IR>,
|
||||||
|
scope: Vec<u64>,
|
||||||
) {
|
) {
|
||||||
match dbg!(pattern) {
|
match dbg!(pattern) {
|
||||||
Pattern::Int { .. } => todo!(),
|
Pattern::Int { .. } => todo!(),
|
||||||
|
@ -453,7 +508,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
Pattern::VarUsage { .. } => todo!(),
|
Pattern::VarUsage { .. } => todo!(),
|
||||||
Pattern::Assign { .. } => todo!(),
|
Pattern::Assign { .. } => todo!(),
|
||||||
Pattern::Discard { .. } => {
|
Pattern::Discard { .. } => {
|
||||||
pattern_vec.push(IR::Discard);
|
pattern_vec.push(IR::Discard { scope });
|
||||||
|
|
||||||
pattern_vec.append(values);
|
pattern_vec.append(values);
|
||||||
}
|
}
|
||||||
|
@ -484,8 +539,9 @@ impl<'a> CodeGenerator<'a> {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
name: item_name,
|
name: item_name,
|
||||||
|
scope: scope.clone(),
|
||||||
});
|
});
|
||||||
self.pattern_ir(a, &mut elements_vec, &mut var_vec);
|
self.pattern_ir(a, &mut elements_vec, &mut var_vec, scope.clone());
|
||||||
}
|
}
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
|
@ -502,6 +558,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
pattern_vec.push(IR::ListAccessor {
|
pattern_vec.push(IR::ListAccessor {
|
||||||
names,
|
names,
|
||||||
tail: tail.is_some(),
|
tail: tail.is_some(),
|
||||||
|
scope,
|
||||||
});
|
});
|
||||||
|
|
||||||
pattern_vec.append(values);
|
pattern_vec.append(values);
|
||||||
|
@ -541,6 +598,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
// push constructor Index
|
// push constructor Index
|
||||||
pattern_vec.push(IR::Int {
|
pattern_vec.push(IR::Int {
|
||||||
value: index.to_string(),
|
value: index.to_string(),
|
||||||
|
scope: scope.clone(),
|
||||||
});
|
});
|
||||||
|
|
||||||
if *is_record {
|
if *is_record {
|
||||||
|
@ -588,6 +646,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
(*index, var_name.clone(), field_type.clone())
|
(*index, var_name.clone(), field_type.clone())
|
||||||
})
|
})
|
||||||
.collect_vec(),
|
.collect_vec(),
|
||||||
|
scope,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -627,11 +686,13 @@ impl<'a> CodeGenerator<'a> {
|
||||||
(*index, name.clone(), field_type.clone())
|
(*index, name.clone(), field_type.clone())
|
||||||
})
|
})
|
||||||
.collect_vec(),
|
.collect_vec(),
|
||||||
|
scope,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pattern_vec.append(values);
|
pattern_vec.append(values);
|
||||||
}
|
}
|
||||||
|
Pattern::Tuple { .. } => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -647,23 +708,25 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
fn gen_uplc(&mut self, ir: IR, arg_stack: &mut Vec<Term<Name>>) {
|
fn gen_uplc(&mut self, ir: IR, arg_stack: &mut Vec<Term<Name>>) {
|
||||||
match ir {
|
match ir {
|
||||||
IR::Int { value } => {
|
IR::Int { value, .. } => {
|
||||||
let integer = value.parse().unwrap();
|
let integer = value.parse().unwrap();
|
||||||
|
|
||||||
let term = Term::Constant(Constant::Integer(integer));
|
let term = Term::Constant(Constant::Integer(integer));
|
||||||
|
|
||||||
arg_stack.push(term);
|
arg_stack.push(term);
|
||||||
}
|
}
|
||||||
IR::String { value } => {
|
IR::String { value, .. } => {
|
||||||
let term = Term::Constant(Constant::String(value));
|
let term = Term::Constant(Constant::String(value));
|
||||||
|
|
||||||
arg_stack.push(term);
|
arg_stack.push(term);
|
||||||
}
|
}
|
||||||
IR::ByteArray { bytes } => {
|
IR::ByteArray { bytes, .. } => {
|
||||||
let term = Term::Constant(Constant::ByteString(bytes));
|
let term = Term::Constant(Constant::ByteString(bytes));
|
||||||
arg_stack.push(term);
|
arg_stack.push(term);
|
||||||
}
|
}
|
||||||
IR::Var { name, constructor } => match constructor.variant {
|
IR::Var {
|
||||||
|
name, constructor, ..
|
||||||
|
} => match constructor.variant {
|
||||||
ValueConstructorVariant::LocalVariable { .. } => arg_stack.push(Term::Var(Name {
|
ValueConstructorVariant::LocalVariable { .. } => arg_stack.push(Term::Var(Name {
|
||||||
text: name,
|
text: name,
|
||||||
unique: 0.into(),
|
unique: 0.into(),
|
||||||
|
@ -686,6 +749,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
},
|
},
|
||||||
Type::Var { .. } => todo!(),
|
Type::Var { .. } => todo!(),
|
||||||
|
Type::Tuple { .. } => todo!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if data_type_key.defined_type == "Bool" {
|
if data_type_key.defined_type == "Bool" {
|
||||||
|
@ -720,10 +784,12 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
IR::Discard => {
|
IR::Discard { .. } => {
|
||||||
arg_stack.push(Term::Constant(Constant::Unit));
|
arg_stack.push(Term::Constant(Constant::Unit));
|
||||||
}
|
}
|
||||||
IR::List { count, tipo, tail } => {
|
IR::List {
|
||||||
|
count, tipo, tail, ..
|
||||||
|
} => {
|
||||||
let mut args = vec![];
|
let mut args = vec![];
|
||||||
|
|
||||||
for _ in 0..count {
|
for _ in 0..count {
|
||||||
|
@ -772,7 +838,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
IR::Tail { .. } => todo!(),
|
IR::Tail { .. } => todo!(),
|
||||||
IR::ListAccessor { names, tail } => {
|
IR::ListAccessor { names, tail, .. } => {
|
||||||
let value = arg_stack.pop().unwrap();
|
let value = arg_stack.pop().unwrap();
|
||||||
let mut term = arg_stack.pop().unwrap();
|
let mut term = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
|
@ -822,7 +888,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
arg_stack.push(term);
|
arg_stack.push(term);
|
||||||
}
|
}
|
||||||
IR::Call { count } => {
|
IR::Call { count, .. } => {
|
||||||
if count >= 2 {
|
if count >= 2 {
|
||||||
let mut term = arg_stack.pop().unwrap();
|
let mut term = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
|
@ -839,7 +905,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IR::Builtin { func } => {
|
IR::Builtin { func, .. } => {
|
||||||
let mut term = Term::Builtin(func);
|
let mut term = Term::Builtin(func);
|
||||||
for _ in 0..func.force_count() {
|
for _ in 0..func.force_count() {
|
||||||
term = Term::Force(term.into());
|
term = Term::Force(term.into());
|
||||||
|
@ -1013,7 +1079,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
IR::DefineConst { .. } => todo!(),
|
IR::DefineConst { .. } => todo!(),
|
||||||
IR::DefineConstrFields { .. } => todo!(),
|
IR::DefineConstrFields { .. } => todo!(),
|
||||||
IR::DefineConstrFieldAccess { .. } => todo!(),
|
IR::DefineConstrFieldAccess { .. } => todo!(),
|
||||||
IR::Lam { name } => {
|
IR::Lam { name, .. } => {
|
||||||
let arg = arg_stack.pop().unwrap();
|
let arg = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
let mut term = arg_stack.pop().unwrap();
|
let mut term = arg_stack.pop().unwrap();
|
||||||
|
@ -1141,13 +1207,13 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
arg_stack.push(term);
|
arg_stack.push(term);
|
||||||
}
|
}
|
||||||
IR::Finally => {
|
IR::Finally { .. } => {
|
||||||
let _clause = arg_stack.pop().unwrap();
|
let _clause = arg_stack.pop().unwrap();
|
||||||
}
|
}
|
||||||
IR::If { .. } => todo!(),
|
IR::If { .. } => todo!(),
|
||||||
IR::Constr { .. } => todo!(),
|
IR::Constr { .. } => todo!(),
|
||||||
IR::Fields { .. } => todo!(),
|
IR::Fields { .. } => todo!(),
|
||||||
IR::RecordAccess { index, tipo } => {
|
IR::RecordAccess { index, tipo, .. } => {
|
||||||
let constr = arg_stack.pop().unwrap();
|
let constr = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
let mut term = Term::Apply {
|
let mut term = Term::Apply {
|
||||||
|
@ -1193,6 +1259,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
IR::FieldsExpose {
|
IR::FieldsExpose {
|
||||||
count: _count,
|
count: _count,
|
||||||
indices,
|
indices,
|
||||||
|
..
|
||||||
} => {
|
} => {
|
||||||
self.needs_field_access = true;
|
self.needs_field_access = true;
|
||||||
|
|
||||||
|
@ -1436,6 +1503,204 @@ impl<'a> CodeGenerator<'a> {
|
||||||
IR::Negate { .. } => todo!(),
|
IR::Negate { .. } => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn define_ir(&mut self, ir_stack: &mut Vec<IR>) {
|
||||||
|
let mut to_be_defined_map: IndexMap<FunctionAccessKey, Vec<u64>> = IndexMap::new();
|
||||||
|
let mut defined_func_and_calls: IndexMap<FunctionAccessKey, FuncComponents> =
|
||||||
|
IndexMap::new();
|
||||||
|
let mut func_index_map: IndexMap<FunctionAccessKey, (usize, Vec<u64>)> = IndexMap::new();
|
||||||
|
|
||||||
|
for (index, ir) in ir_stack.iter().enumerate().rev() {
|
||||||
|
match ir {
|
||||||
|
IR::Var {
|
||||||
|
scope, constructor, ..
|
||||||
|
} => {
|
||||||
|
if let ValueConstructorVariant::ModuleFn {
|
||||||
|
name,
|
||||||
|
module,
|
||||||
|
builtin,
|
||||||
|
..
|
||||||
|
} = &constructor.variant
|
||||||
|
{
|
||||||
|
if builtin.is_none() {
|
||||||
|
let function_key = FunctionAccessKey {
|
||||||
|
module_name: module.clone(),
|
||||||
|
function_name: name.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(scope_prev) = to_be_defined_map.get(&function_key) {
|
||||||
|
let new_scope = get_common_ancestor(scope, scope_prev);
|
||||||
|
|
||||||
|
to_be_defined_map.insert(function_key, new_scope);
|
||||||
|
} else if defined_func_and_calls.get(&function_key).is_some() {
|
||||||
|
to_be_defined_map.insert(function_key.clone(), scope.to_vec());
|
||||||
|
} else {
|
||||||
|
let function = self.functions.get(&function_key).unwrap();
|
||||||
|
|
||||||
|
let mut func_ir = vec![];
|
||||||
|
|
||||||
|
self.build_ir(&function.body, &mut func_ir, scope.to_vec());
|
||||||
|
|
||||||
|
to_be_defined_map.insert(function_key.clone(), scope.to_vec());
|
||||||
|
let mut func_calls = vec![];
|
||||||
|
|
||||||
|
for ir in func_ir.clone() {
|
||||||
|
if let IR::Var {
|
||||||
|
constructor:
|
||||||
|
ValueConstructor {
|
||||||
|
variant:
|
||||||
|
ValueConstructorVariant::ModuleFn {
|
||||||
|
name: func_name,
|
||||||
|
module,
|
||||||
|
..
|
||||||
|
},
|
||||||
|
..
|
||||||
|
},
|
||||||
|
..
|
||||||
|
} = ir
|
||||||
|
{
|
||||||
|
func_calls.push(FunctionAccessKey {
|
||||||
|
module_name: module.clone(),
|
||||||
|
function_name: func_name.clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut args = vec![];
|
||||||
|
|
||||||
|
for arg in function.arguments.iter() {
|
||||||
|
match &arg.arg_name {
|
||||||
|
ArgName::Named { name, .. }
|
||||||
|
| ArgName::NamedLabeled { name, .. } => {
|
||||||
|
args.push(name.clone());
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Ok(index) = func_calls.binary_search(&function_key) {
|
||||||
|
func_calls.remove(index);
|
||||||
|
defined_func_and_calls.insert(
|
||||||
|
function_key,
|
||||||
|
FuncComponents {
|
||||||
|
ir: func_ir,
|
||||||
|
dependencies: func_calls,
|
||||||
|
recursive: true,
|
||||||
|
args,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
defined_func_and_calls.insert(
|
||||||
|
function_key,
|
||||||
|
FuncComponents {
|
||||||
|
ir: func_ir,
|
||||||
|
dependencies: func_calls,
|
||||||
|
recursive: false,
|
||||||
|
args,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a => {
|
||||||
|
let scope = a.scope();
|
||||||
|
|
||||||
|
for func in to_be_defined_map.clone().iter() {
|
||||||
|
println!(
|
||||||
|
"MADE IT HERE 222 and func_scope is {:#?} and scope is {:#?}",
|
||||||
|
func.1.clone(),
|
||||||
|
scope.clone()
|
||||||
|
);
|
||||||
|
|
||||||
|
if dbg!(get_common_ancestor(&scope, func.1) == scope.to_vec()) {
|
||||||
|
if let Some((_, index_scope)) = func_index_map.get(func.0) {
|
||||||
|
if get_common_ancestor(index_scope, func.1) == scope.to_vec() {
|
||||||
|
println!("DID insert again");
|
||||||
|
func_index_map.insert(func.0.clone(), (index, scope.clone()));
|
||||||
|
to_be_defined_map.shift_remove(func.0);
|
||||||
|
} else {
|
||||||
|
println!(
|
||||||
|
"DID update, index_scope is {:#?} and func is {:#?}",
|
||||||
|
index_scope, func.1
|
||||||
|
);
|
||||||
|
to_be_defined_map.insert(
|
||||||
|
func.0.clone(),
|
||||||
|
get_common_ancestor(index_scope, func.1),
|
||||||
|
);
|
||||||
|
println!("to_be_defined: {:#?}", to_be_defined_map);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
println!("DID insert");
|
||||||
|
func_index_map.insert(func.0.clone(), (index, scope.clone()));
|
||||||
|
to_be_defined_map.shift_remove(func.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for func_index in func_index_map.iter() {
|
||||||
|
println!("INDEX FUNC IS {func_index:#?}");
|
||||||
|
let func = func_index.0;
|
||||||
|
let (index, scope) = func_index.1;
|
||||||
|
|
||||||
|
let function_components = defined_func_and_calls.get(func).unwrap();
|
||||||
|
let dependencies = function_components.dependencies.clone();
|
||||||
|
|
||||||
|
let mut sorted_functions = vec![];
|
||||||
|
|
||||||
|
for dependency in dependencies {
|
||||||
|
let (_, dependency_scope) = func_index_map.get(&dependency).unwrap();
|
||||||
|
if get_common_ancestor(scope, dependency_scope) == scope.clone() {
|
||||||
|
let components = defined_func_and_calls.get(&dependency).unwrap();
|
||||||
|
let mut dependency_ir = components.ir.clone();
|
||||||
|
self.define_ir(&mut dependency_ir);
|
||||||
|
sorted_functions.append(&mut dependency_ir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !self.defined_functions.contains_key(func) {
|
||||||
|
for item in sorted_functions.into_iter().rev() {
|
||||||
|
ir_stack.insert(*index, item);
|
||||||
|
}
|
||||||
|
ir_stack.insert(
|
||||||
|
*index,
|
||||||
|
IR::DefineFunc {
|
||||||
|
scope: scope.clone(),
|
||||||
|
func_name: func.function_name.clone(),
|
||||||
|
module_name: func.module_name.clone(),
|
||||||
|
params: function_components.args.clone(),
|
||||||
|
recursive: function_components.recursive,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
self.defined_functions.insert(func.clone(), ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_common_ancestor(scope: &[u64], scope_prev: &[u64]) -> Vec<u64> {
|
||||||
|
let longest_length = if scope.len() >= scope_prev.len() {
|
||||||
|
scope.len()
|
||||||
|
} else {
|
||||||
|
scope_prev.len()
|
||||||
|
};
|
||||||
|
|
||||||
|
if *scope == *scope_prev {
|
||||||
|
return scope.to_vec();
|
||||||
|
}
|
||||||
|
|
||||||
|
for index in 0..longest_length {
|
||||||
|
if scope.get(index).is_none() {
|
||||||
|
return scope.to_vec();
|
||||||
|
} else if scope_prev.get(index).is_none() {
|
||||||
|
return scope_prev.to_vec();
|
||||||
|
} else if scope[index] != scope_prev[index] {
|
||||||
|
return scope[0..index].to_vec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vec![]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list_access_to_uplc(
|
fn list_access_to_uplc(
|
||||||
|
|
|
@ -51,8 +51,8 @@ pub type Datum {
|
||||||
|
|
||||||
pub fn spend(datum: Datum, _rdmr: Nil, _ctx: Nil) -> Bool {
|
pub fn spend(datum: Datum, _rdmr: Nil, _ctx: Nil) -> Bool {
|
||||||
when datum is {
|
when datum is {
|
||||||
Offer { price, thing: t, .. } -> price > 0
|
Offer { price, thing: t, .. } -> add_one(price) > 0
|
||||||
Hold(less) -> less < 0
|
Hold(less) -> less < 0
|
||||||
Sell -> False
|
Sell -> add_one(1) > 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue