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", "miette",
"pretty_assertions", "pretty_assertions",
"thiserror", "thiserror",
"uplc",
"vec1", "vec1",
] ]

View File

@ -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,

View File

@ -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]

View File

@ -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,

View File

@ -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>,

View File

@ -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,
); );

View File

@ -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(),
}); });

View File

@ -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)
}