work out some initial direction for code gen
This commit is contained in:
parent
51302f1730
commit
ffa78e4c30
|
@ -53,9 +53,9 @@ impl UntypedModule {
|
||||||
pub fn dependencies(&self) -> Vec<(String, Span)> {
|
pub fn dependencies(&self) -> Vec<(String, Span)> {
|
||||||
self.definitions()
|
self.definitions()
|
||||||
.flat_map(|def| {
|
.flat_map(|def| {
|
||||||
if let Definition::Use {
|
if let Definition::Use(Use {
|
||||||
location, module, ..
|
location, module, ..
|
||||||
} = def
|
}) = def
|
||||||
{
|
{
|
||||||
Some((module.join("/"), *location))
|
Some((module.join("/"), *location))
|
||||||
} else {
|
} else {
|
||||||
|
@ -69,58 +69,73 @@ impl UntypedModule {
|
||||||
pub type TypedDefinition = Definition<Arc<Type>, TypedExpr, String, String>;
|
pub type TypedDefinition = Definition<Arc<Type>, TypedExpr, String, String>;
|
||||||
pub type UntypedDefinition = Definition<(), UntypedExpr, (), ()>;
|
pub type UntypedDefinition = Definition<(), UntypedExpr, (), ()>;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub struct Function<T, Expr> {
|
||||||
|
pub arguments: Vec<Arg<T>>,
|
||||||
|
pub body: Expr,
|
||||||
|
pub doc: Option<String>,
|
||||||
|
pub location: Span,
|
||||||
|
pub name: String,
|
||||||
|
pub public: bool,
|
||||||
|
pub return_annotation: Option<Annotation>,
|
||||||
|
pub return_type: T,
|
||||||
|
pub end_position: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub struct TypeAlias<T> {
|
||||||
|
pub alias: String,
|
||||||
|
pub annotation: Annotation,
|
||||||
|
pub doc: Option<String>,
|
||||||
|
pub location: Span,
|
||||||
|
pub parameters: Vec<String>,
|
||||||
|
pub public: bool,
|
||||||
|
pub tipo: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub struct DataType<T> {
|
||||||
|
pub constructors: Vec<RecordConstructor<T>>,
|
||||||
|
pub doc: Option<String>,
|
||||||
|
pub location: Span,
|
||||||
|
pub name: String,
|
||||||
|
pub opaque: bool,
|
||||||
|
pub parameters: Vec<String>,
|
||||||
|
pub public: bool,
|
||||||
|
pub typed_parameters: Vec<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub struct Use<PackageName> {
|
||||||
|
pub as_name: Option<String>,
|
||||||
|
pub location: Span,
|
||||||
|
pub module: Vec<String>,
|
||||||
|
pub package: PackageName,
|
||||||
|
pub unqualified: Vec<UnqualifiedImport>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub struct ModuleConstant<T, ConstantRecordTag> {
|
||||||
|
pub doc: Option<String>,
|
||||||
|
pub location: Span,
|
||||||
|
pub public: bool,
|
||||||
|
pub name: String,
|
||||||
|
pub annotation: Option<Annotation>,
|
||||||
|
pub value: Box<Constant<T, ConstantRecordTag>>,
|
||||||
|
pub tipo: T,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum Definition<T, Expr, ConstantRecordTag, PackageName> {
|
pub enum Definition<T, Expr, ConstantRecordTag, PackageName> {
|
||||||
Fn {
|
Fn(Function<T, Expr>),
|
||||||
arguments: Vec<Arg<T>>,
|
|
||||||
body: Expr,
|
|
||||||
doc: Option<String>,
|
|
||||||
location: Span,
|
|
||||||
name: String,
|
|
||||||
public: bool,
|
|
||||||
return_annotation: Option<Annotation>,
|
|
||||||
return_type: T,
|
|
||||||
end_position: usize,
|
|
||||||
},
|
|
||||||
|
|
||||||
TypeAlias {
|
TypeAlias(TypeAlias<T>),
|
||||||
alias: String,
|
|
||||||
annotation: Annotation,
|
|
||||||
doc: Option<String>,
|
|
||||||
location: Span,
|
|
||||||
parameters: Vec<String>,
|
|
||||||
public: bool,
|
|
||||||
tipo: T,
|
|
||||||
},
|
|
||||||
|
|
||||||
DataType {
|
DataType(DataType<T>),
|
||||||
constructors: Vec<RecordConstructor<T>>,
|
|
||||||
doc: Option<String>,
|
|
||||||
location: Span,
|
|
||||||
name: String,
|
|
||||||
opaque: bool,
|
|
||||||
parameters: Vec<String>,
|
|
||||||
public: bool,
|
|
||||||
typed_parameters: Vec<T>,
|
|
||||||
},
|
|
||||||
|
|
||||||
Use {
|
Use(Use<PackageName>),
|
||||||
as_name: Option<String>,
|
|
||||||
location: Span,
|
|
||||||
module: Vec<String>,
|
|
||||||
package: PackageName,
|
|
||||||
unqualified: Vec<UnqualifiedImport>,
|
|
||||||
},
|
|
||||||
|
|
||||||
ModuleConstant {
|
ModuleConstant(ModuleConstant<T, ConstantRecordTag>),
|
||||||
doc: Option<String>,
|
|
||||||
location: Span,
|
|
||||||
public: bool,
|
|
||||||
name: String,
|
|
||||||
annotation: Option<Annotation>,
|
|
||||||
value: Box<Constant<T, ConstantRecordTag>>,
|
|
||||||
tipo: T,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B, C, E> Definition<A, B, C, E> {
|
impl<A, B, C, E> Definition<A, B, C, E> {
|
||||||
|
|
|
@ -119,12 +119,14 @@ pub fn import_parser() -> impl Parser<Token, ast::UntypedDefinition, Error = Par
|
||||||
.then(as_name);
|
.then(as_name);
|
||||||
|
|
||||||
just(Token::Use).ignore_then(module_path).map_with_span(
|
just(Token::Use).ignore_then(module_path).map_with_span(
|
||||||
|((module, unqualified), as_name), span| ast::UntypedDefinition::Use {
|
|((module, unqualified), as_name), span| {
|
||||||
|
ast::UntypedDefinition::Use(ast::Use {
|
||||||
module,
|
module,
|
||||||
as_name,
|
as_name,
|
||||||
unqualified: unqualified.unwrap_or_default(),
|
unqualified: unqualified.unwrap_or_default(),
|
||||||
package: (),
|
package: (),
|
||||||
location: span,
|
location: span,
|
||||||
|
})
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -176,7 +178,7 @@ pub fn data_parser() -> impl Parser<Token, ast::UntypedDefinition, Error = Parse
|
||||||
.then(type_name_with_args())
|
.then(type_name_with_args())
|
||||||
.then(choice((constructors, record_sugar)))
|
.then(choice((constructors, record_sugar)))
|
||||||
.map_with_span(|((pub_opaque, (name, parameters)), constructors), span| {
|
.map_with_span(|((pub_opaque, (name, parameters)), constructors), span| {
|
||||||
ast::UntypedDefinition::DataType {
|
ast::UntypedDefinition::DataType(ast::DataType {
|
||||||
location: span,
|
location: span,
|
||||||
constructors: constructors
|
constructors: constructors
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -196,7 +198,7 @@ pub fn data_parser() -> impl Parser<Token, ast::UntypedDefinition, Error = Parse
|
||||||
parameters: parameters.unwrap_or_default(),
|
parameters: parameters.unwrap_or_default(),
|
||||||
public: pub_opaque.is_some(),
|
public: pub_opaque.is_some(),
|
||||||
typed_parameters: vec![],
|
typed_parameters: vec![],
|
||||||
}
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,7 +209,7 @@ pub fn type_alias_parser() -> impl Parser<Token, ast::UntypedDefinition, Error =
|
||||||
.then_ignore(just(Token::Equal))
|
.then_ignore(just(Token::Equal))
|
||||||
.then(type_parser())
|
.then(type_parser())
|
||||||
.map_with_span(|((opt_pub, (alias, parameters)), annotation), span| {
|
.map_with_span(|((opt_pub, (alias, parameters)), annotation), span| {
|
||||||
ast::UntypedDefinition::TypeAlias {
|
ast::UntypedDefinition::TypeAlias(ast::TypeAlias {
|
||||||
alias,
|
alias,
|
||||||
annotation,
|
annotation,
|
||||||
doc: None,
|
doc: None,
|
||||||
|
@ -215,7 +217,7 @@ pub fn type_alias_parser() -> impl Parser<Token, ast::UntypedDefinition, Error =
|
||||||
parameters: parameters.unwrap_or_default(),
|
parameters: parameters.unwrap_or_default(),
|
||||||
public: opt_pub.is_some(),
|
public: opt_pub.is_some(),
|
||||||
tipo: (),
|
tipo: (),
|
||||||
}
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,7 +241,7 @@ pub fn fn_parser() -> impl Parser<Token, ast::UntypedDefinition, Error = ParseEr
|
||||||
)
|
)
|
||||||
.map_with_span(
|
.map_with_span(
|
||||||
|((((opt_pub, name), (arguments, args_span)), return_annotation), body), span| {
|
|((((opt_pub, name), (arguments, args_span)), return_annotation), body), span| {
|
||||||
ast::UntypedDefinition::Fn {
|
ast::UntypedDefinition::Fn(ast::Function {
|
||||||
arguments,
|
arguments,
|
||||||
body: body.unwrap_or(expr::UntypedExpr::Todo {
|
body: body.unwrap_or(expr::UntypedExpr::Todo {
|
||||||
kind: TodoKind::EmptyFunction,
|
kind: TodoKind::EmptyFunction,
|
||||||
|
@ -259,7 +261,7 @@ pub fn fn_parser() -> impl Parser<Token, ast::UntypedDefinition, Error = ParseEr
|
||||||
public: opt_pub.is_some(),
|
public: opt_pub.is_some(),
|
||||||
return_annotation,
|
return_annotation,
|
||||||
return_type: (),
|
return_type: (),
|
||||||
}
|
})
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,9 @@ use chumsky::prelude::*;
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{self, Span},
|
ast::{self, DataType, Function, Span, TypeAlias, Use},
|
||||||
expr, parser,
|
expr, lexer,
|
||||||
|
parser::module_parser,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -116,14 +117,14 @@ fn module() {
|
||||||
name: "".to_string(),
|
name: "".to_string(),
|
||||||
type_info: (),
|
type_info: (),
|
||||||
definitions: vec![
|
definitions: vec![
|
||||||
ast::UntypedDefinition::Use {
|
ast::UntypedDefinition::Use(Use {
|
||||||
location: Span::new((), 13..25),
|
location: Span::new((), 13..25),
|
||||||
module: vec!["std".to_string(), "list".to_string()],
|
module: vec!["std".to_string(), "list".to_string()],
|
||||||
as_name: None,
|
as_name: None,
|
||||||
unqualified: vec![],
|
unqualified: vec![],
|
||||||
package: (),
|
package: (),
|
||||||
},
|
}),
|
||||||
ast::UntypedDefinition::Use {
|
ast::UntypedDefinition::Use(Use {
|
||||||
location: Span::new((), 38..80),
|
location: Span::new((), 38..80),
|
||||||
module: vec!["std".to_string(), "address".to_string()],
|
module: vec!["std".to_string(), "address".to_string()],
|
||||||
as_name: None,
|
as_name: None,
|
||||||
|
@ -142,15 +143,15 @@ fn module() {
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
package: (),
|
package: (),
|
||||||
},
|
}),
|
||||||
ast::UntypedDefinition::Use {
|
ast::UntypedDefinition::Use(Use {
|
||||||
location: Span::new((), 93..108),
|
location: Span::new((), 93..108),
|
||||||
module: vec!["std".to_string(), "tx".to_string()],
|
module: vec!["std".to_string(), "tx".to_string()],
|
||||||
as_name: Some("t".to_string()),
|
as_name: Some("t".to_string()),
|
||||||
unqualified: vec![],
|
unqualified: vec![],
|
||||||
package: (),
|
package: (),
|
||||||
},
|
}),
|
||||||
ast::UntypedDefinition::DataType {
|
ast::UntypedDefinition::DataType(DataType {
|
||||||
location: Span::new((), 122..240),
|
location: Span::new((), 122..240),
|
||||||
constructors: vec![
|
constructors: vec![
|
||||||
ast::RecordConstructor {
|
ast::RecordConstructor {
|
||||||
|
@ -229,8 +230,8 @@ fn module() {
|
||||||
parameters: vec!["a".to_string(),],
|
parameters: vec!["a".to_string(),],
|
||||||
public: false,
|
public: false,
|
||||||
typed_parameters: vec![],
|
typed_parameters: vec![],
|
||||||
},
|
}),
|
||||||
ast::UntypedDefinition::DataType {
|
ast::UntypedDefinition::DataType(DataType {
|
||||||
location: Span::new((), 254..313),
|
location: Span::new((), 254..313),
|
||||||
constructors: vec![ast::RecordConstructor {
|
constructors: vec![ast::RecordConstructor {
|
||||||
location: Span::new((), 275..313),
|
location: Span::new((), 275..313),
|
||||||
|
@ -254,8 +255,8 @@ fn module() {
|
||||||
parameters: vec![],
|
parameters: vec![],
|
||||||
public: true,
|
public: true,
|
||||||
typed_parameters: vec![],
|
typed_parameters: vec![],
|
||||||
},
|
}),
|
||||||
ast::UntypedDefinition::TypeAlias {
|
ast::UntypedDefinition::TypeAlias(TypeAlias {
|
||||||
alias: "Thing".to_string(),
|
alias: "Thing".to_string(),
|
||||||
annotation: ast::Annotation::Constructor {
|
annotation: ast::Annotation::Constructor {
|
||||||
location: Span::new((), 340..351),
|
location: Span::new((), 340..351),
|
||||||
|
@ -273,8 +274,8 @@ fn module() {
|
||||||
parameters: vec![],
|
parameters: vec![],
|
||||||
public: false,
|
public: false,
|
||||||
tipo: (),
|
tipo: (),
|
||||||
},
|
}),
|
||||||
ast::UntypedDefinition::TypeAlias {
|
ast::UntypedDefinition::TypeAlias(TypeAlias {
|
||||||
alias: "Me".to_string(),
|
alias: "Me".to_string(),
|
||||||
annotation: ast::Annotation::Constructor {
|
annotation: ast::Annotation::Constructor {
|
||||||
location: Span::new((), 379..393),
|
location: Span::new((), 379..393),
|
||||||
|
@ -292,8 +293,9 @@ fn module() {
|
||||||
parameters: vec![],
|
parameters: vec![],
|
||||||
public: true,
|
public: true,
|
||||||
tipo: (),
|
tipo: (),
|
||||||
},
|
}),
|
||||||
ast::UntypedDefinition::Fn {
|
ast::UntypedDefinition::Fn(Function {
|
||||||
|
end_position: 0,
|
||||||
arguments: vec![ast::Arg {
|
arguments: vec![ast::Arg {
|
||||||
arg_name: ast::ArgName::Named {
|
arg_name: ast::ArgName::Named {
|
||||||
name: "a".to_string(),
|
name: "a".to_string(),
|
||||||
|
@ -326,9 +328,8 @@ fn module() {
|
||||||
arguments: vec![],
|
arguments: vec![],
|
||||||
},),
|
},),
|
||||||
return_type: (),
|
return_type: (),
|
||||||
end_position: 466,
|
}),
|
||||||
},
|
ast::UntypedDefinition::Fn(Function {
|
||||||
ast::UntypedDefinition::Fn {
|
|
||||||
end_position: 598,
|
end_position: 598,
|
||||||
arguments: vec![ast::Arg {
|
arguments: vec![ast::Arg {
|
||||||
arg_name: ast::ArgName::NamedLabeled {
|
arg_name: ast::ArgName::NamedLabeled {
|
||||||
|
@ -375,8 +376,8 @@ fn module() {
|
||||||
public: true,
|
public: true,
|
||||||
return_annotation: None,
|
return_annotation: None,
|
||||||
return_type: (),
|
return_type: (),
|
||||||
},
|
}),
|
||||||
ast::UntypedDefinition::Fn {
|
ast::UntypedDefinition::Fn(Function {
|
||||||
end_position: 839,
|
end_position: 839,
|
||||||
arguments: vec![ast::Arg {
|
arguments: vec![ast::Arg {
|
||||||
arg_name: ast::ArgName::Named {
|
arg_name: ast::ArgName::Named {
|
||||||
|
@ -480,8 +481,8 @@ fn module() {
|
||||||
public: true,
|
public: true,
|
||||||
return_annotation: None,
|
return_annotation: None,
|
||||||
return_type: (),
|
return_type: (),
|
||||||
},
|
}),
|
||||||
ast::UntypedDefinition::Fn {
|
ast::UntypedDefinition::Fn(Function {
|
||||||
end_position: 1238,
|
end_position: 1238,
|
||||||
arguments: vec![ast::Arg {
|
arguments: vec![ast::Arg {
|
||||||
arg_name: ast::ArgName::Named {
|
arg_name: ast::ArgName::Named {
|
||||||
|
@ -647,8 +648,8 @@ fn module() {
|
||||||
public: true,
|
public: true,
|
||||||
return_annotation: None,
|
return_annotation: None,
|
||||||
return_type: (),
|
return_type: (),
|
||||||
},
|
}),
|
||||||
ast::UntypedDefinition::Fn {
|
ast::UntypedDefinition::Fn(Function {
|
||||||
end_position: 1377,
|
end_position: 1377,
|
||||||
arguments: vec![],
|
arguments: vec![],
|
||||||
body: expr::UntypedExpr::Sequence {
|
body: expr::UntypedExpr::Sequence {
|
||||||
|
@ -724,8 +725,8 @@ fn module() {
|
||||||
arguments: vec![],
|
arguments: vec![],
|
||||||
},),
|
},),
|
||||||
return_type: (),
|
return_type: (),
|
||||||
},
|
}),
|
||||||
ast::UntypedDefinition::Fn {
|
ast::UntypedDefinition::Fn(Function {
|
||||||
end_position: 1402,
|
end_position: 1402,
|
||||||
arguments: vec![],
|
arguments: vec![],
|
||||||
body: expr::UntypedExpr::Todo {
|
body: expr::UntypedExpr::Todo {
|
||||||
|
@ -739,8 +740,8 @@ fn module() {
|
||||||
public: false,
|
public: false,
|
||||||
return_annotation: None,
|
return_annotation: None,
|
||||||
return_type: (),
|
return_type: (),
|
||||||
},
|
}),
|
||||||
ast::UntypedDefinition::Fn {
|
ast::UntypedDefinition::Fn(Function {
|
||||||
end_position: 1477,
|
end_position: 1477,
|
||||||
arguments: vec![ast::Arg {
|
arguments: vec![ast::Arg {
|
||||||
arg_name: ast::ArgName::Named {
|
arg_name: ast::ArgName::Named {
|
||||||
|
@ -770,8 +771,8 @@ fn module() {
|
||||||
public: false,
|
public: false,
|
||||||
return_annotation: None,
|
return_annotation: None,
|
||||||
return_type: (),
|
return_type: (),
|
||||||
},
|
}),
|
||||||
ast::UntypedDefinition::Fn {
|
ast::UntypedDefinition::Fn(Function {
|
||||||
end_position: 1655,
|
end_position: 1655,
|
||||||
arguments: vec![],
|
arguments: vec![],
|
||||||
body: expr::UntypedExpr::Sequence {
|
body: expr::UntypedExpr::Sequence {
|
||||||
|
@ -912,8 +913,8 @@ fn module() {
|
||||||
public: false,
|
public: false,
|
||||||
return_annotation: None,
|
return_annotation: None,
|
||||||
return_type: (),
|
return_type: (),
|
||||||
},
|
}),
|
||||||
ast::UntypedDefinition::Fn {
|
ast::UntypedDefinition::Fn(Function {
|
||||||
end_position: 1781,
|
end_position: 1781,
|
||||||
arguments: vec![
|
arguments: vec![
|
||||||
ast::Arg {
|
ast::Arg {
|
||||||
|
@ -978,8 +979,8 @@ fn module() {
|
||||||
arguments: vec![],
|
arguments: vec![],
|
||||||
},),
|
},),
|
||||||
return_type: (),
|
return_type: (),
|
||||||
},
|
}),
|
||||||
ast::UntypedDefinition::Fn {
|
ast::UntypedDefinition::Fn(Function {
|
||||||
end_position: 2049,
|
end_position: 2049,
|
||||||
arguments: vec![],
|
arguments: vec![],
|
||||||
body: expr::UntypedExpr::If {
|
body: expr::UntypedExpr::If {
|
||||||
|
@ -1054,7 +1055,7 @@ fn module() {
|
||||||
public: false,
|
public: false,
|
||||||
return_annotation: None,
|
return_annotation: None,
|
||||||
return_type: (),
|
return_type: (),
|
||||||
},
|
}),
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -8,8 +8,9 @@ use itertools::Itertools;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{
|
ast::{
|
||||||
Annotation, ArgName, CallArg, Definition, Pattern, RecordConstructor, RecordConstructorArg,
|
Annotation, ArgName, CallArg, DataType, Definition, Function, ModuleConstant, Pattern,
|
||||||
Span, TypedDefinition, UnqualifiedImport, UntypedDefinition, PIPE_VARIABLE,
|
RecordConstructor, RecordConstructorArg, Span, TypeAlias, TypedDefinition,
|
||||||
|
UnqualifiedImport, UntypedDefinition, Use, PIPE_VARIABLE,
|
||||||
},
|
},
|
||||||
builtins::{function, generic_var, unbound_var},
|
builtins::{function, generic_var, unbound_var},
|
||||||
tipo::fields::FieldMap,
|
tipo::fields::FieldMap,
|
||||||
|
@ -186,7 +187,7 @@ impl<'a> Environment<'a> {
|
||||||
module_name: &String,
|
module_name: &String,
|
||||||
) -> TypedDefinition {
|
) -> TypedDefinition {
|
||||||
match s {
|
match s {
|
||||||
Definition::Fn {
|
Definition::Fn(Function {
|
||||||
doc,
|
doc,
|
||||||
location,
|
location,
|
||||||
name,
|
name,
|
||||||
|
@ -196,7 +197,7 @@ impl<'a> Environment<'a> {
|
||||||
return_annotation,
|
return_annotation,
|
||||||
return_type,
|
return_type,
|
||||||
end_position,
|
end_position,
|
||||||
} => {
|
}) => {
|
||||||
// Lookup the inferred function information
|
// Lookup the inferred function information
|
||||||
let function = self
|
let function = self
|
||||||
.get_variable(&name)
|
.get_variable(&name)
|
||||||
|
@ -230,7 +231,7 @@ impl<'a> Environment<'a> {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
Definition::Fn {
|
Definition::Fn(Function {
|
||||||
doc,
|
doc,
|
||||||
location,
|
location,
|
||||||
name,
|
name,
|
||||||
|
@ -240,7 +241,7 @@ impl<'a> Environment<'a> {
|
||||||
return_type,
|
return_type,
|
||||||
body,
|
body,
|
||||||
end_position,
|
end_position,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
definition @ (Definition::TypeAlias { .. }
|
definition @ (Definition::TypeAlias { .. }
|
||||||
|
@ -655,13 +656,13 @@ impl<'a> Environment<'a> {
|
||||||
|
|
||||||
pub fn register_import(&mut self, def: &UntypedDefinition) -> Result<(), Error> {
|
pub fn register_import(&mut self, def: &UntypedDefinition) -> Result<(), Error> {
|
||||||
match def {
|
match def {
|
||||||
Definition::Use {
|
Definition::Use(Use {
|
||||||
module,
|
module,
|
||||||
as_name,
|
as_name,
|
||||||
unqualified,
|
unqualified,
|
||||||
location,
|
location,
|
||||||
..
|
..
|
||||||
} => {
|
}) => {
|
||||||
let name = module.join("/");
|
let name = module.join("/");
|
||||||
|
|
||||||
// Find imported module
|
// Find imported module
|
||||||
|
@ -819,14 +820,14 @@ impl<'a> Environment<'a> {
|
||||||
names: &mut HashMap<&'a str, &'a Span>,
|
names: &mut HashMap<&'a str, &'a Span>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
match def {
|
match def {
|
||||||
Definition::DataType {
|
Definition::DataType(DataType {
|
||||||
name,
|
name,
|
||||||
public,
|
public,
|
||||||
parameters,
|
parameters,
|
||||||
location,
|
location,
|
||||||
constructors,
|
constructors,
|
||||||
..
|
..
|
||||||
} => {
|
}) => {
|
||||||
assert_unique_type_name(names, name, location)?;
|
assert_unique_type_name(names, name, location)?;
|
||||||
|
|
||||||
// Build a type from the type Annotation
|
// Build a type from the type Annotation
|
||||||
|
@ -864,14 +865,14 @@ impl<'a> Environment<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Definition::TypeAlias {
|
Definition::TypeAlias(TypeAlias {
|
||||||
location,
|
location,
|
||||||
public,
|
public,
|
||||||
parameters: args,
|
parameters: args,
|
||||||
alias: name,
|
alias: name,
|
||||||
annotation: resolved_type,
|
annotation: resolved_type,
|
||||||
..
|
..
|
||||||
} => {
|
}) => {
|
||||||
assert_unique_type_name(names, name, location)?;
|
assert_unique_type_name(names, name, location)?;
|
||||||
|
|
||||||
// Register the paramerterised types
|
// Register the paramerterised types
|
||||||
|
@ -915,14 +916,14 @@ impl<'a> Environment<'a> {
|
||||||
names: &mut HashMap<&'a str, &'a Span>,
|
names: &mut HashMap<&'a str, &'a Span>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
match def {
|
match def {
|
||||||
Definition::Fn {
|
Definition::Fn(Function {
|
||||||
name,
|
name,
|
||||||
arguments: args,
|
arguments: args,
|
||||||
location,
|
location,
|
||||||
return_annotation,
|
return_annotation,
|
||||||
public,
|
public,
|
||||||
..
|
..
|
||||||
} => {
|
}) => {
|
||||||
assert_unique_value_name(names, name, location)?;
|
assert_unique_value_name(names, name, location)?;
|
||||||
|
|
||||||
self.ungeneralised_functions.insert(name.to_string());
|
self.ungeneralised_functions.insert(name.to_string());
|
||||||
|
@ -980,14 +981,14 @@ impl<'a> Environment<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Definition::DataType {
|
Definition::DataType(DataType {
|
||||||
location,
|
location,
|
||||||
public,
|
public,
|
||||||
opaque,
|
opaque,
|
||||||
name,
|
name,
|
||||||
constructors,
|
constructors,
|
||||||
..
|
..
|
||||||
} => {
|
}) => {
|
||||||
let mut hydrator = hydrators
|
let mut hydrator = hydrators
|
||||||
.remove(name)
|
.remove(name)
|
||||||
.expect("Could not find hydrator for register_values custom type");
|
.expect("Could not find hydrator for register_values custom type");
|
||||||
|
@ -1079,7 +1080,7 @@ impl<'a> Environment<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Definition::ModuleConstant { name, location, .. } => {
|
Definition::ModuleConstant(ModuleConstant { name, location, .. }) => {
|
||||||
assert_unique_const_name(names, name, location)?;
|
assert_unique_const_name(names, name, location)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,9 @@ use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{
|
ast::{
|
||||||
Definition, Layer, ModuleKind, RecordConstructor, RecordConstructorArg, TypedDefinition,
|
DataType, Definition, Function, Layer, ModuleConstant, ModuleKind, RecordConstructor,
|
||||||
TypedModule, UntypedDefinition, UntypedModule,
|
RecordConstructorArg, TypeAlias, TypedDefinition, TypedModule, UntypedDefinition,
|
||||||
|
UntypedModule, Use,
|
||||||
},
|
},
|
||||||
builtins::function,
|
builtins::function,
|
||||||
parser::token::Token,
|
parser::token::Token,
|
||||||
|
@ -142,7 +143,7 @@ fn infer_definition(
|
||||||
environment: &mut Environment<'_>,
|
environment: &mut Environment<'_>,
|
||||||
) -> Result<TypedDefinition, Error> {
|
) -> Result<TypedDefinition, Error> {
|
||||||
match def {
|
match def {
|
||||||
Definition::Fn {
|
Definition::Fn(Function {
|
||||||
doc,
|
doc,
|
||||||
location,
|
location,
|
||||||
name,
|
name,
|
||||||
|
@ -152,7 +153,7 @@ fn infer_definition(
|
||||||
return_annotation,
|
return_annotation,
|
||||||
end_position,
|
end_position,
|
||||||
..
|
..
|
||||||
} => {
|
}) => {
|
||||||
let preregistered_fn = environment
|
let preregistered_fn = environment
|
||||||
.get_variable(&name)
|
.get_variable(&name)
|
||||||
.expect("Could not find preregistered type for function");
|
.expect("Could not find preregistered type for function");
|
||||||
|
@ -217,7 +218,7 @@ fn infer_definition(
|
||||||
tipo
|
tipo
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Definition::Fn {
|
Ok(Definition::Fn(Function {
|
||||||
doc,
|
doc,
|
||||||
location,
|
location,
|
||||||
name,
|
name,
|
||||||
|
@ -229,10 +230,10 @@ fn infer_definition(
|
||||||
.expect("Could not find return type for fn"),
|
.expect("Could not find return type for fn"),
|
||||||
body,
|
body,
|
||||||
end_position,
|
end_position,
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
Definition::TypeAlias {
|
Definition::TypeAlias(TypeAlias {
|
||||||
doc,
|
doc,
|
||||||
location,
|
location,
|
||||||
public,
|
public,
|
||||||
|
@ -240,14 +241,14 @@ fn infer_definition(
|
||||||
parameters,
|
parameters,
|
||||||
annotation,
|
annotation,
|
||||||
..
|
..
|
||||||
} => {
|
}) => {
|
||||||
let tipo = environment
|
let tipo = environment
|
||||||
.get_type_constructor(&None, &alias, location)
|
.get_type_constructor(&None, &alias, location)
|
||||||
.expect("Could not find existing type for type alias")
|
.expect("Could not find existing type for type alias")
|
||||||
.tipo
|
.tipo
|
||||||
.clone();
|
.clone();
|
||||||
|
|
||||||
Ok(Definition::TypeAlias {
|
Ok(Definition::TypeAlias(TypeAlias {
|
||||||
doc,
|
doc,
|
||||||
location,
|
location,
|
||||||
public,
|
public,
|
||||||
|
@ -255,10 +256,10 @@ fn infer_definition(
|
||||||
parameters,
|
parameters,
|
||||||
annotation,
|
annotation,
|
||||||
tipo,
|
tipo,
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
Definition::DataType {
|
Definition::DataType(DataType {
|
||||||
doc,
|
doc,
|
||||||
location,
|
location,
|
||||||
public,
|
public,
|
||||||
|
@ -267,7 +268,7 @@ fn infer_definition(
|
||||||
parameters,
|
parameters,
|
||||||
constructors,
|
constructors,
|
||||||
..
|
..
|
||||||
} => {
|
}) => {
|
||||||
let constructors = constructors
|
let constructors = constructors
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(
|
.map(
|
||||||
|
@ -330,7 +331,7 @@ fn infer_definition(
|
||||||
.parameters
|
.parameters
|
||||||
.clone();
|
.clone();
|
||||||
|
|
||||||
Ok(Definition::DataType {
|
Ok(Definition::DataType(DataType {
|
||||||
doc,
|
doc,
|
||||||
location,
|
location,
|
||||||
public,
|
public,
|
||||||
|
@ -339,16 +340,16 @@ fn infer_definition(
|
||||||
parameters,
|
parameters,
|
||||||
constructors,
|
constructors,
|
||||||
typed_parameters,
|
typed_parameters,
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
Definition::Use {
|
Definition::Use(Use {
|
||||||
location,
|
location,
|
||||||
module,
|
module,
|
||||||
as_name,
|
as_name,
|
||||||
mut unqualified,
|
mut unqualified,
|
||||||
..
|
..
|
||||||
} => {
|
}) => {
|
||||||
let name = module.join("/");
|
let name = module.join("/");
|
||||||
|
|
||||||
// Find imported module
|
// Find imported module
|
||||||
|
@ -371,16 +372,16 @@ fn infer_definition(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Definition::Use {
|
Ok(Definition::Use(Use {
|
||||||
location,
|
location,
|
||||||
module,
|
module,
|
||||||
as_name,
|
as_name,
|
||||||
unqualified,
|
unqualified,
|
||||||
package: module_info.package.clone(),
|
package: module_info.package.clone(),
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
Definition::ModuleConstant {
|
Definition::ModuleConstant(ModuleConstant {
|
||||||
doc,
|
doc,
|
||||||
location,
|
location,
|
||||||
name,
|
name,
|
||||||
|
@ -388,7 +389,7 @@ fn infer_definition(
|
||||||
public,
|
public,
|
||||||
value,
|
value,
|
||||||
..
|
..
|
||||||
} => {
|
}) => {
|
||||||
let typed_expr = ExprTyper::new(environment).infer_const(&annotation, *value)?;
|
let typed_expr = ExprTyper::new(environment).infer_const(&annotation, *value)?;
|
||||||
|
|
||||||
let tipo = typed_expr.tipo();
|
let tipo = typed_expr.tipo();
|
||||||
|
@ -411,7 +412,7 @@ fn infer_definition(
|
||||||
environment.init_usage(name.clone(), EntityKind::PrivateConstant, location);
|
environment.init_usage(name.clone(), EntityKind::PrivateConstant, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Definition::ModuleConstant {
|
Ok(Definition::ModuleConstant(ModuleConstant {
|
||||||
doc,
|
doc,
|
||||||
location,
|
location,
|
||||||
name,
|
name,
|
||||||
|
@ -419,7 +420,7 @@ fn infer_definition(
|
||||||
public,
|
public,
|
||||||
value: Box::new(typed_expr),
|
value: Box::new(typed_expr),
|
||||||
tipo,
|
tipo,
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
fs,
|
fs,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
|
rc::Rc,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod config;
|
pub mod config;
|
||||||
|
@ -10,16 +11,22 @@ pub mod format;
|
||||||
pub mod module;
|
pub mod module;
|
||||||
|
|
||||||
use aiken_lang::{
|
use aiken_lang::{
|
||||||
ast::{Definition, ModuleKind},
|
ast::{Definition, Function, ModuleKind},
|
||||||
builtins,
|
builtins,
|
||||||
|
expr::TypedExpr,
|
||||||
tipo::TypeInfo,
|
tipo::TypeInfo,
|
||||||
IdGenerator,
|
IdGenerator,
|
||||||
};
|
};
|
||||||
|
use uplc::{
|
||||||
|
ast::{Constant, Name, NamedDeBruijn, Program, Term, Unique},
|
||||||
|
builtins::DefaultFunction,
|
||||||
|
parser::interner::Interner,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::Config,
|
config::Config,
|
||||||
error::{Error, Warning},
|
error::{Error, Warning},
|
||||||
module::{CheckedModule, CheckedModules, ParsedModule, ParsedModules},
|
module::{self, CheckedModule, CheckedModules, ParsedModule, ParsedModules},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -74,7 +81,7 @@ impl Project {
|
||||||
self.compile(false)
|
self.compile(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile(&mut self, _uplc_gen: bool) -> Result<(), Error> {
|
pub fn compile(&mut self, uplc_gen: bool) -> Result<(), Error> {
|
||||||
self.read_source_files()?;
|
self.read_source_files()?;
|
||||||
|
|
||||||
let parsed_modules = self.parse_sources()?;
|
let parsed_modules = self.parse_sources()?;
|
||||||
|
@ -83,7 +90,11 @@ impl Project {
|
||||||
|
|
||||||
let mut checked_modules = self.type_check(parsed_modules, processing_sequence)?;
|
let mut checked_modules = self.type_check(parsed_modules, processing_sequence)?;
|
||||||
|
|
||||||
let _scripts = self.validate_scripts(&mut checked_modules)?;
|
let scripts = self.validate_scripts(&mut checked_modules)?;
|
||||||
|
|
||||||
|
if uplc_gen {
|
||||||
|
self.code_gen(&scripts, &checked_modules)?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -240,13 +251,13 @@ impl Project {
|
||||||
scripts.push(module.clone());
|
scripts.push(module.clone());
|
||||||
|
|
||||||
for def in module.ast.definitions() {
|
for def in module.ast.definitions() {
|
||||||
if let Definition::Fn {
|
if let Definition::Fn(Function {
|
||||||
arguments,
|
arguments,
|
||||||
location,
|
location,
|
||||||
name,
|
name,
|
||||||
return_type,
|
return_type,
|
||||||
..
|
..
|
||||||
} = def
|
}) = def
|
||||||
{
|
{
|
||||||
if VALIDATOR_NAMES.contains(&name.as_str()) {
|
if VALIDATOR_NAMES.contains(&name.as_str()) {
|
||||||
// validators must return a Bool
|
// validators must return a Bool
|
||||||
|
@ -295,6 +306,286 @@ impl Project {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn code_gen(
|
||||||
|
&mut self,
|
||||||
|
scripts: &[CheckedModule],
|
||||||
|
checked_modules: &CheckedModules,
|
||||||
|
) -> Result<Vec<Program<NamedDeBruijn>>, Error> {
|
||||||
|
let mut programs = Vec::new();
|
||||||
|
let mut uplc_function_holder = Vec::new();
|
||||||
|
let mut functions = HashMap::new();
|
||||||
|
let mut type_aliases = HashMap::new();
|
||||||
|
let mut data_types = HashMap::new();
|
||||||
|
let mut imports = HashMap::new();
|
||||||
|
let mut constants = HashMap::new();
|
||||||
|
|
||||||
|
for module in checked_modules.values() {
|
||||||
|
for def in module.ast.definitions() {
|
||||||
|
match def {
|
||||||
|
Definition::Fn(func) => {
|
||||||
|
functions.insert((module.name.clone(), func.name.clone()), func);
|
||||||
|
}
|
||||||
|
Definition::TypeAlias(ta) => {
|
||||||
|
type_aliases.insert((module.name.clone(), ta.alias.clone()), ta);
|
||||||
|
}
|
||||||
|
Definition::DataType(dt) => {
|
||||||
|
data_types.insert((module.name.clone(), dt.name.clone()), dt);
|
||||||
|
}
|
||||||
|
Definition::Use(import) => {
|
||||||
|
imports.insert((module.name.clone(), import.module.join("/")), import);
|
||||||
|
}
|
||||||
|
Definition::ModuleConstant(mc) => {
|
||||||
|
constants.insert((module.name.clone(), mc.name.clone()), mc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for script in scripts {
|
||||||
|
for def in script.ast.definitions() {
|
||||||
|
if let Definition::Fn(Function {
|
||||||
|
arguments,
|
||||||
|
name,
|
||||||
|
body,
|
||||||
|
..
|
||||||
|
}) = def
|
||||||
|
{
|
||||||
|
if VALIDATOR_NAMES.contains(&name.as_str()) {
|
||||||
|
let type_info = self.module_types.get(&script.name).unwrap();
|
||||||
|
println!("{type_info:#?}");
|
||||||
|
|
||||||
|
let mut term = self.recurse_code_gen(
|
||||||
|
body,
|
||||||
|
scripts,
|
||||||
|
0,
|
||||||
|
&uplc_function_holder,
|
||||||
|
&functions,
|
||||||
|
&type_aliases,
|
||||||
|
&data_types,
|
||||||
|
&imports,
|
||||||
|
&constants,
|
||||||
|
);
|
||||||
|
|
||||||
|
for arg in arguments.iter().rev() {
|
||||||
|
term = Term::Lambda {
|
||||||
|
parameter_name: uplc::ast::Name {
|
||||||
|
text: arg
|
||||||
|
.arg_name
|
||||||
|
.get_variable_name()
|
||||||
|
.unwrap_or("_")
|
||||||
|
.to_string(),
|
||||||
|
unique: Unique::new(0),
|
||||||
|
},
|
||||||
|
body: Rc::new(term),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut program = Program {
|
||||||
|
version: (1, 0, 0),
|
||||||
|
term,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut interner = Interner::new();
|
||||||
|
|
||||||
|
interner.program(&mut program);
|
||||||
|
|
||||||
|
programs.push(program.try_into().unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(programs)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn recurse_code_gen(
|
||||||
|
&self,
|
||||||
|
body: &aiken_lang::expr::TypedExpr,
|
||||||
|
scripts: &[CheckedModule],
|
||||||
|
scope_level: i32,
|
||||||
|
uplc_function_holder: &Vec<Term<Name>>,
|
||||||
|
functions: &HashMap<
|
||||||
|
(String, String),
|
||||||
|
&Function<std::sync::Arc<aiken_lang::tipo::Type>, aiken_lang::expr::TypedExpr>,
|
||||||
|
>,
|
||||||
|
type_aliases: &HashMap<
|
||||||
|
(String, String),
|
||||||
|
&aiken_lang::ast::TypeAlias<std::sync::Arc<aiken_lang::tipo::Type>>,
|
||||||
|
>,
|
||||||
|
data_types: &HashMap<
|
||||||
|
(String, String),
|
||||||
|
&aiken_lang::ast::DataType<std::sync::Arc<aiken_lang::tipo::Type>>,
|
||||||
|
>,
|
||||||
|
imports: &HashMap<(String, String), &aiken_lang::ast::Use<String>>,
|
||||||
|
constants: &HashMap<
|
||||||
|
(String, String),
|
||||||
|
&aiken_lang::ast::ModuleConstant<std::sync::Arc<aiken_lang::tipo::Type>, String>,
|
||||||
|
>,
|
||||||
|
) -> Term<uplc::ast::Name> {
|
||||||
|
let terms = match body {
|
||||||
|
aiken_lang::expr::TypedExpr::Int { value, .. } => {
|
||||||
|
Term::Constant(Constant::Integer(value.parse::<i128>().unwrap()))
|
||||||
|
}
|
||||||
|
aiken_lang::expr::TypedExpr::String { value, .. } => {
|
||||||
|
Term::Constant(Constant::String(value.clone()))
|
||||||
|
}
|
||||||
|
aiken_lang::expr::TypedExpr::ByteArray { bytes, .. } => {
|
||||||
|
Term::Constant(Constant::ByteString(bytes.clone()))
|
||||||
|
}
|
||||||
|
aiken_lang::expr::TypedExpr::Sequence {
|
||||||
|
location,
|
||||||
|
expressions,
|
||||||
|
} => todo!(),
|
||||||
|
aiken_lang::expr::TypedExpr::Pipeline {
|
||||||
|
location,
|
||||||
|
expressions,
|
||||||
|
} => todo!(),
|
||||||
|
aiken_lang::expr::TypedExpr::Var {
|
||||||
|
location,
|
||||||
|
constructor,
|
||||||
|
name,
|
||||||
|
} => todo!(),
|
||||||
|
aiken_lang::expr::TypedExpr::Fn {
|
||||||
|
location,
|
||||||
|
tipo,
|
||||||
|
is_capture,
|
||||||
|
args,
|
||||||
|
body,
|
||||||
|
return_annotation,
|
||||||
|
} => todo!(),
|
||||||
|
aiken_lang::expr::TypedExpr::List {
|
||||||
|
location,
|
||||||
|
tipo,
|
||||||
|
elements,
|
||||||
|
tail,
|
||||||
|
} => todo!(),
|
||||||
|
aiken_lang::expr::TypedExpr::Call {
|
||||||
|
location,
|
||||||
|
tipo,
|
||||||
|
fun,
|
||||||
|
args,
|
||||||
|
} => todo!(),
|
||||||
|
aiken_lang::expr::TypedExpr::BinOp {
|
||||||
|
location,
|
||||||
|
tipo,
|
||||||
|
name,
|
||||||
|
left,
|
||||||
|
right,
|
||||||
|
} => todo!(),
|
||||||
|
aiken_lang::expr::TypedExpr::Assignment {
|
||||||
|
location,
|
||||||
|
tipo,
|
||||||
|
value,
|
||||||
|
pattern,
|
||||||
|
kind,
|
||||||
|
} => todo!(),
|
||||||
|
aiken_lang::expr::TypedExpr::Try {
|
||||||
|
location,
|
||||||
|
tipo,
|
||||||
|
value,
|
||||||
|
then,
|
||||||
|
pattern,
|
||||||
|
} => todo!(),
|
||||||
|
aiken_lang::expr::TypedExpr::When {
|
||||||
|
location,
|
||||||
|
tipo,
|
||||||
|
subjects,
|
||||||
|
clauses,
|
||||||
|
} => todo!(),
|
||||||
|
//if statements increase scope due to branching.
|
||||||
|
aiken_lang::expr::TypedExpr::If {
|
||||||
|
branches,
|
||||||
|
final_else,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
let mut final_if_term = self.recurse_code_gen(
|
||||||
|
final_else,
|
||||||
|
scripts,
|
||||||
|
scope_level + 1,
|
||||||
|
uplc_function_holder,
|
||||||
|
functions,
|
||||||
|
type_aliases,
|
||||||
|
data_types,
|
||||||
|
imports,
|
||||||
|
constants,
|
||||||
|
);
|
||||||
|
|
||||||
|
for branch in branches {
|
||||||
|
// Need some scoping count to potentially replace condition with var since we should assume a condition
|
||||||
|
// may be repeated 3 + times or be large enough series of binops to warrant var replacement
|
||||||
|
let condition_term = self.recurse_code_gen(
|
||||||
|
&branch.condition,
|
||||||
|
scripts,
|
||||||
|
scope_level + 1, // Since this happens before branching. Maybe not increase scope level
|
||||||
|
uplc_function_holder,
|
||||||
|
functions,
|
||||||
|
type_aliases,
|
||||||
|
data_types,
|
||||||
|
imports,
|
||||||
|
constants,
|
||||||
|
);
|
||||||
|
|
||||||
|
let branch_term = self.recurse_code_gen(
|
||||||
|
&branch.body,
|
||||||
|
scripts,
|
||||||
|
scope_level + 1,
|
||||||
|
uplc_function_holder,
|
||||||
|
functions,
|
||||||
|
type_aliases,
|
||||||
|
data_types,
|
||||||
|
imports,
|
||||||
|
constants,
|
||||||
|
);
|
||||||
|
|
||||||
|
final_if_term = Term::Apply {
|
||||||
|
function: Rc::new(Term::Apply {
|
||||||
|
function: Rc::new(Term::Apply {
|
||||||
|
function: Rc::new(Term::Force(Rc::new(Term::Builtin(
|
||||||
|
DefaultFunction::IfThenElse,
|
||||||
|
)))),
|
||||||
|
argument: Rc::new(condition_term),
|
||||||
|
}),
|
||||||
|
//If this is just a var then don't include delay
|
||||||
|
argument: Rc::new(Term::Delay(Rc::new(branch_term))),
|
||||||
|
}),
|
||||||
|
//If this is just a var then don't include delay
|
||||||
|
argument: Rc::new(Term::Delay(Rc::new(final_if_term.clone()))),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Term::Force(Rc::new(final_if_term))
|
||||||
|
}
|
||||||
|
aiken_lang::expr::TypedExpr::RecordAccess {
|
||||||
|
location,
|
||||||
|
tipo,
|
||||||
|
label,
|
||||||
|
index,
|
||||||
|
record,
|
||||||
|
} => todo!(),
|
||||||
|
aiken_lang::expr::TypedExpr::ModuleSelect {
|
||||||
|
location,
|
||||||
|
tipo,
|
||||||
|
label,
|
||||||
|
module_name,
|
||||||
|
module_alias,
|
||||||
|
constructor,
|
||||||
|
} => todo!(),
|
||||||
|
aiken_lang::expr::TypedExpr::Todo {
|
||||||
|
location,
|
||||||
|
label,
|
||||||
|
tipo,
|
||||||
|
} => todo!(),
|
||||||
|
aiken_lang::expr::TypedExpr::RecordUpdate {
|
||||||
|
location,
|
||||||
|
tipo,
|
||||||
|
spread,
|
||||||
|
args,
|
||||||
|
} => todo!(),
|
||||||
|
aiken_lang::expr::TypedExpr::Negate { location, value } => todo!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
terms
|
||||||
|
}
|
||||||
|
|
||||||
fn aiken_files(&mut self, dir: &Path, kind: ModuleKind) -> Result<(), Error> {
|
fn aiken_files(&mut self, dir: &Path, kind: ModuleKind) -> Result<(), Error> {
|
||||||
let paths = walkdir::WalkDir::new(dir)
|
let paths = walkdir::WalkDir::new(dir)
|
||||||
.follow_links(true)
|
.follow_links(true)
|
||||||
|
|
|
@ -9,7 +9,7 @@ use interner::Interner;
|
||||||
use pallas_primitives::{alonzo::PlutusData, Fragment};
|
use pallas_primitives::{alonzo::PlutusData, Fragment};
|
||||||
use peg::{error::ParseError, str::LineCol};
|
use peg::{error::ParseError, str::LineCol};
|
||||||
|
|
||||||
mod interner;
|
pub mod interner;
|
||||||
|
|
||||||
/// Parse a `Program` from a str.
|
/// Parse a `Program` from a str.
|
||||||
pub fn program(src: &str) -> Result<Program<Name>, ParseError<LineCol>> {
|
pub fn program(src: &str) -> Result<Program<Name>, ParseError<LineCol>> {
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
pub type ScriptContext {
|
pub type ScriptContext {
|
||||||
thing: String,
|
thing: String
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Datum {
|
||||||
|
something: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn thing(a: Datum, b){
|
||||||
|
a.something == b
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
|
use sample
|
||||||
use sample/mint
|
use sample/mint
|
||||||
use sample/spend
|
use sample/spend
|
||||||
|
|
||||||
pub type Datum {
|
|
||||||
something: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type Redeemer {
|
pub type Redeemer {
|
||||||
Buy { id: Int }
|
Buy { id: Int }
|
||||||
Sell(Int)
|
Sell(Int)
|
||||||
|
|
Loading…
Reference in New Issue