From 1701cacb523c08fd47f62f86021862a64456c9f8 Mon Sep 17 00:00:00 2001 From: KtorZ Date: Thu, 29 Dec 2022 12:05:30 +0100 Subject: [PATCH] Add builtin functions to the prelude Starting with 'not', will add 'always' and 'identity' later. --- crates/aiken-lang/src/builtins.rs | 72 ++++++++++++++++++++++++++++++- crates/aiken-project/src/lib.rs | 11 ++++- 2 files changed, 81 insertions(+), 2 deletions(-) diff --git a/crates/aiken-lang/src/builtins.rs b/crates/aiken-lang/src/builtins.rs index a9da118a..854aeb58 100644 --- a/crates/aiken-lang/src/builtins.rs +++ b/crates/aiken-lang/src/builtins.rs @@ -5,7 +5,9 @@ use strum::IntoEnumIterator; use uplc::builtins::DefaultFunction; use crate::{ - ast::{ModuleKind, Span}, + ast::{Arg, ArgName, Function, ModuleKind, Span, TypedFunction, UnOp}, + builder::FunctionAccessKey, + expr::TypedExpr, tipo::{ fields::FieldMap, Type, TypeConstructor, TypeInfo, TypeVar, ValueConstructor, ValueConstructorVariant, @@ -119,6 +121,21 @@ pub fn prelude(id_gen: &IdGenerator) -> TypeInfo { }, ); + prelude.values.insert( + "not".to_string(), + ValueConstructor::public( + function(vec![bool()], bool()), + ValueConstructorVariant::ModuleFn { + name: "not".to_string(), + field_map: None, + module: "".to_string(), + arity: 1, + location: Span::empty(), + builtin: None, + }, + ), + ); + // List(a) let list_parameter = generic_var(id_gen.next()); prelude.types.insert( @@ -454,6 +471,59 @@ pub fn from_default_function( }) } +pub fn prelude_functions() -> HashMap { + let mut functions = HashMap::new(); + + // /// Negate the argument. Useful for map/fold and pipelines. + // pub fn not(self: Bool) -> Bool { + // !self + // } + functions.insert( + FunctionAccessKey { + module_name: "".to_string(), + function_name: "not".to_string(), + variant_name: "".to_string(), + }, + Function { + arguments: vec![Arg { + arg_name: ArgName::Named { + name: "self".to_string(), + label: "self".to_string(), + location: Span::empty(), + }, + location: Span::empty(), + annotation: None, + tipo: bool(), + }], + doc: None, + location: Span::empty(), + name: "not".to_string(), + public: true, + return_annotation: None, + return_type: bool(), + end_position: 0, + body: TypedExpr::UnOp { + location: Span::empty(), + tipo: bool(), + op: UnOp::Negate, + value: Box::new(TypedExpr::Var { + location: Span::empty(), + constructor: ValueConstructor { + public: true, + tipo: bool(), + variant: ValueConstructorVariant::LocalVariable { + location: Span::empty(), + }, + }, + name: "self".to_string(), + }), + }, + }, + ); + + functions +} + pub fn int() -> Arc { Arc::new(Type::App { public: true, diff --git a/crates/aiken-project/src/lib.rs b/crates/aiken-project/src/lib.rs index e022dcd7..73a60fde 100644 --- a/crates/aiken-project/src/lib.rs +++ b/crates/aiken-project/src/lib.rs @@ -486,8 +486,12 @@ where let mut imports = HashMap::new(); let mut constants = HashMap::new(); - let option_data_type = TypedDataType::option(generic_var(self.id_gen.next())); + let prelude_functions = builtins::prelude_functions(); + for (access_key, func) in prelude_functions.iter() { + functions.insert(access_key.clone(), func); + } + let option_data_type = TypedDataType::option(generic_var(self.id_gen.next())); data_types.insert( DataTypeKey { module_name: "".to_string(), @@ -582,6 +586,11 @@ where let mut imports = HashMap::new(); let mut constants = HashMap::new(); + let prelude_functions = builtins::prelude_functions(); + for (access_key, func) in prelude_functions.iter() { + functions.insert(access_key.clone(), func); + } + let option_data_type = TypedDataType::option(generic_var(self.id_gen.next())); data_types.insert(