diff --git a/crates/lang/src/ast.rs b/crates/lang/src/ast.rs index 3afbdd82..56e8f84c 100644 --- a/crates/lang/src/ast.rs +++ b/crates/lang/src/ast.rs @@ -66,10 +66,8 @@ impl UntypedModule { } } -pub type TypedDefinition = Definition, TypedExpr, String, String>; -pub type UntypedDefinition = Definition<(), UntypedExpr, (), ()>; - pub type TypedFunction = Function, TypedExpr>; +pub type UntypedFunction = Function<(), UntypedExpr>; #[derive(Debug, Clone, PartialEq)] pub struct Function { @@ -84,6 +82,9 @@ pub struct Function { pub end_position: usize, } +pub type TypedTypeAlias = TypeAlias>; +pub type UntypedTypeAlias = TypeAlias<()>; + #[derive(Debug, Clone, PartialEq)] pub struct TypeAlias { pub alias: String, @@ -95,6 +96,9 @@ pub struct TypeAlias { pub tipo: T, } +pub type TypedDataType = DataType>; +pub type UntypedDataType = DataType<()>; + #[derive(Debug, Clone, PartialEq)] pub struct DataType { pub constructors: Vec>, @@ -107,6 +111,9 @@ pub struct DataType { pub typed_parameters: Vec, } +pub type TypedUse = Use; +pub type UntypedUse = Use<()>; + #[derive(Debug, Clone, PartialEq, Eq)] pub struct Use { pub as_name: Option, @@ -116,6 +123,9 @@ pub struct Use { pub unqualified: Vec, } +pub type TypedModuleConstant = ModuleConstant, String>; +pub type UntypedModuleConstant = ModuleConstant<(), ()>; + #[derive(Debug, Clone, PartialEq)] pub struct ModuleConstant { pub doc: Option, @@ -127,6 +137,9 @@ pub struct ModuleConstant { pub tipo: T, } +pub type TypedDefinition = Definition, TypedExpr, String, String>; +pub type UntypedDefinition = Definition<(), UntypedExpr, (), ()>; + #[derive(Debug, Clone, PartialEq)] pub enum Definition { Fn(Function), diff --git a/crates/lang/src/uplc.rs b/crates/lang/src/uplc.rs index 56416c4c..5a75912b 100644 --- a/crates/lang/src/uplc.rs +++ b/crates/lang/src/uplc.rs @@ -16,8 +16,8 @@ use uplc::{ use crate::{ air::Air, ast::{ - ArgName, AssignmentKind, BinOp, Clause, Constant, DataType, Function, Pattern, Span, - TypedArg, + ArgName, AssignmentKind, BinOp, Clause, Constant, Pattern, Span, TypedArg, TypedDataType, + TypedFunction, }, expr::TypedExpr, tipo::{self, PatternConstructor, Type, TypeInfo, ValueConstructor, ValueConstructorVariant}, @@ -64,9 +64,9 @@ pub struct ClauseProperties { pub struct CodeGenerator<'a> { defined_functions: HashMap, - functions: &'a HashMap, TypedExpr>>, + functions: &'a HashMap, // type_aliases: &'a HashMap<(String, String), &'a TypeAlias>>, - data_types: &'a HashMap>>, + data_types: &'a HashMap, // imports: &'a HashMap<(String, String), &'a Use>, // constants: &'a HashMap<(String, String), &'a ModuleConstant, String>>, module_types: &'a HashMap, @@ -76,9 +76,9 @@ pub struct CodeGenerator<'a> { impl<'a> CodeGenerator<'a> { pub fn new( - functions: &'a HashMap, TypedExpr>>, + functions: &'a HashMap, // type_aliases: &'a HashMap<(String, String), &'a TypeAlias>>, - data_types: &'a HashMap>>, + data_types: &'a HashMap, // imports: &'a HashMap<(String, String), &'a Use>, // constants: &'a HashMap<(String, String), &'a ModuleConstant, String>>, module_types: &'a HashMap, @@ -176,12 +176,20 @@ impl<'a> CodeGenerator<'a> { } TypedExpr::Var { constructor, name, .. - } => { - if let ValueConstructorVariant::ModuleConstant { literal, .. } = - &constructor.variant - { + } => match &constructor.variant { + ValueConstructorVariant::ModuleConstant { literal, .. } => { constants_ir(literal, ir_stack, scope); - } else { + } + ValueConstructorVariant::ModuleFn { + builtin: Some(builtin), + .. + } => { + ir_stack.push(Air::Builtin { + scope, + func: *builtin, + }); + } + _ => { ir_stack.push(Air::Var { scope, constructor: constructor.clone(), @@ -189,7 +197,7 @@ impl<'a> CodeGenerator<'a> { variant_name: String::new(), }); } - } + }, TypedExpr::Fn { args, body, .. } => { let mut func_body = vec![]; let mut func_scope = scope.clone(); @@ -1558,9 +1566,8 @@ impl<'a> CodeGenerator<'a> { let tipo = constructor.tipo; let args_type = match tipo.as_ref() { - Type::Fn { args, .. } => args, - - _ => todo!(), + Type::Fn { args, .. } | Type::App { args, .. } => args, + _ => unreachable!(), }; if let Some(field_map) = field_map.clone() { diff --git a/crates/project/src/lib.rs b/crates/project/src/lib.rs index 9da21946..94d7733a 100644 --- a/crates/project/src/lib.rs +++ b/crates/project/src/lib.rs @@ -13,8 +13,11 @@ pub mod script; pub mod telemetry; use aiken_lang::{ - ast::{Definition, Function, ModuleKind, TypedDefinition, TypedFunction}, - builtins, + ast::{ + Annotation, DataType, Definition, Function, ModuleKind, RecordConstructor, + RecordConstructorArg, Span, TypedDataType, TypedDefinition, TypedFunction, + }, + builtins::{self, generic_var}, tipo::TypeInfo, uplc::{CodeGenerator, DataTypeKey, FunctionAccessKey}, IdGenerator, @@ -387,6 +390,16 @@ where let mut imports = HashMap::new(); let mut constants = HashMap::new(); + let option_data_type = make_option(); + + data_types.insert( + DataTypeKey { + module_name: "".to_string(), + defined_type: "Option".to_string(), + }, + &option_data_type, + ); + for module in checked_modules.values() { for def in module.ast.definitions() { match def { @@ -463,6 +476,16 @@ where let mut imports = HashMap::new(); let mut constants = HashMap::new(); + let option_data_type = make_option(); + + data_types.insert( + DataTypeKey { + module_name: "".to_string(), + defined_type: "Option".to_string(), + }, + &option_data_type, + ); + // let mut indices_to_remove = Vec::new(); let mut scripts = Vec::new(); @@ -558,6 +581,8 @@ where continue; } + println!("{}", script.program.to_pretty()); + match script.program.eval(initial_budget) { (Ok(result), remaining_budget, _) => { let eval_info = EvalInfo { @@ -744,3 +769,40 @@ fn is_aiken_path(path: &Path, dir: impl AsRef) -> bool { .expect("is_aiken_path(): to_str"), ) } + +fn make_option() -> TypedDataType { + DataType { + constructors: vec![ + RecordConstructor { + location: Span::empty(), + name: "Some".to_string(), + arguments: vec![RecordConstructorArg { + label: None, + annotation: Annotation::Var { + location: Span::empty(), + name: "a".to_string(), + }, + location: Span::empty(), + tipo: generic_var(0), + doc: None, + }], + documentation: None, + sugar: false, + }, + RecordConstructor { + location: Span::empty(), + name: "None".to_string(), + arguments: vec![], + documentation: None, + sugar: false, + }, + ], + doc: None, + location: Span::empty(), + name: "Option".to_string(), + opaque: false, + parameters: vec!["a".to_string()], + public: true, + typed_parameters: vec![generic_var(0)], + } +}