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
	
	 KtorZ
						KtorZ