Allow any expression as constants
This is only a start. It compiles, but with a few TODOs left open. In particular, it doesn't currently handle constants depending on other constants or functions; nor does it hoist constants.
This commit is contained in:
parent
79cf0b8d97
commit
cd0a9440e8
|
@ -161,6 +161,7 @@ impl TypedModule {
|
||||||
pub fn register_definitions(
|
pub fn register_definitions(
|
||||||
&self,
|
&self,
|
||||||
functions: &mut IndexMap<FunctionAccessKey, TypedFunction>,
|
functions: &mut IndexMap<FunctionAccessKey, TypedFunction>,
|
||||||
|
constants: &mut IndexMap<FunctionAccessKey, TypedExpr>,
|
||||||
data_types: &mut IndexMap<DataTypeKey, TypedDataType>,
|
data_types: &mut IndexMap<DataTypeKey, TypedDataType>,
|
||||||
) {
|
) {
|
||||||
for def in self.definitions() {
|
for def in self.definitions() {
|
||||||
|
@ -203,7 +204,17 @@ impl TypedModule {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Definition::TypeAlias(_) | Definition::ModuleConstant(_) | Definition::Use(_) => {}
|
Definition::ModuleConstant(ModuleConstant { name, value, .. }) => {
|
||||||
|
constants.insert(
|
||||||
|
FunctionAccessKey {
|
||||||
|
module_name: self.name.clone(),
|
||||||
|
function_name: name.clone(),
|
||||||
|
},
|
||||||
|
value.clone(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Definition::TypeAlias(_) | Definition::Use(_) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -459,18 +470,17 @@ pub struct Use<PackageName> {
|
||||||
pub unqualified: Vec<UnqualifiedImport>,
|
pub unqualified: Vec<UnqualifiedImport>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type TypedModuleConstant = ModuleConstant<Rc<Type>>;
|
pub type TypedModuleConstant = ModuleConstant<TypedExpr>;
|
||||||
pub type UntypedModuleConstant = ModuleConstant<()>;
|
pub type UntypedModuleConstant = ModuleConstant<UntypedExpr>;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||||
pub struct ModuleConstant<T> {
|
pub struct ModuleConstant<Expr> {
|
||||||
pub doc: Option<String>,
|
pub doc: Option<String>,
|
||||||
pub location: Span,
|
pub location: Span,
|
||||||
pub public: bool,
|
pub public: bool,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub annotation: Option<Annotation>,
|
pub annotation: Option<Annotation>,
|
||||||
pub value: Box<Constant>,
|
pub value: Expr,
|
||||||
pub tipo: T,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type TypedValidator = Validator<Rc<Type>, TypedArg, TypedExpr>;
|
pub type TypedValidator = Validator<Rc<Type>, TypedArg, TypedExpr>;
|
||||||
|
@ -746,7 +756,7 @@ pub enum Definition<T, Arg, Expr, PackageName> {
|
||||||
|
|
||||||
Use(Use<PackageName>),
|
Use(Use<PackageName>),
|
||||||
|
|
||||||
ModuleConstant(ModuleConstant<T>),
|
ModuleConstant(ModuleConstant<Expr>),
|
||||||
|
|
||||||
Test(Function<T, Expr, ArgVia<Arg, Expr>>),
|
Test(Function<T, Expr, ArgVia<Arg, Expr>>),
|
||||||
|
|
||||||
|
@ -843,55 +853,6 @@ pub struct DefinitionLocation<'module> {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
|
|
||||||
pub enum Constant {
|
|
||||||
Int {
|
|
||||||
location: Span,
|
|
||||||
value: String,
|
|
||||||
base: Base,
|
|
||||||
},
|
|
||||||
|
|
||||||
String {
|
|
||||||
location: Span,
|
|
||||||
value: String,
|
|
||||||
},
|
|
||||||
|
|
||||||
ByteArray {
|
|
||||||
location: Span,
|
|
||||||
bytes: Vec<u8>,
|
|
||||||
preferred_format: ByteArrayFormatPreference,
|
|
||||||
},
|
|
||||||
|
|
||||||
CurvePoint {
|
|
||||||
location: Span,
|
|
||||||
point: Box<Curve>,
|
|
||||||
preferred_format: ByteArrayFormatPreference,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Constant {
|
|
||||||
pub fn tipo(&self) -> Rc<Type> {
|
|
||||||
match self {
|
|
||||||
Constant::Int { .. } => Type::int(),
|
|
||||||
Constant::String { .. } => Type::string(),
|
|
||||||
Constant::ByteArray { .. } => Type::byte_array(),
|
|
||||||
Constant::CurvePoint { point, .. } => match point.as_ref() {
|
|
||||||
Curve::Bls12_381(Bls12_381Point::G1(_)) => Type::g1_element(),
|
|
||||||
Curve::Bls12_381(Bls12_381Point::G2(_)) => Type::g2_element(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn location(&self) -> Span {
|
|
||||||
match self {
|
|
||||||
Constant::Int { location, .. }
|
|
||||||
| Constant::String { location, .. }
|
|
||||||
| Constant::ByteArray { location, .. }
|
|
||||||
| Constant::CurvePoint { location, .. } => *location,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type TypedCallArg = CallArg<TypedExpr>;
|
pub type TypedCallArg = CallArg<TypedExpr>;
|
||||||
pub type ParsedCallArg = CallArg<Option<UntypedExpr>>;
|
pub type ParsedCallArg = CallArg<Option<UntypedExpr>>;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{
|
ast::{
|
||||||
Annotation, ArgBy, ArgName, ArgVia, AssignmentKind, AssignmentPattern, BinOp,
|
Annotation, ArgBy, ArgName, ArgVia, AssignmentKind, AssignmentPattern, BinOp,
|
||||||
ByteArrayFormatPreference, CallArg, Constant, CurveType, DataType, Definition, Function,
|
ByteArrayFormatPreference, CallArg, CurveType, DataType, Definition, Function,
|
||||||
LogicalOpChainKind, ModuleConstant, OnTestFailure, Pattern, RecordConstructor,
|
LogicalOpChainKind, ModuleConstant, OnTestFailure, Pattern, RecordConstructor,
|
||||||
RecordConstructorArg, RecordUpdateSpread, Span, TraceKind, TypeAlias, TypedArg,
|
RecordConstructorArg, RecordUpdateSpread, Span, TraceKind, TypeAlias, TypedArg,
|
||||||
TypedValidator, UnOp, UnqualifiedImport, UntypedArg, UntypedArgVia, UntypedAssignmentKind,
|
TypedValidator, UnOp, UnqualifiedImport, UntypedArg, UntypedArgVia, UntypedAssignmentKind,
|
||||||
|
@ -9,7 +9,7 @@ use crate::{
|
||||||
UntypedPattern, UntypedRecordUpdateArg, Use, Validator, CAPTURE_VARIABLE,
|
UntypedPattern, UntypedRecordUpdateArg, Use, Validator, CAPTURE_VARIABLE,
|
||||||
},
|
},
|
||||||
docvec,
|
docvec,
|
||||||
expr::{FnStyle, UntypedExpr, DEFAULT_ERROR_STR, DEFAULT_TODO_STR},
|
expr::{FnStyle, TypedExpr, UntypedExpr, DEFAULT_ERROR_STR, DEFAULT_TODO_STR},
|
||||||
parser::{
|
parser::{
|
||||||
extra::{Comment, ModuleExtra},
|
extra::{Comment, ModuleExtra},
|
||||||
token::Base,
|
token::Base,
|
||||||
|
@ -338,34 +338,20 @@ impl<'comments> Formatter<'comments> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn const_expr<'a>(&mut self, value: &'a Constant) -> Document<'a> {
|
fn const_expr<'a>(&mut self, _value: &'a UntypedExpr) -> Document<'a> {
|
||||||
match value {
|
todo!(
|
||||||
Constant::ByteArray {
|
"format const_expr: surround complex expressions with a block, and leave simple expression without"
|
||||||
bytes,
|
);
|
||||||
preferred_format,
|
|
||||||
..
|
|
||||||
} => self.bytearray(bytes, None, preferred_format),
|
|
||||||
Constant::CurvePoint {
|
|
||||||
point,
|
|
||||||
preferred_format,
|
|
||||||
..
|
|
||||||
} => self.bytearray(
|
|
||||||
&point.compress(),
|
|
||||||
Some(point.as_ref().into()),
|
|
||||||
preferred_format,
|
|
||||||
),
|
|
||||||
Constant::Int { value, base, .. } => self.int(value, base),
|
|
||||||
Constant::String { value, .. } => self.string(value),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn docs_const_expr<'a>(&mut self, name: &'a str, value: &'a Constant) -> Document<'a> {
|
pub fn docs_const_expr<'a>(&mut self, name: &'a str, value: &'a TypedExpr) -> Document<'a> {
|
||||||
let mut printer = tipo::pretty::Printer::new();
|
let mut printer = tipo::pretty::Printer::new();
|
||||||
name.to_doc()
|
name.to_doc()
|
||||||
.append(": ")
|
.append(": ")
|
||||||
.append(printer.print(&value.tipo()))
|
.append(printer.print(&value.tipo()))
|
||||||
.append(" = ")
|
// TODO: Show full expression in docs when simple enough
|
||||||
.append(self.const_expr(value))
|
// .append(" = ")
|
||||||
|
// .append(self.const_expr(value))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn documented_definition<'a>(&mut self, s: &'a UntypedDefinition) -> Document<'a> {
|
fn documented_definition<'a>(&mut self, s: &'a UntypedDefinition) -> Document<'a> {
|
||||||
|
|
|
@ -5,9 +5,9 @@ pub mod tree;
|
||||||
use self::{
|
use self::{
|
||||||
air::Air,
|
air::Air,
|
||||||
builder::{
|
builder::{
|
||||||
cast_validator_args, constants_ir, convert_type_to_data, extract_constant,
|
cast_validator_args, convert_type_to_data, extract_constant, modify_cyclic_calls,
|
||||||
modify_cyclic_calls, modify_self_calls, rearrange_list_clauses, AssignmentProperties,
|
modify_self_calls, rearrange_list_clauses, AssignmentProperties, ClauseProperties,
|
||||||
ClauseProperties, CodeGenSpecialFuncs, CycleFunctionNames, HoistableFunction, Variant,
|
CodeGenSpecialFuncs, CycleFunctionNames, HoistableFunction, Variant,
|
||||||
},
|
},
|
||||||
tree::{AirTree, TreePath},
|
tree::{AirTree, TreePath},
|
||||||
};
|
};
|
||||||
|
@ -58,6 +58,7 @@ pub struct CodeGenerator<'a> {
|
||||||
plutus_version: PlutusVersion,
|
plutus_version: PlutusVersion,
|
||||||
/// immutable index maps
|
/// immutable index maps
|
||||||
functions: IndexMap<&'a FunctionAccessKey, &'a TypedFunction>,
|
functions: IndexMap<&'a FunctionAccessKey, &'a TypedFunction>,
|
||||||
|
constants: IndexMap<&'a FunctionAccessKey, &'a TypedExpr>,
|
||||||
data_types: IndexMap<&'a DataTypeKey, &'a TypedDataType>,
|
data_types: IndexMap<&'a DataTypeKey, &'a TypedDataType>,
|
||||||
module_types: IndexMap<&'a str, &'a TypeInfo>,
|
module_types: IndexMap<&'a str, &'a TypeInfo>,
|
||||||
module_src: IndexMap<&'a str, &'a (String, LineNumbers)>,
|
module_src: IndexMap<&'a str, &'a (String, LineNumbers)>,
|
||||||
|
@ -82,6 +83,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
plutus_version: PlutusVersion,
|
plutus_version: PlutusVersion,
|
||||||
functions: IndexMap<&'a FunctionAccessKey, &'a TypedFunction>,
|
functions: IndexMap<&'a FunctionAccessKey, &'a TypedFunction>,
|
||||||
|
constants: IndexMap<&'a FunctionAccessKey, &'a TypedExpr>,
|
||||||
data_types: IndexMap<&'a DataTypeKey, &'a TypedDataType>,
|
data_types: IndexMap<&'a DataTypeKey, &'a TypedDataType>,
|
||||||
module_types: IndexMap<&'a str, &'a TypeInfo>,
|
module_types: IndexMap<&'a str, &'a TypeInfo>,
|
||||||
module_src: IndexMap<&'a str, &'a (String, LineNumbers)>,
|
module_src: IndexMap<&'a str, &'a (String, LineNumbers)>,
|
||||||
|
@ -90,6 +92,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
CodeGenerator {
|
CodeGenerator {
|
||||||
plutus_version,
|
plutus_version,
|
||||||
functions,
|
functions,
|
||||||
|
constants,
|
||||||
data_types,
|
data_types,
|
||||||
module_types,
|
module_types,
|
||||||
module_src,
|
module_src,
|
||||||
|
@ -268,12 +271,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
TypedExpr::Var {
|
TypedExpr::Var {
|
||||||
constructor, name, ..
|
constructor, name, ..
|
||||||
} => match &constructor.variant {
|
} => AirTree::var(constructor.clone(), name, ""),
|
||||||
ValueConstructorVariant::ModuleConstant { literal, .. } => {
|
|
||||||
constants_ir(literal)
|
|
||||||
}
|
|
||||||
_ => AirTree::var(constructor.clone(), name, ""),
|
|
||||||
},
|
|
||||||
|
|
||||||
TypedExpr::Fn { args, body, .. } => AirTree::anon_func(
|
TypedExpr::Fn { args, body, .. } => AirTree::anon_func(
|
||||||
args.iter()
|
args.iter()
|
||||||
|
@ -743,8 +741,16 @@ impl<'a> CodeGenerator<'a> {
|
||||||
AirTree::builtin(*builtin, tipo.clone(), vec![])
|
AirTree::builtin(*builtin, tipo.clone(), vec![])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ModuleValueConstructor::Constant { literal, .. } => {
|
ModuleValueConstructor::Constant { module, name, .. } => {
|
||||||
builder::constants_ir(literal)
|
let type_info = self.module_types.get(module_name.as_str()).unwrap();
|
||||||
|
|
||||||
|
let value = type_info.values.get(name).unwrap();
|
||||||
|
|
||||||
|
AirTree::var(
|
||||||
|
ValueConstructor::public(tipo.clone(), value.variant.clone()),
|
||||||
|
format!("{module}_{name}"),
|
||||||
|
"",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -4245,8 +4251,52 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
)),
|
)),
|
||||||
ValueConstructorVariant::ModuleConstant { .. } => {
|
ValueConstructorVariant::ModuleConstant { module, name, .. } => {
|
||||||
unreachable!("{:#?}, {}", constructor, name)
|
let access_key = FunctionAccessKey {
|
||||||
|
module_name: module.clone(),
|
||||||
|
function_name: name.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let definition = self
|
||||||
|
.constants
|
||||||
|
.get(&access_key)
|
||||||
|
.unwrap_or_else(|| panic!("unknown constant {module}.{name}"));
|
||||||
|
|
||||||
|
let mut value =
|
||||||
|
AirTree::no_op(self.build(definition, &access_key.module_name, &[]));
|
||||||
|
|
||||||
|
value.traverse_tree_with(
|
||||||
|
&mut |air_tree, _| {
|
||||||
|
erase_opaque_type_operations(air_tree, &self.data_types);
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
|
let term = self
|
||||||
|
.uplc_code_gen(value.to_vec())
|
||||||
|
.constr_fields_exposer()
|
||||||
|
.constr_index_exposer();
|
||||||
|
|
||||||
|
let mut program: Program<Name> = Program {
|
||||||
|
version: (1, 0, 0),
|
||||||
|
term: self.special_functions.apply_used_functions(term),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut interner = CodeGenInterner::new();
|
||||||
|
|
||||||
|
interner.program(&mut program);
|
||||||
|
|
||||||
|
let eval_program: Program<NamedDeBruijn> =
|
||||||
|
program.remove_no_inlines().try_into().unwrap();
|
||||||
|
|
||||||
|
Some(
|
||||||
|
eval_program
|
||||||
|
.eval(ExBudget::max())
|
||||||
|
.result()
|
||||||
|
.unwrap_or_else(|e| panic!("Failed to evaluate constant: {e:#?}"))
|
||||||
|
.try_into()
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
ValueConstructorVariant::ModuleFn {
|
ValueConstructorVariant::ModuleFn {
|
||||||
name: func_name,
|
name: func_name,
|
||||||
|
|
|
@ -4,8 +4,8 @@ use super::{
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{
|
ast::{
|
||||||
Constant, DataTypeKey, FunctionAccessKey, Pattern, Span, TraceLevel, TypedArg,
|
DataTypeKey, FunctionAccessKey, Pattern, Span, TraceLevel, TypedArg, TypedAssignmentKind,
|
||||||
TypedAssignmentKind, TypedClause, TypedDataType, TypedPattern,
|
TypedClause, TypedDataType, TypedPattern,
|
||||||
},
|
},
|
||||||
expr::TypedExpr,
|
expr::TypedExpr,
|
||||||
line_numbers::{LineColumn, LineNumbers},
|
line_numbers::{LineColumn, LineNumbers},
|
||||||
|
@ -287,15 +287,6 @@ impl Default for CodeGenSpecialFuncs {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn constants_ir(literal: &Constant) -> AirTree {
|
|
||||||
match literal {
|
|
||||||
Constant::Int { value, .. } => AirTree::int(value),
|
|
||||||
Constant::String { value, .. } => AirTree::string(value),
|
|
||||||
Constant::ByteArray { bytes, .. } => AirTree::byte_array(bytes.clone()),
|
|
||||||
Constant::CurvePoint { point, .. } => AirTree::curve(*point.as_ref()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_generic_variant_name(t: &Rc<Type>) -> String {
|
pub fn get_generic_variant_name(t: &Rc<Type>) -> String {
|
||||||
let uplc_type = t.get_uplc_type();
|
let uplc_type = t.get_uplc_type();
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
use chumsky::prelude::*;
|
|
||||||
use uplc::machine::runtime::Compressable;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast,
|
ast,
|
||||||
parser::{annotation, error::ParseError, literal, token::Token, utils},
|
parser::{annotation, error::ParseError, expr::pure_expression, token::Token, utils},
|
||||||
};
|
};
|
||||||
|
use chumsky::prelude::*;
|
||||||
|
|
||||||
pub fn parser() -> impl Parser<Token, ast::UntypedDefinition, Error = ParseError> {
|
pub fn parser() -> impl Parser<Token, ast::UntypedDefinition, Error = ParseError> {
|
||||||
utils::optional_flag(Token::Pub)
|
utils::optional_flag(Token::Pub)
|
||||||
|
@ -16,7 +14,9 @@ pub fn parser() -> impl Parser<Token, ast::UntypedDefinition, Error = ParseError
|
||||||
.or_not(),
|
.or_not(),
|
||||||
)
|
)
|
||||||
.then_ignore(just(Token::Equal))
|
.then_ignore(just(Token::Equal))
|
||||||
.then(value())
|
.then(recursive(|expression| {
|
||||||
|
recursive(|sequence| pure_expression(sequence, expression))
|
||||||
|
}))
|
||||||
.map_with_span(|(((public, name), annotation), value), span| {
|
.map_with_span(|(((public, name), annotation), value), span| {
|
||||||
ast::UntypedDefinition::ModuleConstant(ast::ModuleConstant {
|
ast::UntypedDefinition::ModuleConstant(ast::ModuleConstant {
|
||||||
doc: None,
|
doc: None,
|
||||||
|
@ -24,67 +24,11 @@ pub fn parser() -> impl Parser<Token, ast::UntypedDefinition, Error = ParseError
|
||||||
public,
|
public,
|
||||||
name,
|
name,
|
||||||
annotation,
|
annotation,
|
||||||
value: Box::new(value),
|
value,
|
||||||
tipo: (),
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn value() -> impl Parser<Token, ast::Constant, Error = ParseError> {
|
|
||||||
let constant_string_parser =
|
|
||||||
select! {Token::String {value} => value}.map_with_span(|value, span| {
|
|
||||||
ast::Constant::String {
|
|
||||||
location: span,
|
|
||||||
value,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let constant_int_parser =
|
|
||||||
literal::int().map_with_span(|(value, base), location| ast::Constant::Int {
|
|
||||||
location,
|
|
||||||
value,
|
|
||||||
base,
|
|
||||||
});
|
|
||||||
|
|
||||||
let constant_bytearray_parser = literal::bytearray(
|
|
||||||
|bytes, preferred_format, curve, location, emit| match curve {
|
|
||||||
Some(curve @ ast::CurveType::Bls12_381(point)) => {
|
|
||||||
let point = match point {
|
|
||||||
ast::Bls12_381PointType::G1 => {
|
|
||||||
blst::blst_p1::uncompress(&bytes).map(ast::Bls12_381Point::G1)
|
|
||||||
}
|
|
||||||
ast::Bls12_381PointType::G2 => {
|
|
||||||
blst::blst_p2::uncompress(&bytes).map(ast::Bls12_381Point::G2)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let point = point.unwrap_or_else(|_err| {
|
|
||||||
emit(ParseError::point_not_on_curve(curve, location));
|
|
||||||
|
|
||||||
ast::Bls12_381Point::default()
|
|
||||||
});
|
|
||||||
|
|
||||||
ast::Constant::CurvePoint {
|
|
||||||
location,
|
|
||||||
point: ast::Curve::Bls12_381(point).into(),
|
|
||||||
preferred_format,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => ast::Constant::ByteArray {
|
|
||||||
location,
|
|
||||||
bytes,
|
|
||||||
preferred_format,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
choice((
|
|
||||||
constant_string_parser,
|
|
||||||
constant_int_parser,
|
|
||||||
constant_bytearray_parser,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::assert_definition;
|
use crate::assert_definition;
|
||||||
|
|
|
@ -49,6 +49,5 @@ ModuleConstant(
|
||||||
),
|
),
|
||||||
preferred_format: HexadecimalString,
|
preferred_format: HexadecimalString,
|
||||||
},
|
},
|
||||||
tipo: (),
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
@ -91,6 +91,5 @@ ModuleConstant(
|
||||||
),
|
),
|
||||||
preferred_format: HexadecimalString,
|
preferred_format: HexadecimalString,
|
||||||
},
|
},
|
||||||
tipo: (),
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
ast,
|
ast,
|
||||||
parser::{definition, error::ParseError, token::Token},
|
parser::{error::ParseError, literal, token::Token},
|
||||||
};
|
};
|
||||||
use chumsky::prelude::*;
|
use chumsky::prelude::*;
|
||||||
|
|
||||||
|
@ -12,13 +12,11 @@ pub fn parser() -> impl Parser<Token, ast::UntypedClauseGuard, Error = ParseErro
|
||||||
}
|
}
|
||||||
.map_with_span(|_name, _span| ast::UntypedClauseGuard {});
|
.map_with_span(|_name, _span| ast::UntypedClauseGuard {});
|
||||||
|
|
||||||
let constant_parser = definition::constant::value().map(|_| ast::UntypedClauseGuard {});
|
|
||||||
|
|
||||||
let block_parser = expression
|
let block_parser = expression
|
||||||
.clone()
|
.clone()
|
||||||
.delimited_by(just(Token::LeftParen), just(Token::RightParen));
|
.delimited_by(just(Token::LeftParen), just(Token::RightParen));
|
||||||
|
|
||||||
let leaf_parser = choice((var_parser, constant_parser, block_parser)).boxed();
|
let leaf_parser = choice((var_parser, constant(), block_parser)).boxed();
|
||||||
|
|
||||||
let unary_op = just(Token::Bang);
|
let unary_op = just(Token::Bang);
|
||||||
|
|
||||||
|
@ -57,3 +55,20 @@ pub fn parser() -> impl Parser<Token, ast::UntypedClauseGuard, Error = ParseErro
|
||||||
.foldl(|_left, (_tok, _right)| ast::UntypedClauseGuard {})
|
.foldl(|_left, (_tok, _right)| ast::UntypedClauseGuard {})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: This is only there for backward-compatibility, in order to provide nicer error message
|
||||||
|
// when a clause guard is found. However, Aiken no longer supports clause guards.
|
||||||
|
pub fn constant() -> impl Parser<Token, ast::UntypedClauseGuard, Error = ParseError> {
|
||||||
|
let constant_string_parser =
|
||||||
|
select! {Token::String {value} => value}.map(|_| ast::UntypedClauseGuard {});
|
||||||
|
|
||||||
|
let constant_int_parser = literal::int().map(|_| ast::UntypedClauseGuard {});
|
||||||
|
|
||||||
|
let constant_bytearray_parser = literal::bytearray(|_, _, _, _, _| ast::UntypedClauseGuard {});
|
||||||
|
|
||||||
|
choice((
|
||||||
|
constant_string_parser,
|
||||||
|
constant_int_parser,
|
||||||
|
constant_bytearray_parser,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use self::{environment::Environment, pretty::Printer};
|
use self::{environment::Environment, pretty::Printer};
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{
|
ast::{
|
||||||
well_known, Annotation, Constant, DataType, DataTypeKey, DefinitionLocation, ModuleKind,
|
well_known, Annotation, DataType, DataTypeKey, DefinitionLocation, ModuleKind, Span,
|
||||||
Span, TypedDataType,
|
TypedDataType,
|
||||||
},
|
},
|
||||||
tipo::fields::FieldMap,
|
tipo::fields::FieldMap,
|
||||||
};
|
};
|
||||||
|
@ -1101,11 +1101,13 @@ impl TypeVar {
|
||||||
Self::Link { tipo } => tipo.get_inner_types(),
|
Self::Link { tipo } => tipo.get_inner_types(),
|
||||||
Self::Unbound { .. } => vec![],
|
Self::Unbound { .. } => vec![],
|
||||||
var => {
|
var => {
|
||||||
vec![Type::Var {
|
vec![
|
||||||
|
Type::Var {
|
||||||
tipo: RefCell::new(var.clone()).into(),
|
tipo: RefCell::new(var.clone()).into(),
|
||||||
alias: None,
|
alias: None,
|
||||||
}
|
}
|
||||||
.into()]
|
.into(),
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1216,7 +1218,7 @@ pub enum ValueConstructorVariant {
|
||||||
ModuleConstant {
|
ModuleConstant {
|
||||||
location: Span,
|
location: Span,
|
||||||
module: String,
|
module: String,
|
||||||
literal: Constant,
|
name: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// A function belonging to the module
|
/// A function belonging to the module
|
||||||
|
@ -1262,11 +1264,14 @@ impl ValueConstructorVariant {
|
||||||
location: *location,
|
location: *location,
|
||||||
},
|
},
|
||||||
|
|
||||||
// TODO: remove this clone with an rc clone
|
|
||||||
Self::ModuleConstant {
|
Self::ModuleConstant {
|
||||||
literal, location, ..
|
name,
|
||||||
|
module,
|
||||||
|
location,
|
||||||
|
..
|
||||||
} => ModuleValueConstructor::Constant {
|
} => ModuleValueConstructor::Constant {
|
||||||
literal: literal.clone(),
|
name: name.clone(),
|
||||||
|
module: module.clone(),
|
||||||
location: *location,
|
location: *location,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1400,8 +1405,9 @@ pub enum ModuleValueConstructor {
|
||||||
},
|
},
|
||||||
|
|
||||||
Constant {
|
Constant {
|
||||||
literal: Constant,
|
|
||||||
location: Span,
|
location: Span,
|
||||||
|
module: String,
|
||||||
|
name: String,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,11 +11,11 @@ use super::{
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{
|
ast::{
|
||||||
self, Annotation, ArgName, AssignmentKind, AssignmentPattern, BinOp, Bls12_381Point,
|
self, Annotation, ArgName, AssignmentKind, AssignmentPattern, BinOp, Bls12_381Point,
|
||||||
ByteArrayFormatPreference, CallArg, Constant, Curve, Function, IfBranch,
|
ByteArrayFormatPreference, CallArg, Curve, Function, IfBranch, LogicalOpChainKind, Pattern,
|
||||||
LogicalOpChainKind, Pattern, RecordUpdateSpread, Span, TraceKind, TraceLevel, Tracing,
|
RecordUpdateSpread, Span, TraceKind, TraceLevel, Tracing, TypedArg, TypedCallArg,
|
||||||
TypedArg, TypedCallArg, TypedClause, TypedIfBranch, TypedPattern, TypedRecordUpdateArg,
|
TypedClause, TypedIfBranch, TypedPattern, TypedRecordUpdateArg, TypedValidator, UnOp,
|
||||||
TypedValidator, UnOp, UntypedArg, UntypedAssignmentKind, UntypedClause, UntypedFunction,
|
UntypedArg, UntypedAssignmentKind, UntypedClause, UntypedFunction, UntypedIfBranch,
|
||||||
UntypedIfBranch, UntypedPattern, UntypedRecordUpdateArg,
|
UntypedPattern, UntypedRecordUpdateArg,
|
||||||
},
|
},
|
||||||
builtins::{from_default_function, BUILTIN},
|
builtins::{from_default_function, BUILTIN},
|
||||||
expr::{FnStyle, TypedExpr, UntypedExpr},
|
expr::{FnStyle, TypedExpr, UntypedExpr},
|
||||||
|
@ -1176,7 +1176,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
Ok((typed_arg, extra_assignment))
|
Ok((typed_arg, extra_assignment))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn infer_assignment(
|
pub fn infer_assignment(
|
||||||
&mut self,
|
&mut self,
|
||||||
untyped_pattern: UntypedPattern,
|
untyped_pattern: UntypedPattern,
|
||||||
untyped_value: UntypedExpr,
|
untyped_value: UntypedExpr,
|
||||||
|
@ -1466,64 +1466,6 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
Ok(typed_patterns)
|
Ok(typed_patterns)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: extract the type annotation checking into a infer_module_const
|
|
||||||
// function that uses this function internally
|
|
||||||
pub fn infer_const(
|
|
||||||
&mut self,
|
|
||||||
annotation: &Option<Annotation>,
|
|
||||||
value: Constant,
|
|
||||||
) -> Result<Constant, Error> {
|
|
||||||
let inferred = match value {
|
|
||||||
Constant::Int {
|
|
||||||
location,
|
|
||||||
value,
|
|
||||||
base,
|
|
||||||
} => Ok(Constant::Int {
|
|
||||||
location,
|
|
||||||
value,
|
|
||||||
base,
|
|
||||||
}),
|
|
||||||
|
|
||||||
Constant::String { location, value } => Ok(Constant::String { location, value }),
|
|
||||||
|
|
||||||
Constant::ByteArray {
|
|
||||||
location,
|
|
||||||
bytes,
|
|
||||||
preferred_format,
|
|
||||||
} => {
|
|
||||||
let _ = self.infer_bytearray(bytes.clone(), preferred_format, location)?;
|
|
||||||
Ok(Constant::ByteArray {
|
|
||||||
location,
|
|
||||||
bytes,
|
|
||||||
preferred_format,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Constant::CurvePoint {
|
|
||||||
location,
|
|
||||||
point,
|
|
||||||
preferred_format,
|
|
||||||
} => Ok(Constant::CurvePoint {
|
|
||||||
location,
|
|
||||||
point,
|
|
||||||
preferred_format,
|
|
||||||
}),
|
|
||||||
}?;
|
|
||||||
|
|
||||||
// Check type annotation is accurate.
|
|
||||||
if let Some(ann) = annotation {
|
|
||||||
let const_ann = self.type_from_annotation(ann)?;
|
|
||||||
|
|
||||||
self.unify(
|
|
||||||
const_ann.clone(),
|
|
||||||
inferred.tipo(),
|
|
||||||
inferred.location(),
|
|
||||||
const_ann.is_data(),
|
|
||||||
)?;
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(inferred)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn infer_if(
|
fn infer_if(
|
||||||
&mut self,
|
&mut self,
|
||||||
branches: Vec1<UntypedIfBranch>,
|
branches: Vec1<UntypedIfBranch>,
|
||||||
|
|
|
@ -9,9 +9,10 @@ use crate::{
|
||||||
ast::{
|
ast::{
|
||||||
Annotation, ArgName, ArgVia, DataType, Definition, Function, ModuleConstant, ModuleKind,
|
Annotation, ArgName, ArgVia, DataType, Definition, Function, ModuleConstant, ModuleKind,
|
||||||
RecordConstructor, RecordConstructorArg, Tracing, TypeAlias, TypedArg, TypedDefinition,
|
RecordConstructor, RecordConstructorArg, Tracing, TypeAlias, TypedArg, TypedDefinition,
|
||||||
TypedModule, TypedValidator, UntypedArg, UntypedDefinition, UntypedModule,
|
TypedModule, TypedValidator, UntypedArg, UntypedDefinition, UntypedModule, UntypedPattern,
|
||||||
UntypedValidator, Use, Validator,
|
UntypedValidator, Use, Validator,
|
||||||
},
|
},
|
||||||
|
expr::{TypedExpr, UntypedAssignmentKind},
|
||||||
tipo::{expr::infer_function, Span, Type, TypeVar},
|
tipo::{expr::infer_function, Span, Type, TypeVar},
|
||||||
IdGenerator,
|
IdGenerator,
|
||||||
};
|
};
|
||||||
|
@ -619,10 +620,22 @@ fn infer_definition(
|
||||||
annotation,
|
annotation,
|
||||||
public,
|
public,
|
||||||
value,
|
value,
|
||||||
tipo: _,
|
|
||||||
}) => {
|
}) => {
|
||||||
let typed_expr =
|
let typed_assignment = ExprTyper::new(environment, tracing).infer_assignment(
|
||||||
ExprTyper::new(environment, tracing).infer_const(&annotation, *value)?;
|
UntypedPattern::Var {
|
||||||
|
location,
|
||||||
|
name: name.clone(),
|
||||||
|
},
|
||||||
|
value,
|
||||||
|
UntypedAssignmentKind::Let { backpassing: false },
|
||||||
|
&annotation,
|
||||||
|
location,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let typed_expr = match typed_assignment {
|
||||||
|
TypedExpr::Assignment { value, .. } => value,
|
||||||
|
_ => unreachable!("infer_assignment inferred something else than an assignment?"),
|
||||||
|
};
|
||||||
|
|
||||||
let tipo = typed_expr.tipo();
|
let tipo = typed_expr.tipo();
|
||||||
|
|
||||||
|
@ -630,7 +643,7 @@ fn infer_definition(
|
||||||
public,
|
public,
|
||||||
variant: ValueConstructorVariant::ModuleConstant {
|
variant: ValueConstructorVariant::ModuleConstant {
|
||||||
location,
|
location,
|
||||||
literal: typed_expr.clone(),
|
name: name.to_owned(),
|
||||||
module: module_name.to_owned(),
|
module: module_name.to_owned(),
|
||||||
},
|
},
|
||||||
tipo: tipo.clone(),
|
tipo: tipo.clone(),
|
||||||
|
@ -650,8 +663,7 @@ fn infer_definition(
|
||||||
name,
|
name,
|
||||||
annotation,
|
annotation,
|
||||||
public,
|
public,
|
||||||
value: Box::new(typed_expr),
|
value: *typed_expr,
|
||||||
tipo,
|
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
use crate::{github::repo::LatestRelease, package_name::PackageName, paths, Error};
|
use crate::{github::repo::LatestRelease, package_name::PackageName, paths, Error};
|
||||||
use aiken_lang::{
|
use aiken_lang::{
|
||||||
ast::{
|
ast::{Annotation, ByteArrayFormatPreference, ModuleConstant, Span, UntypedDefinition},
|
||||||
Annotation, ByteArrayFormatPreference, Constant, ModuleConstant, Span, UntypedDefinition,
|
|
||||||
},
|
|
||||||
expr::UntypedExpr,
|
expr::UntypedExpr,
|
||||||
parser::token::Base,
|
parser::token::Base,
|
||||||
};
|
};
|
||||||
|
@ -78,24 +76,14 @@ impl SimpleExpr {
|
||||||
|
|
||||||
let (value, annotation) = match self {
|
let (value, annotation) = match self {
|
||||||
SimpleExpr::Bool(..) => todo!("requires https://github.com/aiken-lang/aiken/pull/992"),
|
SimpleExpr::Bool(..) => todo!("requires https://github.com/aiken-lang/aiken/pull/992"),
|
||||||
SimpleExpr::Int(i) => (
|
SimpleExpr::Int(_) => (
|
||||||
// TODO: Replace with 'self.as_untyped_expr()' after https://github.com/aiken-lang/aiken/pull/992
|
// TODO: Replace with 'self.as_untyped_expr()' after https://github.com/aiken-lang/aiken/pull/992
|
||||||
Constant::Int {
|
self.as_untyped_expr(),
|
||||||
location,
|
|
||||||
value: format!("{i}"),
|
|
||||||
base: Base::Decimal {
|
|
||||||
numeric_underscore: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Some(Annotation::int(location)),
|
Some(Annotation::int(location)),
|
||||||
),
|
),
|
||||||
SimpleExpr::ByteArray(bs, preferred_format) => (
|
SimpleExpr::ByteArray(_, _) => (
|
||||||
// TODO: Replace with 'self.as_untyped_expr()' after https://github.com/aiken-lang/aiken/pull/992
|
// TODO: Replace with 'self.as_untyped_expr()' after https://github.com/aiken-lang/aiken/pull/992
|
||||||
Constant::ByteArray {
|
self.as_untyped_expr(),
|
||||||
location,
|
|
||||||
bytes: bs.to_vec(),
|
|
||||||
preferred_format: *preferred_format,
|
|
||||||
},
|
|
||||||
Some(Annotation::bytearray(location)),
|
Some(Annotation::bytearray(location)),
|
||||||
),
|
),
|
||||||
SimpleExpr::List(..) => todo!("requires https://github.com/aiken-lang/aiken/pull/992"),
|
SimpleExpr::List(..) => todo!("requires https://github.com/aiken-lang/aiken/pull/992"),
|
||||||
|
@ -107,8 +95,7 @@ impl SimpleExpr {
|
||||||
public: true,
|
public: true,
|
||||||
name: identifier.to_string(),
|
name: identifier.to_string(),
|
||||||
annotation,
|
annotation,
|
||||||
value: Box::new(value),
|
value,
|
||||||
tipo: (),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ use aiken_lang::{
|
||||||
TypedFunction, UntypedDefinition,
|
TypedFunction, UntypedDefinition,
|
||||||
},
|
},
|
||||||
builtins,
|
builtins,
|
||||||
expr::UntypedExpr,
|
expr::{TypedExpr, UntypedExpr},
|
||||||
format::{Formatter, MAX_COLUMNS},
|
format::{Formatter, MAX_COLUMNS},
|
||||||
gen_uplc::CodeGenerator,
|
gen_uplc::CodeGenerator,
|
||||||
line_numbers::LineNumbers,
|
line_numbers::LineNumbers,
|
||||||
|
@ -98,6 +98,7 @@ where
|
||||||
checks_count: Option<usize>,
|
checks_count: Option<usize>,
|
||||||
event_listener: T,
|
event_listener: T,
|
||||||
functions: IndexMap<FunctionAccessKey, TypedFunction>,
|
functions: IndexMap<FunctionAccessKey, TypedFunction>,
|
||||||
|
constants: IndexMap<FunctionAccessKey, TypedExpr>,
|
||||||
data_types: IndexMap<DataTypeKey, TypedDataType>,
|
data_types: IndexMap<DataTypeKey, TypedDataType>,
|
||||||
module_sources: HashMap<String, (String, LineNumbers)>,
|
module_sources: HashMap<String, (String, LineNumbers)>,
|
||||||
}
|
}
|
||||||
|
@ -149,6 +150,7 @@ where
|
||||||
checks_count: None,
|
checks_count: None,
|
||||||
event_listener,
|
event_listener,
|
||||||
functions,
|
functions,
|
||||||
|
constants: IndexMap::new(),
|
||||||
data_types,
|
data_types,
|
||||||
module_sources: HashMap::new(),
|
module_sources: HashMap::new(),
|
||||||
}
|
}
|
||||||
|
@ -158,6 +160,7 @@ where
|
||||||
CodeGenerator::new(
|
CodeGenerator::new(
|
||||||
self.config.plutus,
|
self.config.plutus,
|
||||||
utils::indexmap::as_ref_values(&self.functions),
|
utils::indexmap::as_ref_values(&self.functions),
|
||||||
|
utils::indexmap::as_ref_values(&self.constants),
|
||||||
utils::indexmap::as_ref_values(&self.data_types),
|
utils::indexmap::as_ref_values(&self.data_types),
|
||||||
utils::indexmap::as_str_ref_values(&self.module_types),
|
utils::indexmap::as_str_ref_values(&self.module_types),
|
||||||
utils::indexmap::as_str_ref_values(&self.module_sources),
|
utils::indexmap::as_str_ref_values(&self.module_sources),
|
||||||
|
@ -805,6 +808,7 @@ where
|
||||||
&mut self.module_sources,
|
&mut self.module_sources,
|
||||||
&mut self.module_types,
|
&mut self.module_types,
|
||||||
&mut self.functions,
|
&mut self.functions,
|
||||||
|
&mut self.constants,
|
||||||
&mut self.data_types,
|
&mut self.data_types,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ use aiken_lang::{
|
||||||
Tracing, TypedDataType, TypedFunction, TypedModule, TypedValidator, UntypedModule,
|
Tracing, TypedDataType, TypedFunction, TypedModule, TypedValidator, UntypedModule,
|
||||||
Validator,
|
Validator,
|
||||||
},
|
},
|
||||||
|
expr::TypedExpr,
|
||||||
line_numbers::LineNumbers,
|
line_numbers::LineNumbers,
|
||||||
parser::extra::{comments_before, Comment, ModuleExtra},
|
parser::extra::{comments_before, Comment, ModuleExtra},
|
||||||
tipo::TypeInfo,
|
tipo::TypeInfo,
|
||||||
|
@ -49,6 +50,7 @@ impl ParsedModule {
|
||||||
module_sources: &mut HashMap<String, (String, LineNumbers)>,
|
module_sources: &mut HashMap<String, (String, LineNumbers)>,
|
||||||
module_types: &mut HashMap<String, TypeInfo>,
|
module_types: &mut HashMap<String, TypeInfo>,
|
||||||
functions: &mut IndexMap<FunctionAccessKey, TypedFunction>,
|
functions: &mut IndexMap<FunctionAccessKey, TypedFunction>,
|
||||||
|
constants: &mut IndexMap<FunctionAccessKey, TypedExpr>,
|
||||||
data_types: &mut IndexMap<DataTypeKey, TypedDataType>,
|
data_types: &mut IndexMap<DataTypeKey, TypedDataType>,
|
||||||
) -> Result<(CheckedModule, Vec<Warning>), Error> {
|
) -> Result<(CheckedModule, Vec<Warning>), Error> {
|
||||||
let mut warnings = Vec::new();
|
let mut warnings = Vec::new();
|
||||||
|
@ -92,7 +94,7 @@ impl ParsedModule {
|
||||||
module_types.insert(self.name.clone(), ast.type_info.clone());
|
module_types.insert(self.name.clone(), ast.type_info.clone());
|
||||||
|
|
||||||
// Register function definitions & data-types for easier access later.
|
// Register function definitions & data-types for easier access later.
|
||||||
ast.register_definitions(functions, data_types);
|
ast.register_definitions(functions, constants, data_types);
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
CheckedModule {
|
CheckedModule {
|
||||||
|
|
|
@ -62,7 +62,8 @@ mod test {
|
||||||
|
|
||||||
let mut functions = builtins::prelude_functions(&id_gen, &module_types);
|
let mut functions = builtins::prelude_functions(&id_gen, &module_types);
|
||||||
let mut data_types = builtins::prelude_data_types(&id_gen);
|
let mut data_types = builtins::prelude_data_types(&id_gen);
|
||||||
ast.register_definitions(&mut functions, &mut data_types);
|
let mut constants = IndexMap::new();
|
||||||
|
ast.register_definitions(&mut functions, &mut constants, &mut data_types);
|
||||||
|
|
||||||
let mut module_sources = HashMap::new();
|
let mut module_sources = HashMap::new();
|
||||||
module_sources.insert(
|
module_sources.insert(
|
||||||
|
@ -87,6 +88,7 @@ mod test {
|
||||||
let mut generator = CodeGenerator::new(
|
let mut generator = CodeGenerator::new(
|
||||||
PlutusVersion::default(),
|
PlutusVersion::default(),
|
||||||
utils::indexmap::as_ref_values(&functions),
|
utils::indexmap::as_ref_values(&functions),
|
||||||
|
utils::indexmap::as_ref_values(&constants),
|
||||||
utils::indexmap::as_ref_values(&data_types),
|
utils::indexmap::as_ref_values(&data_types),
|
||||||
utils::indexmap::as_str_ref_values(&module_types),
|
utils::indexmap::as_str_ref_values(&module_types),
|
||||||
utils::indexmap::as_str_ref_values(&module_sources),
|
utils::indexmap::as_str_ref_values(&module_sources),
|
||||||
|
@ -240,13 +242,14 @@ mod test {
|
||||||
}
|
}
|
||||||
"#});
|
"#});
|
||||||
|
|
||||||
assert!(prop
|
assert!(
|
||||||
.run::<()>(
|
prop.run::<()>(
|
||||||
42,
|
42,
|
||||||
PropertyTest::DEFAULT_MAX_SUCCESS,
|
PropertyTest::DEFAULT_MAX_SUCCESS,
|
||||||
&PlutusVersion::default()
|
&PlutusVersion::default()
|
||||||
)
|
)
|
||||||
.is_success());
|
.is_success()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -9,6 +9,7 @@ use aiken_lang::{
|
||||||
DataTypeKey, FunctionAccessKey, ModuleKind, TraceLevel, Tracing, TypedDataType,
|
DataTypeKey, FunctionAccessKey, ModuleKind, TraceLevel, Tracing, TypedDataType,
|
||||||
TypedFunction,
|
TypedFunction,
|
||||||
},
|
},
|
||||||
|
expr::TypedExpr,
|
||||||
gen_uplc::CodeGenerator,
|
gen_uplc::CodeGenerator,
|
||||||
line_numbers::LineNumbers,
|
line_numbers::LineNumbers,
|
||||||
parser,
|
parser,
|
||||||
|
@ -28,6 +29,7 @@ pub struct TestProject {
|
||||||
pub package: PackageName,
|
pub package: PackageName,
|
||||||
pub id_gen: IdGenerator,
|
pub id_gen: IdGenerator,
|
||||||
pub functions: IndexMap<FunctionAccessKey, TypedFunction>,
|
pub functions: IndexMap<FunctionAccessKey, TypedFunction>,
|
||||||
|
pub constants: IndexMap<FunctionAccessKey, TypedExpr>,
|
||||||
pub data_types: IndexMap<DataTypeKey, TypedDataType>,
|
pub data_types: IndexMap<DataTypeKey, TypedDataType>,
|
||||||
pub module_types: HashMap<String, TypeInfo>,
|
pub module_types: HashMap<String, TypeInfo>,
|
||||||
pub module_sources: HashMap<String, (String, LineNumbers)>,
|
pub module_sources: HashMap<String, (String, LineNumbers)>,
|
||||||
|
@ -48,12 +50,14 @@ impl TestProject {
|
||||||
|
|
||||||
let functions = builtins::prelude_functions(&id_gen, &module_types);
|
let functions = builtins::prelude_functions(&id_gen, &module_types);
|
||||||
let data_types = builtins::prelude_data_types(&id_gen);
|
let data_types = builtins::prelude_data_types(&id_gen);
|
||||||
|
let constants = IndexMap::new();
|
||||||
|
|
||||||
TestProject {
|
TestProject {
|
||||||
package,
|
package,
|
||||||
id_gen,
|
id_gen,
|
||||||
module_types,
|
module_types,
|
||||||
functions,
|
functions,
|
||||||
|
constants,
|
||||||
data_types,
|
data_types,
|
||||||
module_sources: HashMap::new(),
|
module_sources: HashMap::new(),
|
||||||
}
|
}
|
||||||
|
@ -63,6 +67,7 @@ impl TestProject {
|
||||||
CodeGenerator::new(
|
CodeGenerator::new(
|
||||||
PlutusVersion::default(),
|
PlutusVersion::default(),
|
||||||
utils::indexmap::as_ref_values(&self.functions),
|
utils::indexmap::as_ref_values(&self.functions),
|
||||||
|
utils::indexmap::as_ref_values(&self.constants),
|
||||||
utils::indexmap::as_ref_values(&self.data_types),
|
utils::indexmap::as_ref_values(&self.data_types),
|
||||||
utils::indexmap::as_str_ref_values(&self.module_types),
|
utils::indexmap::as_str_ref_values(&self.module_types),
|
||||||
utils::indexmap::as_str_ref_values(&self.module_sources),
|
utils::indexmap::as_str_ref_values(&self.module_sources),
|
||||||
|
@ -104,7 +109,11 @@ impl TestProject {
|
||||||
.expect("Failed to type-check module");
|
.expect("Failed to type-check module");
|
||||||
|
|
||||||
// Register function definitions & data-types for easier access later.
|
// Register function definitions & data-types for easier access later.
|
||||||
ast.register_definitions(&mut self.functions, &mut self.data_types);
|
ast.register_definitions(
|
||||||
|
&mut self.functions,
|
||||||
|
&mut self.constants,
|
||||||
|
&mut self.data_types,
|
||||||
|
);
|
||||||
|
|
||||||
// Register module sources for an easier access later.
|
// Register module sources for an easier access later.
|
||||||
self.module_sources.insert(
|
self.module_sources.insert(
|
||||||
|
|
|
@ -19,7 +19,7 @@ pub enum Error {
|
||||||
format!(
|
format!(
|
||||||
"\n{:>13} {}",
|
"\n{:>13} {}",
|
||||||
"Trace",
|
"Trace",
|
||||||
if trace.contains("\n") {
|
if trace.contains('\n') {
|
||||||
trace.lines()
|
trace.lines()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(ix, row)| {
|
.map(|(ix, row)| {
|
||||||
|
|
Loading…
Reference in New Issue