feat: start creating aiken/builtin module

This commit is contained in:
rvcas 2022-10-24 13:30:27 -04:00 committed by Lucas
parent 53b2adb7df
commit d5d2ba9cd7
8 changed files with 150 additions and 17 deletions

1
Cargo.lock generated
View File

@ -81,6 +81,7 @@ dependencies = [
"miette",
"pretty_assertions",
"thiserror",
"uplc",
"vec1",
]

View File

@ -37,6 +37,7 @@ impl Project {
let mut module_types = HashMap::new();
module_types.insert("aiken".to_string(), builtins::prelude(&id_gen));
module_types.insert("aiken/builtin".to_string(), builtins::plutus());
Project {
config,

View File

@ -16,6 +16,7 @@ internment = "0.7.0"
itertools = "0.10.5"
miette = "5.2.0"
thiserror = "1.0.37"
uplc = { path = '../uplc', version = "0.0.21" }
vec1 = "1.8.0"
[dev-dependencies]

View File

@ -1,9 +1,11 @@
use std::{cell::RefCell, collections::HashMap, sync::Arc};
use uplc::builtins::DefaultFunction;
use crate::{
ast::{ModuleKind, Span},
tipo::{
self, fields::FieldMap, Type, TypeConstructor, TypeVar, ValueConstructor,
fields::FieldMap, Type, TypeConstructor, TypeInfo, TypeVar, ValueConstructor,
ValueConstructorVariant,
},
IdGenerator,
@ -19,8 +21,8 @@ const STRING: &str = "String";
/// Build a prelude that can be injected
/// into a compiler pipeline
pub fn prelude(id_gen: &IdGenerator) -> tipo::TypeInfo {
let mut prelude = tipo::TypeInfo {
pub fn prelude(id_gen: &IdGenerator) -> TypeInfo {
let mut prelude = TypeInfo {
name: "aiken".to_string(),
package: "".to_string(),
kind: ModuleKind::Lib,
@ -36,7 +38,7 @@ pub fn prelude(id_gen: &IdGenerator) -> tipo::TypeInfo {
TypeConstructor {
parameters: vec![],
tipo: int(),
origin: Span::empty(),
location: Span::empty(),
module: "".to_string(),
public: true,
},
@ -46,7 +48,7 @@ pub fn prelude(id_gen: &IdGenerator) -> tipo::TypeInfo {
prelude.types.insert(
BYTE_ARRAY.to_string(),
TypeConstructor {
origin: Span::empty(),
location: Span::empty(),
parameters: vec![],
tipo: byte_array(),
module: "".to_string(),
@ -93,7 +95,7 @@ pub fn prelude(id_gen: &IdGenerator) -> tipo::TypeInfo {
prelude.types.insert(
BOOL.to_string(),
TypeConstructor {
origin: Span::empty(),
location: Span::empty(),
parameters: vec![],
tipo: bool(),
module: "".to_string(),
@ -106,7 +108,7 @@ pub fn prelude(id_gen: &IdGenerator) -> tipo::TypeInfo {
prelude.types.insert(
LIST.to_string(),
TypeConstructor {
origin: Span::empty(),
location: Span::empty(),
parameters: vec![list_parameter.clone()],
tipo: list(list_parameter),
module: "".to_string(),
@ -118,7 +120,7 @@ pub fn prelude(id_gen: &IdGenerator) -> tipo::TypeInfo {
prelude.types.insert(
STRING.to_string(),
TypeConstructor {
origin: Span::empty(),
location: Span::empty(),
parameters: vec![],
tipo: string(),
module: "".to_string(),
@ -145,7 +147,7 @@ pub fn prelude(id_gen: &IdGenerator) -> tipo::TypeInfo {
prelude.types.insert(
NIL.to_string(),
TypeConstructor {
origin: Span::empty(),
location: Span::empty(),
parameters: vec![],
tipo: nil(),
module: "".to_string(),
@ -160,7 +162,7 @@ pub fn prelude(id_gen: &IdGenerator) -> tipo::TypeInfo {
prelude.types.insert(
RESULT.to_string(),
TypeConstructor {
origin: Span::empty(),
location: Span::empty(),
parameters: vec![result_value.clone(), result_error.clone()],
tipo: result(result_value, result_error),
module: "".to_string(),
@ -210,6 +212,122 @@ pub fn prelude(id_gen: &IdGenerator) -> tipo::TypeInfo {
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> {
Arc::new(Type::App {
public: true,

View File

@ -1,5 +1,7 @@
use std::{cell::RefCell, collections::HashMap, ops::Deref, sync::Arc};
use uplc::builtins::DefaultFunction;
use crate::{
ast::{Constant, DefinitionLocation, ModuleKind, Span, TypedConstant},
tipo::fields::FieldMap,
@ -354,6 +356,7 @@ pub enum ValueConstructorVariant {
module: String,
arity: usize,
location: Span,
builtin: Option<DefaultFunction>,
},
/// A constructor for a custom type
@ -445,7 +448,7 @@ pub struct TypeInfo {
#[derive(Debug, Clone)]
pub struct TypeConstructor {
pub public: bool,
pub origin: Span,
pub location: Span,
pub module: String,
pub parameters: Vec<Arc<Type>>,
pub tipo: Arc<Type>,

View File

@ -224,6 +224,7 @@ impl<'a> Environment<'a> {
module: module_name.to_owned(),
arity: args.len(),
location,
builtin: None,
},
},
);
@ -461,7 +462,7 @@ impl<'a> Environment<'a> {
info: TypeConstructor,
) -> Result<(), Error> {
let name = type_name.clone();
let location = info.origin;
let location = info.location;
match self.module_types.insert(type_name, info) {
None => Ok(()),
@ -469,7 +470,7 @@ impl<'a> Environment<'a> {
Some(previous) => Err(Error::DuplicateTypeName {
name,
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
if let Some(typ) = module_info.types.get(name) {
let typ_info = TypeConstructor {
origin: *location,
location: *location,
..typ.clone()
};
@ -843,7 +844,7 @@ impl<'a> Environment<'a> {
self.insert_type_constructor(
name.clone(),
TypeConstructor {
origin: *location,
location: *location,
module: module.to_owned(),
public: *public,
parameters,
@ -884,7 +885,7 @@ impl<'a> Environment<'a> {
self.insert_type_constructor(
name.clone(),
TypeConstructor {
origin: *location,
location: *location,
module: module.to_owned(),
public: *public,
parameters,
@ -967,6 +968,7 @@ impl<'a> Environment<'a> {
module: module_name.to_owned(),
arity: args.len(),
location: *location,
builtin: None,
},
tipo,
);

View File

@ -206,6 +206,7 @@ fn infer_definition(
module: module_name.to_owned(),
arity: args.len(),
location,
builtin: None,
};
environment.insert_variable(name.clone(), module_fn, tipo.clone());
@ -422,7 +423,7 @@ fn infer_definition(
}
fn validate_module_name(name: &str) -> Result<(), Error> {
if name == "aiken" {
if name == "aiken" || name == "aiken/builtin" {
return Err(Error::ReservedModuleName {
name: name.to_string(),
});

View File

@ -1,3 +1,5 @@
use aiken/builtin.{addInteger}
pub type ScriptContext {
idk: Int
}
@ -5,3 +7,7 @@ pub type ScriptContext {
pub fn append(a: ByteArray, b: ByteArray) -> ByteArray {
todo
}
pub fn add(a, b) {
addInteger(a, b)
}