Allow serialisable (Data-able) arguments to trace
Somehow, we have to patch some function in gen_uplc because of the module name. I have to look further into this because it isn't normal.
This commit is contained in:
parent
beb5ac4643
commit
f8236817fe
|
@ -43,7 +43,6 @@ use itertools::Itertools;
|
||||||
use petgraph::{algo, Graph};
|
use petgraph::{algo, Graph};
|
||||||
use std::{collections::HashMap, rc::Rc};
|
use std::{collections::HashMap, rc::Rc};
|
||||||
use tree::Fields;
|
use tree::Fields;
|
||||||
|
|
||||||
use uplc::{
|
use uplc::{
|
||||||
ast::{Constant as UplcConstant, Name, NamedDeBruijn, Program, Term, Type as UplcType},
|
ast::{Constant as UplcConstant, Name, NamedDeBruijn, Program, Term, Type as UplcType},
|
||||||
builder::{CONSTR_FIELDS_EXPOSER, CONSTR_INDEX_EXPOSER, EXPECT_ON_LIST},
|
builder::{CONSTR_FIELDS_EXPOSER, CONSTR_INDEX_EXPOSER, EXPECT_ON_LIST},
|
||||||
|
@ -749,7 +748,11 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
ModuleValueConstructor::Fn { name, module, .. } => {
|
ModuleValueConstructor::Fn { name, module, .. } => {
|
||||||
let func = self.functions.get(&FunctionAccessKey {
|
let func = self.functions.get(&FunctionAccessKey {
|
||||||
module_name: module_name.clone(),
|
module_name: if module_name == "aiken" {
|
||||||
|
"".to_string()
|
||||||
|
} else {
|
||||||
|
module_name.clone()
|
||||||
|
},
|
||||||
function_name: name.clone(),
|
function_name: name.clone(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,8 @@ use crate::{
|
||||||
UntypedRecordUpdateArg,
|
UntypedRecordUpdateArg,
|
||||||
},
|
},
|
||||||
builtins::{
|
builtins::{
|
||||||
bool, byte_array, from_default_function, function, g1_element, g2_element, int, list, pair,
|
bool, byte_array, data, from_default_function, function, g1_element, g2_element, int, list,
|
||||||
string, tuple, void, BUILTIN,
|
pair, string, tuple, void, BUILTIN, PRELUDE,
|
||||||
},
|
},
|
||||||
expr::{FnStyle, TypedExpr, UntypedExpr},
|
expr::{FnStyle, TypedExpr, UntypedExpr},
|
||||||
format,
|
format,
|
||||||
|
@ -2407,6 +2407,17 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
TypedExpr::ErrorTerm { location, tipo }
|
TypedExpr::ErrorTerm { location, tipo }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn infer_trace_arg(&mut self, arg: UntypedExpr) -> Result<TypedExpr, Error> {
|
||||||
|
let typed_arg = self.infer(arg)?;
|
||||||
|
match self.unify(string(), typed_arg.tipo(), typed_arg.location(), false) {
|
||||||
|
Err(_) => {
|
||||||
|
self.unify(data(), typed_arg.tipo(), typed_arg.location(), true)?;
|
||||||
|
Ok(diagnose_expr(typed_arg))
|
||||||
|
}
|
||||||
|
Ok(()) => Ok(typed_arg),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn infer_trace(
|
fn infer_trace(
|
||||||
&mut self,
|
&mut self,
|
||||||
kind: TraceKind,
|
kind: TraceKind,
|
||||||
|
@ -2415,16 +2426,11 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
label: UntypedExpr,
|
label: UntypedExpr,
|
||||||
arguments: Vec<UntypedExpr>,
|
arguments: Vec<UntypedExpr>,
|
||||||
) -> Result<TypedExpr, Error> {
|
) -> Result<TypedExpr, Error> {
|
||||||
let label = self.infer(label)?;
|
let label = self.infer_trace_arg(label)?;
|
||||||
self.unify(string(), label.tipo(), label.location(), false)?;
|
|
||||||
|
|
||||||
let typed_arguments = arguments
|
let typed_arguments = arguments
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|arg| {
|
.map(|arg| self.infer_trace_arg(arg))
|
||||||
let arg = self.infer(arg)?;
|
|
||||||
self.unify(string(), arg.tipo(), arg.location(), false)?;
|
|
||||||
Ok(arg)
|
|
||||||
})
|
|
||||||
.collect::<Result<Vec<_>, Error>>()?;
|
.collect::<Result<Vec<_>, Error>>()?;
|
||||||
|
|
||||||
let text = if typed_arguments.is_empty() {
|
let text = if typed_arguments.is_empty() {
|
||||||
|
@ -2815,15 +2821,84 @@ pub fn ensure_serialisable(is_top_level: bool, t: Rc<Type>, location: Span) -> R
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn append_string_expr(left: TypedExpr, right: TypedExpr) -> TypedExpr {
|
fn diagnose_expr(expr: TypedExpr) -> TypedExpr {
|
||||||
let value_constructor =
|
// NOTE: The IdGenerator is unused. See similar note in 'append_string_expr'
|
||||||
from_default_function(DefaultFunction::AppendString, &IdGenerator::new());
|
let decode_utf8_constructor =
|
||||||
let append_string = TypedExpr::ModuleSelect {
|
from_default_function(DefaultFunction::DecodeUtf8, &IdGenerator::new());
|
||||||
|
|
||||||
|
let decode_utf8 = TypedExpr::ModuleSelect {
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
tipo: value_constructor.tipo,
|
tipo: decode_utf8_constructor.tipo.clone(),
|
||||||
label: DefaultFunction::AppendString.aiken_name(),
|
label: DefaultFunction::DecodeUtf8.aiken_name(),
|
||||||
module_name: BUILTIN.to_string(),
|
module_name: BUILTIN.to_string(),
|
||||||
module_alias: BUILTIN.to_string(),
|
module_alias: BUILTIN.to_string(),
|
||||||
|
constructor: decode_utf8_constructor.variant.to_module_value_constructor(
|
||||||
|
decode_utf8_constructor.tipo,
|
||||||
|
BUILTIN,
|
||||||
|
&DefaultFunction::AppendString.aiken_name(),
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
let diagnostic_constructor = ValueConstructor::public(
|
||||||
|
function(vec![data(), byte_array()], byte_array()),
|
||||||
|
ValueConstructorVariant::ModuleFn {
|
||||||
|
name: "diagnostic".to_string(),
|
||||||
|
field_map: None,
|
||||||
|
module: PRELUDE.to_string(),
|
||||||
|
arity: 2,
|
||||||
|
location: Span::empty(),
|
||||||
|
builtin: None,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
let diagnostic = TypedExpr::ModuleSelect {
|
||||||
|
location: Span::empty(),
|
||||||
|
tipo: diagnostic_constructor.tipo.clone(),
|
||||||
|
label: "diagnostic".to_string(),
|
||||||
|
module_name: PRELUDE.to_string(),
|
||||||
|
module_alias: "".to_string(),
|
||||||
|
constructor: diagnostic_constructor.variant.to_module_value_constructor(
|
||||||
|
diagnostic_constructor.tipo,
|
||||||
|
"",
|
||||||
|
"diagnostic",
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
let location = expr.location();
|
||||||
|
|
||||||
|
TypedExpr::Call {
|
||||||
|
tipo: string(),
|
||||||
|
fun: Box::new(decode_utf8.clone()),
|
||||||
|
args: vec![CallArg {
|
||||||
|
label: None,
|
||||||
|
location: expr.location(),
|
||||||
|
value: TypedExpr::Call {
|
||||||
|
tipo: string(),
|
||||||
|
fun: Box::new(diagnostic.clone()),
|
||||||
|
args: vec![
|
||||||
|
CallArg {
|
||||||
|
label: None,
|
||||||
|
value: expr,
|
||||||
|
location,
|
||||||
|
},
|
||||||
|
CallArg {
|
||||||
|
label: None,
|
||||||
|
location,
|
||||||
|
value: TypedExpr::ByteArray {
|
||||||
|
tipo: byte_array(),
|
||||||
|
bytes: vec![],
|
||||||
|
location,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
location,
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
location,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn append_string_expr(left: TypedExpr, right: TypedExpr) -> TypedExpr {
|
||||||
// NOTE: The IdGenerator is unused here, as it's only necessary for generic builtin
|
// NOTE: The IdGenerator is unused here, as it's only necessary for generic builtin
|
||||||
// functions such as if_then_else or head_list. However, if such functions were needed,
|
// functions such as if_then_else or head_list. However, if such functions were needed,
|
||||||
// passing a brand new IdGenerator here would be WRONG and cause issues down the line.
|
// passing a brand new IdGenerator here would be WRONG and cause issues down the line.
|
||||||
|
@ -2831,8 +2906,17 @@ pub fn append_string_expr(left: TypedExpr, right: TypedExpr) -> TypedExpr {
|
||||||
// So this is merely a small work-around for convenience. The proper way here would be to
|
// So this is merely a small work-around for convenience. The proper way here would be to
|
||||||
// pull the function definition for append_string from the pre-registered builtins
|
// pull the function definition for append_string from the pre-registered builtins
|
||||||
// functions somewhere in the environment.
|
// functions somewhere in the environment.
|
||||||
|
let value_constructor =
|
||||||
|
from_default_function(DefaultFunction::AppendString, &IdGenerator::new());
|
||||||
|
|
||||||
|
let append_string = TypedExpr::ModuleSelect {
|
||||||
|
location: Span::empty(),
|
||||||
|
tipo: value_constructor.tipo.clone(),
|
||||||
|
label: DefaultFunction::AppendString.aiken_name(),
|
||||||
|
module_name: BUILTIN.to_string(),
|
||||||
|
module_alias: BUILTIN.to_string(),
|
||||||
constructor: value_constructor.variant.to_module_value_constructor(
|
constructor: value_constructor.variant.to_module_value_constructor(
|
||||||
string(),
|
value_constructor.tipo,
|
||||||
BUILTIN,
|
BUILTIN,
|
||||||
&DefaultFunction::AppendString.aiken_name(),
|
&DefaultFunction::AppendString.aiken_name(),
|
||||||
),
|
),
|
||||||
|
|
Loading…
Reference in New Issue