feat: start creating aiken/builtin module
This commit is contained in:
parent
53b2adb7df
commit
d5d2ba9cd7
|
@ -81,6 +81,7 @@ dependencies = [
|
||||||
"miette",
|
"miette",
|
||||||
"pretty_assertions",
|
"pretty_assertions",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"uplc",
|
||||||
"vec1",
|
"vec1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ impl Project {
|
||||||
let mut module_types = HashMap::new();
|
let mut module_types = HashMap::new();
|
||||||
|
|
||||||
module_types.insert("aiken".to_string(), builtins::prelude(&id_gen));
|
module_types.insert("aiken".to_string(), builtins::prelude(&id_gen));
|
||||||
|
module_types.insert("aiken/builtin".to_string(), builtins::plutus());
|
||||||
|
|
||||||
Project {
|
Project {
|
||||||
config,
|
config,
|
||||||
|
|
|
@ -16,6 +16,7 @@ internment = "0.7.0"
|
||||||
itertools = "0.10.5"
|
itertools = "0.10.5"
|
||||||
miette = "5.2.0"
|
miette = "5.2.0"
|
||||||
thiserror = "1.0.37"
|
thiserror = "1.0.37"
|
||||||
|
uplc = { path = '../uplc', version = "0.0.21" }
|
||||||
vec1 = "1.8.0"
|
vec1 = "1.8.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
use std::{cell::RefCell, collections::HashMap, sync::Arc};
|
use std::{cell::RefCell, collections::HashMap, sync::Arc};
|
||||||
|
|
||||||
|
use uplc::builtins::DefaultFunction;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{ModuleKind, Span},
|
ast::{ModuleKind, Span},
|
||||||
tipo::{
|
tipo::{
|
||||||
self, fields::FieldMap, Type, TypeConstructor, TypeVar, ValueConstructor,
|
fields::FieldMap, Type, TypeConstructor, TypeInfo, TypeVar, ValueConstructor,
|
||||||
ValueConstructorVariant,
|
ValueConstructorVariant,
|
||||||
},
|
},
|
||||||
IdGenerator,
|
IdGenerator,
|
||||||
|
@ -19,8 +21,8 @@ const STRING: &str = "String";
|
||||||
|
|
||||||
/// Build a prelude that can be injected
|
/// Build a prelude that can be injected
|
||||||
/// into a compiler pipeline
|
/// into a compiler pipeline
|
||||||
pub fn prelude(id_gen: &IdGenerator) -> tipo::TypeInfo {
|
pub fn prelude(id_gen: &IdGenerator) -> TypeInfo {
|
||||||
let mut prelude = tipo::TypeInfo {
|
let mut prelude = TypeInfo {
|
||||||
name: "aiken".to_string(),
|
name: "aiken".to_string(),
|
||||||
package: "".to_string(),
|
package: "".to_string(),
|
||||||
kind: ModuleKind::Lib,
|
kind: ModuleKind::Lib,
|
||||||
|
@ -36,7 +38,7 @@ pub fn prelude(id_gen: &IdGenerator) -> tipo::TypeInfo {
|
||||||
TypeConstructor {
|
TypeConstructor {
|
||||||
parameters: vec![],
|
parameters: vec![],
|
||||||
tipo: int(),
|
tipo: int(),
|
||||||
origin: Span::empty(),
|
location: Span::empty(),
|
||||||
module: "".to_string(),
|
module: "".to_string(),
|
||||||
public: true,
|
public: true,
|
||||||
},
|
},
|
||||||
|
@ -46,7 +48,7 @@ pub fn prelude(id_gen: &IdGenerator) -> tipo::TypeInfo {
|
||||||
prelude.types.insert(
|
prelude.types.insert(
|
||||||
BYTE_ARRAY.to_string(),
|
BYTE_ARRAY.to_string(),
|
||||||
TypeConstructor {
|
TypeConstructor {
|
||||||
origin: Span::empty(),
|
location: Span::empty(),
|
||||||
parameters: vec![],
|
parameters: vec![],
|
||||||
tipo: byte_array(),
|
tipo: byte_array(),
|
||||||
module: "".to_string(),
|
module: "".to_string(),
|
||||||
|
@ -93,7 +95,7 @@ pub fn prelude(id_gen: &IdGenerator) -> tipo::TypeInfo {
|
||||||
prelude.types.insert(
|
prelude.types.insert(
|
||||||
BOOL.to_string(),
|
BOOL.to_string(),
|
||||||
TypeConstructor {
|
TypeConstructor {
|
||||||
origin: Span::empty(),
|
location: Span::empty(),
|
||||||
parameters: vec![],
|
parameters: vec![],
|
||||||
tipo: bool(),
|
tipo: bool(),
|
||||||
module: "".to_string(),
|
module: "".to_string(),
|
||||||
|
@ -106,7 +108,7 @@ pub fn prelude(id_gen: &IdGenerator) -> tipo::TypeInfo {
|
||||||
prelude.types.insert(
|
prelude.types.insert(
|
||||||
LIST.to_string(),
|
LIST.to_string(),
|
||||||
TypeConstructor {
|
TypeConstructor {
|
||||||
origin: Span::empty(),
|
location: Span::empty(),
|
||||||
parameters: vec![list_parameter.clone()],
|
parameters: vec![list_parameter.clone()],
|
||||||
tipo: list(list_parameter),
|
tipo: list(list_parameter),
|
||||||
module: "".to_string(),
|
module: "".to_string(),
|
||||||
|
@ -118,7 +120,7 @@ pub fn prelude(id_gen: &IdGenerator) -> tipo::TypeInfo {
|
||||||
prelude.types.insert(
|
prelude.types.insert(
|
||||||
STRING.to_string(),
|
STRING.to_string(),
|
||||||
TypeConstructor {
|
TypeConstructor {
|
||||||
origin: Span::empty(),
|
location: Span::empty(),
|
||||||
parameters: vec![],
|
parameters: vec![],
|
||||||
tipo: string(),
|
tipo: string(),
|
||||||
module: "".to_string(),
|
module: "".to_string(),
|
||||||
|
@ -145,7 +147,7 @@ pub fn prelude(id_gen: &IdGenerator) -> tipo::TypeInfo {
|
||||||
prelude.types.insert(
|
prelude.types.insert(
|
||||||
NIL.to_string(),
|
NIL.to_string(),
|
||||||
TypeConstructor {
|
TypeConstructor {
|
||||||
origin: Span::empty(),
|
location: Span::empty(),
|
||||||
parameters: vec![],
|
parameters: vec![],
|
||||||
tipo: nil(),
|
tipo: nil(),
|
||||||
module: "".to_string(),
|
module: "".to_string(),
|
||||||
|
@ -160,7 +162,7 @@ pub fn prelude(id_gen: &IdGenerator) -> tipo::TypeInfo {
|
||||||
prelude.types.insert(
|
prelude.types.insert(
|
||||||
RESULT.to_string(),
|
RESULT.to_string(),
|
||||||
TypeConstructor {
|
TypeConstructor {
|
||||||
origin: Span::empty(),
|
location: Span::empty(),
|
||||||
parameters: vec![result_value.clone(), result_error.clone()],
|
parameters: vec![result_value.clone(), result_error.clone()],
|
||||||
tipo: result(result_value, result_error),
|
tipo: result(result_value, result_error),
|
||||||
module: "".to_string(),
|
module: "".to_string(),
|
||||||
|
@ -210,6 +212,122 @@ pub fn prelude(id_gen: &IdGenerator) -> tipo::TypeInfo {
|
||||||
prelude
|
prelude
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn plutus() -> TypeInfo {
|
||||||
|
let mut plutus = TypeInfo {
|
||||||
|
name: "aiken/builtin".to_string(),
|
||||||
|
package: "".to_string(),
|
||||||
|
kind: ModuleKind::Lib,
|
||||||
|
types: HashMap::new(),
|
||||||
|
types_constructors: HashMap::new(),
|
||||||
|
values: HashMap::new(),
|
||||||
|
accessors: HashMap::new(),
|
||||||
|
};
|
||||||
|
|
||||||
|
plutus.values.insert(
|
||||||
|
DefaultFunction::AddInteger.to_string(),
|
||||||
|
DefaultFunction::AddInteger.into(),
|
||||||
|
);
|
||||||
|
|
||||||
|
plutus.values.insert(
|
||||||
|
DefaultFunction::SubtractInteger.to_string(),
|
||||||
|
DefaultFunction::SubtractInteger.into(),
|
||||||
|
);
|
||||||
|
|
||||||
|
plutus.values.insert(
|
||||||
|
DefaultFunction::MultiplyInteger.to_string(),
|
||||||
|
DefaultFunction::MultiplyInteger.into(),
|
||||||
|
);
|
||||||
|
|
||||||
|
plutus.values.insert(
|
||||||
|
DefaultFunction::DivideInteger.to_string(),
|
||||||
|
DefaultFunction::DivideInteger.into(),
|
||||||
|
);
|
||||||
|
|
||||||
|
plutus
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<DefaultFunction> for ValueConstructor {
|
||||||
|
fn from(builtin: DefaultFunction) -> Self {
|
||||||
|
let (tipo, arity) = match builtin {
|
||||||
|
DefaultFunction::AddInteger
|
||||||
|
| DefaultFunction::SubtractInteger
|
||||||
|
| DefaultFunction::MultiplyInteger
|
||||||
|
| DefaultFunction::DivideInteger
|
||||||
|
| DefaultFunction::QuotientInteger
|
||||||
|
| DefaultFunction::RemainderInteger
|
||||||
|
| DefaultFunction::ModInteger => {
|
||||||
|
let tipo = function(vec![int(), int()], int());
|
||||||
|
|
||||||
|
(tipo, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
DefaultFunction::EqualsInteger
|
||||||
|
| DefaultFunction::LessThanInteger
|
||||||
|
| DefaultFunction::LessThanEqualsInteger => {
|
||||||
|
let tipo = function(vec![int(), int()], bool());
|
||||||
|
|
||||||
|
(tipo, 2)
|
||||||
|
}
|
||||||
|
DefaultFunction::AppendByteString => todo!(),
|
||||||
|
DefaultFunction::ConsByteString => todo!(),
|
||||||
|
DefaultFunction::SliceByteString => todo!(),
|
||||||
|
DefaultFunction::LengthOfByteString => todo!(),
|
||||||
|
DefaultFunction::IndexByteString => todo!(),
|
||||||
|
DefaultFunction::EqualsByteString => todo!(),
|
||||||
|
DefaultFunction::LessThanByteString => todo!(),
|
||||||
|
DefaultFunction::LessThanEqualsByteString => todo!(),
|
||||||
|
DefaultFunction::Sha2_256 => todo!(),
|
||||||
|
DefaultFunction::Sha3_256 => todo!(),
|
||||||
|
DefaultFunction::Blake2b_256 => todo!(),
|
||||||
|
DefaultFunction::VerifyEd25519Signature => todo!(),
|
||||||
|
DefaultFunction::VerifyEcdsaSecp256k1Signature => todo!(),
|
||||||
|
DefaultFunction::VerifySchnorrSecp256k1Signature => todo!(),
|
||||||
|
DefaultFunction::AppendString => todo!(),
|
||||||
|
DefaultFunction::EqualsString => todo!(),
|
||||||
|
DefaultFunction::EncodeUtf8 => todo!(),
|
||||||
|
DefaultFunction::DecodeUtf8 => todo!(),
|
||||||
|
DefaultFunction::IfThenElse => todo!(),
|
||||||
|
DefaultFunction::ChooseUnit => todo!(),
|
||||||
|
DefaultFunction::Trace => todo!(),
|
||||||
|
DefaultFunction::FstPair => todo!(),
|
||||||
|
DefaultFunction::SndPair => todo!(),
|
||||||
|
DefaultFunction::ChooseList => todo!(),
|
||||||
|
DefaultFunction::MkCons => todo!(),
|
||||||
|
DefaultFunction::HeadList => todo!(),
|
||||||
|
DefaultFunction::TailList => todo!(),
|
||||||
|
DefaultFunction::NullList => todo!(),
|
||||||
|
DefaultFunction::ChooseData => todo!(),
|
||||||
|
DefaultFunction::ConstrData => todo!(),
|
||||||
|
DefaultFunction::MapData => todo!(),
|
||||||
|
DefaultFunction::ListData => todo!(),
|
||||||
|
DefaultFunction::IData => todo!(),
|
||||||
|
DefaultFunction::BData => todo!(),
|
||||||
|
DefaultFunction::UnConstrData => todo!(),
|
||||||
|
DefaultFunction::UnMapData => todo!(),
|
||||||
|
DefaultFunction::UnListData => todo!(),
|
||||||
|
DefaultFunction::UnIData => todo!(),
|
||||||
|
DefaultFunction::UnBData => todo!(),
|
||||||
|
DefaultFunction::EqualsData => todo!(),
|
||||||
|
DefaultFunction::SerialiseData => todo!(),
|
||||||
|
DefaultFunction::MkPairData => todo!(),
|
||||||
|
DefaultFunction::MkNilData => todo!(),
|
||||||
|
DefaultFunction::MkNilPairData => todo!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
ValueConstructor::public(
|
||||||
|
tipo,
|
||||||
|
ValueConstructorVariant::ModuleFn {
|
||||||
|
name: builtin.to_string(),
|
||||||
|
field_map: None,
|
||||||
|
module: "".to_string(),
|
||||||
|
arity,
|
||||||
|
location: Span::empty(),
|
||||||
|
builtin: Some(builtin),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn int() -> Arc<Type> {
|
pub fn int() -> Arc<Type> {
|
||||||
Arc::new(Type::App {
|
Arc::new(Type::App {
|
||||||
public: true,
|
public: true,
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
use std::{cell::RefCell, collections::HashMap, ops::Deref, sync::Arc};
|
use std::{cell::RefCell, collections::HashMap, ops::Deref, sync::Arc};
|
||||||
|
|
||||||
|
use uplc::builtins::DefaultFunction;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{Constant, DefinitionLocation, ModuleKind, Span, TypedConstant},
|
ast::{Constant, DefinitionLocation, ModuleKind, Span, TypedConstant},
|
||||||
tipo::fields::FieldMap,
|
tipo::fields::FieldMap,
|
||||||
|
@ -354,6 +356,7 @@ pub enum ValueConstructorVariant {
|
||||||
module: String,
|
module: String,
|
||||||
arity: usize,
|
arity: usize,
|
||||||
location: Span,
|
location: Span,
|
||||||
|
builtin: Option<DefaultFunction>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// A constructor for a custom type
|
/// A constructor for a custom type
|
||||||
|
@ -445,7 +448,7 @@ pub struct TypeInfo {
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct TypeConstructor {
|
pub struct TypeConstructor {
|
||||||
pub public: bool,
|
pub public: bool,
|
||||||
pub origin: Span,
|
pub location: Span,
|
||||||
pub module: String,
|
pub module: String,
|
||||||
pub parameters: Vec<Arc<Type>>,
|
pub parameters: Vec<Arc<Type>>,
|
||||||
pub tipo: Arc<Type>,
|
pub tipo: Arc<Type>,
|
||||||
|
|
|
@ -224,6 +224,7 @@ impl<'a> Environment<'a> {
|
||||||
module: module_name.to_owned(),
|
module: module_name.to_owned(),
|
||||||
arity: args.len(),
|
arity: args.len(),
|
||||||
location,
|
location,
|
||||||
|
builtin: None,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -461,7 +462,7 @@ impl<'a> Environment<'a> {
|
||||||
info: TypeConstructor,
|
info: TypeConstructor,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let name = type_name.clone();
|
let name = type_name.clone();
|
||||||
let location = info.origin;
|
let location = info.location;
|
||||||
|
|
||||||
match self.module_types.insert(type_name, info) {
|
match self.module_types.insert(type_name, info) {
|
||||||
None => Ok(()),
|
None => Ok(()),
|
||||||
|
@ -469,7 +470,7 @@ impl<'a> Environment<'a> {
|
||||||
Some(previous) => Err(Error::DuplicateTypeName {
|
Some(previous) => Err(Error::DuplicateTypeName {
|
||||||
name,
|
name,
|
||||||
location,
|
location,
|
||||||
previous_location: previous.origin,
|
previous_location: previous.location,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -720,7 +721,7 @@ impl<'a> Environment<'a> {
|
||||||
// Register the unqualified import if it is a type constructor
|
// Register the unqualified import if it is a type constructor
|
||||||
if let Some(typ) = module_info.types.get(name) {
|
if let Some(typ) = module_info.types.get(name) {
|
||||||
let typ_info = TypeConstructor {
|
let typ_info = TypeConstructor {
|
||||||
origin: *location,
|
location: *location,
|
||||||
..typ.clone()
|
..typ.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -843,7 +844,7 @@ impl<'a> Environment<'a> {
|
||||||
self.insert_type_constructor(
|
self.insert_type_constructor(
|
||||||
name.clone(),
|
name.clone(),
|
||||||
TypeConstructor {
|
TypeConstructor {
|
||||||
origin: *location,
|
location: *location,
|
||||||
module: module.to_owned(),
|
module: module.to_owned(),
|
||||||
public: *public,
|
public: *public,
|
||||||
parameters,
|
parameters,
|
||||||
|
@ -884,7 +885,7 @@ impl<'a> Environment<'a> {
|
||||||
self.insert_type_constructor(
|
self.insert_type_constructor(
|
||||||
name.clone(),
|
name.clone(),
|
||||||
TypeConstructor {
|
TypeConstructor {
|
||||||
origin: *location,
|
location: *location,
|
||||||
module: module.to_owned(),
|
module: module.to_owned(),
|
||||||
public: *public,
|
public: *public,
|
||||||
parameters,
|
parameters,
|
||||||
|
@ -967,6 +968,7 @@ impl<'a> Environment<'a> {
|
||||||
module: module_name.to_owned(),
|
module: module_name.to_owned(),
|
||||||
arity: args.len(),
|
arity: args.len(),
|
||||||
location: *location,
|
location: *location,
|
||||||
|
builtin: None,
|
||||||
},
|
},
|
||||||
tipo,
|
tipo,
|
||||||
);
|
);
|
||||||
|
|
|
@ -206,6 +206,7 @@ fn infer_definition(
|
||||||
module: module_name.to_owned(),
|
module: module_name.to_owned(),
|
||||||
arity: args.len(),
|
arity: args.len(),
|
||||||
location,
|
location,
|
||||||
|
builtin: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
environment.insert_variable(name.clone(), module_fn, tipo.clone());
|
environment.insert_variable(name.clone(), module_fn, tipo.clone());
|
||||||
|
@ -422,7 +423,7 @@ fn infer_definition(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate_module_name(name: &str) -> Result<(), Error> {
|
fn validate_module_name(name: &str) -> Result<(), Error> {
|
||||||
if name == "aiken" {
|
if name == "aiken" || name == "aiken/builtin" {
|
||||||
return Err(Error::ReservedModuleName {
|
return Err(Error::ReservedModuleName {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use aiken/builtin.{addInteger}
|
||||||
|
|
||||||
pub type ScriptContext {
|
pub type ScriptContext {
|
||||||
idk: Int
|
idk: Int
|
||||||
}
|
}
|
||||||
|
@ -5,3 +7,7 @@ pub type ScriptContext {
|
||||||
pub fn append(a: ByteArray, b: ByteArray) -> ByteArray {
|
pub fn append(a: ByteArray, b: ByteArray) -> ByteArray {
|
||||||
todo
|
todo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add(a, b) {
|
||||||
|
addInteger(a, b)
|
||||||
|
}
|
Loading…
Reference in New Issue