DRY builtins types creation to ensure proper consistency.
This commit is contained in:
parent
5b61a75088
commit
7ec3f2e8df
|
@ -1,8 +1,6 @@
|
||||||
|
pub mod well_known;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
builtins::{
|
|
||||||
self, g1_element, g2_element, SCRIPT_CONTEXT, SCRIPT_PURPOSE, SCRIPT_PURPOSE_MINT,
|
|
||||||
SCRIPT_PURPOSE_SPEND, SCRIPT_PURPOSE_WITHDRAW,
|
|
||||||
},
|
|
||||||
expr::{TypedExpr, UntypedExpr},
|
expr::{TypedExpr, UntypedExpr},
|
||||||
line_numbers::LineNumbers,
|
line_numbers::LineNumbers,
|
||||||
parser::token::{Base, Token},
|
parser::token::{Base, Token},
|
||||||
|
@ -28,12 +26,12 @@ pub const ENV_MODULE: &str = "env";
|
||||||
pub const CONFIG_MODULE: &str = "config";
|
pub const CONFIG_MODULE: &str = "config";
|
||||||
pub const DEFAULT_ENV_MODULE: &str = "default";
|
pub const DEFAULT_ENV_MODULE: &str = "default";
|
||||||
|
|
||||||
pub const PURPOSE_SPEND: &str = "spend";
|
pub const HANDLER_SPEND: &str = "spend";
|
||||||
pub const PURPOSE_MINT: &str = "mint";
|
pub const HANDLER_MINT: &str = "mint";
|
||||||
pub const PURPOSE_WITHDRAW: &str = "withdraw";
|
pub const HANDLER_WITHDRAW: &str = "withdraw";
|
||||||
pub const PURPOSE_PUBLISH: &str = "publish";
|
pub const HANDLER_PUBLISH: &str = "publish";
|
||||||
pub const PURPOSE_VOTE: &str = "vote";
|
pub const HANDLER_VOTE: &str = "vote";
|
||||||
pub const PURPOSE_PROPOSE: &str = "propose";
|
pub const HANDLER_PROPOSE: &str = "propose";
|
||||||
|
|
||||||
pub type TypedModule = Module<TypeInfo, TypedDefinition>;
|
pub type TypedModule = Module<TypeInfo, TypedDefinition>;
|
||||||
pub type UntypedModule = Module<(), UntypedDefinition>;
|
pub type UntypedModule = Module<(), UntypedDefinition>;
|
||||||
|
@ -281,23 +279,23 @@ impl TypedFunction {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_valid_purpose_name(&self) -> bool {
|
pub fn has_valid_purpose_name(&self) -> bool {
|
||||||
self.name == PURPOSE_SPEND
|
self.name == HANDLER_SPEND
|
||||||
|| self.name == PURPOSE_PUBLISH
|
|| self.name == HANDLER_PUBLISH
|
||||||
|| self.name == PURPOSE_PROPOSE
|
|| self.name == HANDLER_PROPOSE
|
||||||
|| self.name == PURPOSE_MINT
|
|| self.name == HANDLER_MINT
|
||||||
|| self.name == PURPOSE_WITHDRAW
|
|| self.name == HANDLER_WITHDRAW
|
||||||
|| self.name == PURPOSE_VOTE
|
|| self.name == HANDLER_VOTE
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn validator_arity(&self) -> usize {
|
pub fn validator_arity(&self) -> usize {
|
||||||
if self.name == PURPOSE_SPEND
|
if self.name == HANDLER_SPEND
|
||||||
|| self.name == PURPOSE_PUBLISH
|
|| self.name == HANDLER_PUBLISH
|
||||||
|| self.name == PURPOSE_PROPOSE
|
|| self.name == HANDLER_PROPOSE
|
||||||
{
|
{
|
||||||
4
|
4
|
||||||
} else if self.name == PURPOSE_MINT
|
} else if self.name == HANDLER_MINT
|
||||||
|| self.name == PURPOSE_WITHDRAW
|
|| self.name == HANDLER_WITHDRAW
|
||||||
|| self.name == PURPOSE_VOTE
|
|| self.name == HANDLER_VOTE
|
||||||
{
|
{
|
||||||
3
|
3
|
||||||
} else {
|
} else {
|
||||||
|
@ -383,207 +381,24 @@ pub struct FunctionAccessKey {
|
||||||
pub function_name: String,
|
pub function_name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type UntypedDataType = DataType<()>;
|
||||||
pub type TypedDataType = DataType<Rc<Type>>;
|
pub type TypedDataType = DataType<Rc<Type>>;
|
||||||
|
|
||||||
impl TypedDataType {
|
impl TypedDataType {
|
||||||
pub fn data() -> Self {
|
pub fn known_enum(name: &str, constructors: &[&str]) -> Self {
|
||||||
DataType {
|
Self {
|
||||||
constructors: vec![],
|
name: name.to_string(),
|
||||||
doc: None,
|
constructors: RecordConstructor::known_enum(constructors),
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
name: "Data".to_string(),
|
|
||||||
opaque: false,
|
opaque: false,
|
||||||
|
public: true,
|
||||||
parameters: vec![],
|
parameters: vec![],
|
||||||
public: true,
|
|
||||||
typed_parameters: vec![],
|
typed_parameters: vec![],
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn bool() -> Self {
|
|
||||||
DataType {
|
|
||||||
constructors: vec![
|
|
||||||
RecordConstructor {
|
|
||||||
location: Span::empty(),
|
|
||||||
name: "False".to_string(),
|
|
||||||
arguments: vec![],
|
|
||||||
doc: None,
|
doc: None,
|
||||||
sugar: false,
|
|
||||||
},
|
|
||||||
RecordConstructor {
|
|
||||||
location: Span::empty(),
|
|
||||||
name: "True".to_string(),
|
|
||||||
arguments: vec![],
|
|
||||||
doc: None,
|
|
||||||
sugar: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
doc: None,
|
|
||||||
location: Span::empty(),
|
|
||||||
name: "Bool".to_string(),
|
|
||||||
opaque: false,
|
|
||||||
parameters: vec![],
|
|
||||||
public: true,
|
|
||||||
typed_parameters: vec![],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn script_purpose() -> Self {
|
|
||||||
DataType {
|
|
||||||
constructors: vec![
|
|
||||||
RecordConstructor {
|
|
||||||
location: Span::empty(),
|
|
||||||
name: SCRIPT_PURPOSE_MINT.to_string(),
|
|
||||||
arguments: vec![],
|
|
||||||
doc: None,
|
|
||||||
sugar: false,
|
|
||||||
},
|
|
||||||
RecordConstructor {
|
|
||||||
location: Span::empty(),
|
|
||||||
name: SCRIPT_PURPOSE_SPEND.to_string(),
|
|
||||||
arguments: vec![],
|
|
||||||
doc: None,
|
|
||||||
sugar: false,
|
|
||||||
},
|
|
||||||
RecordConstructor {
|
|
||||||
location: Span::empty(),
|
|
||||||
name: SCRIPT_PURPOSE_WITHDRAW.to_string(),
|
|
||||||
arguments: vec![],
|
|
||||||
doc: None,
|
|
||||||
sugar: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
doc: None,
|
|
||||||
location: Span::empty(),
|
|
||||||
name: SCRIPT_PURPOSE.to_string(),
|
|
||||||
opaque: false,
|
|
||||||
parameters: vec![],
|
|
||||||
public: true,
|
|
||||||
typed_parameters: vec![],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn script_context() -> Self {
|
|
||||||
DataType {
|
|
||||||
constructors: vec![RecordConstructor {
|
|
||||||
location: Span::empty(),
|
|
||||||
name: SCRIPT_CONTEXT.to_string(),
|
|
||||||
arguments: vec![],
|
|
||||||
doc: None,
|
|
||||||
sugar: false,
|
|
||||||
}],
|
|
||||||
doc: None,
|
|
||||||
location: Span::empty(),
|
|
||||||
name: SCRIPT_CONTEXT.to_string(),
|
|
||||||
opaque: false,
|
|
||||||
parameters: vec![],
|
|
||||||
public: true,
|
|
||||||
typed_parameters: vec![],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn prng() -> Self {
|
|
||||||
DataType {
|
|
||||||
constructors: vec![
|
|
||||||
RecordConstructor {
|
|
||||||
location: Span::empty(),
|
|
||||||
name: "Seeded".to_string(),
|
|
||||||
arguments: vec![],
|
|
||||||
doc: None,
|
|
||||||
sugar: false,
|
|
||||||
},
|
|
||||||
RecordConstructor {
|
|
||||||
location: Span::empty(),
|
|
||||||
name: "Replayed".to_string(),
|
|
||||||
arguments: vec![],
|
|
||||||
doc: None,
|
|
||||||
sugar: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
doc: None,
|
|
||||||
location: Span::empty(),
|
|
||||||
name: "PRNG".to_string(),
|
|
||||||
opaque: false,
|
|
||||||
parameters: vec![],
|
|
||||||
public: true,
|
|
||||||
typed_parameters: vec![],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn ordering() -> Self {
|
|
||||||
DataType {
|
|
||||||
constructors: vec![
|
|
||||||
RecordConstructor {
|
|
||||||
location: Span::empty(),
|
|
||||||
name: "Less".to_string(),
|
|
||||||
arguments: vec![],
|
|
||||||
doc: None,
|
|
||||||
sugar: false,
|
|
||||||
},
|
|
||||||
RecordConstructor {
|
|
||||||
location: Span::empty(),
|
|
||||||
name: "Equal".to_string(),
|
|
||||||
arguments: vec![],
|
|
||||||
doc: None,
|
|
||||||
sugar: false,
|
|
||||||
},
|
|
||||||
RecordConstructor {
|
|
||||||
location: Span::empty(),
|
|
||||||
name: "Greater".to_string(),
|
|
||||||
arguments: vec![],
|
|
||||||
doc: None,
|
|
||||||
sugar: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
doc: None,
|
|
||||||
location: Span::empty(),
|
|
||||||
name: "Ordering".to_string(),
|
|
||||||
opaque: false,
|
|
||||||
parameters: vec![],
|
|
||||||
public: true,
|
|
||||||
typed_parameters: vec![],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn option(tipo: Rc<Type>) -> Self {
|
|
||||||
DataType {
|
|
||||||
constructors: vec![
|
|
||||||
RecordConstructor {
|
|
||||||
location: Span::empty(),
|
|
||||||
name: "Some".to_string(),
|
|
||||||
arguments: vec![RecordConstructorArg {
|
|
||||||
label: None,
|
|
||||||
annotation: Annotation::Var {
|
|
||||||
location: Span::empty(),
|
|
||||||
name: "a".to_string(),
|
|
||||||
},
|
|
||||||
location: Span::empty(),
|
|
||||||
tipo: tipo.clone(),
|
|
||||||
doc: None,
|
|
||||||
}],
|
|
||||||
doc: None,
|
|
||||||
sugar: false,
|
|
||||||
},
|
|
||||||
RecordConstructor {
|
|
||||||
location: Span::empty(),
|
|
||||||
name: "None".to_string(),
|
|
||||||
arguments: vec![],
|
|
||||||
doc: None,
|
|
||||||
sugar: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
doc: None,
|
|
||||||
location: Span::empty(),
|
|
||||||
name: "Option".to_string(),
|
|
||||||
opaque: false,
|
|
||||||
parameters: vec!["a".to_string()],
|
|
||||||
public: true,
|
|
||||||
typed_parameters: vec![tipo],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type UntypedDataType = DataType<()>;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||||
pub struct DataType<T> {
|
pub struct DataType<T> {
|
||||||
pub constructors: Vec<RecordConstructor<T>>,
|
pub constructors: Vec<RecordConstructor<T>>,
|
||||||
|
@ -647,14 +462,14 @@ pub struct Validator<T, Arg, Expr> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypedValidator {
|
impl TypedValidator {
|
||||||
pub fn available_purposes() -> Vec<String> {
|
pub fn available_handler_names() -> Vec<String> {
|
||||||
vec![
|
vec![
|
||||||
PURPOSE_SPEND.to_string(),
|
HANDLER_SPEND.to_string(),
|
||||||
PURPOSE_MINT.to_string(),
|
HANDLER_MINT.to_string(),
|
||||||
PURPOSE_WITHDRAW.to_string(),
|
HANDLER_WITHDRAW.to_string(),
|
||||||
PURPOSE_PUBLISH.to_string(),
|
HANDLER_PUBLISH.to_string(),
|
||||||
PURPOSE_VOTE.to_string(),
|
HANDLER_VOTE.to_string(),
|
||||||
PURPOSE_PROPOSE.to_string(),
|
HANDLER_PROPOSE.to_string(),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -838,12 +653,12 @@ pub enum Constant {
|
||||||
impl Constant {
|
impl Constant {
|
||||||
pub fn tipo(&self) -> Rc<Type> {
|
pub fn tipo(&self) -> Rc<Type> {
|
||||||
match self {
|
match self {
|
||||||
Constant::Int { .. } => builtins::int(),
|
Constant::Int { .. } => Type::int(),
|
||||||
Constant::String { .. } => builtins::string(),
|
Constant::String { .. } => Type::string(),
|
||||||
Constant::ByteArray { .. } => builtins::byte_array(),
|
Constant::ByteArray { .. } => Type::byte_array(),
|
||||||
Constant::CurvePoint { point, .. } => match point.as_ref() {
|
Constant::CurvePoint { point, .. } => match point.as_ref() {
|
||||||
Curve::Bls12_381(Bls12_381Point::G1(_)) => builtins::g1_element(),
|
Curve::Bls12_381(Bls12_381Point::G1(_)) => Type::g1_element(),
|
||||||
Curve::Bls12_381(Bls12_381Point::G2(_)) => builtins::g2_element(),
|
Curve::Bls12_381(Bls12_381Point::G2(_)) => Type::g2_element(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -896,6 +711,19 @@ impl<A> RecordConstructor<A> {
|
||||||
pub fn put_doc(&mut self, new_doc: String) {
|
pub fn put_doc(&mut self, new_doc: String) {
|
||||||
self.doc = Some(new_doc);
|
self.doc = Some(new_doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn known_enum(names: &[&str]) -> Vec<RecordConstructor<A>> {
|
||||||
|
names
|
||||||
|
.iter()
|
||||||
|
.map(|name| RecordConstructor {
|
||||||
|
location: Span::empty(),
|
||||||
|
name: name.to_string(),
|
||||||
|
arguments: vec![],
|
||||||
|
doc: None,
|
||||||
|
sugar: false,
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||||
|
@ -1601,8 +1429,8 @@ impl TypedPattern {
|
||||||
// TODO: This function definition is weird, see where this is used and how.
|
// TODO: This function definition is weird, see where this is used and how.
|
||||||
pub fn tipo(&self, value: &TypedExpr) -> Option<Rc<Type>> {
|
pub fn tipo(&self, value: &TypedExpr) -> Option<Rc<Type>> {
|
||||||
match self {
|
match self {
|
||||||
Pattern::Int { .. } => Some(builtins::int()),
|
Pattern::Int { .. } => Some(Type::int()),
|
||||||
Pattern::ByteArray { .. } => Some(builtins::byte_array()),
|
Pattern::ByteArray { .. } => Some(Type::byte_array()),
|
||||||
Pattern::Constructor { tipo, .. } => Some(tipo.clone()),
|
Pattern::Constructor { tipo, .. } => Some(tipo.clone()),
|
||||||
Pattern::Var { .. } | Pattern::Assign { .. } | Pattern::Discard { .. } => {
|
Pattern::Var { .. } | Pattern::Assign { .. } | Pattern::Discard { .. } => {
|
||||||
Some(value.tipo())
|
Some(value.tipo())
|
||||||
|
@ -1800,8 +1628,8 @@ impl<'de> serde::Deserialize<'de> for Bls12_381Point {
|
||||||
impl Bls12_381Point {
|
impl Bls12_381Point {
|
||||||
pub fn tipo(&self) -> Rc<Type> {
|
pub fn tipo(&self) -> Rc<Type> {
|
||||||
match self {
|
match self {
|
||||||
Bls12_381Point::G1(_) => g1_element(),
|
Bls12_381Point::G1(_) => Type::g1_element(),
|
||||||
Bls12_381Point::G2(_) => g2_element(),
|
Bls12_381Point::G2(_) => Type::g2_element(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,339 @@
|
||||||
|
use crate::{
|
||||||
|
ast::{Annotation, Span},
|
||||||
|
tipo::{Type, TypeAliasAnnotation, TypeVar},
|
||||||
|
};
|
||||||
|
use std::{cell::RefCell, rc::Rc};
|
||||||
|
|
||||||
|
pub const BOOL: &str = "Bool";
|
||||||
|
pub const BOOL_CONSTRUCTORS: &[&str] = &["False", "True"];
|
||||||
|
pub const BYTE_ARRAY: &str = "ByteArray";
|
||||||
|
pub const DATA: &str = "Data";
|
||||||
|
pub const FUZZER: &str = "Fuzzer";
|
||||||
|
pub const G1_ELEMENT: &str = "G1Element";
|
||||||
|
pub const G2_ELEMENT: &str = "G2Element";
|
||||||
|
pub const INT: &str = "Int";
|
||||||
|
pub const LIST: &str = "List";
|
||||||
|
pub const MILLER_LOOP_RESULT: &str = "MillerLoopResult";
|
||||||
|
pub const OPTION: &str = "Option";
|
||||||
|
pub const OPTION_CONSTRUCTORS: &[&str] = &["Some", "None"];
|
||||||
|
pub const ORDERING: &str = "Ordering";
|
||||||
|
pub const ORDERING_CONSTRUCTORS: &[&str] = &["Less", "Equal", "Greater"];
|
||||||
|
pub const PAIR: &str = "Pair";
|
||||||
|
pub const PAIRS: &str = "Pairs";
|
||||||
|
pub const PRNG: &str = "PRNG";
|
||||||
|
pub const PRNG_CONSTRUCTORS: &[&str] = &["Seeded", "Replayed"];
|
||||||
|
pub const REDEEMER_WRAPPER: &str = "RedeemerWrapper";
|
||||||
|
pub const STRING: &str = "String";
|
||||||
|
pub const VOID: &str = "Void";
|
||||||
|
pub const VOID_CONSTRUCTORS: &[&str] = &["Void"];
|
||||||
|
|
||||||
|
pub const SCRIPT_CONTEXT: &str = "__ScriptContext";
|
||||||
|
pub const SCRIPT_CONTEXT_CONSTRUCTORS: &[&str] = &["__ScriptContext"];
|
||||||
|
pub const SCRIPT_CONTEXT_TRANSACTION: &str = "__Transaction";
|
||||||
|
pub const SCRIPT_CONTEXT_REDEEMER: &str = "__Redeemer";
|
||||||
|
pub const SCRIPT_CONTEXT_PURPOSE: &str = "__ScriptPurpose";
|
||||||
|
|
||||||
|
pub const SCRIPT_PURPOSE: &str = "__ScriptPurpose";
|
||||||
|
pub const SCRIPT_PURPOSE_MINT: &str = "__Mint";
|
||||||
|
pub const SCRIPT_PURPOSE_SPEND: &str = "__Spend";
|
||||||
|
pub const SCRIPT_PURPOSE_WITHDRAW: &str = "__Withdraw";
|
||||||
|
pub const SCRIPT_PURPOSE_PUBLISH: &str = "__Publish";
|
||||||
|
pub const SCRIPT_PURPOSE_VOTE: &str = "__Vote";
|
||||||
|
pub const SCRIPT_PURPOSE_PROPOSE: &str = "__Propose";
|
||||||
|
pub const SCRIPT_PURPOSE_CONSTRUCTORS: &[&str] = &[
|
||||||
|
SCRIPT_PURPOSE_MINT,
|
||||||
|
SCRIPT_PURPOSE_SPEND,
|
||||||
|
SCRIPT_PURPOSE_WITHDRAW,
|
||||||
|
SCRIPT_PURPOSE_PUBLISH,
|
||||||
|
SCRIPT_PURPOSE_VOTE,
|
||||||
|
SCRIPT_PURPOSE_PROPOSE,
|
||||||
|
];
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Types
|
||||||
|
|
||||||
|
impl Type {
|
||||||
|
pub fn data() -> Rc<Type> {
|
||||||
|
Rc::new(Type::App {
|
||||||
|
public: true,
|
||||||
|
contains_opaque: false,
|
||||||
|
name: DATA.to_string(),
|
||||||
|
module: "".to_string(),
|
||||||
|
args: vec![],
|
||||||
|
alias: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn int() -> Rc<Type> {
|
||||||
|
Rc::new(Type::App {
|
||||||
|
public: true,
|
||||||
|
contains_opaque: false,
|
||||||
|
name: INT.to_string(),
|
||||||
|
module: "".to_string(),
|
||||||
|
args: vec![],
|
||||||
|
alias: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bool() -> Rc<Self> {
|
||||||
|
Rc::new(Type::App {
|
||||||
|
args: vec![],
|
||||||
|
public: true,
|
||||||
|
contains_opaque: false,
|
||||||
|
name: BOOL.to_string(),
|
||||||
|
module: "".to_string(),
|
||||||
|
alias: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn byte_array() -> Rc<Type> {
|
||||||
|
Rc::new(Type::App {
|
||||||
|
args: vec![],
|
||||||
|
public: true,
|
||||||
|
contains_opaque: false,
|
||||||
|
name: BYTE_ARRAY.to_string(),
|
||||||
|
module: "".to_string(),
|
||||||
|
alias: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn g1_element() -> Rc<Type> {
|
||||||
|
Rc::new(Type::App {
|
||||||
|
public: true,
|
||||||
|
contains_opaque: false,
|
||||||
|
module: "".to_string(),
|
||||||
|
name: G1_ELEMENT.to_string(),
|
||||||
|
args: vec![],
|
||||||
|
alias: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn g2_element() -> Rc<Type> {
|
||||||
|
Rc::new(Type::App {
|
||||||
|
public: true,
|
||||||
|
contains_opaque: false,
|
||||||
|
module: "".to_string(),
|
||||||
|
name: G2_ELEMENT.to_string(),
|
||||||
|
args: vec![],
|
||||||
|
alias: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn miller_loop_result() -> Rc<Type> {
|
||||||
|
Rc::new(Type::App {
|
||||||
|
public: true,
|
||||||
|
contains_opaque: false,
|
||||||
|
module: "".to_string(),
|
||||||
|
name: MILLER_LOOP_RESULT.to_string(),
|
||||||
|
args: vec![],
|
||||||
|
alias: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tuple(elems: Vec<Rc<Type>>) -> Rc<Type> {
|
||||||
|
Rc::new(Type::Tuple { elems, alias: None })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pair(fst: Rc<Type>, snd: Rc<Type>) -> Rc<Type> {
|
||||||
|
Rc::new(Type::Pair {
|
||||||
|
fst,
|
||||||
|
snd,
|
||||||
|
alias: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn script_purpose() -> Rc<Type> {
|
||||||
|
Rc::new(Type::App {
|
||||||
|
args: vec![],
|
||||||
|
public: true,
|
||||||
|
contains_opaque: false,
|
||||||
|
name: SCRIPT_PURPOSE.to_string(),
|
||||||
|
module: "".to_string(),
|
||||||
|
alias: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn script_context() -> Rc<Type> {
|
||||||
|
Rc::new(Type::App {
|
||||||
|
args: vec![],
|
||||||
|
public: true,
|
||||||
|
contains_opaque: false,
|
||||||
|
name: SCRIPT_CONTEXT.to_string(),
|
||||||
|
module: "".to_string(),
|
||||||
|
alias: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prng() -> Rc<Type> {
|
||||||
|
Rc::new(Type::App {
|
||||||
|
args: vec![],
|
||||||
|
public: true,
|
||||||
|
contains_opaque: false,
|
||||||
|
name: PRNG.to_string(),
|
||||||
|
module: "".to_string(),
|
||||||
|
alias: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fuzzer(a: Rc<Type>) -> Rc<Type> {
|
||||||
|
let prng_annotation = Annotation::Constructor {
|
||||||
|
location: Span::empty(),
|
||||||
|
module: None,
|
||||||
|
name: PRNG.to_string(),
|
||||||
|
arguments: vec![],
|
||||||
|
};
|
||||||
|
|
||||||
|
Rc::new(Type::Fn {
|
||||||
|
args: vec![Type::prng()],
|
||||||
|
ret: Type::option(Type::tuple(vec![Type::prng(), a])),
|
||||||
|
alias: Some(
|
||||||
|
TypeAliasAnnotation {
|
||||||
|
alias: FUZZER.to_string(),
|
||||||
|
parameters: vec!["a".to_string()],
|
||||||
|
annotation: Annotation::Fn {
|
||||||
|
location: Span::empty(),
|
||||||
|
arguments: vec![prng_annotation.clone()],
|
||||||
|
ret: Annotation::Constructor {
|
||||||
|
location: Span::empty(),
|
||||||
|
module: None,
|
||||||
|
name: OPTION.to_string(),
|
||||||
|
arguments: vec![Annotation::Tuple {
|
||||||
|
location: Span::empty(),
|
||||||
|
elems: vec![
|
||||||
|
prng_annotation,
|
||||||
|
Annotation::Var {
|
||||||
|
location: Span::empty(),
|
||||||
|
name: "a".to_string(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}],
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn map(k: Rc<Type>, v: Rc<Type>) -> Rc<Type> {
|
||||||
|
Rc::new(Type::App {
|
||||||
|
public: true,
|
||||||
|
contains_opaque: false,
|
||||||
|
module: "".to_string(),
|
||||||
|
name: LIST.to_string(),
|
||||||
|
args: vec![Type::pair(k, v)],
|
||||||
|
alias: Some(
|
||||||
|
TypeAliasAnnotation {
|
||||||
|
alias: PAIRS.to_string(),
|
||||||
|
parameters: vec!["k".to_string(), "v".to_string()],
|
||||||
|
annotation: Annotation::Constructor {
|
||||||
|
location: Span::empty(),
|
||||||
|
module: None,
|
||||||
|
name: LIST.to_string(),
|
||||||
|
arguments: vec![Annotation::Pair {
|
||||||
|
location: Span::empty(),
|
||||||
|
fst: Box::new(Annotation::Var {
|
||||||
|
location: Span::empty(),
|
||||||
|
name: "k".to_string(),
|
||||||
|
}),
|
||||||
|
snd: Box::new(Annotation::Var {
|
||||||
|
location: Span::empty(),
|
||||||
|
name: "v".to_string(),
|
||||||
|
}),
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn list(t: Rc<Type>) -> Rc<Type> {
|
||||||
|
Rc::new(Type::App {
|
||||||
|
public: true,
|
||||||
|
// FIXME: We should probably have t.contains_opaque here?
|
||||||
|
contains_opaque: false,
|
||||||
|
name: LIST.to_string(),
|
||||||
|
module: "".to_string(),
|
||||||
|
args: vec![t],
|
||||||
|
alias: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn string() -> Rc<Type> {
|
||||||
|
Rc::new(Type::App {
|
||||||
|
args: vec![],
|
||||||
|
public: true,
|
||||||
|
contains_opaque: false,
|
||||||
|
name: STRING.to_string(),
|
||||||
|
module: "".to_string(),
|
||||||
|
alias: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn void() -> Rc<Type> {
|
||||||
|
Rc::new(Type::App {
|
||||||
|
args: vec![],
|
||||||
|
public: true,
|
||||||
|
contains_opaque: false,
|
||||||
|
name: VOID.to_string(),
|
||||||
|
module: "".to_string(),
|
||||||
|
alias: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn option(a: Rc<Type>) -> Rc<Type> {
|
||||||
|
Rc::new(Type::App {
|
||||||
|
public: true,
|
||||||
|
// FIXME: We should probably have t.contains_opaque here?
|
||||||
|
contains_opaque: false,
|
||||||
|
name: OPTION.to_string(),
|
||||||
|
module: "".to_string(),
|
||||||
|
args: vec![a],
|
||||||
|
alias: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ordering() -> Rc<Type> {
|
||||||
|
Rc::new(Type::App {
|
||||||
|
public: true,
|
||||||
|
contains_opaque: false,
|
||||||
|
name: ORDERING.to_string(),
|
||||||
|
module: "".to_string(),
|
||||||
|
args: vec![],
|
||||||
|
alias: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn function(args: Vec<Rc<Type>>, ret: Rc<Type>) -> Rc<Type> {
|
||||||
|
Rc::new(Type::Fn {
|
||||||
|
ret,
|
||||||
|
args,
|
||||||
|
alias: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generic_var(id: u64) -> Rc<Type> {
|
||||||
|
let tipo = Rc::new(RefCell::new(TypeVar::Generic { id }));
|
||||||
|
|
||||||
|
Rc::new(Type::Var { tipo, alias: None })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unbound_var(id: u64) -> Rc<Type> {
|
||||||
|
let tipo = Rc::new(RefCell::new(TypeVar::Unbound { id }));
|
||||||
|
|
||||||
|
Rc::new(Type::Var { tipo, alias: None })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn wrapped_redeemer(redeemer: Rc<Type>) -> Rc<Type> {
|
||||||
|
Rc::new(Type::App {
|
||||||
|
public: true,
|
||||||
|
contains_opaque: false,
|
||||||
|
module: "".to_string(),
|
||||||
|
name: REDEEMER_WRAPPER.to_string(),
|
||||||
|
args: vec![redeemer],
|
||||||
|
alias: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,3 @@
|
||||||
use crate::tipo::ValueConstructorVariant;
|
|
||||||
pub(crate) use crate::{
|
pub(crate) use crate::{
|
||||||
ast::{
|
ast::{
|
||||||
self, Annotation, ArgBy, ArgName, AssignmentPattern, BinOp, Bls12_381Point,
|
self, Annotation, ArgBy, ArgName, AssignmentPattern, BinOp, Bls12_381Point,
|
||||||
|
@ -8,7 +7,6 @@ pub(crate) use crate::{
|
||||||
TypedDataType, TypedIfBranch, TypedRecordUpdateArg, UnOp, UntypedArg,
|
TypedDataType, TypedIfBranch, TypedRecordUpdateArg, UnOp, UntypedArg,
|
||||||
UntypedAssignmentKind, UntypedClause, UntypedIfBranch, UntypedRecordUpdateArg,
|
UntypedAssignmentKind, UntypedClause, UntypedIfBranch, UntypedRecordUpdateArg,
|
||||||
},
|
},
|
||||||
builtins::void,
|
|
||||||
parser::token::Base,
|
parser::token::Base,
|
||||||
tipo::{
|
tipo::{
|
||||||
check_replaceable_opaque_type, convert_opaque_type, lookup_data_type_by_tipo,
|
check_replaceable_opaque_type, convert_opaque_type, lookup_data_type_by_tipo,
|
||||||
|
@ -224,9 +222,10 @@ impl TypedExpr {
|
||||||
| Self::RecordAccess { tipo, .. }
|
| Self::RecordAccess { tipo, .. }
|
||||||
| Self::RecordUpdate { tipo, .. }
|
| Self::RecordUpdate { tipo, .. }
|
||||||
| Self::CurvePoint { tipo, .. } => tipo.clone(),
|
| Self::CurvePoint { tipo, .. } => tipo.clone(),
|
||||||
Self::Pipeline { expressions, .. } | Self::Sequence { expressions, .. } => {
|
Self::Pipeline { expressions, .. } | Self::Sequence { expressions, .. } => expressions
|
||||||
expressions.last().map(TypedExpr::tipo).unwrap_or_else(void)
|
.last()
|
||||||
}
|
.map(TypedExpr::tipo)
|
||||||
|
.unwrap_or_else(Type::void),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -491,7 +490,7 @@ impl TypedExpr {
|
||||||
module: String::new(),
|
module: String::new(),
|
||||||
constructors_count: 1,
|
constructors_count: 1,
|
||||||
},
|
},
|
||||||
tipo: void(),
|
tipo: Type::void(),
|
||||||
},
|
},
|
||||||
location,
|
location,
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,14 +13,11 @@ use self::{
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{
|
ast::{
|
||||||
ArgName, AssignmentKind, BinOp, Bls12_381Point, CallArg, Curve, DataTypeKey,
|
well_known, ArgName, AssignmentKind, BinOp, Bls12_381Point, CallArg, Curve, DataTypeKey,
|
||||||
FunctionAccessKey, OnTestFailure, Pattern, Span, TraceLevel, Tracing, TypedArg,
|
FunctionAccessKey, OnTestFailure, Pattern, Span, TraceLevel, Tracing, TypedArg,
|
||||||
TypedClause, TypedDataType, TypedFunction, TypedPattern, TypedValidator, UnOp,
|
TypedClause, TypedDataType, TypedFunction, TypedPattern, TypedValidator, UnOp,
|
||||||
},
|
},
|
||||||
builtins::{
|
builtins::PRELUDE,
|
||||||
bool, byte_array, data, function, int, list, option, pair, script_context, script_purpose,
|
|
||||||
void, PRELUDE, SCRIPT_PURPOSE_MINT, SCRIPT_PURPOSE_SPEND, SCRIPT_PURPOSE_WITHDRAW,
|
|
||||||
},
|
|
||||||
expr::TypedExpr,
|
expr::TypedExpr,
|
||||||
gen_uplc::{
|
gen_uplc::{
|
||||||
air::ExpectLevel,
|
air::ExpectLevel,
|
||||||
|
@ -138,14 +135,14 @@ impl<'a> CodeGenerator<'a> {
|
||||||
annotation: None,
|
annotation: None,
|
||||||
doc: None,
|
doc: None,
|
||||||
is_validator_param: false,
|
is_validator_param: false,
|
||||||
tipo: data(),
|
tipo: Type::data(),
|
||||||
}],
|
}],
|
||||||
body: TypedExpr::Sequence {
|
body: TypedExpr::Sequence {
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
expressions: vec![
|
expressions: vec![
|
||||||
TypedExpr::Assignment {
|
TypedExpr::Assignment {
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
tipo: script_context(),
|
tipo: Type::script_context(),
|
||||||
value: TypedExpr::Var {
|
value: TypedExpr::Var {
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
constructor: ValueConstructor {
|
constructor: ValueConstructor {
|
||||||
|
@ -153,7 +150,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
variant: ValueConstructorVariant::LocalVariable {
|
variant: ValueConstructorVariant::LocalVariable {
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
},
|
},
|
||||||
tipo: script_context(),
|
tipo: Type::script_context(),
|
||||||
},
|
},
|
||||||
name: "__context__".to_string(),
|
name: "__context__".to_string(),
|
||||||
}
|
}
|
||||||
|
@ -194,13 +191,16 @@ impl<'a> CodeGenerator<'a> {
|
||||||
field_map: None,
|
field_map: None,
|
||||||
},
|
},
|
||||||
spread_location: None,
|
spread_location: None,
|
||||||
tipo: function(vec![data(), data(), script_purpose()], data()),
|
tipo: Type::function(
|
||||||
|
vec![Type::data(), Type::data(), Type::script_purpose()],
|
||||||
|
Type::data(),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
kind: AssignmentKind::let_(),
|
kind: AssignmentKind::let_(),
|
||||||
},
|
},
|
||||||
TypedExpr::When {
|
TypedExpr::When {
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
tipo: bool(),
|
tipo: Type::bool(),
|
||||||
subject: TypedExpr::Var {
|
subject: TypedExpr::Var {
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
constructor: ValueConstructor {
|
constructor: ValueConstructor {
|
||||||
|
@ -208,7 +208,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
variant: ValueConstructorVariant::LocalVariable {
|
variant: ValueConstructorVariant::LocalVariable {
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
},
|
},
|
||||||
tipo: script_purpose(),
|
tipo: Type::script_purpose(),
|
||||||
},
|
},
|
||||||
name: "__purpose__".to_string(),
|
name: "__purpose__".to_string(),
|
||||||
}
|
}
|
||||||
|
@ -241,7 +241,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
"spend" => TypedPattern::Constructor {
|
"spend" => TypedPattern::Constructor {
|
||||||
is_record: false,
|
is_record: false,
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
name: SCRIPT_PURPOSE_SPEND.to_string(),
|
name: well_known::SCRIPT_PURPOSE_SPEND.to_string(),
|
||||||
arguments: vec![
|
arguments: vec![
|
||||||
CallArg {
|
CallArg {
|
||||||
label: None,
|
label: None,
|
||||||
|
@ -262,20 +262,20 @@ impl<'a> CodeGenerator<'a> {
|
||||||
],
|
],
|
||||||
module: None,
|
module: None,
|
||||||
constructor: PatternConstructor::Record {
|
constructor: PatternConstructor::Record {
|
||||||
name: SCRIPT_PURPOSE_SPEND.to_string(),
|
name: well_known::SCRIPT_PURPOSE_SPEND.to_string(),
|
||||||
field_map: None,
|
field_map: None,
|
||||||
},
|
},
|
||||||
spread_location: None,
|
spread_location: None,
|
||||||
tipo: function(
|
tipo: Type::function(
|
||||||
vec![data(), option(data())],
|
vec![Type::data(), Type::option(Type::data())],
|
||||||
script_purpose(),
|
Type::script_purpose(),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
||||||
"mint" => TypedPattern::Constructor {
|
"mint" => TypedPattern::Constructor {
|
||||||
is_record: false,
|
is_record: false,
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
name: SCRIPT_PURPOSE_MINT.to_string(),
|
name: well_known::SCRIPT_PURPOSE_MINT.to_string(),
|
||||||
arguments: vec![CallArg {
|
arguments: vec![CallArg {
|
||||||
label: None,
|
label: None,
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
|
@ -286,17 +286,20 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}],
|
}],
|
||||||
module: None,
|
module: None,
|
||||||
constructor: PatternConstructor::Record {
|
constructor: PatternConstructor::Record {
|
||||||
name: SCRIPT_PURPOSE_MINT.to_string(),
|
name: well_known::SCRIPT_PURPOSE_MINT.to_string(),
|
||||||
field_map: None,
|
field_map: None,
|
||||||
},
|
},
|
||||||
spread_location: None,
|
spread_location: None,
|
||||||
tipo: function(vec![byte_array()], script_purpose()),
|
tipo: Type::function(
|
||||||
|
vec![Type::byte_array()],
|
||||||
|
Type::script_purpose(),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
|
|
||||||
"withdraw" => TypedPattern::Constructor {
|
"withdraw" => TypedPattern::Constructor {
|
||||||
is_record: false,
|
is_record: false,
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
name: SCRIPT_PURPOSE_WITHDRAW.to_string(),
|
name: well_known::SCRIPT_PURPOSE_WITHDRAW.to_string(),
|
||||||
arguments: vec![CallArg {
|
arguments: vec![CallArg {
|
||||||
label: None,
|
label: None,
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
|
@ -307,11 +310,14 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}],
|
}],
|
||||||
module: None,
|
module: None,
|
||||||
constructor: PatternConstructor::Record {
|
constructor: PatternConstructor::Record {
|
||||||
name: SCRIPT_PURPOSE_WITHDRAW.to_string(),
|
name: well_known::SCRIPT_PURPOSE_WITHDRAW.to_string(),
|
||||||
field_map: None,
|
field_map: None,
|
||||||
},
|
},
|
||||||
spread_location: None,
|
spread_location: None,
|
||||||
tipo: function(vec![data()], script_purpose()),
|
tipo: Type::function(
|
||||||
|
vec![Type::data()],
|
||||||
|
Type::script_purpose(),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
|
|
||||||
purpose => {
|
purpose => {
|
||||||
|
@ -332,7 +338,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
variant: ValueConstructorVariant::LocalVariable {
|
variant: ValueConstructorVariant::LocalVariable {
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
},
|
},
|
||||||
tipo: data(),
|
tipo: Type::data(),
|
||||||
},
|
},
|
||||||
name: "__redeemer__".to_string(),
|
name: "__redeemer__".to_string(),
|
||||||
}
|
}
|
||||||
|
@ -364,7 +370,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
variant: ValueConstructorVariant::LocalVariable {
|
variant: ValueConstructorVariant::LocalVariable {
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
},
|
},
|
||||||
tipo: option(data()),
|
tipo: Type::option(Type::data()),
|
||||||
},
|
},
|
||||||
name: "__datum__".to_string(),
|
name: "__datum__".to_string(),
|
||||||
}
|
}
|
||||||
|
@ -396,7 +402,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
variant: ValueConstructorVariant::LocalVariable {
|
variant: ValueConstructorVariant::LocalVariable {
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
},
|
},
|
||||||
tipo: data(),
|
tipo: Type::data(),
|
||||||
},
|
},
|
||||||
name: "__purpose_arg__".to_string(),
|
name: "__purpose_arg__".to_string(),
|
||||||
}
|
}
|
||||||
|
@ -421,7 +427,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
variant: ValueConstructorVariant::LocalVariable {
|
variant: ValueConstructorVariant::LocalVariable {
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
},
|
},
|
||||||
tipo: data(),
|
tipo: Type::data(),
|
||||||
},
|
},
|
||||||
name: "__transaction__".to_string(),
|
name: "__transaction__".to_string(),
|
||||||
}
|
}
|
||||||
|
@ -504,7 +510,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
name: "wrapper_validator".to_string(),
|
name: "wrapper_validator".to_string(),
|
||||||
public: true,
|
public: true,
|
||||||
return_annotation: None,
|
return_annotation: None,
|
||||||
return_type: bool(),
|
return_type: Type::bool(),
|
||||||
end_position: 0,
|
end_position: 0,
|
||||||
on_test_failure: OnTestFailure::FailImmediately,
|
on_test_failure: OnTestFailure::FailImmediately,
|
||||||
};
|
};
|
||||||
|
@ -619,7 +625,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
self.special_functions.insert_new_function(
|
self.special_functions.insert_new_function(
|
||||||
msg_func_name.clone(),
|
msg_func_name.clone(),
|
||||||
Term::Error.delayed_trace(Term::string(msg)).delay(),
|
Term::Error.delayed_trace(Term::string(msg)).delay(),
|
||||||
void(),
|
Type::void(),
|
||||||
);
|
);
|
||||||
Some(self.special_functions.use_function_tree(msg_func_name))
|
Some(self.special_functions.use_function_tree(msg_func_name))
|
||||||
}
|
}
|
||||||
|
@ -1024,17 +1030,21 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let function_name = format!("__access_index_{}", *index);
|
let function_name = format!("__access_index_{}", *index);
|
||||||
|
|
||||||
if self.code_gen_functions.get(&function_name).is_none() {
|
if self.code_gen_functions.get(&function_name).is_none() {
|
||||||
let mut body = AirTree::local_var("__fields", list(data()));
|
let mut body = AirTree::local_var("__fields", Type::list(Type::data()));
|
||||||
|
|
||||||
for _ in 0..*index {
|
for _ in 0..*index {
|
||||||
body = AirTree::builtin(
|
body = AirTree::builtin(
|
||||||
DefaultFunction::TailList,
|
DefaultFunction::TailList,
|
||||||
list(data()),
|
Type::list(Type::data()),
|
||||||
vec![body],
|
vec![body],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
body = AirTree::builtin(DefaultFunction::HeadList, data(), vec![body]);
|
body = AirTree::builtin(
|
||||||
|
DefaultFunction::HeadList,
|
||||||
|
Type::data(),
|
||||||
|
vec![body],
|
||||||
|
);
|
||||||
|
|
||||||
self.code_gen_functions.insert(
|
self.code_gen_functions.insert(
|
||||||
function_name.clone(),
|
function_name.clone(),
|
||||||
|
@ -1048,7 +1058,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let list_of_fields = AirTree::call(
|
let list_of_fields = AirTree::call(
|
||||||
self.special_functions
|
self.special_functions
|
||||||
.use_function_tree(CONSTR_FIELDS_EXPOSER.to_string()),
|
.use_function_tree(CONSTR_FIELDS_EXPOSER.to_string()),
|
||||||
list(data()),
|
Type::list(Type::data()),
|
||||||
vec![self.build(record, module_build_name, &[])],
|
vec![self.build(record, module_build_name, &[])],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1163,17 +1173,21 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let function_name = format!("__access_index_{}", *index);
|
let function_name = format!("__access_index_{}", *index);
|
||||||
|
|
||||||
if self.code_gen_functions.get(&function_name).is_none() {
|
if self.code_gen_functions.get(&function_name).is_none() {
|
||||||
let mut body = AirTree::local_var("__fields", list(data()));
|
let mut body = AirTree::local_var("__fields", Type::list(Type::data()));
|
||||||
|
|
||||||
for _ in 0..*index {
|
for _ in 0..*index {
|
||||||
body = AirTree::builtin(
|
body = AirTree::builtin(
|
||||||
DefaultFunction::TailList,
|
DefaultFunction::TailList,
|
||||||
list(data()),
|
Type::list(Type::data()),
|
||||||
vec![body],
|
vec![body],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
body = AirTree::builtin(DefaultFunction::HeadList, data(), vec![body]);
|
body = AirTree::builtin(
|
||||||
|
DefaultFunction::HeadList,
|
||||||
|
Type::data(),
|
||||||
|
vec![body],
|
||||||
|
);
|
||||||
|
|
||||||
self.code_gen_functions.insert(
|
self.code_gen_functions.insert(
|
||||||
function_name.clone(),
|
function_name.clone(),
|
||||||
|
@ -1282,7 +1296,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let otherwise = match &props.otherwise {
|
let otherwise = match &props.otherwise {
|
||||||
Some(x) => x.clone(),
|
Some(x) => x.clone(),
|
||||||
// (delay (error ))
|
// (delay (error ))
|
||||||
None => AirTree::anon_func(vec![], AirTree::error(void(), false), true),
|
None => AirTree::anon_func(vec![], AirTree::error(Type::void(), false), true),
|
||||||
};
|
};
|
||||||
|
|
||||||
match pattern {
|
match pattern {
|
||||||
|
@ -1298,10 +1312,10 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
let expect = AirTree::binop(
|
let expect = AirTree::binop(
|
||||||
BinOp::Eq,
|
BinOp::Eq,
|
||||||
bool(),
|
Type::bool(),
|
||||||
AirTree::int(expected_int),
|
AirTree::int(expected_int),
|
||||||
AirTree::local_var(&name, int()),
|
AirTree::local_var(&name, Type::int()),
|
||||||
int(),
|
Type::int(),
|
||||||
);
|
);
|
||||||
|
|
||||||
assign_casted_value(
|
assign_casted_value(
|
||||||
|
@ -1320,10 +1334,10 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
let expect = AirTree::binop(
|
let expect = AirTree::binop(
|
||||||
BinOp::Eq,
|
BinOp::Eq,
|
||||||
bool(),
|
Type::bool(),
|
||||||
AirTree::byte_array(expected_bytes.clone()),
|
AirTree::byte_array(expected_bytes.clone()),
|
||||||
AirTree::local_var(&name, byte_array()),
|
AirTree::local_var(&name, Type::byte_array()),
|
||||||
byte_array(),
|
Type::byte_array(),
|
||||||
);
|
);
|
||||||
|
|
||||||
assign_casted_value(
|
assign_casted_value(
|
||||||
|
@ -1831,7 +1845,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
AirTree::when(
|
AirTree::when(
|
||||||
&subject_name,
|
&subject_name,
|
||||||
void(),
|
Type::void(),
|
||||||
tipo.clone(),
|
tipo.clone(),
|
||||||
AirTree::local_var(&constructor_name, tipo.clone()),
|
AirTree::local_var(&constructor_name, tipo.clone()),
|
||||||
AirTree::assert_constr_index(
|
AirTree::assert_constr_index(
|
||||||
|
@ -2000,11 +2014,14 @@ impl<'a> CodeGenerator<'a> {
|
||||||
defined_data_types,
|
defined_data_types,
|
||||||
location,
|
location,
|
||||||
AirTree::call(
|
AirTree::call(
|
||||||
AirTree::local_var(format!("__curried_expect_on_list_{}", depth), void()),
|
AirTree::local_var(
|
||||||
void(),
|
format!("__curried_expect_on_list_{}", depth),
|
||||||
|
Type::void(),
|
||||||
|
),
|
||||||
|
Type::void(),
|
||||||
vec![AirTree::builtin(
|
vec![AirTree::builtin(
|
||||||
DefaultFunction::TailList,
|
DefaultFunction::TailList,
|
||||||
list(data()),
|
Type::list(Type::data()),
|
||||||
vec![AirTree::local_var(
|
vec![AirTree::local_var(
|
||||||
format!("__list_{}", depth),
|
format!("__list_{}", depth),
|
||||||
tipo.clone(),
|
tipo.clone(),
|
||||||
|
@ -2039,7 +2056,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
&pair_name,
|
&pair_name,
|
||||||
AirTree::builtin(
|
AirTree::builtin(
|
||||||
DefaultFunction::HeadList,
|
DefaultFunction::HeadList,
|
||||||
pair(data(), data()),
|
Type::pair(Type::data(), Type::data()),
|
||||||
vec![AirTree::local_var(
|
vec![AirTree::local_var(
|
||||||
format!("__list_{}", depth),
|
format!("__list_{}", depth),
|
||||||
tipo.clone(),
|
tipo.clone(),
|
||||||
|
@ -2083,7 +2100,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let func_call = AirTree::call(
|
let func_call = AirTree::call(
|
||||||
AirTree::var(
|
AirTree::var(
|
||||||
ValueConstructor::public(
|
ValueConstructor::public(
|
||||||
void(),
|
Type::void(),
|
||||||
ValueConstructorVariant::ModuleFn {
|
ValueConstructorVariant::ModuleFn {
|
||||||
name: EXPECT_ON_LIST.to_string(),
|
name: EXPECT_ON_LIST.to_string(),
|
||||||
field_map: None,
|
field_map: None,
|
||||||
|
@ -2096,7 +2113,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
EXPECT_ON_LIST,
|
EXPECT_ON_LIST,
|
||||||
"",
|
"",
|
||||||
),
|
),
|
||||||
void(),
|
Type::void(),
|
||||||
vec![AirTree::local_var(&map_name, tipo.clone()), unwrap_function],
|
vec![AirTree::local_var(&map_name, tipo.clone()), unwrap_function],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -2176,7 +2193,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
&item_name,
|
&item_name,
|
||||||
AirTree::builtin(
|
AirTree::builtin(
|
||||||
DefaultFunction::HeadList,
|
DefaultFunction::HeadList,
|
||||||
data(),
|
Type::data(),
|
||||||
vec![AirTree::local_var(
|
vec![AirTree::local_var(
|
||||||
format!("__list_{}", depth),
|
format!("__list_{}", depth),
|
||||||
tipo.clone(),
|
tipo.clone(),
|
||||||
|
@ -2185,7 +2202,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
AirTree::soft_cast_assignment(
|
AirTree::soft_cast_assignment(
|
||||||
&item_name,
|
&item_name,
|
||||||
inner_list_type.clone(),
|
inner_list_type.clone(),
|
||||||
AirTree::local_var(&item_name, data()),
|
AirTree::local_var(&item_name, Type::data()),
|
||||||
self.expect_type_assign(
|
self.expect_type_assign(
|
||||||
inner_list_type,
|
inner_list_type,
|
||||||
AirTree::local_var(&item_name, inner_list_type.clone()),
|
AirTree::local_var(&item_name, inner_list_type.clone()),
|
||||||
|
@ -2194,12 +2211,12 @@ impl<'a> CodeGenerator<'a> {
|
||||||
AirTree::call(
|
AirTree::call(
|
||||||
AirTree::local_var(
|
AirTree::local_var(
|
||||||
format!("__curried_expect_on_list_{}", depth),
|
format!("__curried_expect_on_list_{}", depth),
|
||||||
void(),
|
Type::void(),
|
||||||
),
|
),
|
||||||
void(),
|
Type::void(),
|
||||||
vec![AirTree::builtin(
|
vec![AirTree::builtin(
|
||||||
DefaultFunction::TailList,
|
DefaultFunction::TailList,
|
||||||
list(data()),
|
Type::list(Type::data()),
|
||||||
vec![AirTree::local_var(
|
vec![AirTree::local_var(
|
||||||
format!("__list_{}", depth),
|
format!("__list_{}", depth),
|
||||||
tipo.clone(),
|
tipo.clone(),
|
||||||
|
@ -2243,7 +2260,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let func_call = AirTree::call(
|
let func_call = AirTree::call(
|
||||||
AirTree::var(
|
AirTree::var(
|
||||||
ValueConstructor::public(
|
ValueConstructor::public(
|
||||||
void(),
|
Type::void(),
|
||||||
ValueConstructorVariant::ModuleFn {
|
ValueConstructorVariant::ModuleFn {
|
||||||
name: EXPECT_ON_LIST.to_string(),
|
name: EXPECT_ON_LIST.to_string(),
|
||||||
field_map: None,
|
field_map: None,
|
||||||
|
@ -2256,7 +2273,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
EXPECT_ON_LIST,
|
EXPECT_ON_LIST,
|
||||||
"",
|
"",
|
||||||
),
|
),
|
||||||
void(),
|
Type::void(),
|
||||||
vec![
|
vec![
|
||||||
AirTree::local_var(&list_name, tipo.clone()),
|
AirTree::local_var(&list_name, tipo.clone()),
|
||||||
unwrap_function,
|
unwrap_function,
|
||||||
|
@ -2347,10 +2364,13 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let current_defined = defined_data_types.clone();
|
let current_defined = defined_data_types.clone();
|
||||||
let mut diff_defined_types = vec![];
|
let mut diff_defined_types = vec![];
|
||||||
|
|
||||||
let var_then =
|
let var_then = AirTree::call(
|
||||||
AirTree::call(AirTree::local_var("then_delayed", void()), void(), vec![]);
|
AirTree::local_var("then_delayed", Type::void()),
|
||||||
|
Type::void(),
|
||||||
|
vec![],
|
||||||
|
);
|
||||||
|
|
||||||
let otherwise_delayed = AirTree::local_var("otherwise_delayed", void());
|
let otherwise_delayed = AirTree::local_var("otherwise_delayed", Type::void());
|
||||||
|
|
||||||
let constr_clauses = data_type.constructors.iter().enumerate().rfold(
|
let constr_clauses = data_type.constructors.iter().enumerate().rfold(
|
||||||
otherwise_delayed.clone(),
|
otherwise_delayed.clone(),
|
||||||
|
@ -2431,13 +2451,13 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
let when_expr = AirTree::when(
|
let when_expr = AirTree::when(
|
||||||
format!("__subject_span_{}_{}", location.start, location.end),
|
format!("__subject_span_{}_{}", location.start, location.end),
|
||||||
void(),
|
Type::void(),
|
||||||
tipo.clone(),
|
tipo.clone(),
|
||||||
AirTree::local_var(
|
AirTree::local_var(
|
||||||
format!("__constr_var_span_{}_{}", location.start, location.end),
|
format!("__constr_var_span_{}_{}", location.start, location.end),
|
||||||
tipo.clone(),
|
tipo.clone(),
|
||||||
),
|
),
|
||||||
AirTree::call(constr_clauses, void(), vec![]),
|
AirTree::call(constr_clauses, Type::void(), vec![]),
|
||||||
);
|
);
|
||||||
|
|
||||||
let func_body = AirTree::let_assignment(
|
let func_body = AirTree::let_assignment(
|
||||||
|
@ -2490,7 +2510,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
"",
|
"",
|
||||||
);
|
);
|
||||||
|
|
||||||
AirTree::call(func_var, void(), args)
|
AirTree::call(func_var, Type::void(), args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3014,7 +3034,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
// Since check_last_item is false this will never get added to the final uplc anyway
|
// Since check_last_item is false this will never get added to the final uplc anyway
|
||||||
ExpectLevel::None,
|
ExpectLevel::None,
|
||||||
elems_then,
|
elems_then,
|
||||||
AirTree::error(void(), false),
|
AirTree::error(Type::void(), false),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
assert!(defined_tails.len() >= elems.len());
|
assert!(defined_tails.len() >= elems.len());
|
||||||
|
@ -3095,7 +3115,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
AirTree::local_var(props.clause_var_name.clone(), subject_tipo.clone()),
|
AirTree::local_var(props.clause_var_name.clone(), subject_tipo.clone()),
|
||||||
false,
|
false,
|
||||||
next_then,
|
next_then,
|
||||||
AirTree::error(void(), false),
|
AirTree::error(Type::void(), false),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3226,7 +3246,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
AirTree::local_var(props.clause_var_name.clone(), subject_tipo.clone()),
|
AirTree::local_var(props.clause_var_name.clone(), subject_tipo.clone()),
|
||||||
false,
|
false,
|
||||||
next_then,
|
next_then,
|
||||||
AirTree::error(void(), false),
|
AirTree::error(Type::void(), false),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3355,7 +3375,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
AirTree::local_var(&props.clause_var_name, subject_tipo.clone()),
|
AirTree::local_var(&props.clause_var_name, subject_tipo.clone()),
|
||||||
false,
|
false,
|
||||||
tuple_name_assigns,
|
tuple_name_assigns,
|
||||||
AirTree::error(void(), false),
|
AirTree::error(Type::void(), false),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
@ -3383,7 +3403,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
AirTree::clause_guard(
|
AirTree::clause_guard(
|
||||||
&props.original_subject_name,
|
&props.original_subject_name,
|
||||||
AirTree::int(value),
|
AirTree::int(value),
|
||||||
int(),
|
Type::int(),
|
||||||
then,
|
then,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -3392,7 +3412,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
AirTree::clause_guard(
|
AirTree::clause_guard(
|
||||||
&props.original_subject_name,
|
&props.original_subject_name,
|
||||||
AirTree::byte_array(value.clone()),
|
AirTree::byte_array(value.clone()),
|
||||||
byte_array(),
|
Type::byte_array(),
|
||||||
then,
|
then,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -3517,14 +3537,14 @@ impl<'a> CodeGenerator<'a> {
|
||||||
AirTree::clause_guard(
|
AirTree::clause_guard(
|
||||||
&props.original_subject_name,
|
&props.original_subject_name,
|
||||||
AirTree::bool(constr_name == "True"),
|
AirTree::bool(constr_name == "True"),
|
||||||
bool(),
|
Type::bool(),
|
||||||
then,
|
then,
|
||||||
)
|
)
|
||||||
} else if subject_tipo.is_void() {
|
} else if subject_tipo.is_void() {
|
||||||
AirTree::clause_guard(
|
AirTree::clause_guard(
|
||||||
&props.original_subject_name,
|
&props.original_subject_name,
|
||||||
AirTree::void(),
|
AirTree::void(),
|
||||||
void(),
|
Type::void(),
|
||||||
then,
|
then,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
@ -3596,7 +3616,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
arg_names.push(arg_name.clone());
|
arg_names.push(arg_name.clone());
|
||||||
|
|
||||||
let param = AirTree::local_var(&arg_name, data());
|
let param = AirTree::local_var(&arg_name, Type::data());
|
||||||
|
|
||||||
let actual_type = convert_opaque_type(&arg.tipo, &self.data_types, true);
|
let actual_type = convert_opaque_type(&arg.tipo, &self.data_types, true);
|
||||||
|
|
||||||
|
@ -3621,7 +3641,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
self.special_functions.insert_new_function(
|
self.special_functions.insert_new_function(
|
||||||
msg_func_name.clone(),
|
msg_func_name.clone(),
|
||||||
Term::Error.delayed_trace(Term::string(msg)).delay(),
|
Term::Error.delayed_trace(Term::string(msg)).delay(),
|
||||||
void(),
|
Type::void(),
|
||||||
);
|
);
|
||||||
|
|
||||||
Some(self.special_functions.use_function_tree(msg_func_name))
|
Some(self.special_functions.use_function_tree(msg_func_name))
|
||||||
|
@ -3637,7 +3657,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
inner_then,
|
inner_then,
|
||||||
&actual_type,
|
&actual_type,
|
||||||
AssignmentProperties {
|
AssignmentProperties {
|
||||||
value_type: data(),
|
value_type: Type::data(),
|
||||||
kind: AssignmentKind::expect(),
|
kind: AssignmentKind::expect(),
|
||||||
remove_unused: false,
|
remove_unused: false,
|
||||||
full_check: true,
|
full_check: true,
|
||||||
|
|
|
@ -7,7 +7,6 @@ use crate::{
|
||||||
Constant, DataTypeKey, FunctionAccessKey, Pattern, Span, TraceLevel, TypedArg,
|
Constant, DataTypeKey, FunctionAccessKey, Pattern, Span, TraceLevel, TypedArg,
|
||||||
TypedAssignmentKind, TypedClause, TypedDataType, TypedPattern,
|
TypedAssignmentKind, TypedClause, TypedDataType, TypedPattern,
|
||||||
},
|
},
|
||||||
builtins::{data, function, int, list, void},
|
|
||||||
expr::TypedExpr,
|
expr::TypedExpr,
|
||||||
line_numbers::{LineColumn, LineNumbers},
|
line_numbers::{LineColumn, LineNumbers},
|
||||||
tipo::{
|
tipo::{
|
||||||
|
@ -212,7 +211,7 @@ impl CodeGenSpecialFuncs {
|
||||||
Term::snd_pair()
|
Term::snd_pair()
|
||||||
.apply(Term::unconstr_data().apply(Term::var("__constr_var")))
|
.apply(Term::unconstr_data().apply(Term::var("__constr_var")))
|
||||||
.lambda("__constr_var"),
|
.lambda("__constr_var"),
|
||||||
function(vec![data()], list(data())),
|
Type::function(vec![Type::data()], Type::list(Type::data())),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -222,7 +221,7 @@ impl CodeGenSpecialFuncs {
|
||||||
Term::fst_pair()
|
Term::fst_pair()
|
||||||
.apply(Term::unconstr_data().apply(Term::var("__constr_var")))
|
.apply(Term::unconstr_data().apply(Term::var("__constr_var")))
|
||||||
.lambda("__constr_var"),
|
.lambda("__constr_var"),
|
||||||
function(vec![data()], int()),
|
Type::function(vec![Type::data()], Type::int()),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -784,7 +783,7 @@ pub fn rearrange_list_clauses(
|
||||||
tipo: tipo.clone(),
|
tipo: tipo.clone(),
|
||||||
text: Box::new(TypedExpr::String {
|
text: Box::new(TypedExpr::String {
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
tipo: crate::builtins::string(),
|
tipo: Type::string(),
|
||||||
value: format!("Clause hole found for {index} elements."),
|
value: format!("Clause hole found for {index} elements."),
|
||||||
}),
|
}),
|
||||||
then: Box::new(TypedExpr::ErrorTerm {
|
then: Box::new(TypedExpr::ErrorTerm {
|
||||||
|
@ -1688,15 +1687,15 @@ pub fn cast_validator_args(term: Term<Name>, arguments: &[TypedArg]) -> Term<Nam
|
||||||
|
|
||||||
pub fn wrap_validator_condition(air_tree: AirTree, trace: TraceLevel) -> AirTree {
|
pub fn wrap_validator_condition(air_tree: AirTree, trace: TraceLevel) -> AirTree {
|
||||||
let otherwise = match trace {
|
let otherwise = match trace {
|
||||||
TraceLevel::Silent | TraceLevel::Compact => AirTree::error(void(), true),
|
TraceLevel::Silent | TraceLevel::Compact => AirTree::error(Type::void(), true),
|
||||||
TraceLevel::Verbose => AirTree::trace(
|
TraceLevel::Verbose => AirTree::trace(
|
||||||
AirTree::string("Validator returned false"),
|
AirTree::string("Validator returned false"),
|
||||||
void(),
|
Type::void(),
|
||||||
AirTree::error(void(), true),
|
AirTree::error(Type::void(), true),
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
AirTree::if_branch(void(), air_tree, AirTree::void(), otherwise)
|
AirTree::if_branch(Type::void(), air_tree, AirTree::void(), otherwise)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extract_constant(term: &Term<Name>) -> Option<Rc<UplcConstant>> {
|
pub fn extract_constant(term: &Term<Name>) -> Option<Rc<UplcConstant>> {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use super::air::{Air, ExpectLevel};
|
use super::air::{Air, ExpectLevel};
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{BinOp, Curve, Span, UnOp},
|
ast::{BinOp, Curve, Span, UnOp},
|
||||||
builtins::{bool, byte_array, data, int, list, string, void},
|
|
||||||
tipo::{Type, ValueConstructor, ValueConstructorVariant},
|
tipo::{Type, ValueConstructor, ValueConstructorVariant},
|
||||||
};
|
};
|
||||||
use indexmap::IndexSet;
|
use indexmap::IndexSet;
|
||||||
|
@ -113,7 +112,7 @@ pub enum AirMsg {
|
||||||
impl AirMsg {
|
impl AirMsg {
|
||||||
pub fn to_air_tree(&self) -> AirTree {
|
pub fn to_air_tree(&self) -> AirTree {
|
||||||
match self {
|
match self {
|
||||||
AirMsg::LocalVar(name) => AirTree::local_var(name, string()),
|
AirMsg::LocalVar(name) => AirTree::local_var(name, Type::string()),
|
||||||
AirMsg::Msg(msg) => AirTree::string(msg),
|
AirMsg::Msg(msg) => AirTree::string(msg),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -862,8 +861,8 @@ impl AirTree {
|
||||||
AirTree::var(
|
AirTree::var(
|
||||||
ValueConstructor::public(
|
ValueConstructor::public(
|
||||||
Type::Fn {
|
Type::Fn {
|
||||||
args: vec![list(data())],
|
args: vec![Type::list(Type::data())],
|
||||||
ret: data(),
|
ret: Type::data(),
|
||||||
alias: None,
|
alias: None,
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
|
@ -879,7 +878,7 @@ impl AirTree {
|
||||||
function_name,
|
function_name,
|
||||||
"",
|
"",
|
||||||
),
|
),
|
||||||
data(),
|
Type::data(),
|
||||||
vec![list_of_fields],
|
vec![list_of_fields],
|
||||||
),
|
),
|
||||||
tipo.clone(),
|
tipo.clone(),
|
||||||
|
@ -984,7 +983,7 @@ impl AirTree {
|
||||||
} else {
|
} else {
|
||||||
DefaultFunction::SndPair
|
DefaultFunction::SndPair
|
||||||
},
|
},
|
||||||
data(),
|
Type::data(),
|
||||||
vec![tuple],
|
vec![tuple],
|
||||||
),
|
),
|
||||||
tipo.clone(),
|
tipo.clone(),
|
||||||
|
@ -1039,9 +1038,9 @@ impl AirTree {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expect_on_list2() -> AirTree {
|
pub fn expect_on_list2() -> AirTree {
|
||||||
let inner_expect_on_list = AirTree::local_var(INNER_EXPECT_ON_LIST, void());
|
let inner_expect_on_list = AirTree::local_var(INNER_EXPECT_ON_LIST, Type::void());
|
||||||
|
|
||||||
let list_var = AirTree::local_var("__list_to_check", list(data()));
|
let list_var = AirTree::local_var("__list_to_check", Type::list(Type::data()));
|
||||||
|
|
||||||
AirTree::let_assignment(
|
AirTree::let_assignment(
|
||||||
INNER_EXPECT_ON_LIST,
|
INNER_EXPECT_ON_LIST,
|
||||||
|
@ -1051,13 +1050,13 @@ impl AirTree {
|
||||||
"__list_to_check".to_string(),
|
"__list_to_check".to_string(),
|
||||||
],
|
],
|
||||||
AirTree::call(
|
AirTree::call(
|
||||||
AirTree::local_var("__check_with", void()),
|
AirTree::local_var("__check_with", Type::void()),
|
||||||
void(),
|
Type::void(),
|
||||||
vec![
|
vec![
|
||||||
list_var.clone(),
|
list_var.clone(),
|
||||||
AirTree::call(
|
AirTree::call(
|
||||||
inner_expect_on_list.clone(),
|
inner_expect_on_list.clone(),
|
||||||
void(),
|
Type::void(),
|
||||||
vec![inner_expect_on_list.clone()],
|
vec![inner_expect_on_list.clone()],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -1066,27 +1065,27 @@ impl AirTree {
|
||||||
),
|
),
|
||||||
AirTree::call(
|
AirTree::call(
|
||||||
inner_expect_on_list.clone(),
|
inner_expect_on_list.clone(),
|
||||||
void(),
|
Type::void(),
|
||||||
vec![inner_expect_on_list, list_var],
|
vec![inner_expect_on_list, list_var],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expect_on_list() -> AirTree {
|
pub fn expect_on_list() -> AirTree {
|
||||||
let list_var = AirTree::local_var("__list_to_check", list(data()));
|
let list_var = AirTree::local_var("__list_to_check", Type::list(Type::data()));
|
||||||
|
|
||||||
let head_list = AirTree::builtin(DefaultFunction::HeadList, data(), vec![list_var]);
|
let head_list = AirTree::builtin(DefaultFunction::HeadList, Type::data(), vec![list_var]);
|
||||||
|
|
||||||
let expect_on_head = AirTree::call(
|
let expect_on_head = AirTree::call(
|
||||||
AirTree::local_var("__check_with", void()),
|
AirTree::local_var("__check_with", Type::void()),
|
||||||
void(),
|
Type::void(),
|
||||||
vec![head_list],
|
vec![head_list],
|
||||||
);
|
);
|
||||||
|
|
||||||
let next_call = AirTree::call(
|
let next_call = AirTree::call(
|
||||||
AirTree::var(
|
AirTree::var(
|
||||||
ValueConstructor::public(
|
ValueConstructor::public(
|
||||||
void(),
|
Type::void(),
|
||||||
ValueConstructorVariant::ModuleFn {
|
ValueConstructorVariant::ModuleFn {
|
||||||
name: EXPECT_ON_LIST.to_string(),
|
name: EXPECT_ON_LIST.to_string(),
|
||||||
field_map: None,
|
field_map: None,
|
||||||
|
@ -1099,14 +1098,17 @@ impl AirTree {
|
||||||
EXPECT_ON_LIST,
|
EXPECT_ON_LIST,
|
||||||
"",
|
"",
|
||||||
),
|
),
|
||||||
void(),
|
Type::void(),
|
||||||
vec![
|
vec![
|
||||||
AirTree::builtin(
|
AirTree::builtin(
|
||||||
DefaultFunction::TailList,
|
DefaultFunction::TailList,
|
||||||
list(data()),
|
Type::list(Type::data()),
|
||||||
vec![AirTree::local_var("__list_to_check", list(data()))],
|
vec![AirTree::local_var(
|
||||||
|
"__list_to_check",
|
||||||
|
Type::list(Type::data()),
|
||||||
|
)],
|
||||||
),
|
),
|
||||||
AirTree::local_var("__check_with", void()),
|
AirTree::local_var("__check_with", Type::void()),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1114,7 +1116,7 @@ impl AirTree {
|
||||||
|
|
||||||
AirTree::list_clause(
|
AirTree::list_clause(
|
||||||
"__list_to_check",
|
"__list_to_check",
|
||||||
void(),
|
Type::void(),
|
||||||
AirTree::void(),
|
AirTree::void(),
|
||||||
assign,
|
assign,
|
||||||
None,
|
None,
|
||||||
|
@ -1675,10 +1677,10 @@ impl AirTree {
|
||||||
|
|
||||||
pub fn return_type(&self) -> Rc<Type> {
|
pub fn return_type(&self) -> Rc<Type> {
|
||||||
match self {
|
match self {
|
||||||
AirTree::Int { .. } => int(),
|
AirTree::Int { .. } => Type::int(),
|
||||||
AirTree::String { .. } => string(),
|
AirTree::String { .. } => Type::string(),
|
||||||
AirTree::ByteArray { .. } => byte_array(),
|
AirTree::ByteArray { .. } => Type::byte_array(),
|
||||||
AirTree::Bool { .. } => bool(),
|
AirTree::Bool { .. } => Type::bool(),
|
||||||
AirTree::CurvePoint { point } => point.tipo(),
|
AirTree::CurvePoint { point } => point.tipo(),
|
||||||
AirTree::List { tipo, .. }
|
AirTree::List { tipo, .. }
|
||||||
| AirTree::Tuple { tipo, .. }
|
| AirTree::Tuple { tipo, .. }
|
||||||
|
@ -1693,14 +1695,14 @@ impl AirTree {
|
||||||
| AirTree::RecordUpdate { tipo, .. }
|
| AirTree::RecordUpdate { tipo, .. }
|
||||||
| AirTree::ErrorTerm { tipo, .. }
|
| AirTree::ErrorTerm { tipo, .. }
|
||||||
| AirTree::Trace { tipo, .. } => tipo.clone(),
|
| AirTree::Trace { tipo, .. } => tipo.clone(),
|
||||||
AirTree::Void => void(),
|
AirTree::Void => Type::void(),
|
||||||
AirTree::Var { constructor, .. } => constructor.tipo.clone(),
|
AirTree::Var { constructor, .. } => constructor.tipo.clone(),
|
||||||
AirTree::Fn { func_body, .. } => func_body.return_type(),
|
AirTree::Fn { func_body, .. } => func_body.return_type(),
|
||||||
AirTree::UnOp { op, .. } => match op {
|
AirTree::UnOp { op, .. } => match op {
|
||||||
UnOp::Not => bool(),
|
UnOp::Not => Type::bool(),
|
||||||
UnOp::Negate => int(),
|
UnOp::Negate => Type::int(),
|
||||||
},
|
},
|
||||||
AirTree::CastToData { .. } => data(),
|
AirTree::CastToData { .. } => Type::data(),
|
||||||
AirTree::Clause { then, .. }
|
AirTree::Clause { then, .. }
|
||||||
| AirTree::ListClause { then, .. }
|
| AirTree::ListClause { then, .. }
|
||||||
| AirTree::WrapClause { then, .. }
|
| AirTree::WrapClause { then, .. }
|
||||||
|
@ -1725,7 +1727,7 @@ impl AirTree {
|
||||||
| AirTree::FieldsEmpty { then, .. }
|
| AirTree::FieldsEmpty { then, .. }
|
||||||
| AirTree::ListEmpty { then, .. }
|
| AirTree::ListEmpty { then, .. }
|
||||||
| AirTree::NoOp { then } => then.return_type(),
|
| AirTree::NoOp { then } => then.return_type(),
|
||||||
AirTree::MultiValidator { .. } => void(),
|
AirTree::MultiValidator { .. } => Type::void(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use super::{error::ParseError, token::Token};
|
use super::{error::ParseError, token::Token};
|
||||||
use crate::{
|
use crate::{
|
||||||
ast,
|
ast::{self, well_known},
|
||||||
builtins::{PAIR, PRELUDE},
|
builtins::PRELUDE,
|
||||||
};
|
};
|
||||||
use chumsky::prelude::*;
|
use chumsky::prelude::*;
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ pub fn parser() -> impl Parser<Token, ast::Annotation, Error = ParseError> {
|
||||||
select! {Token::Name { name } if name == PRELUDE => name}
|
select! {Token::Name { name } if name == PRELUDE => name}
|
||||||
.then_ignore(just(Token::Dot))
|
.then_ignore(just(Token::Dot))
|
||||||
.or_not()
|
.or_not()
|
||||||
.then_ignore(select! {Token::UpName { name } if name == PAIR => name})
|
.then_ignore(select! {Token::UpName { name } if name == well_known::PAIR => name})
|
||||||
.ignore_then(
|
.ignore_then(
|
||||||
expression
|
expression
|
||||||
.clone()
|
.clone()
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
builtins::{PAIR, PRELUDE},
|
ast::well_known,
|
||||||
|
builtins::PRELUDE,
|
||||||
expr::UntypedExpr,
|
expr::UntypedExpr,
|
||||||
parser::{error::ParseError, token::Token},
|
parser::{error::ParseError, token::Token},
|
||||||
};
|
};
|
||||||
|
@ -11,7 +12,7 @@ pub fn parser(
|
||||||
select! {Token::Name { name } if name == PRELUDE => name}
|
select! {Token::Name { name } if name == PRELUDE => name}
|
||||||
.then_ignore(just(Token::Dot))
|
.then_ignore(just(Token::Dot))
|
||||||
.or_not()
|
.or_not()
|
||||||
.then_ignore(select! {Token::UpName { name } if name == PAIR => name})
|
.then_ignore(select! {Token::UpName { name } if name == well_known::PAIR => name})
|
||||||
.ignore_then(
|
.ignore_then(
|
||||||
r.clone()
|
r.clone()
|
||||||
.separated_by(just(Token::Comma))
|
.separated_by(just(Token::Comma))
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::UntypedPattern,
|
ast::{well_known, UntypedPattern},
|
||||||
builtins::PAIR,
|
|
||||||
parser::{error::ParseError, token::Token},
|
parser::{error::ParseError, token::Token},
|
||||||
};
|
};
|
||||||
use chumsky::prelude::*;
|
use chumsky::prelude::*;
|
||||||
|
@ -8,7 +7,7 @@ use chumsky::prelude::*;
|
||||||
pub fn parser(
|
pub fn parser(
|
||||||
pattern: Recursive<'_, Token, UntypedPattern, ParseError>,
|
pattern: Recursive<'_, Token, UntypedPattern, ParseError>,
|
||||||
) -> impl Parser<Token, UntypedPattern, Error = ParseError> + '_ {
|
) -> impl Parser<Token, UntypedPattern, Error = ParseError> + '_ {
|
||||||
select! {Token::UpName { name } if name == PAIR => name}
|
select! {Token::UpName { name } if name == well_known::PAIR => name}
|
||||||
.ignore_then(choice((
|
.ignore_then(choice((
|
||||||
just(Token::LeftParen),
|
just(Token::LeftParen),
|
||||||
just(Token::NewLineLeftParen),
|
just(Token::NewLineLeftParen),
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
use self::{environment::Environment, pretty::Printer};
|
use self::{environment::Environment, pretty::Printer};
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{
|
ast::{
|
||||||
Annotation, Constant, DataType, DataTypeKey, DefinitionLocation, ModuleKind, Span,
|
well_known, Annotation, Constant, DataType, DataTypeKey, DefinitionLocation, ModuleKind,
|
||||||
TypedDataType,
|
Span, TypedDataType,
|
||||||
},
|
},
|
||||||
builtins::{G1_ELEMENT, G2_ELEMENT, MILLER_LOOP_RESULT},
|
|
||||||
tipo::fields::FieldMap,
|
tipo::fields::FieldMap,
|
||||||
};
|
};
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
|
@ -304,7 +303,7 @@ impl Type {
|
||||||
|
|
||||||
pub fn is_int(&self) -> bool {
|
pub fn is_int(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::App { module, name, .. } if "Int" == name && module.is_empty() => true,
|
Self::App { module, name, .. } if well_known::INT == name && module.is_empty() => true,
|
||||||
Self::Var { tipo, .. } => tipo.borrow().is_int(),
|
Self::Var { tipo, .. } => tipo.borrow().is_int(),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
|
@ -312,7 +311,11 @@ impl Type {
|
||||||
|
|
||||||
pub fn is_bytearray(&self) -> bool {
|
pub fn is_bytearray(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::App { module, name, .. } if "ByteArray" == name && module.is_empty() => true,
|
Self::App { module, name, .. }
|
||||||
|
if well_known::BYTE_ARRAY == name && module.is_empty() =>
|
||||||
|
{
|
||||||
|
true
|
||||||
|
}
|
||||||
Self::Var { tipo, .. } => tipo.borrow().is_bytearray(),
|
Self::Var { tipo, .. } => tipo.borrow().is_bytearray(),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
|
@ -320,7 +323,7 @@ impl Type {
|
||||||
|
|
||||||
pub fn is_bls381_12_g1(&self) -> bool {
|
pub fn is_bls381_12_g1(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::App { module, name, .. } => G1_ELEMENT == name && module.is_empty(),
|
Self::App { module, name, .. } => well_known::G1_ELEMENT == name && module.is_empty(),
|
||||||
|
|
||||||
Self::Var { tipo, .. } => tipo.borrow().is_bls381_12_g1(),
|
Self::Var { tipo, .. } => tipo.borrow().is_bls381_12_g1(),
|
||||||
_ => false,
|
_ => false,
|
||||||
|
@ -329,7 +332,7 @@ impl Type {
|
||||||
|
|
||||||
pub fn is_bls381_12_g2(&self) -> bool {
|
pub fn is_bls381_12_g2(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::App { module, name, .. } => G2_ELEMENT == name && module.is_empty(),
|
Self::App { module, name, .. } => well_known::G2_ELEMENT == name && module.is_empty(),
|
||||||
|
|
||||||
Self::Var { tipo, .. } => tipo.borrow().is_bls381_12_g2(),
|
Self::Var { tipo, .. } => tipo.borrow().is_bls381_12_g2(),
|
||||||
_ => false,
|
_ => false,
|
||||||
|
@ -338,7 +341,9 @@ impl Type {
|
||||||
|
|
||||||
pub fn is_ml_result(&self) -> bool {
|
pub fn is_ml_result(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::App { module, name, .. } => MILLER_LOOP_RESULT == name && module.is_empty(),
|
Self::App { module, name, .. } => {
|
||||||
|
well_known::MILLER_LOOP_RESULT == name && module.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
Self::Var { tipo, .. } => tipo.borrow().is_ml_result(),
|
Self::Var { tipo, .. } => tipo.borrow().is_ml_result(),
|
||||||
_ => false,
|
_ => false,
|
||||||
|
@ -422,31 +427,33 @@ impl Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_generic(&self) -> bool {
|
pub fn is_generic(&self) -> bool {
|
||||||
match self {
|
!self.collect_generics().is_empty()
|
||||||
Self::App { args, .. } => {
|
|
||||||
let mut is_a_generic = false;
|
|
||||||
for arg in args {
|
|
||||||
is_a_generic = is_a_generic || arg.is_generic();
|
|
||||||
}
|
|
||||||
is_a_generic
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Self::Var { tipo, .. } => tipo.borrow().is_generic(),
|
pub fn collect_generics(&self) -> Vec<Rc<Type>> {
|
||||||
Self::Tuple { elems, .. } => {
|
match self {
|
||||||
let mut is_a_generic = false;
|
Self::App { args, .. } => args.iter().flat_map(|arg| arg.collect_generics()).collect(),
|
||||||
for elem in elems {
|
Self::Var { tipo, .. } => {
|
||||||
is_a_generic = is_a_generic || elem.is_generic();
|
if tipo.borrow().is_generic() {
|
||||||
|
vec![self.clone().into()]
|
||||||
|
} else {
|
||||||
|
Vec::new()
|
||||||
}
|
}
|
||||||
is_a_generic
|
|
||||||
}
|
}
|
||||||
Self::Fn { args, ret, .. } => {
|
Self::Tuple { elems, .. } => elems
|
||||||
let mut is_a_generic = false;
|
.iter()
|
||||||
for arg in args {
|
.flat_map(|arg| arg.collect_generics())
|
||||||
is_a_generic = is_a_generic || arg.is_generic();
|
.collect(),
|
||||||
|
Self::Fn { args, ret, .. } => args
|
||||||
|
.iter()
|
||||||
|
.chain(std::iter::once(ret))
|
||||||
|
.flat_map(|arg| arg.collect_generics())
|
||||||
|
.collect(),
|
||||||
|
Self::Pair { fst, snd, .. } => {
|
||||||
|
let mut generics = fst.collect_generics();
|
||||||
|
generics.extend(snd.collect_generics());
|
||||||
|
generics
|
||||||
}
|
}
|
||||||
is_a_generic || ret.is_generic()
|
|
||||||
}
|
|
||||||
Self::Pair { fst, snd, .. } => fst.is_generic() || snd.is_generic(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1068,7 +1075,7 @@ impl TypeVar {
|
||||||
match self {
|
match self {
|
||||||
TypeVar::Generic { .. } => true,
|
TypeVar::Generic { .. } => true,
|
||||||
TypeVar::Link { tipo } => tipo.is_generic(),
|
TypeVar::Link { tipo } => tipo.is_generic(),
|
||||||
_ => false,
|
TypeVar::Unbound { .. } => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1092,11 +1099,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(),
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1118,6 +1127,51 @@ impl ValueConstructor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn known_enum(
|
||||||
|
values: &mut HashMap<String, Self>,
|
||||||
|
tipo: Rc<Type>,
|
||||||
|
constructors: &[&str],
|
||||||
|
) -> Vec<String> {
|
||||||
|
for constructor in &constructors[..] {
|
||||||
|
values.insert(
|
||||||
|
constructor.to_string(),
|
||||||
|
ValueConstructor::public(
|
||||||
|
tipo.clone(),
|
||||||
|
ValueConstructorVariant::known_enum_variant(constructor, constructors.len(), 0),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
constructors
|
||||||
|
.into_iter()
|
||||||
|
.map(|constructor| constructor.to_string())
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn known_adt(
|
||||||
|
values: &mut HashMap<String, Self>,
|
||||||
|
constructors: &[(&str, Rc<Type>)],
|
||||||
|
) -> Vec<String> {
|
||||||
|
for (constructor, tipo) in &constructors[..] {
|
||||||
|
values.insert(
|
||||||
|
constructor.to_string(),
|
||||||
|
ValueConstructor::public(
|
||||||
|
tipo.clone(),
|
||||||
|
ValueConstructorVariant::known_enum_variant(
|
||||||
|
constructor,
|
||||||
|
constructors.len(),
|
||||||
|
tipo.fn_arity().unwrap_or(0),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
constructors
|
||||||
|
.into_iter()
|
||||||
|
.map(|(constructor, _)| constructor.to_string())
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
fn field_map(&self) -> Option<&FieldMap> {
|
fn field_map(&self) -> Option<&FieldMap> {
|
||||||
match &self.variant {
|
match &self.variant {
|
||||||
ValueConstructorVariant::ModuleFn { field_map, .. }
|
ValueConstructorVariant::ModuleFn { field_map, .. }
|
||||||
|
@ -1248,6 +1302,17 @@ impl ValueConstructorVariant {
|
||||||
pub fn is_local_variable(&self) -> bool {
|
pub fn is_local_variable(&self) -> bool {
|
||||||
matches!(self, Self::LocalVariable { .. })
|
matches!(self, Self::LocalVariable { .. })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn known_enum_variant(name: &str, constructors_count: usize, arity: usize) -> Self {
|
||||||
|
ValueConstructorVariant::Record {
|
||||||
|
module: "".into(),
|
||||||
|
name: name.to_string(),
|
||||||
|
field_map: None::<FieldMap>,
|
||||||
|
arity,
|
||||||
|
location: Span::empty(),
|
||||||
|
constructors_count: constructors_count as u16,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||||
|
@ -1271,6 +1336,18 @@ pub struct TypeConstructor {
|
||||||
pub tipo: Rc<Type>,
|
pub tipo: Rc<Type>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TypeConstructor {
|
||||||
|
pub fn primitive(tipo: Rc<Type>) -> Self {
|
||||||
|
TypeConstructor {
|
||||||
|
location: Span::empty(),
|
||||||
|
parameters: tipo.collect_generics(),
|
||||||
|
tipo,
|
||||||
|
module: "".to_string(),
|
||||||
|
public: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||||
pub struct AccessorsMap {
|
pub struct AccessorsMap {
|
||||||
pub public: bool,
|
pub public: bool,
|
||||||
|
|
|
@ -12,7 +12,6 @@ use crate::{
|
||||||
TypedPattern, UnqualifiedImport, UntypedArg, UntypedDefinition, UntypedFunction, Use,
|
TypedPattern, UnqualifiedImport, UntypedArg, UntypedDefinition, UntypedFunction, Use,
|
||||||
Validator, PIPE_VARIABLE,
|
Validator, PIPE_VARIABLE,
|
||||||
},
|
},
|
||||||
builtins::{function, generic_var, pair, tuple, unbound_var},
|
|
||||||
tipo::{fields::FieldMap, TypeAliasAnnotation},
|
tipo::{fields::FieldMap, TypeAliasAnnotation},
|
||||||
IdGenerator,
|
IdGenerator,
|
||||||
};
|
};
|
||||||
|
@ -183,7 +182,7 @@ impl<'a> Environment<'a> {
|
||||||
|
|
||||||
if let Some((args, ret)) = new_value {
|
if let Some((args, ret)) = new_value {
|
||||||
*tipo.borrow_mut() = TypeVar::Link {
|
*tipo.borrow_mut() = TypeVar::Link {
|
||||||
tipo: function(args.clone(), ret.clone()),
|
tipo: Type::function(args.clone(), ret.clone()),
|
||||||
};
|
};
|
||||||
|
|
||||||
return Ok((args, Type::with_alias(ret, alias.clone())));
|
return Ok((args, Type::with_alias(ret, alias.clone())));
|
||||||
|
@ -690,7 +689,7 @@ impl<'a> Environment<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Type::Fn { args, ret, alias } => Type::with_alias(
|
Type::Fn { args, ret, alias } => Type::with_alias(
|
||||||
function(
|
Type::function(
|
||||||
args.iter()
|
args.iter()
|
||||||
.map(|t| self.instantiate(t.clone(), ids, hydrator))
|
.map(|t| self.instantiate(t.clone(), ids, hydrator))
|
||||||
.collect(),
|
.collect(),
|
||||||
|
@ -700,7 +699,7 @@ impl<'a> Environment<'a> {
|
||||||
),
|
),
|
||||||
|
|
||||||
Type::Tuple { elems, alias } => Type::with_alias(
|
Type::Tuple { elems, alias } => Type::with_alias(
|
||||||
tuple(
|
Type::tuple(
|
||||||
elems
|
elems
|
||||||
.iter()
|
.iter()
|
||||||
.map(|t| self.instantiate(t.clone(), ids, hydrator))
|
.map(|t| self.instantiate(t.clone(), ids, hydrator))
|
||||||
|
@ -709,7 +708,7 @@ impl<'a> Environment<'a> {
|
||||||
alias.clone(),
|
alias.clone(),
|
||||||
),
|
),
|
||||||
Type::Pair { fst, snd, alias } => Type::with_alias(
|
Type::Pair { fst, snd, alias } => Type::with_alias(
|
||||||
pair(
|
Type::pair(
|
||||||
self.instantiate(fst.clone(), ids, hydrator),
|
self.instantiate(fst.clone(), ids, hydrator),
|
||||||
self.instantiate(snd.clone(), ids, hydrator),
|
self.instantiate(snd.clone(), ids, hydrator),
|
||||||
),
|
),
|
||||||
|
@ -795,13 +794,13 @@ impl<'a> Environment<'a> {
|
||||||
|
|
||||||
/// Create a new generic type that can stand in for any type.
|
/// Create a new generic type that can stand in for any type.
|
||||||
pub fn new_generic_var(&mut self) -> Rc<Type> {
|
pub fn new_generic_var(&mut self) -> Rc<Type> {
|
||||||
generic_var(self.next_uid())
|
Type::generic_var(self.next_uid())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new unbound type that is a specific type, we just don't
|
/// Create a new unbound type that is a specific type, we just don't
|
||||||
/// know which one yet.
|
/// know which one yet.
|
||||||
pub fn new_unbound_var(&mut self) -> Rc<Type> {
|
pub fn new_unbound_var(&mut self) -> Rc<Type> {
|
||||||
unbound_var(self.next_uid())
|
Type::unbound_var(self.next_uid())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next_uid(&mut self) -> u64 {
|
pub fn next_uid(&mut self) -> u64 {
|
||||||
|
@ -1214,7 +1213,7 @@ impl<'a> Environment<'a> {
|
||||||
|
|
||||||
let return_type = hydrator.type_from_option_annotation(return_annotation, self)?;
|
let return_type = hydrator.type_from_option_annotation(return_annotation, self)?;
|
||||||
|
|
||||||
let tipo = function(arg_types, return_type);
|
let tipo = Type::function(arg_types, return_type);
|
||||||
|
|
||||||
// Keep track of which types we create from annotations so we can know
|
// Keep track of which types we create from annotations so we can know
|
||||||
// which generic types not to instantiate later when performing
|
// which generic types not to instantiate later when performing
|
||||||
|
@ -1415,7 +1414,7 @@ impl<'a> Environment<'a> {
|
||||||
// Insert constructor function into module scope
|
// Insert constructor function into module scope
|
||||||
let typ = match constructor.arguments.len() {
|
let typ = match constructor.arguments.len() {
|
||||||
0 => typ.clone(),
|
0 => typ.clone(),
|
||||||
_ => function(args_types, typ.clone()),
|
_ => Type::function(args_types, typ.clone()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let constructor_info = ValueConstructorVariant::Record {
|
let constructor_info = ValueConstructorVariant::Record {
|
||||||
|
@ -2013,7 +2012,7 @@ pub(crate) fn generalise(t: Rc<Type>, ctx_level: usize) -> Rc<Type> {
|
||||||
match t.deref() {
|
match t.deref() {
|
||||||
Type::Var { tipo, alias } => Type::with_alias(
|
Type::Var { tipo, alias } => Type::with_alias(
|
||||||
match tipo.borrow().deref() {
|
match tipo.borrow().deref() {
|
||||||
TypeVar::Unbound { id } => generic_var(*id),
|
TypeVar::Unbound { id } => Type::generic_var(*id),
|
||||||
TypeVar::Link { tipo } => generalise(tipo.clone(), ctx_level),
|
TypeVar::Link { tipo } => generalise(tipo.clone(), ctx_level),
|
||||||
TypeVar::Generic { .. } => Rc::new(Type::Var {
|
TypeVar::Generic { .. } => Rc::new(Type::Var {
|
||||||
tipo: tipo.clone(),
|
tipo: tipo.clone(),
|
||||||
|
@ -2047,7 +2046,7 @@ pub(crate) fn generalise(t: Rc<Type>, ctx_level: usize) -> Rc<Type> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Type::Fn { args, ret, alias } => Type::with_alias(
|
Type::Fn { args, ret, alias } => Type::with_alias(
|
||||||
function(
|
Type::function(
|
||||||
args.iter()
|
args.iter()
|
||||||
.map(|t| generalise(t.clone(), ctx_level))
|
.map(|t| generalise(t.clone(), ctx_level))
|
||||||
.collect(),
|
.collect(),
|
||||||
|
@ -2057,7 +2056,7 @@ pub(crate) fn generalise(t: Rc<Type>, ctx_level: usize) -> Rc<Type> {
|
||||||
),
|
),
|
||||||
|
|
||||||
Type::Tuple { elems, alias } => Type::with_alias(
|
Type::Tuple { elems, alias } => Type::with_alias(
|
||||||
tuple(
|
Type::tuple(
|
||||||
elems
|
elems
|
||||||
.iter()
|
.iter()
|
||||||
.map(|t| generalise(t.clone(), ctx_level))
|
.map(|t| generalise(t.clone(), ctx_level))
|
||||||
|
@ -2066,7 +2065,7 @@ pub(crate) fn generalise(t: Rc<Type>, ctx_level: usize) -> Rc<Type> {
|
||||||
alias.clone(),
|
alias.clone(),
|
||||||
),
|
),
|
||||||
Type::Pair { fst, snd, alias } => Type::with_alias(
|
Type::Pair { fst, snd, alias } => Type::with_alias(
|
||||||
pair(
|
Type::pair(
|
||||||
generalise(fst.clone(), ctx_level),
|
generalise(fst.clone(), ctx_level),
|
||||||
generalise(snd.clone(), ctx_level),
|
generalise(snd.clone(), ctx_level),
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
ast,
|
ast,
|
||||||
builtins::{self},
|
tipo::{self, environment::Environment, error::Error, Type},
|
||||||
tipo::{self, environment::Environment, error::Error},
|
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use std::{collections::BTreeMap, iter, ops::Deref};
|
use std::{collections::BTreeMap, iter, ops::Deref};
|
||||||
|
@ -500,8 +499,8 @@ fn pretty_tail(tail: Pattern) -> String {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list_constructors() -> Vec<tipo::ValueConstructor> {
|
fn list_constructors() -> Vec<tipo::ValueConstructor> {
|
||||||
let list_parameter = builtins::generic_var(0);
|
let list_parameter = Type::generic_var(0);
|
||||||
let list_type = builtins::list(list_parameter);
|
let list_type = Type::list(list_parameter);
|
||||||
|
|
||||||
vec![
|
vec![
|
||||||
tipo::ValueConstructor {
|
tipo::ValueConstructor {
|
||||||
|
|
|
@ -17,10 +17,7 @@ use crate::{
|
||||||
UnOp, UntypedArg, UntypedAssignmentKind, UntypedClause, UntypedFunction, UntypedIfBranch,
|
UnOp, UntypedArg, UntypedAssignmentKind, UntypedClause, UntypedFunction, UntypedIfBranch,
|
||||||
UntypedPattern, UntypedRecordUpdateArg,
|
UntypedPattern, UntypedRecordUpdateArg,
|
||||||
},
|
},
|
||||||
builtins::{
|
builtins::{from_default_function, BUILTIN},
|
||||||
bool, byte_array, data, from_default_function, function, g1_element, g2_element, int, list,
|
|
||||||
pair, string, tuple, void, BUILTIN,
|
|
||||||
},
|
|
||||||
expr::{FnStyle, TypedExpr, UntypedExpr},
|
expr::{FnStyle, TypedExpr, UntypedExpr},
|
||||||
format,
|
format,
|
||||||
tipo::{fields::FieldMap, DefaultFunction, PatternConstructor, TypeVar},
|
tipo::{fields::FieldMap, DefaultFunction, PatternConstructor, TypeVar},
|
||||||
|
@ -163,7 +160,7 @@ pub(crate) fn infer_function(
|
||||||
|
|
||||||
let args_types = arguments.iter().map(|a| a.tipo.clone()).collect();
|
let args_types = arguments.iter().map(|a| a.tipo.clone()).collect();
|
||||||
|
|
||||||
let tipo = function(args_types, return_type);
|
let tipo = Type::function(args_types, return_type);
|
||||||
|
|
||||||
let safe_to_generalise = !expr_typer.ungeneralised_function_used;
|
let safe_to_generalise = !expr_typer.ungeneralised_function_used;
|
||||||
|
|
||||||
|
@ -594,15 +591,15 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
Ok(TypedExpr::ByteArray {
|
Ok(TypedExpr::ByteArray {
|
||||||
location,
|
location,
|
||||||
bytes,
|
bytes,
|
||||||
tipo: byte_array(),
|
tipo: Type::byte_array(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn infer_curve_point(&mut self, curve: Curve, location: Span) -> Result<TypedExpr, Error> {
|
fn infer_curve_point(&mut self, curve: Curve, location: Span) -> Result<TypedExpr, Error> {
|
||||||
let tipo = match curve {
|
let tipo = match curve {
|
||||||
Curve::Bls12_381(point) => match point {
|
Curve::Bls12_381(point) => match point {
|
||||||
Bls12_381Point::G1(_) => g1_element(),
|
Bls12_381Point::G1(_) => Type::g1_element(),
|
||||||
Bls12_381Point::G2(_) => g2_element(),
|
Bls12_381Point::G2(_) => Type::g2_element(),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -631,7 +628,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
module: String::new(),
|
module: String::new(),
|
||||||
constructors_count: 2,
|
constructors_count: 2,
|
||||||
},
|
},
|
||||||
tipo: bool(),
|
tipo: Type::bool(),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -648,14 +645,14 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
module: String::new(),
|
module: String::new(),
|
||||||
constructors_count: 2,
|
constructors_count: 2,
|
||||||
},
|
},
|
||||||
tipo: bool(),
|
tipo: Type::bool(),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let text = match self.tracing.trace_level(false) {
|
let text = match self.tracing.trace_level(false) {
|
||||||
TraceLevel::Verbose => Some(TypedExpr::String {
|
TraceLevel::Verbose => Some(TypedExpr::String {
|
||||||
location,
|
location,
|
||||||
tipo: string(),
|
tipo: Type::string(),
|
||||||
value: format!(
|
value: format!(
|
||||||
"{} ? False",
|
"{} ? False",
|
||||||
format::Formatter::new()
|
format::Formatter::new()
|
||||||
|
@ -668,7 +665,12 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
|
|
||||||
let typed_value = self.infer(value)?;
|
let typed_value = self.infer(value)?;
|
||||||
|
|
||||||
self.unify(bool(), typed_value.tipo(), typed_value.location(), false)?;
|
self.unify(
|
||||||
|
Type::bool(),
|
||||||
|
typed_value.tipo(),
|
||||||
|
typed_value.location(),
|
||||||
|
false,
|
||||||
|
)?;
|
||||||
|
|
||||||
match text {
|
match text {
|
||||||
None => Ok(typed_value),
|
None => Ok(typed_value),
|
||||||
|
@ -682,11 +684,11 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
}],
|
}],
|
||||||
final_else: Box::new(TypedExpr::Trace {
|
final_else: Box::new(TypedExpr::Trace {
|
||||||
location,
|
location,
|
||||||
tipo: bool(),
|
tipo: Type::bool(),
|
||||||
text: Box::new(text),
|
text: Box::new(text),
|
||||||
then: Box::new(var_false),
|
then: Box::new(var_false),
|
||||||
}),
|
}),
|
||||||
tipo: bool(),
|
tipo: Type::bool(),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -714,22 +716,22 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
return Ok(TypedExpr::BinOp {
|
return Ok(TypedExpr::BinOp {
|
||||||
location,
|
location,
|
||||||
name,
|
name,
|
||||||
tipo: bool(),
|
tipo: Type::bool(),
|
||||||
left: Box::new(left),
|
left: Box::new(left),
|
||||||
right: Box::new(right),
|
right: Box::new(right),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
BinOp::And => (bool(), bool()),
|
BinOp::And => (Type::bool(), Type::bool()),
|
||||||
BinOp::Or => (bool(), bool()),
|
BinOp::Or => (Type::bool(), Type::bool()),
|
||||||
BinOp::LtInt => (int(), bool()),
|
BinOp::LtInt => (Type::int(), Type::bool()),
|
||||||
BinOp::LtEqInt => (int(), bool()),
|
BinOp::LtEqInt => (Type::int(), Type::bool()),
|
||||||
BinOp::GtEqInt => (int(), bool()),
|
BinOp::GtEqInt => (Type::int(), Type::bool()),
|
||||||
BinOp::GtInt => (int(), bool()),
|
BinOp::GtInt => (Type::int(), Type::bool()),
|
||||||
BinOp::AddInt => (int(), int()),
|
BinOp::AddInt => (Type::int(), Type::int()),
|
||||||
BinOp::SubInt => (int(), int()),
|
BinOp::SubInt => (Type::int(), Type::int()),
|
||||||
BinOp::MultInt => (int(), int()),
|
BinOp::MultInt => (Type::int(), Type::int()),
|
||||||
BinOp::DivInt => (int(), int()),
|
BinOp::DivInt => (Type::int(), Type::int()),
|
||||||
BinOp::ModInt => (int(), int()),
|
BinOp::ModInt => (Type::int(), Type::int()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let left = self.infer(left)?;
|
let left = self.infer(left)?;
|
||||||
|
@ -896,8 +898,8 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
let value = self.infer(value)?;
|
let value = self.infer(value)?;
|
||||||
|
|
||||||
let tipo = match op {
|
let tipo = match op {
|
||||||
UnOp::Not => bool(),
|
UnOp::Not => Type::bool(),
|
||||||
UnOp::Negate => int(),
|
UnOp::Negate => Type::int(),
|
||||||
};
|
};
|
||||||
|
|
||||||
self.unify(tipo.clone(), value.tipo(), value.location(), false)?;
|
self.unify(tipo.clone(), value.tipo(), value.location(), false)?;
|
||||||
|
@ -1603,7 +1605,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
let condition = self.infer(branch.condition.clone())?;
|
let condition = self.infer(branch.condition.clone())?;
|
||||||
|
|
||||||
self.unify(
|
self.unify(
|
||||||
bool(),
|
Type::bool(),
|
||||||
condition.tipo(),
|
condition.tipo(),
|
||||||
condition.type_defining_location(),
|
condition.type_defining_location(),
|
||||||
false,
|
false,
|
||||||
|
@ -1647,7 +1649,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
|
|
||||||
let args_types = args.iter().map(|a| a.tipo.clone()).collect();
|
let args_types = args.iter().map(|a| a.tipo.clone()).collect();
|
||||||
|
|
||||||
let tipo = function(args_types, return_type);
|
let tipo = Type::function(args_types, return_type);
|
||||||
|
|
||||||
Ok(TypedExpr::Fn {
|
Ok(TypedExpr::Fn {
|
||||||
location,
|
location,
|
||||||
|
@ -1745,7 +1747,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
TypedExpr::UInt {
|
TypedExpr::UInt {
|
||||||
location,
|
location,
|
||||||
value,
|
value,
|
||||||
tipo: int(),
|
tipo: Type::int(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1772,7 +1774,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
ensure_serialisable(false, tipo.clone(), location)?;
|
ensure_serialisable(false, tipo.clone(), location)?;
|
||||||
|
|
||||||
// Type check the ..tail, if there is one
|
// Type check the ..tail, if there is one
|
||||||
let tipo = list(tipo);
|
let tipo = Type::list(tipo);
|
||||||
|
|
||||||
let tail = match tail {
|
let tail = match tail {
|
||||||
Some(tail) => {
|
Some(tail) => {
|
||||||
|
@ -1807,7 +1809,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
let typed_expression = self.infer(expression)?;
|
let typed_expression = self.infer(expression)?;
|
||||||
|
|
||||||
self.unify(
|
self.unify(
|
||||||
bool(),
|
Type::bool(),
|
||||||
typed_expression.tipo(),
|
typed_expression.tipo(),
|
||||||
typed_expression.location(),
|
typed_expression.location(),
|
||||||
false,
|
false,
|
||||||
|
@ -1831,7 +1833,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
.rev()
|
.rev()
|
||||||
.reduce(|acc, typed_expression| TypedExpr::BinOp {
|
.reduce(|acc, typed_expression| TypedExpr::BinOp {
|
||||||
location,
|
location,
|
||||||
tipo: bool(),
|
tipo: Type::bool(),
|
||||||
name,
|
name,
|
||||||
left: typed_expression.into(),
|
left: typed_expression.into(),
|
||||||
right: acc.into(),
|
right: acc.into(),
|
||||||
|
@ -2151,7 +2153,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
TypedExpr::String {
|
TypedExpr::String {
|
||||||
location,
|
location,
|
||||||
value,
|
value,
|
||||||
tipo: string(),
|
tipo: Type::string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2169,7 +2171,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
|
|
||||||
Ok(TypedExpr::Pair {
|
Ok(TypedExpr::Pair {
|
||||||
location,
|
location,
|
||||||
tipo: pair(typed_fst.tipo(), typed_snd.tipo()),
|
tipo: Type::pair(typed_fst.tipo(), typed_snd.tipo()),
|
||||||
fst: typed_fst.into(),
|
fst: typed_fst.into(),
|
||||||
snd: typed_snd.into(),
|
snd: typed_snd.into(),
|
||||||
})
|
})
|
||||||
|
@ -2187,7 +2189,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
typed_elems.push(typed_elem);
|
typed_elems.push(typed_elem);
|
||||||
}
|
}
|
||||||
|
|
||||||
let tipo = tuple(typed_elems.iter().map(|e| e.tipo()).collect());
|
let tipo = Type::tuple(typed_elems.iter().map(|e| e.tipo()).collect());
|
||||||
|
|
||||||
Ok(TypedExpr::Tuple {
|
Ok(TypedExpr::Tuple {
|
||||||
location,
|
location,
|
||||||
|
@ -2255,9 +2257,14 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
|
|
||||||
fn infer_trace_arg(&mut self, arg: UntypedExpr) -> Result<TypedExpr, Error> {
|
fn infer_trace_arg(&mut self, arg: UntypedExpr) -> Result<TypedExpr, Error> {
|
||||||
let typed_arg = self.infer(arg)?;
|
let typed_arg = self.infer(arg)?;
|
||||||
match self.unify(string(), typed_arg.tipo(), typed_arg.location(), false) {
|
match self.unify(
|
||||||
|
Type::string(),
|
||||||
|
typed_arg.tipo(),
|
||||||
|
typed_arg.location(),
|
||||||
|
false,
|
||||||
|
) {
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
self.unify(data(), typed_arg.tipo(), typed_arg.location(), true)?;
|
self.unify(Type::data(), typed_arg.tipo(), typed_arg.location(), true)?;
|
||||||
Ok(diagnose_expr(typed_arg))
|
Ok(diagnose_expr(typed_arg))
|
||||||
}
|
}
|
||||||
Ok(()) => Ok(typed_arg),
|
Ok(()) => Ok(typed_arg),
|
||||||
|
@ -2291,7 +2298,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
TraceLevel::Silent => Ok(then),
|
TraceLevel::Silent => Ok(then),
|
||||||
TraceLevel::Compact => {
|
TraceLevel::Compact => {
|
||||||
let text = self.infer(label)?;
|
let text = self.infer(label)?;
|
||||||
self.unify(string(), text.tipo(), text.location(), false)?;
|
self.unify(Type::string(), text.tipo(), text.location(), false)?;
|
||||||
Ok(TypedExpr::Trace {
|
Ok(TypedExpr::Trace {
|
||||||
location,
|
location,
|
||||||
tipo,
|
tipo,
|
||||||
|
@ -2307,7 +2314,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
} else {
|
} else {
|
||||||
let delimiter = |ix| TypedExpr::String {
|
let delimiter = |ix| TypedExpr::String {
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
tipo: string(),
|
tipo: Type::string(),
|
||||||
value: if ix == 0 { ": " } else { ", " }.to_string(),
|
value: if ix == 0 { ": " } else { ", " }.to_string(),
|
||||||
};
|
};
|
||||||
typed_arguments
|
typed_arguments
|
||||||
|
@ -2594,7 +2601,7 @@ fn assert_assignment(expr: TypedExpr) -> Result<TypedExpr, Error> {
|
||||||
if expr.tipo().is_void() {
|
if expr.tipo().is_void() {
|
||||||
return Ok(TypedExpr::Assignment {
|
return Ok(TypedExpr::Assignment {
|
||||||
location: expr.location(),
|
location: expr.location(),
|
||||||
tipo: void(),
|
tipo: Type::void(),
|
||||||
value: expr.clone().into(),
|
value: expr.clone().into(),
|
||||||
pattern: Pattern::Constructor {
|
pattern: Pattern::Constructor {
|
||||||
is_record: false,
|
is_record: false,
|
||||||
|
@ -2607,7 +2614,7 @@ fn assert_assignment(expr: TypedExpr) -> Result<TypedExpr, Error> {
|
||||||
arguments: vec![],
|
arguments: vec![],
|
||||||
module: None,
|
module: None,
|
||||||
spread_location: None,
|
spread_location: None,
|
||||||
tipo: void(),
|
tipo: Type::void(),
|
||||||
},
|
},
|
||||||
kind: AssignmentKind::let_(),
|
kind: AssignmentKind::let_(),
|
||||||
});
|
});
|
||||||
|
@ -2713,7 +2720,7 @@ fn diagnose_expr(expr: TypedExpr) -> TypedExpr {
|
||||||
name: "diagnostic".to_string(),
|
name: "diagnostic".to_string(),
|
||||||
constructor: ValueConstructor {
|
constructor: ValueConstructor {
|
||||||
public: true,
|
public: true,
|
||||||
tipo: function(vec![data(), byte_array()], byte_array()),
|
tipo: Type::function(vec![Type::data(), Type::byte_array()], Type::byte_array()),
|
||||||
variant: ValueConstructorVariant::ModuleFn {
|
variant: ValueConstructorVariant::ModuleFn {
|
||||||
name: "diagnostic".to_string(),
|
name: "diagnostic".to_string(),
|
||||||
field_map: None,
|
field_map: None,
|
||||||
|
@ -2728,13 +2735,13 @@ fn diagnose_expr(expr: TypedExpr) -> TypedExpr {
|
||||||
let location = expr.location();
|
let location = expr.location();
|
||||||
|
|
||||||
TypedExpr::Call {
|
TypedExpr::Call {
|
||||||
tipo: string(),
|
tipo: Type::string(),
|
||||||
fun: Box::new(decode_utf8.clone()),
|
fun: Box::new(decode_utf8.clone()),
|
||||||
args: vec![CallArg {
|
args: vec![CallArg {
|
||||||
label: None,
|
label: None,
|
||||||
location: expr.location(),
|
location: expr.location(),
|
||||||
value: TypedExpr::Call {
|
value: TypedExpr::Call {
|
||||||
tipo: byte_array(),
|
tipo: Type::byte_array(),
|
||||||
fun: Box::new(diagnostic.clone()),
|
fun: Box::new(diagnostic.clone()),
|
||||||
args: vec![
|
args: vec![
|
||||||
CallArg {
|
CallArg {
|
||||||
|
@ -2746,7 +2753,7 @@ fn diagnose_expr(expr: TypedExpr) -> TypedExpr {
|
||||||
label: None,
|
label: None,
|
||||||
location,
|
location,
|
||||||
value: TypedExpr::ByteArray {
|
value: TypedExpr::ByteArray {
|
||||||
tipo: byte_array(),
|
tipo: Type::byte_array(),
|
||||||
bytes: vec![],
|
bytes: vec![],
|
||||||
location,
|
location,
|
||||||
},
|
},
|
||||||
|
@ -2785,7 +2792,7 @@ fn append_string_expr(left: TypedExpr, right: TypedExpr) -> TypedExpr {
|
||||||
|
|
||||||
TypedExpr::Call {
|
TypedExpr::Call {
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
tipo: string(),
|
tipo: Type::string(),
|
||||||
fun: Box::new(append_string.clone()),
|
fun: Box::new(append_string.clone()),
|
||||||
args: vec![
|
args: vec![
|
||||||
CallArg {
|
CallArg {
|
||||||
|
|
|
@ -3,11 +3,7 @@ use super::{
|
||||||
error::{Error, Warning},
|
error::{Error, Warning},
|
||||||
Type, TypeConstructor,
|
Type, TypeConstructor,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{ast::Annotation, tipo::Span};
|
||||||
ast::Annotation,
|
|
||||||
builtins::{function, pair, tuple},
|
|
||||||
tipo::Span,
|
|
||||||
};
|
|
||||||
use std::{collections::HashMap, rc::Rc};
|
use std::{collections::HashMap, rc::Rc};
|
||||||
|
|
||||||
/// The Hydrator takes an AST representing a type (i.e. a type annotation
|
/// The Hydrator takes an AST representing a type (i.e. a type annotation
|
||||||
|
@ -201,7 +197,7 @@ impl Hydrator {
|
||||||
|
|
||||||
let ret = self.do_type_from_annotation(ret, environment, unbounds)?;
|
let ret = self.do_type_from_annotation(ret, environment, unbounds)?;
|
||||||
|
|
||||||
Ok(function(args, ret))
|
Ok(Type::function(args, ret))
|
||||||
}
|
}
|
||||||
|
|
||||||
Annotation::Var { name, location, .. } => match self.created_type_variables.get(name) {
|
Annotation::Var { name, location, .. } => match self.created_type_variables.get(name) {
|
||||||
|
@ -244,13 +240,13 @@ impl Hydrator {
|
||||||
typed_elems.push(typed_elem)
|
typed_elems.push(typed_elem)
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(tuple(typed_elems))
|
Ok(Type::tuple(typed_elems))
|
||||||
}
|
}
|
||||||
Annotation::Pair { fst, snd, .. } => {
|
Annotation::Pair { fst, snd, .. } => {
|
||||||
let fst = self.do_type_from_annotation(fst, environment, unbounds)?;
|
let fst = self.do_type_from_annotation(fst, environment, unbounds)?;
|
||||||
let snd = self.do_type_from_annotation(snd, environment, unbounds)?;
|
let snd = self.do_type_from_annotation(snd, environment, unbounds)?;
|
||||||
|
|
||||||
Ok(pair(fst, snd))
|
Ok(Type::pair(fst, snd))
|
||||||
}
|
}
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@ use crate::{
|
||||||
RecordConstructor, RecordConstructorArg, Tracing, TypeAlias, TypedArg, TypedDefinition,
|
RecordConstructor, RecordConstructorArg, Tracing, TypeAlias, TypedArg, TypedDefinition,
|
||||||
TypedModule, TypedValidator, UntypedArg, UntypedDefinition, UntypedModule, Use, Validator,
|
TypedModule, TypedValidator, UntypedArg, UntypedDefinition, UntypedModule, Use, Validator,
|
||||||
},
|
},
|
||||||
builtins::{self, fuzzer, generic_var},
|
|
||||||
tipo::{expr::infer_function, Span, Type, TypeVar},
|
tipo::{expr::infer_function, Span, Type, TypeVar},
|
||||||
IdGenerator,
|
IdGenerator,
|
||||||
};
|
};
|
||||||
|
@ -214,7 +213,7 @@ fn infer_definition(
|
||||||
location: typed_fun
|
location: typed_fun
|
||||||
.location
|
.location
|
||||||
.map(|start, _end| (start, start + typed_fun.name.len())),
|
.map(|start, _end| (start, start + typed_fun.name.len())),
|
||||||
available_purposes: TypedValidator::available_purposes(),
|
available_purposes: TypedValidator::available_handler_names(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,7 +227,7 @@ fn infer_definition(
|
||||||
|
|
||||||
for arg in typed_fun.arguments.iter_mut() {
|
for arg in typed_fun.arguments.iter_mut() {
|
||||||
if arg.tipo.is_unbound() {
|
if arg.tipo.is_unbound() {
|
||||||
arg.tipo = builtins::data();
|
arg.tipo = Type::data();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,7 +262,7 @@ fn infer_definition(
|
||||||
.drain(0..params_length)
|
.drain(0..params_length)
|
||||||
.map(|mut arg| {
|
.map(|mut arg| {
|
||||||
if arg.tipo.is_unbound() {
|
if arg.tipo.is_unbound() {
|
||||||
arg.tipo = builtins::data();
|
arg.tipo = Type::data();
|
||||||
}
|
}
|
||||||
|
|
||||||
arg
|
arg
|
||||||
|
@ -280,7 +279,7 @@ fn infer_definition(
|
||||||
|
|
||||||
for arg in typed_fallback.arguments.iter_mut() {
|
for arg in typed_fallback.arguments.iter_mut() {
|
||||||
if arg.tipo.is_unbound() {
|
if arg.tipo.is_unbound() {
|
||||||
arg.tipo = builtins::data();
|
arg.tipo = Type::data();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -383,14 +382,14 @@ fn infer_definition(
|
||||||
|
|
||||||
let is_bool = environment.unify(
|
let is_bool = environment.unify(
|
||||||
typed_f.return_type.clone(),
|
typed_f.return_type.clone(),
|
||||||
builtins::bool(),
|
Type::bool(),
|
||||||
typed_f.location,
|
typed_f.location,
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
|
||||||
let is_void = environment.unify(
|
let is_void = environment.unify(
|
||||||
typed_f.return_type.clone(),
|
typed_f.return_type.clone(),
|
||||||
builtins::void(),
|
Type::void(),
|
||||||
typed_f.location,
|
typed_f.location,
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
@ -642,10 +641,10 @@ fn infer_fuzzer(
|
||||||
) -> Result<(Annotation, Rc<Type>), Error> {
|
) -> Result<(Annotation, Rc<Type>), Error> {
|
||||||
let could_not_unify = || Error::CouldNotUnify {
|
let could_not_unify = || Error::CouldNotUnify {
|
||||||
location: *location,
|
location: *location,
|
||||||
expected: fuzzer(
|
expected: Type::fuzzer(
|
||||||
expected_inner_type
|
expected_inner_type
|
||||||
.clone()
|
.clone()
|
||||||
.unwrap_or_else(|| generic_var(0)),
|
.unwrap_or_else(|| Type::generic_var(0)),
|
||||||
),
|
),
|
||||||
given: tipo.clone(),
|
given: tipo.clone(),
|
||||||
situation: None,
|
situation: None,
|
||||||
|
@ -681,7 +680,7 @@ fn infer_fuzzer(
|
||||||
// `unify` now that we have figured out the type carried by the fuzzer.
|
// `unify` now that we have figured out the type carried by the fuzzer.
|
||||||
environment.unify(
|
environment.unify(
|
||||||
tipo.clone(),
|
tipo.clone(),
|
||||||
fuzzer(wrapped.clone()),
|
Type::fuzzer(wrapped.clone()),
|
||||||
*location,
|
*location,
|
||||||
false,
|
false,
|
||||||
)?;
|
)?;
|
||||||
|
|
|
@ -6,10 +6,7 @@ use super::{
|
||||||
hydrator::Hydrator,
|
hydrator::Hydrator,
|
||||||
PatternConstructor, Type, ValueConstructorVariant,
|
PatternConstructor, Type, ValueConstructorVariant,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::ast::{CallArg, Pattern, Span, TypedPattern, UntypedPattern};
|
||||||
ast::{CallArg, Pattern, Span, TypedPattern, UntypedPattern},
|
|
||||||
builtins::{byte_array, int, list, pair, tuple},
|
|
||||||
};
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, HashSet},
|
collections::{HashMap, HashSet},
|
||||||
|
@ -190,7 +187,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> {
|
||||||
value,
|
value,
|
||||||
base,
|
base,
|
||||||
} => {
|
} => {
|
||||||
self.environment.unify(tipo, int(), location, false)?;
|
self.environment.unify(tipo, Type::int(), location, false)?;
|
||||||
|
|
||||||
Ok(Pattern::Int {
|
Ok(Pattern::Int {
|
||||||
location,
|
location,
|
||||||
|
@ -205,7 +202,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> {
|
||||||
preferred_format,
|
preferred_format,
|
||||||
} => {
|
} => {
|
||||||
self.environment
|
self.environment
|
||||||
.unify(tipo, byte_array(), location, false)?;
|
.unify(tipo, Type::byte_array(), location, false)?;
|
||||||
|
|
||||||
Ok(Pattern::ByteArray {
|
Ok(Pattern::ByteArray {
|
||||||
location,
|
location,
|
||||||
|
@ -231,7 +228,12 @@ impl<'a, 'b> PatternTyper<'a, 'b> {
|
||||||
.try_collect()?;
|
.try_collect()?;
|
||||||
|
|
||||||
let tail = match tail {
|
let tail = match tail {
|
||||||
Some(tail) => Some(Box::new(self.unify(*tail, list(tipo), None, false)?)),
|
Some(tail) => Some(Box::new(self.unify(
|
||||||
|
*tail,
|
||||||
|
Type::list(tipo),
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
)?)),
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -243,7 +245,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> {
|
||||||
}
|
}
|
||||||
|
|
||||||
None => Err(Error::CouldNotUnify {
|
None => Err(Error::CouldNotUnify {
|
||||||
given: list(self.environment.new_unbound_var()),
|
given: Type::list(self.environment.new_unbound_var()),
|
||||||
expected: tipo.clone(),
|
expected: tipo.clone(),
|
||||||
situation: None,
|
situation: None,
|
||||||
location,
|
location,
|
||||||
|
@ -267,7 +269,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> {
|
||||||
let t_snd = self.environment.new_unbound_var();
|
let t_snd = self.environment.new_unbound_var();
|
||||||
|
|
||||||
self.environment.unify(
|
self.environment.unify(
|
||||||
pair(t_fst.clone(), t_snd.clone()),
|
Type::pair(t_fst.clone(), t_snd.clone()),
|
||||||
tipo,
|
tipo,
|
||||||
location,
|
location,
|
||||||
false,
|
false,
|
||||||
|
@ -280,7 +282,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> {
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => Err(Error::CouldNotUnify {
|
_ => Err(Error::CouldNotUnify {
|
||||||
given: pair(
|
given: Type::pair(
|
||||||
self.environment.new_unbound_var(),
|
self.environment.new_unbound_var(),
|
||||||
self.environment.new_unbound_var(),
|
self.environment.new_unbound_var(),
|
||||||
),
|
),
|
||||||
|
@ -322,8 +324,12 @@ impl<'a, 'b> PatternTyper<'a, 'b> {
|
||||||
.map(|_| self.environment.new_unbound_var())
|
.map(|_| self.environment.new_unbound_var())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
self.environment
|
self.environment.unify(
|
||||||
.unify(tuple(elems_types.clone()), tipo, location, false)?;
|
Type::tuple(elems_types.clone()),
|
||||||
|
tipo,
|
||||||
|
location,
|
||||||
|
false,
|
||||||
|
)?;
|
||||||
|
|
||||||
let mut patterns = vec![];
|
let mut patterns = vec![];
|
||||||
|
|
||||||
|
@ -345,7 +351,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> {
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
Err(Error::CouldNotUnify {
|
Err(Error::CouldNotUnify {
|
||||||
given: tuple(elems_types),
|
given: Type::tuple(elems_types),
|
||||||
expected: tipo,
|
expected: tipo,
|
||||||
situation: None,
|
situation: None,
|
||||||
location,
|
location,
|
||||||
|
|
|
@ -5,7 +5,6 @@ use super::{
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{AssignmentKind, CallArg, Pattern, Span, PIPE_VARIABLE},
|
ast::{AssignmentKind, CallArg, Pattern, Span, PIPE_VARIABLE},
|
||||||
builtins::function,
|
|
||||||
expr::{TypedExpr, UntypedExpr},
|
expr::{TypedExpr, UntypedExpr},
|
||||||
};
|
};
|
||||||
use std::{ops::Deref, rc::Rc};
|
use std::{ops::Deref, rc::Rc};
|
||||||
|
@ -257,7 +256,7 @@ impl<'a, 'b, 'c> PipeTyper<'a, 'b, 'c> {
|
||||||
.environment
|
.environment
|
||||||
.unify(
|
.unify(
|
||||||
func.tipo(),
|
func.tipo(),
|
||||||
function(vec![self.argument_type.clone()], return_type.clone()),
|
Type::function(vec![self.argument_type.clone()], return_type.clone()),
|
||||||
func.location(),
|
func.location(),
|
||||||
if let Type::Fn { args, .. } = func.tipo().deref() {
|
if let Type::Fn { args, .. } = func.tipo().deref() {
|
||||||
if let Some(typ) = args.first() {
|
if let Some(typ) = args.first() {
|
||||||
|
|
|
@ -296,10 +296,7 @@ fn resolve_alias(
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{
|
use crate::tipo::{Span, Type};
|
||||||
builtins::{function, int},
|
|
||||||
tipo::Span,
|
|
||||||
};
|
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
|
||||||
|
@ -490,7 +487,7 @@ mod tests {
|
||||||
"?",
|
"?",
|
||||||
);
|
);
|
||||||
assert_string!(
|
assert_string!(
|
||||||
function(
|
Type::function(
|
||||||
vec![Rc::new(Type::Var {
|
vec![Rc::new(Type::Var {
|
||||||
tipo: Rc::new(RefCell::new(TypeVar::Unbound { id: 78 })),
|
tipo: Rc::new(RefCell::new(TypeVar::Unbound { id: 78 })),
|
||||||
alias: None,
|
alias: None,
|
||||||
|
@ -503,7 +500,7 @@ mod tests {
|
||||||
"fn(?) -> ?",
|
"fn(?) -> ?",
|
||||||
);
|
);
|
||||||
assert_string!(
|
assert_string!(
|
||||||
function(
|
Type::function(
|
||||||
vec![Rc::new(Type::Var {
|
vec![Rc::new(Type::Var {
|
||||||
tipo: Rc::new(RefCell::new(TypeVar::Generic { id: 78 })),
|
tipo: Rc::new(RefCell::new(TypeVar::Generic { id: 78 })),
|
||||||
alias: None,
|
alias: None,
|
||||||
|
@ -692,10 +689,16 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn function_test() {
|
fn function_test() {
|
||||||
assert_eq!(pretty_print(function(vec![], int())), "fn() -> Int");
|
assert_eq!(
|
||||||
|
pretty_print(Type::function(vec![], Type::int())),
|
||||||
|
"fn() -> Int"
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
pretty_print(function(vec![int(), int(), int()], int())),
|
pretty_print(Type::function(
|
||||||
|
vec![Type::int(), Type::int(), Type::int()],
|
||||||
|
Type::int()
|
||||||
|
)),
|
||||||
"fn(Int, Int, Int) -> Int"
|
"fn(Int, Int, Int) -> Int"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,7 +153,7 @@ impl From<&Config> for Preamble {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use aiken_lang::builtins;
|
use aiken_lang::tipo::Type;
|
||||||
use schema::{Data, Declaration, Items, Schema};
|
use schema::{Data, Declaration, Items, Schema};
|
||||||
use serde_json::{self, json};
|
use serde_json::{self, json};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
@ -225,17 +225,17 @@ mod tests {
|
||||||
fn serialize_with_definitions() {
|
fn serialize_with_definitions() {
|
||||||
let mut definitions = Definitions::new();
|
let mut definitions = Definitions::new();
|
||||||
definitions
|
definitions
|
||||||
.register::<_, Error>(&builtins::int(), &HashMap::new(), |_| {
|
.register::<_, Error>(&Type::int(), &HashMap::new(), |_| {
|
||||||
Ok(Schema::Data(Data::Integer).into())
|
Ok(Schema::Data(Data::Integer).into())
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
definitions
|
definitions
|
||||||
.register::<_, Error>(
|
.register::<_, Error>(
|
||||||
&builtins::list(builtins::byte_array()),
|
&Type::list(Type::byte_array()),
|
||||||
&HashMap::new(),
|
&HashMap::new(),
|
||||||
|definitions| {
|
|definitions| {
|
||||||
let ref_bytes = definitions.register::<_, Error>(
|
let ref_bytes = definitions.register::<_, Error>(
|
||||||
&builtins::byte_array(),
|
&Type::byte_array(),
|
||||||
&HashMap::new(),
|
&HashMap::new(),
|
||||||
|_| Ok(Schema::Data(Data::Bytes).into()),
|
|_| Ok(Schema::Data(Data::Bytes).into()),
|
||||||
)?;
|
)?;
|
||||||
|
|
|
@ -4,7 +4,6 @@ use crate::{
|
||||||
};
|
};
|
||||||
use aiken_lang::{
|
use aiken_lang::{
|
||||||
ast::{Definition, TypedDataType, TypedDefinition},
|
ast::{Definition, TypedDataType, TypedDefinition},
|
||||||
builtins::wrapped_redeemer,
|
|
||||||
tipo::{pretty, Type, TypeVar},
|
tipo::{pretty, Type, TypeVar},
|
||||||
};
|
};
|
||||||
use owo_colors::{OwoColorize, Stream::Stdout};
|
use owo_colors::{OwoColorize, Stream::Stdout};
|
||||||
|
@ -142,7 +141,7 @@ impl Annotated<Schema> {
|
||||||
) -> Reference {
|
) -> Reference {
|
||||||
definitions
|
definitions
|
||||||
.register(
|
.register(
|
||||||
&wrapped_redeemer(type_info),
|
&Type::wrapped_redeemer(type_info),
|
||||||
&HashMap::new(),
|
&HashMap::new(),
|
||||||
|_| {
|
|_| {
|
||||||
Ok::<_, Error>(Annotated {
|
Ok::<_, Error>(Annotated {
|
||||||
|
|
|
@ -272,7 +272,7 @@ mod tests {
|
||||||
use aiken_lang::{
|
use aiken_lang::{
|
||||||
self,
|
self,
|
||||||
ast::{TraceLevel, Tracing},
|
ast::{TraceLevel, Tracing},
|
||||||
builtins,
|
tipo::Type,
|
||||||
};
|
};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use uplc::ast as uplc_ast;
|
use uplc::ast as uplc_ast;
|
||||||
|
@ -336,7 +336,7 @@ mod tests {
|
||||||
// "dataType": "integer"
|
// "dataType": "integer"
|
||||||
// }
|
// }
|
||||||
definitions
|
definitions
|
||||||
.register::<_, Error>(&builtins::int(), &HashMap::new(), |_| {
|
.register::<_, Error>(&Type::int(), &HashMap::new(), |_| {
|
||||||
Ok(Schema::Data(Data::Integer).into())
|
Ok(Schema::Data(Data::Integer).into())
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -347,7 +347,7 @@ mod tests {
|
||||||
// "dataType": "bytes"
|
// "dataType": "bytes"
|
||||||
// }
|
// }
|
||||||
definitions
|
definitions
|
||||||
.register::<_, Error>(&builtins::byte_array(), &HashMap::new(), |_| {
|
.register::<_, Error>(&Type::byte_array(), &HashMap::new(), |_| {
|
||||||
Ok(Schema::Data(Data::Bytes).into())
|
Ok(Schema::Data(Data::Bytes).into())
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use aiken_lang::ast::OnTestFailure;
|
use aiken_lang::ast::OnTestFailure;
|
||||||
pub(crate) use aiken_lang::{
|
pub(crate) use aiken_lang::{
|
||||||
ast::{BinOp, DataTypeKey, IfBranch, Span, TypedArg, TypedDataType, TypedTest},
|
ast::{BinOp, DataTypeKey, IfBranch, Span, TypedArg, TypedDataType, TypedTest},
|
||||||
builtins::bool,
|
|
||||||
expr::{TypedExpr, UntypedExpr},
|
expr::{TypedExpr, UntypedExpr},
|
||||||
format::Formatter,
|
format::Formatter,
|
||||||
gen_uplc::CodeGenerator,
|
gen_uplc::CodeGenerator,
|
||||||
|
@ -1056,7 +1055,7 @@ impl TryFrom<TypedExpr> for Assertion<TypedExpr> {
|
||||||
left,
|
left,
|
||||||
right,
|
right,
|
||||||
..
|
..
|
||||||
} if tipo == bool() => {
|
} if tipo == Type::bool() => {
|
||||||
// 'and' and 'or' are left-associative operators.
|
// 'and' and 'or' are left-associative operators.
|
||||||
match (*right).clone().try_into() {
|
match (*right).clone().try_into() {
|
||||||
Ok(Assertion {
|
Ok(Assertion {
|
||||||
|
@ -1094,7 +1093,7 @@ impl TryFrom<TypedExpr> for Assertion<TypedExpr> {
|
||||||
let then_is_true = match body {
|
let then_is_true = match body {
|
||||||
TypedExpr::Var {
|
TypedExpr::Var {
|
||||||
name, constructor, ..
|
name, constructor, ..
|
||||||
} => name == "True" && constructor.tipo == bool(),
|
} => name == "True" && constructor.tipo == Type::bool(),
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1102,7 +1101,7 @@ impl TryFrom<TypedExpr> for Assertion<TypedExpr> {
|
||||||
TypedExpr::Trace { then, .. } => match *then {
|
TypedExpr::Trace { then, .. } => match *then {
|
||||||
TypedExpr::Var {
|
TypedExpr::Var {
|
||||||
name, constructor, ..
|
name, constructor, ..
|
||||||
} => name == "False" && constructor.tipo == bool(),
|
} => name == "False" && constructor.tipo == Type::bool(),
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
_ => false,
|
_ => false,
|
||||||
|
|
Loading…
Reference in New Issue