feat: function insertion IR done, code gen will be easy

This commit is contained in:
Kasey White 2022-11-29 13:37:16 -05:00 committed by Lucas
parent 4129cf92c9
commit 02ee129615
4 changed files with 413 additions and 78 deletions

View File

@ -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 }
// } // }

View File

@ -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, ..
} => { } => {

View File

@ -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(

View File

@ -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
} }
} }