DRY builtins types creation to ensure proper consistency.
This commit is contained in:
339
crates/aiken-lang/src/ast/well_known.rs
Normal file
339
crates/aiken-lang/src/ast/well_known.rs
Normal file
@@ -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,
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user