diff --git a/crates/aiken-lang/src/tests/parser.rs b/crates/aiken-lang/src/tests/parser.rs index 1eb01af7..b06f027f 100644 --- a/crates/aiken-lang/src/tests/parser.rs +++ b/crates/aiken-lang/src/tests/parser.rs @@ -1,34 +1,11 @@ -use crate::{ - ast::{self, Constant, DataType, Function, ModuleConstant, Span, TypeAlias, Use}, - expr, - parser::{self, token::Base}, -}; -use chumsky::prelude::*; -use indoc::indoc; -use pretty_assertions::assert_eq; -use vec1::vec1; - -fn assert_definitions(code: &str, definitions: Vec) { - let (module, _extra) = parser::module(code, ast::ModuleKind::Validator).unwrap(); - - assert_eq!( - ast::UntypedModule { - docs: vec![], - kind: ast::ModuleKind::Validator, - name: "".to_string(), - type_info: (), - definitions, - }, - module - ) -} +use crate::{ast, parser}; macro_rules! assert_parse { ($name:ident, $code:expr) => { #[test] fn $name() { let (module, _) = - parser::module($code, ast::ModuleKind::Validator).expect("Failed to parse code"); + parser::module(indoc::indoc!{ $code }, ast::ModuleKind::Validator).expect("Failed to parse code"); insta::with_settings!({ info => &stringify!($name), @@ -42,204 +19,47 @@ macro_rules! assert_parse { } assert_parse!(windows_newline, "use aiken/list\r\n"); - -#[test] -fn can_handle_comments_at_end_of_file() { - let code = indoc! {r#" +assert_parse!( + can_handle_comments_at_end_of_file, + r#" use aiken // some comment - // more comments"#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::Use(Use { - location: Span::new((), 0..9), - module: vec!["aiken".to_string()], - as_name: None, - unqualified: vec![], - package: (), - })], - ) -} - -#[test] -fn type_annotation_with_module_prefix() { - let code = indoc! {r#" + // more comments"# +); +assert_parse!( + type_annotation_with_module_prefix, + r#" use aiken pub fn go() -> aiken.Option { False } - "#}; - - assert_definitions( - code, - vec![ - ast::UntypedDefinition::Use(ast::Use { - as_name: None, - location: Span::new((), 0..9), - module: vec!["aiken".to_string()], - package: (), - unqualified: vec![], - }), - ast::UntypedDefinition::Fn(ast::Function { - arguments: vec![], - body: expr::UntypedExpr::Var { - location: Span::new((), 48..53), - name: "False".to_string(), - }, - doc: None, - location: Span::new((), 11..43), - name: "go".to_string(), - public: true, - return_annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 26..43), - module: Some("aiken".to_string()), - name: "Option".to_string(), - arguments: vec![ast::Annotation::Constructor { - location: Span::new((), 39..42), - module: None, - name: "Int".to_string(), - arguments: vec![], - }], - }), - return_type: (), - end_position: 54, - can_error: true, - }), - ], - ) -} - -#[test] -fn test_fail() { - let code = indoc! {r#" + "# +); +assert_parse!( + test_fail, + r#" !test invalid_inputs() { expect True = False False } - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::Test(ast::Function { - arguments: vec![], - body: expr::UntypedExpr::Sequence { - location: Span::new((), 27..55), - expressions: vec![ - expr::UntypedExpr::Assignment { - location: Span::new((), 27..46), - value: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 41..46), - name: "False".to_string(), - }), - pattern: ast::UntypedPattern::Constructor { - is_record: false, - location: Span::new((), 34..38), - name: "True".to_string(), - arguments: vec![], - module: None, - constructor: (), - with_spread: false, - tipo: (), - }, - kind: ast::AssignmentKind::Expect, - annotation: None, - }, - expr::UntypedExpr::Var { - location: Span::new((), 50..55), - name: "False".to_string(), - }, - ], - }, - doc: None, - location: Span::new((), 0..22), - name: "invalid_inputs".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 56, - can_error: true, - })], - ); -} - -#[test] -fn validator() { - let code = indoc! {r#" + "# +); +assert_parse!( + validator, + r#" validator { fn foo(datum, rdmr, ctx) { True } } - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::Validator(ast::Validator { - doc: None, - end_position: 54, - fun: Function { - can_error: true, - arguments: vec![ - ast::Arg { - arg_name: ast::ArgName::Named { - name: "datum".to_string(), - label: "datum".to_string(), - location: Span::new((), 21..26), - is_validator_param: false, - }, - location: Span::new((), 21..26), - annotation: None, - tipo: (), - }, - ast::Arg { - arg_name: ast::ArgName::Named { - name: "rdmr".to_string(), - label: "rdmr".to_string(), - location: Span::new((), 28..32), - is_validator_param: false, - }, - location: Span::new((), 28..32), - annotation: None, - tipo: (), - }, - ast::Arg { - arg_name: ast::ArgName::Named { - name: "ctx".to_string(), - label: "ctx".to_string(), - location: Span::new((), 34..37), - is_validator_param: false, - }, - location: Span::new((), 34..37), - annotation: None, - tipo: (), - }, - ], - body: expr::UntypedExpr::Var { - location: Span::new((), 45..49), - name: "True".to_string(), - }, - doc: None, - location: Span::new((), 14..38), - name: "foo".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 52, - }, - other_fun: None, - location: Span::new((), 0..9), - params: vec![], - })], - ) -} - -#[test] -fn double_validator() { - let code = indoc! {r#" + "# +); +assert_parse!( + double_validator, + r#" validator { fn foo(datum, rdmr, ctx) { True @@ -249,597 +69,92 @@ fn double_validator() { True } } - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::Validator(ast::Validator { - doc: None, - end_position: 90, - fun: Function { - can_error: true, - arguments: vec![ - ast::Arg { - arg_name: ast::ArgName::Named { - name: "datum".to_string(), - label: "datum".to_string(), - location: Span::new((), 21..26), - is_validator_param: false, - }, - location: Span::new((), 21..26), - annotation: None, - tipo: (), - }, - ast::Arg { - arg_name: ast::ArgName::Named { - name: "rdmr".to_string(), - label: "rdmr".to_string(), - location: Span::new((), 28..32), - is_validator_param: false, - }, - location: Span::new((), 28..32), - annotation: None, - tipo: (), - }, - ast::Arg { - arg_name: ast::ArgName::Named { - name: "ctx".to_string(), - label: "ctx".to_string(), - location: Span::new((), 34..37), - is_validator_param: false, - }, - location: Span::new((), 34..37), - annotation: None, - tipo: (), - }, - ], - body: expr::UntypedExpr::Var { - location: Span::new((), 45..49), - name: "True".to_string(), - }, - doc: None, - location: Span::new((), 14..38), - name: "foo".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 52, - }, - other_fun: Some(Function { - can_error: true, - arguments: vec![ - ast::Arg { - arg_name: ast::ArgName::Named { - name: "rdmr".to_string(), - label: "rdmr".to_string(), - location: Span::new((), 64..68), - is_validator_param: false, - }, - location: Span::new((), 64..68), - annotation: None, - tipo: (), - }, - ast::Arg { - arg_name: ast::ArgName::Named { - name: "ctx".to_string(), - label: "ctx".to_string(), - location: Span::new((), 70..73), - is_validator_param: false, - }, - location: Span::new((), 70..73), - annotation: None, - tipo: (), - }, - ], - body: expr::UntypedExpr::Var { - location: Span::new((), 81..85), - name: "True".to_string(), - }, - doc: None, - location: Span::new((), 57..74), - name: "bar".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 88, - }), - location: Span::new((), 0..9), - params: vec![], - })], - ) -} - -#[test] -fn import() { - let code = indoc! {r#" + "# +); +assert_parse!( + import, + r#" use std/list - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::Use(Use { - location: Span::new((), 0..12), - module: vec!["std".to_string(), "list".to_string()], - as_name: None, - unqualified: vec![], - package: (), - })], - ) -} - -#[test] -fn unqualified_imports() { - let code = indoc! {r#" + "# +); +assert_parse!( + unqualified_imports, + r#" use std/address.{Address as A, thing as w} - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::Use(Use { - location: Span::new((), 0..42), - module: vec!["std".to_string(), "address".to_string()], - as_name: None, - unqualified: vec![ - ast::UnqualifiedImport { - as_name: Some("A".to_string()), - location: Span::new((), 17..29), - layer: Default::default(), - name: "Address".to_string(), - }, - ast::UnqualifiedImport { - as_name: Some("w".to_string()), - location: Span::new((), 31..41), - layer: Default::default(), - name: "thing".to_string(), - }, - ], - package: (), - })], - ) -} - -#[test] -fn import_alias() { - let code = indoc! {r#" + "# +); +assert_parse!( + import_alias, + r#" use std/tx as t - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::Use(Use { - location: Span::new((), 0..15), - module: vec!["std".to_string(), "tx".to_string()], - as_name: Some("t".to_string()), - unqualified: vec![], - package: (), - })], - ) -} - -#[test] -fn custom_type() { - let code = indoc! {r#" + "# +); +assert_parse!( + custom_type, + r#" type Option { Some(a, Int) None Wow { name: Int, age: Int } } - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::DataType(DataType { - constructors: vec![ - ast::RecordConstructor { - location: Span::new((), 19..31), - name: "Some".to_string(), - arguments: vec![ - ast::RecordConstructorArg { - label: None, - annotation: ast::Annotation::Var { - location: Span::new((), 24..25), - name: "a".to_string(), - }, - location: Span::new((), 24..25), - tipo: (), - doc: None, - }, - ast::RecordConstructorArg { - label: None, - annotation: ast::Annotation::Constructor { - location: Span::new((), 27..30), - module: None, - name: "Int".to_string(), - arguments: vec![], - }, - location: Span::new((), 27..30), - tipo: (), - doc: None, - }, - ], - doc: None, - sugar: false, - }, - ast::RecordConstructor { - location: Span::new((), 34..38), - name: "None".to_string(), - arguments: vec![], - doc: None, - sugar: false, - }, - ast::RecordConstructor { - location: Span::new((), 41..68), - name: "Wow".to_string(), - arguments: vec![ - ast::RecordConstructorArg { - label: Some("name".to_string()), - annotation: ast::Annotation::Constructor { - location: Span::new((), 53..56), - module: None, - name: "Int".to_string(), - arguments: vec![], - }, - location: Span::new((), 47..56), - tipo: (), - doc: None, - }, - ast::RecordConstructorArg { - label: Some("age".to_string()), - annotation: ast::Annotation::Constructor { - location: Span::new((), 63..66), - module: None, - name: "Int".to_string(), - arguments: vec![], - }, - location: Span::new((), 58..66), - tipo: (), - doc: None, - }, - ], - doc: None, - sugar: false, - }, - ], - doc: None, - location: Span::new((), 0..70), - name: "Option".to_string(), - opaque: false, - parameters: vec!["a".to_string()], - public: false, - typed_parameters: vec![], - })], - ) -} - -#[test] -fn opaque_type() { - let code = indoc! {r#" + "# +); +assert_parse!( + opaque_type, + r#" pub opaque type User { name: _w } - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::DataType(DataType { - constructors: vec![ast::RecordConstructor { - location: Span::new((), 21..35), - name: "User".to_string(), - arguments: vec![ast::RecordConstructorArg { - label: Some("name".to_string()), - annotation: ast::Annotation::Hole { - location: Span::new((), 31..33), - name: "_w".to_string(), - }, - location: Span::new((), 25..33), - tipo: (), - doc: None, - }], - doc: None, - sugar: true, - }], - doc: None, - location: Span::new((), 0..35), - name: "User".to_string(), - opaque: true, - parameters: vec![], - public: true, - typed_parameters: vec![], - })], - ) -} - -#[test] -fn type_alias() { - let code = indoc! {r#" + "# +); +assert_parse!( + type_alias, + r#" type Thing = Option - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::TypeAlias(TypeAlias { - alias: "Thing".to_string(), - annotation: ast::Annotation::Constructor { - location: Span::new((), 13..24), - module: None, - name: "Option".to_string(), - arguments: vec![ast::Annotation::Constructor { - location: Span::new((), 20..23), - module: None, - name: "Int".to_string(), - arguments: vec![], - }], - }, - doc: None, - location: Span::new((), 0..24), - parameters: vec![], - public: false, - tipo: (), - })], - ) -} - -#[test] -fn pub_type_alias() { - let code = indoc! {r#" + "# +); +assert_parse!( + pub_type_alias, + r#" pub type Me = Option - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::TypeAlias(TypeAlias { - alias: "Me".to_string(), - annotation: ast::Annotation::Constructor { - location: Span::new((), 14..28), - module: None, - name: "Option".to_string(), - arguments: vec![ast::Annotation::Constructor { - location: Span::new((), 21..27), - module: None, - name: "String".to_string(), - arguments: vec![], - }], - }, - doc: None, - location: Span::new((), 0..28), - parameters: vec![], - public: true, - tipo: (), - })], - ) -} - -#[test] -fn empty_function() { - let code = indoc! {r#" + "# +); +assert_parse!( + empty_function, + r#" pub fn run() {} - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::Fn(Function { - can_error: true, - arguments: vec![], - body: expr::UntypedExpr::Trace { - kind: ast::TraceKind::Todo, - location: Span::new((), 0..15), - text: Box::new(expr::UntypedExpr::String { - value: "aiken::todo".to_string(), - location: Span::new((), 0..15), - }), - then: Box::new(expr::UntypedExpr::ErrorTerm { - location: Span::new((), 0..15), - }), - }, - doc: None, - location: Span::new((), 0..12), - name: "run".to_string(), - public: true, - return_annotation: None, - return_type: (), - end_position: 14, - })], - ) -} - -#[test] -fn expect() { - let code = indoc! {r#" + "# +); +assert_parse!( + expect, + r#" pub fn run() { expect Some(x) = something.field x.other_field } - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::Fn(Function { - can_error: true, - arguments: vec![], - body: expr::UntypedExpr::Sequence { - location: Span::new((), 19..69), - expressions: vec![ - expr::UntypedExpr::Assignment { - location: Span::new((), 19..51), - value: expr::UntypedExpr::FieldAccess { - location: Span::new((), 36..51), - label: "field".to_string(), - container: expr::UntypedExpr::Var { - location: Span::new((), 36..45), - name: "something".to_string(), - } - .into(), - } - .into(), - pattern: ast::Pattern::Constructor { - is_record: false, - location: Span::new((), 26..33), - name: "Some".to_string(), - arguments: vec![ast::CallArg { - label: None, - location: Span::new((), 31..32), - value: ast::Pattern::Var { - location: Span::new((), 31..32), - name: "x".to_string(), - }, - }], - module: None, - constructor: (), - with_spread: false, - tipo: (), - }, - kind: ast::AssignmentKind::Expect, - annotation: None, - }, - expr::UntypedExpr::FieldAccess { - location: Span::new((), 56..69), - label: "other_field".to_string(), - container: expr::UntypedExpr::Var { - location: Span::new((), 56..57), - name: "x".to_string(), - } - .into(), - }, - ], - }, - doc: None, - - location: Span::new((), 0..12), - name: "run".to_string(), - public: true, - return_annotation: None, - return_type: (), - end_position: 70, - })], - ) -} - -#[test] -fn plus_binop() { - let code = indoc! {r#" + "# +); +assert_parse!( + plus_binop, + r#" pub fn add_one(a) -> Int { a + 1 } - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::Fn(Function { - can_error: true, - arguments: vec![ast::Arg { - arg_name: ast::ArgName::Named { - label: "a".to_string(), - name: "a".to_string(), - location: Span::new((), 15..16), - is_validator_param: false, - }, - location: Span::new((), 15..16), - annotation: None, - tipo: (), - }], - body: expr::UntypedExpr::BinOp { - location: Span::new((), 29..34), - name: ast::BinOp::AddInt, - left: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 29..30), - name: "a".to_string(), - }), - right: Box::new(expr::UntypedExpr::Int { - location: Span::new((), 33..34), - value: "1".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }), - }, - doc: None, - location: Span::new((), 0..24), - name: "add_one".to_string(), - public: true, - return_annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 21..24), - module: None, - name: "Int".to_string(), - arguments: vec![], - }), - return_type: (), - end_position: 35, - })], - ) -} - -#[test] -fn pipeline() { - let code = indoc! {r#" + "# +); +assert_parse!( + pipeline, + r#" pub fn thing(thing a: Int) { a + 2 |> add_one |> add_one } - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::Fn(Function { - can_error: true, - arguments: vec![ast::Arg { - arg_name: ast::ArgName::Named { - name: "a".to_string(), - label: "thing".to_string(), - location: Span::new((), 13..20), - is_validator_param: false, - }, - location: Span::new((), 13..25), - annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 22..25), - module: None, - name: "Int".to_string(), - arguments: vec![], - }), - tipo: (), - }], - body: expr::UntypedExpr::PipeLine { - one_liner: false, - expressions: vec1::vec1![ - expr::UntypedExpr::BinOp { - location: Span::new((), 31..36), - name: ast::BinOp::AddInt, - left: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 31..32), - name: "a".to_string(), - }), - right: Box::new(expr::UntypedExpr::Int { - location: Span::new((), 35..36), - value: "2".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }), - }, - expr::UntypedExpr::Var { - location: Span::new((), 42..49), - name: "add_one".to_string(), - }, - expr::UntypedExpr::Var { - location: Span::new((), 55..62), - name: "add_one".to_string(), - }, - ], - }, - doc: None, - location: Span::new((), 0..26), - name: "thing".to_string(), - public: true, - return_annotation: None, - return_type: (), - end_position: 63, - })], - ) -} - -#[test] -fn if_expression() { - let code = indoc! {r#" + "# +); +assert_parse!( + if_expression, + r#" fn ifs() { if True { 1 + 1 @@ -851,111 +166,11 @@ fn if_expression() { 3 } } - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::Fn(Function { - can_error: true, - arguments: vec![], - body: expr::UntypedExpr::If { - location: Span::new((), 13..106), - branches: vec1::vec1![ - ast::IfBranch { - condition: expr::UntypedExpr::Var { - location: Span::new((), 16..20), - name: "True".to_string(), - }, - body: expr::UntypedExpr::BinOp { - location: Span::new((), 27..32), - name: ast::BinOp::AddInt, - left: Box::new(expr::UntypedExpr::Int { - location: Span::new((), 27..28), - value: "1".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }), - right: Box::new(expr::UntypedExpr::Int { - location: Span::new((), 31..32), - value: "1".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }), - }, - location: Span::new((), 16..36), - }, - ast::IfBranch { - condition: expr::UntypedExpr::BinOp { - location: Span::new((), 45..50), - name: ast::BinOp::LtInt, - left: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 45..46), - name: "a".to_string(), - }), - right: Box::new(expr::UntypedExpr::Int { - location: Span::new((), 49..50), - value: "4".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }), - }, - body: expr::UntypedExpr::Int { - location: Span::new((), 57..58), - value: "5".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }, - location: Span::new((), 45..62), - }, - ast::IfBranch { - condition: expr::UntypedExpr::BinOp { - location: Span::new((), 71..77), - name: ast::BinOp::Or, - left: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 71..72), - name: "a".to_string(), - }), - right: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 76..77), - name: "b".to_string(), - }), - }, - body: expr::UntypedExpr::Int { - location: Span::new((), 84..85), - value: "6".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }, - location: Span::new((), 71..89), - }, - ], - final_else: Box::new(expr::UntypedExpr::Int { - location: Span::new((), 101..102), - value: "3".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }), - }, - doc: None, - location: Span::new((), 0..8), - name: "ifs".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 107, - })], - ) -} - -#[test] -fn let_bindings() { - let code = indoc! {r#" + "# +); +assert_parse!( + let_bindings, + r#" pub fn wow(a: Int) { let x = a + 2 @@ -968,134 +183,11 @@ fn let_bindings() { y } - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::Fn(Function { - can_error: true, - arguments: vec![ast::Arg { - arg_name: ast::ArgName::Named { - label: "a".to_string(), - name: "a".to_string(), - location: Span::new((), 11..12), - is_validator_param: false, - }, - location: Span::new((), 11..17), - annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 14..17), - module: None, - name: "Int".to_string(), - arguments: vec![], - }), - tipo: (), - }], - body: expr::UntypedExpr::Sequence { - location: Span::new((), 23..121), - expressions: vec![ - expr::UntypedExpr::Assignment { - location: Span::new((), 23..70), - value: Box::new(expr::UntypedExpr::PipeLine { - one_liner: false, - expressions: vec1::vec1![ - expr::UntypedExpr::BinOp { - location: Span::new((), 35..40), - name: ast::BinOp::AddInt, - left: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 35..36), - name: "a".to_string(), - }), - right: Box::new(expr::UntypedExpr::Int { - location: Span::new((), 39..40), - value: "2".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }), - }, - expr::UntypedExpr::Var { - location: Span::new((), 48..55), - name: "add_one".to_string(), - }, - expr::UntypedExpr::Var { - location: Span::new((), 63..70), - name: "add_one".to_string(), - }, - ], - }), - pattern: ast::Pattern::Var { - location: Span::new((), 27..28), - name: "x".to_string(), - }, - kind: ast::AssignmentKind::Let, - annotation: None, - }, - expr::UntypedExpr::Assignment { - location: Span::new((), 74..97), - value: Box::new(expr::UntypedExpr::List { - location: Span::new((), 86..97), - elements: vec![ - expr::UntypedExpr::Int { - location: Span::new((), 88..89), - value: "1".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }, - expr::UntypedExpr::Int { - location: Span::new((), 91..92), - value: "2".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }, - expr::UntypedExpr::Var { - location: Span::new((), 94..95), - name: "a".to_string(), - }, - ], - tail: None, - }), - pattern: ast::Pattern::Var { - location: Span::new((), 78..83), - name: "thing".to_string(), - }, - kind: ast::AssignmentKind::Let, - annotation: None, - }, - expr::UntypedExpr::Assignment { - location: Span::new((), 101..116), - value: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 111..116), - name: "thing".to_string(), - }), - pattern: ast::Pattern::Var { - location: Span::new((), 105..108), - name: "idk".to_string(), - }, - kind: ast::AssignmentKind::Let, - annotation: None, - }, - expr::UntypedExpr::Var { - location: Span::new((), 120..121), - name: "y".to_string(), - }, - ], - }, - doc: None, - location: Span::new((), 0..18), - name: "wow".to_string(), - public: true, - return_annotation: None, - return_type: (), - end_position: 122, - })], - ) -} - -#[test] -fn block() { - let code = indoc! {r#" + "# +); +assert_parse!( + block, + r#" pub fn wow2(a: Int){ let b = { let x = 4 @@ -1105,96 +197,11 @@ fn block() { b } - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::Fn(Function { - can_error: true, - arguments: vec![ast::Arg { - arg_name: ast::ArgName::Named { - label: "a".to_string(), - name: "a".to_string(), - location: Span::new((), 12..13), - is_validator_param: false, - }, - location: Span::new((), 12..18), - annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 15..18), - module: None, - name: "Int".to_string(), - arguments: vec![], - }), - tipo: (), - }], - body: expr::UntypedExpr::Sequence { - location: Span::new((), 23..66), - expressions: vec![ - expr::UntypedExpr::Assignment { - location: Span::new((), 23..61), - value: Box::new(expr::UntypedExpr::Sequence { - location: Span::new((), 37..57), - expressions: vec![ - expr::UntypedExpr::Assignment { - location: Span::new((), 37..46), - value: Box::new(expr::UntypedExpr::Int { - location: Span::new((), 45..46), - value: "4".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }), - pattern: ast::Pattern::Var { - location: Span::new((), 41..42), - name: "x".to_string(), - }, - kind: ast::AssignmentKind::Let, - annotation: None, - }, - expr::UntypedExpr::BinOp { - location: Span::new((), 52..57), - name: ast::BinOp::AddInt, - left: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 52..53), - name: "x".to_string(), - }), - right: Box::new(expr::UntypedExpr::Int { - location: Span::new((), 56..57), - value: "5".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }), - }, - ], - }), - pattern: ast::Pattern::Var { - location: Span::new((), 27..28), - name: "b".to_string(), - }, - kind: ast::AssignmentKind::Let, - annotation: None, - }, - expr::UntypedExpr::Var { - location: Span::new((), 65..66), - name: "b".to_string(), - }, - ], - }, - doc: None, - location: Span::new((), 0..19), - name: "wow2".to_string(), - public: true, - return_annotation: None, - return_type: (), - end_position: 67, - })], - ) -} - -#[test] -fn when() { - let code = indoc! {r#" + "# +); +assert_parse!( + when, + r#" pub fn wow2(a: Int){ when a is { 2 -> 3 @@ -1206,303 +213,29 @@ fn when() { _ -> 4 } } - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::Fn(Function { - can_error: true, - arguments: vec![ast::Arg { - arg_name: ast::ArgName::Named { - label: "a".to_string(), - name: "a".to_string(), - location: Span::new((), 12..13), - is_validator_param: false, - }, - location: Span::new((), 12..18), - annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 15..18), - module: None, - name: "Int".to_string(), - arguments: vec![], - }), - tipo: (), - }], - body: expr::UntypedExpr::When { - location: Span::new((), 23..132), - subject: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 28..29), - name: "a".to_string(), - }), - clauses: vec![ - ast::UntypedClause { - location: Span::new((), 39..45), - patterns: vec1![ast::Pattern::Int { - location: Span::new((), 39..40), - value: "2".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }], - guard: None, - then: expr::UntypedExpr::Int { - location: Span::new((), 44..45), - value: "3".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }, - }, - ast::UntypedClause { - location: Span::new((), 50..106), - patterns: vec1![ - ast::Pattern::Int { - location: Span::new((), 50..51), - value: "1".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }, - ast::Pattern::Int { - location: Span::new((), 54..55), - value: "4".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }, - ast::Pattern::Int { - location: Span::new((), 58..59), - value: "5".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }, - ], - guard: None, - then: expr::UntypedExpr::Sequence { - location: Span::new((), 71..100), - expressions: vec![ - expr::UntypedExpr::Assignment { - location: Span::new((), 71..86), - value: Box::new(expr::UntypedExpr::Int { - location: Span::new((), 85..86), - value: "5".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }), - pattern: ast::Pattern::Var { - location: Span::new((), 75..82), - name: "amazing".to_string(), - }, - kind: ast::AssignmentKind::Let, - annotation: None, - }, - expr::UntypedExpr::Var { - location: Span::new((), 93..100), - name: "amazing".to_string(), - }, - ], - }, - }, - ast::UntypedClause { - location: Span::new((), 111..117), - patterns: vec1![ast::Pattern::Int { - location: Span::new((), 111..112), - value: "3".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }], - guard: None, - then: expr::UntypedExpr::Int { - location: Span::new((), 116..117), - value: "9".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }, - }, - ast::UntypedClause { - location: Span::new((), 122..128), - patterns: vec1![ast::Pattern::Discard { - name: "_".to_string(), - location: Span::new((), 122..123), - }], - guard: None, - then: expr::UntypedExpr::Int { - location: Span::new((), 127..128), - value: "4".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }, - }, - ], - }, - doc: None, - location: Span::new((), 0..19), - name: "wow2".to_string(), - public: true, - return_annotation: None, - return_type: (), - end_position: 133, - })], - ) -} - -#[test] -fn anonymous_function() { - let code = indoc! {r#" + "# +); +assert_parse!( + anonymous_function, + r#" pub fn such() -> Int { let add_one = fn (a: Int) -> Int { a + 1 } 2 |> add_one } - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::Fn(Function { - can_error: true, - arguments: vec![], - body: expr::UntypedExpr::Sequence { - location: Span::new((), 25..83), - expressions: vec![ - expr::UntypedExpr::Assignment { - location: Span::new((), 25..67), - value: Box::new(expr::UntypedExpr::Fn { - location: Span::new((), 39..67), - fn_style: expr::FnStyle::Plain, - arguments: vec![ast::Arg { - arg_name: ast::ArgName::Named { - label: "a".to_string(), - name: "a".to_string(), - location: Span::new((), 43..44), - is_validator_param: false, - }, - location: Span::new((), 43..49), - annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 46..49), - module: None, - name: "Int".to_string(), - arguments: vec![], - }), - tipo: (), - }], - body: Box::new(expr::UntypedExpr::BinOp { - location: Span::new((), 60..65), - name: ast::BinOp::AddInt, - left: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 60..61), - name: "a".to_string(), - }), - right: Box::new(expr::UntypedExpr::Int { - location: Span::new((), 64..65), - value: "1".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }), - }), - return_annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 54..57), - module: None, - name: "Int".to_string(), - arguments: vec![], - }), - }), - pattern: ast::Pattern::Var { - location: Span::new((), 29..36), - name: "add_one".to_string(), - }, - kind: ast::AssignmentKind::Let, - annotation: None, - }, - expr::UntypedExpr::PipeLine { - one_liner: true, - expressions: vec1::vec1![ - expr::UntypedExpr::Int { - location: Span::new((), 71..72), - value: "2".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }, - expr::UntypedExpr::Var { - location: Span::new((), 76..83), - name: "add_one".to_string(), - }, - ], - }, - ], - }, - doc: None, - location: Span::new((), 0..20), - name: "such".to_string(), - public: true, - return_annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 17..20), - module: None, - name: "Int".to_string(), - arguments: vec![], - }), - return_type: (), - end_position: 84, - })], - ) -} - -#[test] -fn field_access() { - let code = indoc! {r#" + "# +); +assert_parse!( + field_access, + r#" fn name(user: User) { user.name } - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::Fn(Function { - can_error: true, - arguments: vec![ast::Arg { - arg_name: ast::ArgName::Named { - label: "user".to_string(), - name: "user".to_string(), - location: Span::new((), 8..12), - is_validator_param: false, - }, - location: Span::new((), 8..18), - annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 14..18), - module: None, - name: "User".to_string(), - arguments: vec![], - }), - tipo: (), - }], - body: expr::UntypedExpr::FieldAccess { - location: Span::new((), 24..33), - label: "name".to_string(), - container: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 24..28), - name: "user".to_string(), - }), - }, - doc: None, - location: Span::new((), 0..19), - name: "name".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 34, - })], - ) -} - -#[test] -fn call() { - let code = indoc! {r#" + "# +); +assert_parse!( + call, + r#" fn calls() { let x = add_one(3) @@ -1510,2174 +243,138 @@ fn call() { map_add_x([ 1, 2, 3 ]) } - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::Fn(Function { - can_error: true, - arguments: vec![], - body: expr::UntypedExpr::Sequence { - location: Span::new((), 15..108), - expressions: vec![ - expr::UntypedExpr::Assignment { - location: Span::new((), 15..33), - value: Box::new(expr::UntypedExpr::Call { - arguments: vec![ast::CallArg { - label: None, - location: Span::new((), 31..32), - value: expr::UntypedExpr::Int { - location: Span::new((), 31..32), - value: "3".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }, - }], - fun: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 23..30), - name: "add_one".to_string(), - }), - location: Span::new((), 23..33), - }), - pattern: ast::Pattern::Var { - location: Span::new((), 19..20), - name: "x".to_string(), - }, - kind: ast::AssignmentKind::Let, - annotation: None, - }, - expr::UntypedExpr::Assignment { - location: Span::new((), 37..82), - value: Box::new(expr::UntypedExpr::Fn { - location: Span::new((), 53..82), - fn_style: expr::FnStyle::Capture, - arguments: vec![ast::Arg { - arg_name: ast::ArgName::Named { - label: "_capture__0".to_string(), - name: "_capture__0".to_string(), - location: Span::new((), 0..0), - is_validator_param: false, - }, - location: Span::new((), 0..0), - annotation: None, - tipo: (), - }], - body: Box::new(expr::UntypedExpr::Call { - arguments: vec![ - ast::CallArg { - label: None, - location: Span::new((), 62..63), - value: expr::UntypedExpr::Var { - location: Span::new((), 62..63), - name: "_capture__0".to_string(), - }, - }, - ast::CallArg { - label: None, - location: Span::new((), 65..81), - value: expr::UntypedExpr::Fn { - location: Span::new((), 65..81), - fn_style: expr::FnStyle::Plain, - arguments: vec![ast::Arg { - arg_name: ast::ArgName::Named { - label: "y".to_string(), - name: "y".to_string(), - location: Span::new((), 69..70), - is_validator_param: false, - }, - location: Span::new((), 69..70), - annotation: None, - tipo: (), - }], - body: Box::new(expr::UntypedExpr::BinOp { - location: Span::new((), 74..79), - name: ast::BinOp::AddInt, - left: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 74..75), - name: "x".to_string(), - }), - right: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 78..79), - name: "y".to_string(), - }), - }), - return_annotation: None, - }, - }, - ], - fun: Box::new(expr::UntypedExpr::FieldAccess { - location: Span::new((), 53..61), - label: "map".to_string(), - container: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 53..57), - name: "list".to_string(), - }), - }), - location: Span::new((), 53..82), - }), - return_annotation: None, - }), - pattern: ast::Pattern::Var { - location: Span::new((), 41..50), - name: "map_add_x".to_string(), - }, - kind: ast::AssignmentKind::Let, - annotation: None, - }, - expr::UntypedExpr::Call { - arguments: vec![ast::CallArg { - label: None, - location: Span::new((), 96..107), - value: expr::UntypedExpr::List { - location: Span::new((), 96..107), - elements: vec![ - expr::UntypedExpr::Int { - location: Span::new((), 98..99), - value: "1".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }, - expr::UntypedExpr::Int { - location: Span::new((), 101..102), - value: "2".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }, - expr::UntypedExpr::Int { - location: Span::new((), 104..105), - value: "3".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }, - ], - tail: None, - }, - }], - fun: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 86..95), - name: "map_add_x".to_string(), - }), - location: Span::new((), 86..108), - }, - ], - }, - doc: None, - location: Span::new((), 0..10), - name: "calls".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 109, - })], - ) -} - -#[test] -fn record_update() { - let code = indoc! {r#" + "# +); +assert_parse!( + record_update, + r#" fn update_name(user: User, name: ByteArray) -> User { User { ..user, name: "Aiken", age } } - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::Fn(Function { - can_error: true, - arguments: vec![ - ast::Arg { - arg_name: ast::ArgName::Named { - label: "user".to_string(), - name: "user".to_string(), - location: Span::new((), 15..19), - is_validator_param: false, - }, - location: Span::new((), 15..25), - annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 21..25), - module: None, - name: "User".to_string(), - arguments: vec![], - }), - tipo: (), - }, - ast::Arg { - arg_name: ast::ArgName::Named { - label: "name".to_string(), - name: "name".to_string(), - location: Span::new((), 27..31), - is_validator_param: false, - }, - location: Span::new((), 27..42), - annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 33..42), - module: None, - name: "ByteArray".to_string(), - arguments: vec![], - }), - tipo: (), - }, - ], - body: expr::UntypedExpr::RecordUpdate { - location: Span::new((), 56..91), - constructor: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 56..60), - name: "User".to_string(), - }), - spread: ast::RecordUpdateSpread { - base: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 65..69), - name: "user".to_string(), - }), - location: Span::new((), 63..69), - }, - arguments: vec![ - ast::UntypedRecordUpdateArg { - label: "name".to_string(), - location: Span::new((), 71..84), - value: expr::UntypedExpr::ByteArray { - location: Span::new((), 77..84), - bytes: String::from("Aiken").into_bytes(), - preferred_format: ast::ByteArrayFormatPreference::Utf8String, - }, - }, - ast::UntypedRecordUpdateArg { - label: "age".to_string(), - location: Span::new((), 86..89), - value: expr::UntypedExpr::Var { - location: Span::new((), 86..89), - name: "age".to_string(), - }, - }, - ], - }, - doc: None, - location: Span::new((), 0..51), - name: "update_name".to_string(), - public: false, - return_annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 47..51), - module: None, - name: "User".to_string(), - arguments: vec![], - }), - return_type: (), - end_position: 92, - })], - ) -} - -#[test] -fn record_create_labeled() { - let code = indoc! {r#" + "# +); +assert_parse!( + record_create_labeled, + r#" fn create() { User { name: "Aiken", age, thing: 2 } } - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::Fn(ast::Function { - can_error: true, - arguments: vec![], - body: expr::UntypedExpr::Call { - arguments: vec![ - ast::CallArg { - label: Some("name".to_string()), - location: Span::new((), 23..36), - value: expr::UntypedExpr::ByteArray { - location: Span::new((), 29..36), - bytes: String::from("Aiken").into_bytes(), - preferred_format: ast::ByteArrayFormatPreference::Utf8String, - }, - }, - ast::CallArg { - label: Some("age".to_string()), - location: Span::new((), 38..41), - value: expr::UntypedExpr::Var { - location: Span::new((), 38..41), - name: "age".to_string(), - }, - }, - ast::CallArg { - label: Some("thing".to_string()), - location: Span::new((), 43..51), - value: expr::UntypedExpr::Int { - location: Span::new((), 50..51), - value: "2".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }, - }, - ], - fun: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 16..20), - name: "User".to_string(), - }), - location: Span::new((), 16..53), - }, - doc: None, - location: Span::new((), 0..11), - name: "create".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 54, - })], - ) -} - -#[test] -fn record_create_labeled_with_field_access() { - let code = indoc! {r#" + "# +); +assert_parse!( + record_create_labeled_with_field_access, + r#" fn create() { some_module.User { name: "Aiken", age, thing: 2 } } - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::Fn(ast::Function { - can_error: true, - arguments: vec![], - body: expr::UntypedExpr::Call { - arguments: vec![ - ast::CallArg { - label: Some("name".to_string()), - location: Span::new((), 35..48), - value: expr::UntypedExpr::ByteArray { - location: Span::new((), 41..48), - bytes: String::from("Aiken").into_bytes(), - preferred_format: ast::ByteArrayFormatPreference::Utf8String, - }, - }, - ast::CallArg { - label: Some("age".to_string()), - location: Span::new((), 50..53), - value: expr::UntypedExpr::Var { - location: Span::new((), 50..53), - name: "age".to_string(), - }, - }, - ast::CallArg { - label: Some("thing".to_string()), - location: Span::new((), 55..63), - value: expr::UntypedExpr::Int { - location: Span::new((), 62..63), - value: "2".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }, - }, - ], - fun: Box::new(expr::UntypedExpr::FieldAccess { - location: Span::new((), 16..32), - label: "User".to_string(), - container: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 16..27), - name: "some_module".to_string(), - }), - }), - location: Span::new((), 16..65), - }, - doc: None, - location: Span::new((), 0..11), - name: "create".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 66, - })], - ) -} - -#[test] -fn record_create_unlabeled() { - let code = indoc! {r#" + "# +); +assert_parse!( + cargo_create_unlabeled, + r#" fn create() { some_module.Thing(1, a) } - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::Fn(ast::Function { - can_error: true, - arguments: vec![], - body: expr::UntypedExpr::Call { - arguments: vec![ - ast::CallArg { - label: None, - location: Span::new((), 34..35), - value: expr::UntypedExpr::Int { - location: Span::new((), 34..35), - value: "1".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }, - }, - ast::CallArg { - label: None, - location: Span::new((), 37..38), - value: expr::UntypedExpr::Var { - location: Span::new((), 37..38), - name: "a".to_string(), - }, - }, - ], - fun: Box::new(expr::UntypedExpr::FieldAccess { - location: Span::new((), 16..33), - label: "Thing".to_string(), - container: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 16..27), - name: "some_module".to_string(), - }), - }), - location: Span::new((), 16..39), - }, - doc: None, - location: Span::new((), 0..11), - name: "create".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 40, - })], - ) -} - -#[test] -fn parse_tuple() { - let code = indoc! {r#" - fn foo() { - let tuple = (1, 2, 3, 4) - tuple.1st + tuple.2nd + tuple.3rd + tuple.4th - } - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::Fn(Function { - can_error: true, - arguments: vec![], - body: expr::UntypedExpr::Sequence { - location: Span::new((), 13..85), - expressions: vec![ - expr::UntypedExpr::Assignment { - location: Span::new((), 13..37), - value: Box::new(expr::UntypedExpr::Tuple { - location: Span::new((), 25..37), - elems: vec![ - expr::UntypedExpr::Int { - location: Span::new((), 26..27), - value: "1".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }, - expr::UntypedExpr::Int { - location: Span::new((), 29..30), - value: "2".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }, - expr::UntypedExpr::Int { - location: Span::new((), 32..33), - value: "3".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }, - expr::UntypedExpr::Int { - location: Span::new((), 35..36), - value: "4".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }, - ], - }), - pattern: ast::Pattern::Var { - location: Span::new((), 17..22), - name: "tuple".to_string(), - }, - kind: ast::AssignmentKind::Let, - annotation: None, - }, - expr::UntypedExpr::BinOp { - location: Span::new((), 40..85), - name: ast::BinOp::AddInt, - left: Box::new(expr::UntypedExpr::BinOp { - location: Span::new((), 40..73), - name: ast::BinOp::AddInt, - left: Box::new(expr::UntypedExpr::BinOp { - location: Span::new((), 40..61), - name: ast::BinOp::AddInt, - left: Box::new(expr::UntypedExpr::TupleIndex { - location: Span::new((), 40..49), - index: 0, - tuple: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 40..45), - name: "tuple".to_string(), - }), - }), - right: Box::new(expr::UntypedExpr::TupleIndex { - location: Span::new((), 52..61), - index: 1, - tuple: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 52..57), - name: "tuple".to_string(), - }), - }), - }), - right: Box::new(expr::UntypedExpr::TupleIndex { - location: Span::new((), 64..73), - index: 2, - tuple: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 64..69), - name: "tuple".to_string(), - }), - }), - }), - right: Box::new(expr::UntypedExpr::TupleIndex { - location: Span::new((), 76..85), - index: 3, - tuple: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 76..81), - name: "tuple".to_string(), - }), - }), - }, - ], - }, - doc: None, - location: Span::new((), 0..8), - name: "foo".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 86, - })], - ) -} - -#[test] -fn parse_tuple2() { - let code = indoc! {r#" - fn foo() { - let a = foo(14) - (a, 42) - } - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::Fn(Function { - can_error: true, - arguments: vec![], - body: expr::UntypedExpr::Sequence { - location: Span::new((), 13..38), - expressions: vec![ - expr::UntypedExpr::Assignment { - location: Span::new((), 13..28), - value: Box::new(expr::UntypedExpr::Call { - arguments: vec![ast::CallArg { - label: None, - location: Span::new((), 25..27), - value: expr::UntypedExpr::Int { - location: Span::new((), 25..27), - value: "14".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }, - }], - fun: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 21..24), - name: "foo".to_string(), - }), - location: Span::new((), 21..28), - }), - pattern: ast::Pattern::Var { - location: Span::new((), 17..18), - name: "a".to_string(), - }, - kind: ast::AssignmentKind::Let, - annotation: None, - }, - expr::UntypedExpr::Tuple { - location: Span::new((), 31..38), - elems: vec![ - expr::UntypedExpr::Var { - location: Span::new((), 32..33), - name: "a".to_string(), - }, - expr::UntypedExpr::Int { - location: Span::new((), 35..37), - value: "42".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }, - ], - }, - ], - }, - doc: None, - location: Span::new((), 0..8), - name: "foo".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 39, - })], - ); -} - -#[test] -fn large_integer_constants() { - let code = indoc! {r#" - pub const my_big_int = 999999999999999999999999 - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::ModuleConstant(ModuleConstant { - doc: None, - location: Span::new((), 0..47), - public: true, - name: "my_big_int".to_string(), - annotation: None, - value: Box::new(ast::Constant::Int { - location: Span::new((), 23..47), - value: "999999999999999999999999".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }), - tipo: (), - })], - ) -} - -#[test] -fn plain_bytearray_literals() { - let code = indoc! {r#" + "# +); +assert_parse!( + parse_tuple, + r#" + fn foo() { + let tuple = (1, 2, 3, 4) + tuple.1st + tuple.2nd + tuple.3rd + tuple.4th + } + "# +); +assert_parse!( + parse_tuple2, + r#" + fn foo() { + let a = foo(14) + (a, 42) + } + "# +); +assert_parse!( + plain_bytearray_literals, + r#" pub const my_policy_id = #[0, 170, 255] - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::ModuleConstant(ModuleConstant { - doc: None, - location: Span::new((), 0..39), - public: true, - name: "my_policy_id".to_string(), - annotation: None, - value: Box::new(Constant::ByteArray { - location: Span::new((), 25..39), - bytes: vec![0, 170, 255], - preferred_format: ast::ByteArrayFormatPreference::ArrayOfBytes(Base::Decimal { - numeric_underscore: false, - }), - }), - tipo: (), - })], - ) -} - -#[test] -fn base16_bytearray_literals() { - let code = indoc! {r#" + "# +); +assert_parse!( + base16_bytearray_literals, + r#" pub const my_policy_id = #"00aaff" pub fn foo() { my_policy_id == #"00aaff" } - "#}; - - assert_definitions( - code, - vec![ - ast::UntypedDefinition::ModuleConstant(ModuleConstant { - doc: None, - location: Span::new((), 0..34), - public: true, - name: "my_policy_id".to_string(), - annotation: None, - value: Box::new(Constant::ByteArray { - location: Span::new((), 25..34), - bytes: vec![0, 170, 255], - preferred_format: ast::ByteArrayFormatPreference::HexadecimalString, - }), - tipo: (), - }), - ast::UntypedDefinition::Fn(Function { - can_error: true, - arguments: vec![], - body: expr::UntypedExpr::BinOp { - location: Span::new((), 55..80), - name: ast::BinOp::Eq, - left: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 55..67), - name: "my_policy_id".to_string(), - }), - right: Box::new(expr::UntypedExpr::ByteArray { - location: Span::new((), 71..80), - bytes: vec![0, 170, 255], - preferred_format: ast::ByteArrayFormatPreference::HexadecimalString, - }), - }, - doc: None, - location: Span::new((), 36..48), - name: "foo".to_string(), - public: true, - return_annotation: None, - return_type: (), - end_position: 81, - }), - ], - ) -} - -#[test] -fn function_def() { - let code = indoc! {r#" - fn foo() {} - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::Fn(Function { - can_error: true, - doc: None, - arguments: vec![], - body: expr::UntypedExpr::Trace { - kind: ast::TraceKind::Todo, - location: Span::new((), 0..11), - text: Box::new(expr::UntypedExpr::String { - value: "aiken::todo".to_string(), - location: Span::new((), 0..11), - }), - then: Box::new(expr::UntypedExpr::ErrorTerm { - location: Span::new((), 0..11), - }), - }, - location: Span::new((), 0..8), - name: "foo".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 10, - })], - ) -} - -#[test] -fn function_invoke() { - let code = indoc! {r#" - fn foo() { + "# +); +assert_parse!( + function_def, + r#" + fn foo() {} + "# +); +assert_parse!( + function_invoke, + r#" + fn foo() { let a = bar(42) - } - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::Fn(Function { - can_error: true, - doc: None, - arguments: vec![], - body: expr::UntypedExpr::Assignment { - location: Span::new((), 13..28), - kind: ast::AssignmentKind::Let, - annotation: None, - pattern: ast::Pattern::Var { - location: Span::new((), 17..18), - name: "a".to_string(), - }, - value: Box::new(expr::UntypedExpr::Call { - location: Span::new((), 21..28), - fun: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 21..24), - name: "bar".to_string(), - }), - arguments: vec![ast::CallArg { - label: None, - location: Span::new((), 25..27), - value: expr::UntypedExpr::Int { - location: Span::new((), 25..27), - value: "42".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }, - }], - }), - }, - location: Span::new((), 0..8), - name: "foo".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 29, - })], - ) -} - -#[test] -fn function_ambiguous_sequence() { - let code = indoc! {r#" - fn foo_1() { - let a = bar - (40) - } - - fn foo_2() { - let a = bar - {40} - } - - fn foo_3() { - let a = (40+2) - } - - fn foo_4() { - let a = bar(42) - (a + 14) * 42 - } - "#}; - - assert_definitions( - code, - vec![ - ast::UntypedDefinition::Fn(Function { - can_error: true, - arguments: vec![], - body: expr::UntypedExpr::Sequence { - location: Span::new((), 15..32), - expressions: vec![ - expr::UntypedExpr::Assignment { - location: Span::new((), 15..26), - value: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 23..26), - name: "bar".to_string(), - }), - pattern: ast::Pattern::Var { - location: Span::new((), 19..20), - name: "a".to_string(), - }, - kind: ast::AssignmentKind::Let, - annotation: None, - }, - expr::UntypedExpr::Int { - location: Span::new((), 30..32), - value: "40".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }, - ], - }, - doc: None, - location: Span::new((), 0..10), - name: "foo_1".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 34, - }), - ast::UntypedDefinition::Fn(Function { - can_error: true, - arguments: vec![], - body: expr::UntypedExpr::Sequence { - location: Span::new((), 52..69), - expressions: vec![ - expr::UntypedExpr::Assignment { - location: Span::new((), 52..63), - value: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 60..63), - name: "bar".to_string(), - }), - pattern: ast::Pattern::Var { - location: Span::new((), 56..57), - name: "a".to_string(), - }, - kind: ast::AssignmentKind::Let, - annotation: None, - }, - expr::UntypedExpr::Int { - location: Span::new((), 67..69), - value: "40".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }, - ], - }, - doc: None, - location: Span::new((), 37..47), - name: "foo_2".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 71, - }), - ast::UntypedDefinition::Fn(Function { - can_error: true, - arguments: vec![], - body: expr::UntypedExpr::Assignment { - location: Span::new((), 89..103), - value: Box::new(expr::UntypedExpr::BinOp { - location: Span::new((), 98..102), - name: ast::BinOp::AddInt, - left: Box::new(expr::UntypedExpr::Int { - location: Span::new((), 98..100), - value: "40".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }), - right: Box::new(expr::UntypedExpr::Int { - location: Span::new((), 101..102), - value: "2".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }), - }), - pattern: ast::Pattern::Var { - location: Span::new((), 93..94), - name: "a".to_string(), - }, - kind: ast::AssignmentKind::Let, - annotation: None, - }, - doc: None, - location: Span::new((), 74..84), - name: "foo_3".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 104, - }), - ast::UntypedDefinition::Fn(Function { - can_error: true, - arguments: vec![], - body: expr::UntypedExpr::Sequence { - location: Span::new((), 122..153), - expressions: vec![ - expr::UntypedExpr::Assignment { - location: Span::new((), 122..137), - value: Box::new(expr::UntypedExpr::Call { - arguments: vec![ast::CallArg { - label: None, - location: Span::new((), 134..136), - value: expr::UntypedExpr::Int { - location: Span::new((), 134..136), - value: "42".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }, - }], - fun: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 130..133), - name: "bar".to_string(), - }), - location: Span::new((), 130..137), - }), - pattern: ast::Pattern::Var { - location: Span::new((), 126..127), - name: "a".to_string(), - }, - kind: ast::AssignmentKind::Let, - annotation: None, - }, - expr::UntypedExpr::BinOp { - location: Span::new((), 141..153), - name: ast::BinOp::MultInt, - left: Box::new(expr::UntypedExpr::BinOp { - location: Span::new((), 141..147), - name: ast::BinOp::AddInt, - left: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 141..142), - name: "a".to_string(), - }), - right: Box::new(expr::UntypedExpr::Int { - location: Span::new((), 145..147), - value: "14".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }), - }), - right: Box::new(expr::UntypedExpr::Int { - location: Span::new((), 151..153), - value: "42".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }), - }, - ], - }, - doc: None, - location: Span::new((), 107..117), - name: "foo_4".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 154, - }), - ], - ) -} - -#[test] -fn tuple_type_alias() { - let code = indoc! {r#" - type RoyaltyToken = - (PolicyId, AssetName) - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::TypeAlias(TypeAlias { - alias: "RoyaltyToken".to_string(), - annotation: ast::Annotation::Tuple { - location: Span::new((), 22..43), - elems: vec![ - ast::Annotation::Constructor { - location: Span::new((), 23..31), - module: None, - name: "PolicyId".to_string(), - arguments: vec![], - }, - ast::Annotation::Constructor { - location: Span::new((), 33..42), - module: None, - name: "AssetName".to_string(), - arguments: vec![], - }, - ], - }, - doc: None, - location: Span::new((), 0..43), - parameters: vec![], - public: false, - tipo: (), - })], - ) -} - -#[test] -fn tuple_pattern() { - let code = indoc! {r#" - fn foo() { - when a is { - (u, dic) -> True - } - } - "#}; - - assert_definitions( - code, - vec![ast::UntypedDefinition::Fn(Function { - can_error: true, - arguments: vec![], - body: expr::UntypedExpr::When { - location: Span::new((), 13..49), - subject: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 18..19), - name: "a".to_string(), - }), - clauses: vec![ast::UntypedClause { - location: Span::new((), 29..45), - patterns: vec1![ast::Pattern::Tuple { - location: Span::new((), 29..37), - elems: vec![ - ast::Pattern::Var { - location: Span::new((), 30..31), - name: "u".to_string(), - }, - ast::Pattern::Var { - location: Span::new((), 33..36), - name: "dic".to_string(), - }, - ], - }], - guard: None, - then: expr::UntypedExpr::Var { - location: Span::new((), 41..45), - name: "True".to_string(), - }, - }], - }, - doc: None, - location: Span::new((), 0..8), - name: "foo".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 50, - })], - ); -} - -#[test] -fn subtraction_vs_negate() { - let code = indoc! {r#" - fn foo() { - (1-1) == 0 - let x = -2 - bar()-4 - bar(-1) - 42 - } - "#}; - assert_definitions( - code, - vec![ast::Definition::Fn(Function { - can_error: true, - arguments: vec![], - body: expr::UntypedExpr::Sequence { - location: Span::new((), 14..61), - expressions: vec![ - expr::UntypedExpr::BinOp { - location: Span::new((), 14..23), - name: ast::BinOp::Eq, - left: Box::new(expr::UntypedExpr::BinOp { - location: Span::new((), 14..17), - name: ast::BinOp::SubInt, - left: Box::new(expr::UntypedExpr::Int { - location: Span::new((), 14..15), - value: "1".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }), - right: Box::new(expr::UntypedExpr::Int { - location: Span::new((), 16..17), - value: "1".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }), - }), - right: Box::new(expr::UntypedExpr::Int { - location: Span::new((), 22..23), - value: "0".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }), - }, - expr::UntypedExpr::Assignment { - location: Span::new((), 26..36), - value: Box::new(expr::UntypedExpr::UnOp { - op: ast::UnOp::Negate, - location: Span::new((), 34..36), - value: Box::new(expr::UntypedExpr::Int { - location: Span::new((), 35..36), - value: "2".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }), - }), - pattern: ast::Pattern::Var { - location: Span::new((), 30..31), - name: "x".to_string(), - }, - kind: ast::AssignmentKind::Let, - annotation: None, - }, - expr::UntypedExpr::BinOp { - location: Span::new((), 39..46), - name: ast::BinOp::SubInt, - left: Box::new(expr::UntypedExpr::Call { - arguments: vec![], - fun: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 39..42), - name: "bar".to_string(), - }), - location: Span::new((), 39..44), - }), - right: Box::new(expr::UntypedExpr::Int { - location: Span::new((), 45..46), - value: "4".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }), - }, - expr::UntypedExpr::BinOp { - location: Span::new((), 49..61), - name: ast::BinOp::SubInt, - left: Box::new(expr::UntypedExpr::Call { - arguments: vec![ast::CallArg { - label: None, - location: Span::new((), 53..55), - value: expr::UntypedExpr::UnOp { - op: ast::UnOp::Negate, - location: Span::new((), 53..55), - value: Box::new(expr::UntypedExpr::Int { - location: Span::new((), 54..55), - value: "1".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }), - }, - }], - fun: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 49..52), - name: "bar".to_string(), - }), - location: Span::new((), 49..56), - }), - right: Box::new(expr::UntypedExpr::Int { - location: Span::new((), 59..61), - value: "42".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }), - }, - ], - }, - doc: None, - location: Span::new((), 0..8), - name: "foo".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 62, - })], - ); -} - -#[test] -fn clause_guards() { - let code = indoc! {r#" - fn foo() { - when a is { - _ if 42 -> Void - _ if bar -> Void - _ if True -> Void - _ if a || b && c -> Void - _ if (a || b) && c -> Void - _ if a <= 42 || b > 14 || "str" -> Void - _ if a == 14 && !b -> Void - _ if !!True -> Void - } - } - "#}; - assert_definitions( - code, - vec![ast::Definition::Fn(Function { - can_error: true, - arguments: vec![], - body: expr::UntypedExpr::When { - location: Span::new((), 13..250), - subject: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 18..19), - name: "a".to_string(), - }), - clauses: vec![ - ast::UntypedClause { - location: Span::new((), 29..44), - patterns: vec1![ast::Pattern::Discard { - name: "_".to_string(), - location: Span::new((), 29..30), - }], - guard: Some(ast::UntypedClauseGuard::Constant(ast::Constant::Int { - location: Span::new((), 34..36), - value: "42".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - })), - then: expr::UntypedExpr::Var { - location: Span::new((), 40..44), - name: "Void".to_string(), - }, - }, - ast::UntypedClause { - location: Span::new((), 49..65), - patterns: vec1![ast::Pattern::Discard { - name: "_".to_string(), - location: Span::new((), 49..50), - }], - guard: Some(ast::UntypedClauseGuard::Var { - location: Span::new((), 54..57), - name: "bar".to_string(), - tipo: (), - }), - then: expr::UntypedExpr::Var { - location: Span::new((), 61..65), - name: "Void".to_string(), - }, - }, - ast::UntypedClause { - location: Span::new((), 70..87), - patterns: vec1![ast::Pattern::Discard { - name: "_".to_string(), - location: Span::new((), 70..71), - }], - guard: Some(ast::UntypedClauseGuard::Var { - location: Span::new((), 75..79), - tipo: (), - name: "True".to_string(), - }), - then: expr::UntypedExpr::Var { - location: Span::new((), 83..87), - name: "Void".to_string(), - }, - }, - ast::UntypedClause { - location: Span::new((), 92..116), - patterns: vec1![ast::Pattern::Discard { - name: "_".to_string(), - location: Span::new((), 92..93), - }], - guard: Some(ast::UntypedClauseGuard::Or { - location: Span::new((), 97..108), - left: Box::new(ast::UntypedClauseGuard::Var { - location: Span::new((), 97..98), - name: "a".to_string(), - tipo: (), - }), - right: Box::new(ast::UntypedClauseGuard::And { - location: Span::new((), 102..108), - left: Box::new(ast::UntypedClauseGuard::Var { - location: Span::new((), 102..103), - name: "b".to_string(), - tipo: (), - }), - right: Box::new(ast::UntypedClauseGuard::Var { - location: Span::new((), 107..108), - name: "c".to_string(), - tipo: (), - }), - }), - }), - then: expr::UntypedExpr::Var { - location: Span::new((), 112..116), - name: "Void".to_string(), - }, - }, - ast::UntypedClause { - location: Span::new((), 121..147), - patterns: vec1![ast::Pattern::Discard { - name: "_".to_string(), - location: Span::new((), 121..122), - }], - guard: Some(ast::UntypedClauseGuard::And { - location: Span::new((), 127..139), - left: Box::new(ast::UntypedClauseGuard::Or { - location: Span::new((), 127..133), - left: Box::new(ast::UntypedClauseGuard::Var { - location: Span::new((), 127..128), - name: "a".to_string(), - tipo: (), - }), - right: Box::new(ast::UntypedClauseGuard::Var { - location: Span::new((), 132..133), - name: "b".to_string(), - tipo: (), - }), - }), - right: Box::new(ast::UntypedClauseGuard::Var { - location: Span::new((), 138..139), - name: "c".to_string(), - tipo: (), - }), - }), - then: expr::UntypedExpr::Var { - location: Span::new((), 143..147), - name: "Void".to_string(), - }, - }, - ast::UntypedClause { - location: Span::new((), 152..191), - patterns: vec1![ast::Pattern::Discard { - name: "_".to_string(), - location: Span::new((), 152..153), - }], - guard: Some(ast::UntypedClauseGuard::Or { - location: Span::new((), 157..183), - left: Box::new(ast::UntypedClauseGuard::Or { - location: Span::new((), 157..174), - left: Box::new(ast::UntypedClauseGuard::LtEqInt { - location: Span::new((), 157..164), - left: Box::new(ast::UntypedClauseGuard::Var { - location: Span::new((), 157..158), - name: "a".to_string(), - tipo: (), - }), - right: Box::new(ast::UntypedClauseGuard::Constant( - ast::Constant::Int { - location: Span::new((), 162..164), - value: "42".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }, - )), - }), - right: Box::new(ast::UntypedClauseGuard::GtInt { - location: Span::new((), 168..174), - left: Box::new(ast::UntypedClauseGuard::Var { - location: Span::new((), 168..169), - name: "b".to_string(), - tipo: (), - }), - right: Box::new(ast::UntypedClauseGuard::Constant( - ast::Constant::Int { - location: Span::new((), 172..174), - value: "14".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }, - )), - }), - }), - right: Box::new(ast::UntypedClauseGuard::Constant( - ast::Constant::ByteArray { - location: Span::new((), 178..183), - bytes: String::from("str").into_bytes(), - preferred_format: ast::ByteArrayFormatPreference::Utf8String, - }, - )), - }), - then: expr::UntypedExpr::Var { - location: Span::new((), 187..191), - name: "Void".to_string(), - }, - }, - ast::UntypedClause { - location: Span::new((), 196..222), - patterns: vec1![ast::Pattern::Discard { - name: "_".to_string(), - location: Span::new((), 196..197), - }], - guard: Some(ast::UntypedClauseGuard::And { - location: Span::new((), 201..214), - left: Box::new(ast::UntypedClauseGuard::Equals { - location: Span::new((), 201..208), - left: Box::new(ast::UntypedClauseGuard::Var { - location: Span::new((), 201..202), - name: "a".to_string(), - tipo: (), - }), - right: Box::new(ast::UntypedClauseGuard::Constant( - ast::Constant::Int { - location: Span::new((), 206..208), - value: "14".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }, - )), - }), - right: Box::new(ast::UntypedClauseGuard::Not { - location: Span::new((), 212..214), - value: Box::new(ast::UntypedClauseGuard::Var { - location: Span::new((), 213..214), - name: "b".to_string(), - tipo: (), - }), - }), - }), - then: expr::UntypedExpr::Var { - location: Span::new((), 218..222), - name: "Void".to_string(), - }, - }, - ast::UntypedClause { - location: Span::new((), 227..246), - patterns: vec1![ast::Pattern::Discard { - name: "_".to_string(), - location: Span::new((), 227..228), - }], - guard: Some(ast::UntypedClauseGuard::Not { - location: Span::new((), 232..238), - value: Box::new(ast::UntypedClauseGuard::Not { - location: Span::new((), 233..238), - value: Box::new(ast::UntypedClauseGuard::Var { - location: Span::new((), 234..238), - tipo: (), - name: "True".to_string(), - }), - }), - }), - then: expr::UntypedExpr::Var { - location: Span::new((), 242..246), - name: "Void".to_string(), - }, - }, - ], - }, - doc: None, - location: Span::new((), 0..8), - name: "foo".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 251, - })], - ); -} - -#[test] -fn scope_logical_expression() { - let code = indoc! {r#" - fn foo() { - let x = !(a && b) - let y = a || b && c || d - x - } - "#}; - assert_definitions( - code, - vec![ast::Definition::Fn(Function { - can_error: true, - arguments: vec![], - body: expr::UntypedExpr::Sequence { - location: Span::new((), 13..61), - expressions: vec![ - expr::UntypedExpr::Assignment { - location: Span::new((), 13..30), - value: Box::new(expr::UntypedExpr::UnOp { - op: ast::UnOp::Not, - location: Span::new((), 21..29), - value: Box::new(expr::UntypedExpr::BinOp { - location: Span::new((), 23..29), - name: ast::BinOp::And, - left: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 23..24), - name: "a".to_string(), - }), - right: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 28..29), - name: "b".to_string(), - }), - }), - }), - pattern: ast::Pattern::Var { - location: Span::new((), 17..18), - name: "x".to_string(), - }, - kind: ast::AssignmentKind::Let, - annotation: None, - }, - expr::UntypedExpr::Assignment { - location: Span::new((), 33..57), - value: Box::new(expr::UntypedExpr::BinOp { - location: Span::new((), 41..57), - name: ast::BinOp::Or, - left: Box::new(expr::UntypedExpr::BinOp { - location: Span::new((), 41..52), - name: ast::BinOp::Or, - left: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 41..42), - name: "a".to_string(), - }), - right: Box::new(expr::UntypedExpr::BinOp { - location: Span::new((), 46..52), - name: ast::BinOp::And, - left: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 46..47), - name: "b".to_string(), - }), - right: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 51..52), - name: "c".to_string(), - }), - }), - }), - right: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 56..57), - name: "d".to_string(), - }), - }), - pattern: ast::Pattern::Var { - location: Span::new((), 37..38), - name: "y".to_string(), - }, - kind: ast::AssignmentKind::Let, - annotation: None, - }, - expr::UntypedExpr::Var { - location: Span::new((), 60..61), - name: "x".to_string(), - }, - ], - }, - doc: None, - location: Span::new((), 0..8), - name: "foo".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 62, - })], - ) -} - -#[test] -fn trace_expressions() { - let code = indoc! {r#" - fn foo() { - let msg1 = @"FOO" - trace @"INLINE" - trace msg1 - trace string.concat(msg1, @"BAR") - trace ( 14 + 42 * 1337 ) - Void - } - "#}; - assert_definitions( - code, - vec![ast::Definition::Fn(Function { - can_error: true, - arguments: vec![], - body: expr::UntypedExpr::Sequence { - location: Span::new((), 13..131), - expressions: vec![ - expr::UntypedExpr::Assignment { - location: Span::new((), 13..30), - value: Box::new(expr::UntypedExpr::String { - location: Span::new((), 24..30), - value: "FOO".to_string(), - }), - pattern: ast::Pattern::Var { - location: Span::new((), 17..21), - name: "msg1".to_string(), - }, - kind: ast::AssignmentKind::Let, - annotation: None, - }, - expr::UntypedExpr::Trace { - kind: ast::TraceKind::Trace, - location: Span::new((), 33..131), - then: Box::new(expr::UntypedExpr::Trace { - kind: ast::TraceKind::Trace, - location: Span::new((), 51..131), - then: Box::new(expr::UntypedExpr::Trace { - kind: ast::TraceKind::Trace, - location: Span::new((), 64..131), - then: Box::new(expr::UntypedExpr::Trace { - kind: ast::TraceKind::Trace, - location: Span::new((), 100..131), - then: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 127..131), - name: "Void".to_string(), - }), - text: Box::new(expr::UntypedExpr::BinOp { - location: Span::new((), 108..122), - name: ast::BinOp::AddInt, - left: Box::new(expr::UntypedExpr::Int { - location: Span::new((), 108..110), - value: "14".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }), - right: Box::new(expr::UntypedExpr::BinOp { - location: Span::new((), 113..122), - name: ast::BinOp::MultInt, - left: Box::new(expr::UntypedExpr::Int { - location: Span::new((), 113..115), - value: "42".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }), - right: Box::new(expr::UntypedExpr::Int { - location: Span::new((), 118..122), - value: "1337".to_string(), - base: Base::Decimal { - numeric_underscore: false, - }, - }), - }), - }), - }), - text: Box::new(expr::UntypedExpr::Call { - arguments: vec![ - ast::CallArg { - label: None, - location: Span::new((), 84..88), - value: expr::UntypedExpr::Var { - location: Span::new((), 84..88), - name: "msg1".to_string(), - }, - }, - ast::CallArg { - label: None, - location: Span::new((), 90..96), - value: expr::UntypedExpr::String { - location: Span::new((), 90..96), - value: "BAR".to_string(), - }, - }, - ], - fun: Box::new(expr::UntypedExpr::FieldAccess { - location: Span::new((), 70..83), - label: "concat".to_string(), - container: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 70..76), - name: "string".to_string(), - }), - }), - location: Span::new((), 70..97), - }), - }), - text: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 57..61), - name: "msg1".to_string(), - }), - }), - text: Box::new(expr::UntypedExpr::String { - location: Span::new((), 39..48), - value: "INLINE".to_string(), - }), - }, - ], - }, - doc: None, - location: Span::new((), 0..8), - name: "foo".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 132, - })], - ) -} - -#[test] -fn parse_keyword_error() { - let code = indoc! {r#" - fn foo() { - error @"not implemented" - } - - fn bar() { - when x is { - Something -> Void - _ -> error - } - } - "#}; - assert_definitions( - code, - vec![ - ast::Definition::Fn(Function { - can_error: true, - arguments: vec![], - body: expr::UntypedExpr::Trace { - kind: ast::TraceKind::Error, - location: Span::new((), 13..37), - then: Box::new(expr::UntypedExpr::ErrorTerm { - location: Span::new((), 13..37), - }), - text: Box::new(expr::UntypedExpr::String { - location: Span::new((), 19..37), - value: "not implemented".to_string(), - }), - }, - doc: None, - location: Span::new((), 0..8), - name: "foo".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 38, - }), - ast::Definition::Fn(Function { - can_error: true, - arguments: vec![], - body: expr::UntypedExpr::When { - location: Span::new((), 54..110), - subject: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 59..60), - name: "x".to_string(), - }), - clauses: vec![ - ast::UntypedClause { - location: Span::new((), 72..89), - patterns: vec1![ast::Pattern::Constructor { - is_record: false, - location: Span::new((), 72..81), - name: "Something".to_string(), - arguments: vec![], - module: None, - constructor: (), - with_spread: false, - tipo: (), - }], - guard: None, - then: expr::UntypedExpr::Var { - location: Span::new((), 85..89), - name: "Void".to_string(), - }, - }, - ast::UntypedClause { - location: Span::new((), 96..106), - patterns: vec1![ast::Pattern::Discard { - name: "_".to_string(), - location: Span::new((), 96..97), - }], - guard: None, - then: expr::UntypedExpr::Trace { - kind: ast::TraceKind::Error, - location: Span::new((), 101..106), - then: Box::new(expr::UntypedExpr::ErrorTerm { - location: Span::new((), 101..106), - }), - text: Box::new(expr::UntypedExpr::String { - location: Span::new((), 101..106), - value: "aiken::error".to_string(), - }), - }, - }, - ], - }, - doc: None, - location: Span::new((), 41..49), - name: "bar".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 111, - }), - ], - ) -} - -#[test] -fn parse_keyword_todo() { - let code = indoc! {r#" - fn foo() { - todo @"not implemented" - } - - fn bar() { - when x is { - Foo -> todo - Bar -> True - _ -> False - } - } - "#}; - assert_definitions( - code, - vec![ - ast::Definition::Fn(Function { - can_error: true, - arguments: vec![], - body: expr::UntypedExpr::Trace { - kind: ast::TraceKind::Todo, - location: Span::new((), 13..36), - then: Box::new(expr::UntypedExpr::ErrorTerm { - location: Span::new((), 13..36), - }), - text: Box::new(expr::UntypedExpr::String { - location: Span::new((), 18..36), - value: "not implemented".to_string(), - }), - }, - doc: None, - location: Span::new((), 0..8), - name: "foo".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 37, - }), - ast::Definition::Fn(Function { - can_error: true, - arguments: vec![], - body: expr::UntypedExpr::When { - location: Span::new((), 53..121), - subject: Box::new(expr::UntypedExpr::Var { - location: Span::new((), 58..59), - name: "x".to_string(), - }), - clauses: vec![ - ast::UntypedClause { - location: Span::new((), 71..82), - patterns: vec1![ast::Pattern::Constructor { - is_record: false, - location: Span::new((), 71..74), - name: "Foo".to_string(), - arguments: vec![], - module: None, - constructor: (), - with_spread: false, - tipo: (), - }], - guard: None, - then: expr::UntypedExpr::Trace { - kind: ast::TraceKind::Todo, - location: Span::new((), 78..82), - then: Box::new(expr::UntypedExpr::ErrorTerm { - location: Span::new((), 78..82), - }), - text: Box::new(expr::UntypedExpr::String { - location: Span::new((), 78..82), - value: "aiken::todo".to_string(), - }), - }, - }, - ast::UntypedClause { - location: Span::new((), 89..100), - patterns: vec1![ast::Pattern::Constructor { - is_record: false, - location: Span::new((), 89..92), - name: "Bar".to_string(), - arguments: vec![], - module: None, - constructor: (), - with_spread: false, - tipo: (), - }], - guard: None, - then: expr::UntypedExpr::Var { - location: Span::new((), 96..100), - name: "True".to_string(), - }, - }, - ast::UntypedClause { - location: Span::new((), 107..117), - patterns: vec1![ast::Pattern::Discard { - name: "_".to_string(), - location: Span::new((), 107..108), - }], - guard: None, - then: expr::UntypedExpr::Var { - location: Span::new((), 112..117), - name: "False".to_string(), - }, - }, - ], - }, - doc: None, - location: Span::new((), 40..48), - name: "bar".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 122, - }), - ], - ) -} - -#[test] -fn brackets_followed_by_parenthesis() { - fn assert_sequence(code: &str) { - let (module, _extra) = parser::module(code, ast::ModuleKind::Validator).unwrap(); - assert!( - matches!( - module.definitions[..], - [ast::Definition::Test(Function { - body: expr::UntypedExpr::Sequence { .. }, - .. - })] - ), - "{}", - code.to_string() - ); - } - - assert_sequence(indoc! {r#" - test foo () { - let a = [] - (x |> y) == [] - } - "#}); - - assert_sequence(indoc! {r#" - test foo () { - let a = [] - (x |> y) == [] - } - "#}); - - assert_sequence(indoc! {r#" - test foo () { - let a = [] - // foo - (x |> y) == [] } - "#}); -} + "# +); +assert_parse!( + function_ambiguous_sequence, + r#" + fn foo_1() { + let a = bar + (40) + } -#[test] -fn int_parsing_hex() { - let code = indoc! {r#" - fn foo() { - let i = 0xff - } - "#}; - assert_definitions( - code, - vec![ast::Definition::Fn(Function { - arguments: vec![], - body: expr::UntypedExpr::Assignment { - location: Span::new((), 13..25), - value: Box::new(expr::UntypedExpr::Int { - location: Span::new((), 21..25), - value: "255".to_string(), - base: Base::Hexadecimal, - }), - pattern: ast::Pattern::Var { - location: Span::new((), 17..18), - name: "i".to_string(), - }, - kind: ast::AssignmentKind::Let, - annotation: None, - }, - doc: None, - location: Span::new((), 0..8), - name: "foo".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 26, - can_error: true, - })], - ) -} + fn foo_2() { + let a = bar + {40} + } -#[test] -fn int_parsing_hex_bytes() { - let code = indoc! {r#" + fn foo_3() { + let a = (40+2) + } + + fn foo_4() { + let a = bar(42) + (a + 14) * 42 + } + "# +); +assert_parse!( + tuple_type_alias, + r#" + type RoyaltyToken = (PolicyId, AssetName) + "# +); +assert_parse!( + int_parsing_hex_bytes, + r#" fn foo() { #[ 0x01, 0xa2, 0x03 ] } - "#}; - assert_definitions( - code, - vec![ast::Definition::Fn(Function { - arguments: vec![], - body: expr::UntypedExpr::ByteArray { - location: Span::new((), 13..34), - bytes: vec![1, 162, 3], - preferred_format: ast::ByteArrayFormatPreference::ArrayOfBytes(Base::Hexadecimal), - }, - doc: None, - location: Span::new((), 0..8), - name: "foo".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 35, - can_error: true, - })], - ) -} - -#[test] -fn int_parsing_numeric_underscore() { - let code = indoc! {r#" + "# +); +assert_parse!( + test_parsing_numeric_underscore, + r#" fn foo() { let i = 1_234_567 let j = 1_000_000 let k = -10_000 } - "#}; - assert_definitions( - code, - vec![ast::Definition::Fn(Function { - arguments: vec![], - body: expr::UntypedExpr::Sequence { - location: Span::new((), 17..76), - expressions: vec![ - expr::UntypedExpr::Assignment { - location: Span::new((), 17..34), - value: Box::new(expr::UntypedExpr::Int { - location: Span::new((), 25..34), - value: "1234567".to_string(), - base: Base::Decimal { - numeric_underscore: true, - }, - }), - pattern: ast::Pattern::Var { - location: Span::new((), 21..22), - name: "i".to_string(), - }, - kind: ast::AssignmentKind::Let, - annotation: None, - }, - expr::UntypedExpr::Assignment { - location: Span::new((), 39..56), - value: Box::new(expr::UntypedExpr::Int { - location: Span::new((), 47..56), - value: "1000000".to_string(), - base: Base::Decimal { - numeric_underscore: true, - }, - }), - pattern: ast::Pattern::Var { - location: Span::new((), 43..44), - name: "j".to_string(), - }, - kind: ast::AssignmentKind::Let, - annotation: None, - }, - expr::UntypedExpr::Assignment { - location: Span::new((), 61..76), - value: Box::new(expr::UntypedExpr::UnOp { - op: ast::UnOp::Negate, - location: Span::new((), 69..76), - value: Box::new(expr::UntypedExpr::Int { - location: Span::new((), 70..76), - value: "10000".to_string(), - base: Base::Decimal { - numeric_underscore: true, - }, - }), - }), - pattern: ast::Pattern::Var { - location: Span::new((), 65..66), - name: "k".to_string(), - }, - kind: ast::AssignmentKind::Let, - annotation: None, - }, - ], - }, - doc: None, - location: Span::new((), 2..10), - name: "foo".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 77, - can_error: true, - })], - ) -} - -#[test] -fn first_class_binop() { - use ast::{Arg, ArgName::*, BinOp::*, CallArg}; - use expr::UntypedExpr::*; - - let code = indoc! {r#" + "# +); +assert_parse!( + first_class_binop, + r#" fn foo() { compare_with(a, >, b) compare_with(a, >=, b) @@ -3693,1210 +390,29 @@ fn first_class_binop() { compute_with(a, *, b) compute_with(a, %, b) } - "#}; + "# +); - assert_definitions( - code, - vec![ast::Definition::Fn(Function { - arguments: vec![], - body: Sequence { - location: Span::new((), 13..328), - expressions: vec![ - Call { - arguments: vec![ - ast::CallArg { - label: None, - location: Span::new((), 26..27), - value: Var { - location: Span::new((), 26..27), - name: "a".to_string(), - }, - }, - ast::CallArg { - label: None, - location: Span::new((), 29..30), - value: Fn { - location: Span::new((), 29..30), - fn_style: expr::FnStyle::BinOp(ast::BinOp::GtInt), - arguments: vec![ - Arg { - arg_name: Named { - name: "left".to_string(), - label: "left".to_string(), - location: Span::new((), 29..30), - is_validator_param: false, - }, - location: Span::new((), 29..30), - annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 29..30), - module: None, - name: "Int".to_string(), - arguments: vec![], - }), - tipo: (), - }, - Arg { - arg_name: Named { - name: "right".to_string(), - label: "right".to_string(), - location: Span::new((), 29..30), - is_validator_param: false, - }, - location: Span::new((), 29..30), - annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 29..30), - module: None, - name: "Int".to_string(), - arguments: vec![], - }), - tipo: (), - }, - ], - body: Box::new(BinOp { - location: Span::new((), 29..30), - name: GtInt, - left: Box::new(Var { - location: Span::new((), 29..30), - name: "left".to_string(), - }), - right: Box::new(Var { - location: Span::new((), 29..30), - name: "right".to_string(), - }), - }), - return_annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 29..30), - module: None, - name: "Bool".to_string(), - arguments: vec![], - }), - }, - }, - CallArg { - label: None, - location: Span::new((), 32..33), - value: Var { - location: Span::new((), 32..33), - name: "b".to_string(), - }, - }, - ], - fun: Box::new(Var { - location: Span::new((), 13..25), - name: "compare_with".to_string(), - }), - location: Span::new((), 13..34), - }, - Call { - arguments: vec![ - ast::CallArg { - label: None, - location: Span::new((), 50..51), - value: Var { - location: Span::new((), 50..51), - name: "a".to_string(), - }, - }, - ast::CallArg { - label: None, - location: Span::new((), 53..55), - value: Fn { - location: Span::new((), 53..55), - fn_style: expr::FnStyle::BinOp(GtEqInt), - arguments: vec![ - Arg { - arg_name: Named { - name: "left".to_string(), - label: "left".to_string(), - location: Span::new((), 53..55), - is_validator_param: false, - }, - location: Span::new((), 53..55), - annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 53..55), - module: None, - name: "Int".to_string(), - arguments: vec![], - }), - tipo: (), - }, - Arg { - arg_name: Named { - name: "right".to_string(), - label: "right".to_string(), - location: Span::new((), 53..55), - is_validator_param: false, - }, - location: Span::new((), 53..55), - annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 53..55), - module: None, - name: "Int".to_string(), - arguments: vec![], - }), - tipo: (), - }, - ], - body: Box::new(BinOp { - location: Span::new((), 53..55), - name: GtEqInt, - left: Box::new(Var { - location: Span::new((), 53..55), - name: "left".to_string(), - }), - right: Box::new(Var { - location: Span::new((), 53..55), - name: "right".to_string(), - }), - }), - return_annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 53..55), - module: None, - name: "Bool".to_string(), - arguments: vec![], - }), - }, - }, - ast::CallArg { - label: None, - location: Span::new((), 57..58), - value: Var { - location: Span::new((), 57..58), - name: "b".to_string(), - }, - }, - ], - fun: Box::new(Var { - location: Span::new((), 37..49), - name: "compare_with".to_string(), - }), - location: Span::new((), 37..59), - }, - Call { - arguments: vec![ - CallArg { - label: None, - location: Span::new((), 75..76), - value: Var { - location: Span::new((), 75..76), - name: "a".to_string(), - }, - }, - CallArg { - label: None, - location: Span::new((), 78..79), - value: Fn { - location: Span::new((), 78..79), - fn_style: expr::FnStyle::BinOp(LtInt), - arguments: vec![ - Arg { - arg_name: Named { - name: "left".to_string(), - label: "left".to_string(), - location: Span::new((), 78..79), - is_validator_param: false, - }, - location: Span::new((), 78..79), - annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 78..79), - module: None, - name: "Int".to_string(), - arguments: vec![], - }), - tipo: (), - }, - Arg { - arg_name: Named { - name: "right".to_string(), - label: "right".to_string(), - location: Span::new((), 78..79), - is_validator_param: false, - }, - location: Span::new((), 78..79), - annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 78..79), - module: None, - name: "Int".to_string(), - arguments: vec![], - }), - tipo: (), - }, - ], - body: Box::new(BinOp { - location: Span::new((), 78..79), - name: LtInt, - left: Box::new(Var { - location: Span::new((), 78..79), - name: "left".to_string(), - }), - right: Box::new(Var { - location: Span::new((), 78..79), - name: "right".to_string(), - }), - }), - return_annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 78..79), - module: None, - name: "Bool".to_string(), - arguments: vec![], - }), - }, - }, - CallArg { - label: None, - location: Span::new((), 81..82), - value: Var { - location: Span::new((), 81..82), - name: "b".to_string(), - }, - }, - ], - fun: Box::new(Var { - location: Span::new((), 62..74), - name: "compare_with".to_string(), - }), - location: Span::new((), 62..83), - }, - Call { - arguments: vec![ - CallArg { - label: None, - location: Span::new((), 99..100), - value: Var { - location: Span::new((), 99..100), - name: "a".to_string(), - }, - }, - CallArg { - label: None, - location: Span::new((), 102..104), - value: Fn { - location: Span::new((), 102..104), - fn_style: expr::FnStyle::BinOp(LtEqInt), - arguments: vec![ - Arg { - arg_name: Named { - name: "left".to_string(), - label: "left".to_string(), - location: Span::new((), 102..104), - is_validator_param: false, - }, - location: Span::new((), 102..104), - annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 102..104), - module: None, - name: "Int".to_string(), - arguments: vec![], - }), - tipo: (), - }, - Arg { - arg_name: Named { - name: "right".to_string(), - label: "right".to_string(), - location: Span::new((), 102..104), - is_validator_param: false, - }, - location: Span::new((), 102..104), - annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 102..104), - module: None, - name: "Int".to_string(), - arguments: vec![], - }), - tipo: (), - }, - ], - body: Box::new(BinOp { - location: Span::new((), 102..104), - name: LtEqInt, - left: Box::new(Var { - location: Span::new((), 102..104), - name: "left".to_string(), - }), - right: Box::new(Var { - location: Span::new((), 102..104), - name: "right".to_string(), - }), - }), - return_annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 102..104), - module: None, - name: "Bool".to_string(), - arguments: vec![], - }), - }, - }, - CallArg { - label: None, - location: Span::new((), 106..107), - value: Var { - location: Span::new((), 106..107), - name: "b".to_string(), - }, - }, - ], - fun: Box::new(Var { - location: Span::new((), 86..98), - name: "compare_with".to_string(), - }), - location: Span::new((), 86..108), - }, - Call { - arguments: vec![ - CallArg { - label: None, - location: Span::new((), 124..125), - value: Var { - location: Span::new((), 124..125), - name: "a".to_string(), - }, - }, - CallArg { - label: None, - location: Span::new((), 127..129), - value: Fn { - location: Span::new((), 127..129), - fn_style: expr::FnStyle::BinOp(Eq), - arguments: vec![ - Arg { - arg_name: Named { - name: "left".to_string(), - label: "left".to_string(), - location: Span::new((), 127..129), - is_validator_param: false, - }, - location: Span::new((), 127..129), - annotation: None, - tipo: (), - }, - Arg { - arg_name: Named { - name: "right".to_string(), - label: "right".to_string(), - location: Span::new((), 127..129), - is_validator_param: false, - }, - location: Span::new((), 127..129), - annotation: None, - tipo: (), - }, - ], - body: Box::new(BinOp { - location: Span::new((), 127..129), - name: Eq, - left: Box::new(Var { - location: Span::new((), 127..129), - name: "left".to_string(), - }), - right: Box::new(Var { - location: Span::new((), 127..129), - name: "right".to_string(), - }), - }), - return_annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 127..129), - module: None, - name: "Bool".to_string(), - arguments: vec![], - }), - }, - }, - CallArg { - label: None, - location: Span::new((), 131..132), - value: Var { - location: Span::new((), 131..132), - name: "b".to_string(), - }, - }, - ], - fun: Box::new(Var { - location: Span::new((), 111..123), - name: "compare_with".to_string(), - }), - location: Span::new((), 111..133), - }, - Call { - arguments: vec![ - CallArg { - label: None, - location: Span::new((), 149..150), - value: Var { - location: Span::new((), 149..150), - name: "a".to_string(), - }, - }, - CallArg { - label: None, - location: Span::new((), 152..154), - value: Fn { - location: Span::new((), 152..154), - fn_style: expr::FnStyle::BinOp(NotEq), - arguments: vec![ - Arg { - arg_name: Named { - name: "left".to_string(), - label: "left".to_string(), - location: Span::new((), 152..154), - is_validator_param: false, - }, - location: Span::new((), 152..154), - annotation: None, - tipo: (), - }, - Arg { - arg_name: Named { - name: "right".to_string(), - label: "right".to_string(), - location: Span::new((), 152..154), - is_validator_param: false, - }, - location: Span::new((), 152..154), - annotation: None, - tipo: (), - }, - ], - body: Box::new(BinOp { - location: Span::new((), 152..154), - name: NotEq, - left: Box::new(Var { - location: Span::new((), 152..154), - name: "left".to_string(), - }), - right: Box::new(Var { - location: Span::new((), 152..154), - name: "right".to_string(), - }), - }), - return_annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 152..154), - module: None, - name: "Bool".to_string(), - arguments: vec![], - }), - }, - }, - CallArg { - label: None, - location: Span::new((), 156..157), - value: Var { - location: Span::new((), 156..157), - name: "b".to_string(), - }, - }, - ], - fun: Box::new(Var { - location: Span::new((), 136..148), - name: "compare_with".to_string(), - }), - location: Span::new((), 136..158), - }, - Call { - arguments: vec![ - CallArg { - label: None, - location: Span::new((), 174..175), - value: Var { - location: Span::new((), 174..175), - name: "a".to_string(), - }, - }, - CallArg { - label: None, - location: Span::new((), 177..179), - value: Fn { - location: Span::new((), 177..179), - fn_style: expr::FnStyle::BinOp(And), - arguments: vec![ - Arg { - arg_name: Named { - name: "left".to_string(), - label: "left".to_string(), - location: Span::new((), 177..179), - is_validator_param: false, - }, - location: Span::new((), 177..179), - annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 177..179), - module: None, - name: "Bool".to_string(), - arguments: vec![], - }), - tipo: (), - }, - Arg { - arg_name: Named { - name: "right".to_string(), - label: "right".to_string(), - location: Span::new((), 177..179), - is_validator_param: false, - }, - location: Span::new((), 177..179), - annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 177..179), - module: None, - name: "Bool".to_string(), - arguments: vec![], - }), - tipo: (), - }, - ], - body: Box::new(BinOp { - location: Span::new((), 177..179), - name: And, - left: Box::new(Var { - location: Span::new((), 177..179), - name: "left".to_string(), - }), - right: Box::new(Var { - location: Span::new((), 177..179), - name: "right".to_string(), - }), - }), - return_annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 177..179), - module: None, - name: "Bool".to_string(), - arguments: vec![], - }), - }, - }, - CallArg { - label: None, - location: Span::new((), 181..182), - value: Var { - location: Span::new((), 181..182), - name: "b".to_string(), - }, - }, - ], - fun: Box::new(Var { - location: Span::new((), 161..173), - name: "combine_with".to_string(), - }), - location: Span::new((), 161..183), - }, - Call { - arguments: vec![ - CallArg { - label: None, - location: Span::new((), 199..200), - value: Var { - location: Span::new((), 199..200), - name: "a".to_string(), - }, - }, - CallArg { - label: None, - location: Span::new((), 202..204), - value: Fn { - location: Span::new((), 202..204), - fn_style: expr::FnStyle::BinOp(Or), - arguments: vec![ - Arg { - arg_name: Named { - name: "left".to_string(), - label: "left".to_string(), - location: Span::new((), 202..204), - is_validator_param: false, - }, - location: Span::new((), 202..204), - annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 202..204), - module: None, - name: "Bool".to_string(), - arguments: vec![], - }), - tipo: (), - }, - Arg { - arg_name: Named { - name: "right".to_string(), - label: "right".to_string(), - location: Span::new((), 202..204), - is_validator_param: false, - }, - location: Span::new((), 202..204), - annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 202..204), - module: None, - name: "Bool".to_string(), - arguments: vec![], - }), - tipo: (), - }, - ], - body: Box::new(BinOp { - location: Span::new((), 202..204), - name: Or, - left: Box::new(Var { - location: Span::new((), 202..204), - name: "left".to_string(), - }), - right: Box::new(Var { - location: Span::new((), 202..204), - name: "right".to_string(), - }), - }), - return_annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 202..204), - module: None, - name: "Bool".to_string(), - arguments: vec![], - }), - }, - }, - CallArg { - label: None, - location: Span::new((), 206..207), - value: Var { - location: Span::new((), 206..207), - name: "b".to_string(), - }, - }, - ], - fun: Box::new(Var { - location: Span::new((), 186..198), - name: "combine_with".to_string(), - }), - location: Span::new((), 186..208), - }, - Call { - arguments: vec![ - CallArg { - label: None, - location: Span::new((), 224..225), - value: Var { - location: Span::new((), 224..225), - name: "a".to_string(), - }, - }, - CallArg { - label: None, - location: Span::new((), 227..228), - value: Fn { - location: Span::new((), 227..228), - fn_style: expr::FnStyle::BinOp(AddInt), - arguments: vec![ - Arg { - arg_name: Named { - name: "left".to_string(), - label: "left".to_string(), - location: Span::new((), 227..228), - is_validator_param: false, - }, - location: Span::new((), 227..228), - annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 227..228), - module: None, - name: "Int".to_string(), - arguments: vec![], - }), - tipo: (), - }, - Arg { - arg_name: Named { - name: "right".to_string(), - label: "right".to_string(), - location: Span::new((), 227..228), - is_validator_param: false, - }, - location: Span::new((), 227..228), - annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 227..228), - module: None, - name: "Int".to_string(), - arguments: vec![], - }), - tipo: (), - }, - ], - body: Box::new(BinOp { - location: Span::new((), 227..228), - name: AddInt, - left: Box::new(Var { - location: Span::new((), 227..228), - name: "left".to_string(), - }), - right: Box::new(Var { - location: Span::new((), 227..228), - name: "right".to_string(), - }), - }), - return_annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 227..228), - module: None, - name: "Int".to_string(), - arguments: vec![], - }), - }, - }, - CallArg { - label: None, - location: Span::new((), 230..231), - value: Var { - location: Span::new((), 230..231), - name: "b".to_string(), - }, - }, - ], - fun: Box::new(Var { - location: Span::new((), 211..223), - name: "compute_with".to_string(), - }), - location: Span::new((), 211..232), - }, - Call { - arguments: vec![ - CallArg { - label: None, - location: Span::new((), 248..249), - value: Var { - location: Span::new((), 248..249), - name: "a".to_string(), - }, - }, - CallArg { - label: None, - location: Span::new((), 251..252), - value: Fn { - location: Span::new((), 251..252), - fn_style: expr::FnStyle::BinOp(SubInt), - arguments: vec![ - Arg { - arg_name: Named { - name: "left".to_string(), - label: "left".to_string(), - location: Span::new((), 251..252), - is_validator_param: false, - }, - location: Span::new((), 251..252), - annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 251..252), - module: None, - name: "Int".to_string(), - arguments: vec![], - }), - tipo: (), - }, - Arg { - arg_name: Named { - name: "right".to_string(), - label: "right".to_string(), - location: Span::new((), 251..252), - is_validator_param: false, - }, - location: Span::new((), 251..252), - annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 251..252), - module: None, - name: "Int".to_string(), - arguments: vec![], - }), - tipo: (), - }, - ], - body: Box::new(BinOp { - location: Span::new((), 251..252), - name: SubInt, - left: Box::new(Var { - location: Span::new((), 251..252), - name: "left".to_string(), - }), - right: Box::new(Var { - location: Span::new((), 251..252), - name: "right".to_string(), - }), - }), - return_annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 251..252), - module: None, - name: "Int".to_string(), - arguments: vec![], - }), - }, - }, - CallArg { - label: None, - location: Span::new((), 254..255), - value: Var { - location: Span::new((), 254..255), - name: "b".to_string(), - }, - }, - ], - fun: Box::new(Var { - location: Span::new((), 235..247), - name: "compute_with".to_string(), - }), - location: Span::new((), 235..256), - }, - Call { - arguments: vec![ - CallArg { - label: None, - location: Span::new((), 272..273), - value: Var { - location: Span::new((), 272..273), - name: "a".to_string(), - }, - }, - CallArg { - label: None, - location: Span::new((), 275..276), - value: Fn { - location: Span::new((), 275..276), - fn_style: expr::FnStyle::BinOp(DivInt), - arguments: vec![ - Arg { - arg_name: Named { - name: "left".to_string(), - label: "left".to_string(), - location: Span::new((), 275..276), - is_validator_param: false, - }, - location: Span::new((), 275..276), - annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 275..276), - module: None, - name: "Int".to_string(), - arguments: vec![], - }), - tipo: (), - }, - Arg { - arg_name: Named { - name: "right".to_string(), - label: "right".to_string(), - location: Span::new((), 275..276), - is_validator_param: false, - }, - location: Span::new((), 275..276), - annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 275..276), - module: None, - name: "Int".to_string(), - arguments: vec![], - }), - tipo: (), - }, - ], - body: Box::new(BinOp { - location: Span::new((), 275..276), - name: DivInt, - left: Box::new(Var { - location: Span::new((), 275..276), - name: "left".to_string(), - }), - right: Box::new(Var { - location: Span::new((), 275..276), - name: "right".to_string(), - }), - }), - return_annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 275..276), - module: None, - name: "Int".to_string(), - arguments: vec![], - }), - }, - }, - CallArg { - label: None, - location: Span::new((), 278..279), - value: Var { - location: Span::new((), 278..279), - name: "b".to_string(), - }, - }, - ], - fun: Box::new(Var { - location: Span::new((), 259..271), - name: "compute_with".to_string(), - }), - location: Span::new((), 259..280), - }, - Call { - arguments: vec![ - CallArg { - label: None, - location: Span::new((), 296..297), - value: Var { - location: Span::new((), 296..297), - name: "a".to_string(), - }, - }, - CallArg { - label: None, - location: Span::new((), 299..300), - value: Fn { - location: Span::new((), 299..300), - fn_style: expr::FnStyle::BinOp(MultInt), - arguments: vec![ - Arg { - arg_name: Named { - name: "left".to_string(), - label: "left".to_string(), - location: Span::new((), 299..300), - is_validator_param: false, - }, - location: Span::new((), 299..300), - annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 299..300), - module: None, - name: "Int".to_string(), - arguments: vec![], - }), - tipo: (), - }, - Arg { - arg_name: Named { - name: "right".to_string(), - label: "right".to_string(), - location: Span::new((), 299..300), - is_validator_param: false, - }, - location: Span::new((), 299..300), - annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 299..300), - module: None, - name: "Int".to_string(), - arguments: vec![], - }), - tipo: (), - }, - ], - body: Box::new(BinOp { - location: Span::new((), 299..300), - name: MultInt, - left: Box::new(Var { - location: Span::new((), 299..300), - name: "left".to_string(), - }), - right: Box::new(Var { - location: Span::new((), 299..300), - name: "right".to_string(), - }), - }), - return_annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 299..300), - module: None, - name: "Int".to_string(), - arguments: vec![], - }), - }, - }, - CallArg { - label: None, - location: Span::new((), 302..303), - value: Var { - location: Span::new((), 302..303), - name: "b".to_string(), - }, - }, - ], - fun: Box::new(Var { - location: Span::new((), 283..295), - name: "compute_with".to_string(), - }), - location: Span::new((), 283..304), - }, - Call { - arguments: vec![ - CallArg { - label: None, - location: Span::new((), 320..321), - value: Var { - location: Span::new((), 320..321), - name: "a".to_string(), - }, - }, - CallArg { - label: None, - location: Span::new((), 323..324), - value: Fn { - location: Span::new((), 323..324), - fn_style: expr::FnStyle::BinOp(ModInt), - arguments: vec![ - Arg { - arg_name: Named { - name: "left".to_string(), - label: "left".to_string(), - location: Span::new((), 323..324), - is_validator_param: false, - }, - location: Span::new((), 323..324), - annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 323..324), - module: None, - name: "Int".to_string(), - arguments: vec![], - }), - tipo: (), - }, - Arg { - arg_name: Named { - name: "right".to_string(), - label: "right".to_string(), - location: Span::new((), 323..324), - is_validator_param: false, - }, - location: Span::new((), 323..324), - annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 323..324), - module: None, - name: "Int".to_string(), - arguments: vec![], - }), - tipo: (), - }, - ], - body: Box::new(BinOp { - location: Span::new((), 323..324), - name: ModInt, - left: Box::new(Var { - location: Span::new((), 323..324), - name: "left".to_string(), - }), - right: Box::new(Var { - location: Span::new((), 323..324), - name: "right".to_string(), - }), - }), - return_annotation: Some(ast::Annotation::Constructor { - location: Span::new((), 323..324), - module: None, - name: "Int".to_string(), - arguments: vec![], - }), - }, - }, - CallArg { - label: None, - location: Span::new((), 326..327), - value: Var { - location: Span::new((), 326..327), - name: "b".to_string(), - }, - }, - ], - fun: Box::new(Var { - location: Span::new((), 307..319), - name: "compute_with".to_string(), - }), - location: Span::new((), 307..328), - }, - ], - }, - doc: None, - location: Span::new((), 0..8), - name: "foo".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 329, - can_error: true, - })], +#[test] +fn parse_unicode_offset_1() { + assert_module!( + r#" + fn foo() { + let x = "★" + x + } + "# ); } -#[test] -fn parse_unicode_offset_1() { - use expr::UntypedExpr::*; - - let code = indoc! {r#" - fn foo() { - let x = "★" - x - } - "#}; - - assert_definitions( - code, - vec![ast::Definition::Fn(Function { - arguments: vec![], - body: Sequence { - location: Span::new((), 13..30), - expressions: vec![ - Assignment { - location: Span::new((), 13..26), - value: Box::new(ByteArray { - location: Span::new((), 21..26), - bytes: vec![226, 152, 133], - preferred_format: ast::ByteArrayFormatPreference::Utf8String, - }), - pattern: ast::Pattern::Var { - location: Span::new((), 17..18), - name: "x".to_string(), - }, - kind: ast::AssignmentKind::Let, - annotation: None, - }, - Var { - location: Span::new((), 29..30), - name: "x".to_string(), - }, - ], - }, - doc: None, - location: Span::new((), 0..8), - name: "foo".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 31, - can_error: true, - })], - ) -} - #[test] fn parse_unicode_offset_2() { - use expr::UntypedExpr::*; - - let code = indoc! {r#" - fn foo() { - let x = "*" - x - } - "#}; - - assert_definitions( - code, - vec![ast::Definition::Fn(Function { - arguments: vec![], - body: Sequence { - location: Span::new((), 13..28), - expressions: vec![ - Assignment { - location: Span::new((), 13..24), - value: Box::new(ByteArray { - location: Span::new((), 21..24), - bytes: vec![42], - preferred_format: ast::ByteArrayFormatPreference::Utf8String, - }), - pattern: ast::Pattern::Var { - location: Span::new((), 17..18), - name: "x".to_string(), - }, - kind: ast::AssignmentKind::Let, - annotation: None, - }, - Var { - location: Span::new((), 27..28), - name: "x".to_string(), - }, - ], - }, - doc: None, - location: Span::new((), 0..8), - name: "foo".to_string(), - public: false, - return_annotation: None, - return_type: (), - end_position: 29, - can_error: true, - })], - ) + assert_module!( + r#" + fn foo() { + let x = "*" + x + } + "# + ); } diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__anonymous_function.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__anonymous_function.snap new file mode 100644 index 00000000..450af3be --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__anonymous_function.snap @@ -0,0 +1,110 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n pub fn such() -> Int {\n let add_one = fn (a: Int) -> Int { a + 1 }\n\n 2 |> add_one\n }\n " +info: anonymous_function +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + Fn( + Function { + arguments: [], + body: Sequence { + location: 25..83, + expressions: [ + Assignment { + location: 25..67, + value: Fn { + location: 39..67, + fn_style: Plain, + arguments: [ + Arg { + arg_name: Named { + name: "a", + label: "a", + location: 43..44, + is_validator_param: false, + }, + location: 43..49, + annotation: Some( + Constructor { + location: 46..49, + module: None, + name: "Int", + arguments: [], + }, + ), + tipo: (), + }, + ], + body: BinOp { + location: 60..65, + name: AddInt, + left: Var { + location: 60..61, + name: "a", + }, + right: Int { + location: 64..65, + value: "1", + base: Decimal { + numeric_underscore: false, + }, + }, + }, + return_annotation: Some( + Constructor { + location: 54..57, + module: None, + name: "Int", + arguments: [], + }, + ), + }, + pattern: Var { + location: 29..36, + name: "add_one", + }, + kind: Let, + annotation: None, + }, + PipeLine { + expressions: [ + Int { + location: 71..72, + value: "2", + base: Decimal { + numeric_underscore: false, + }, + }, + Var { + location: 76..83, + name: "add_one", + }, + ], + one_liner: true, + }, + ], + }, + doc: None, + location: 0..20, + name: "such", + public: true, + return_annotation: Some( + Constructor { + location: 17..20, + module: None, + name: "Int", + arguments: [], + }, + ), + return_type: (), + end_position: 84, + can_error: true, + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__base16_bytearray_literals.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__base16_bytearray_literals.snap new file mode 100644 index 00000000..fe0b51dd --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__base16_bytearray_literals.snap @@ -0,0 +1,62 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n pub const my_policy_id = #\"00aaff\"\n\n pub fn foo() {\n my_policy_id == #\"00aaff\"\n }\n " +info: base16_bytearray_literals +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + ModuleConstant( + ModuleConstant { + doc: None, + location: 0..34, + public: true, + name: "my_policy_id", + annotation: None, + value: ByteArray { + location: 25..34, + bytes: [ + 0, + 170, + 255, + ], + preferred_format: HexadecimalString, + }, + tipo: (), + }, + ), + Fn( + Function { + arguments: [], + body: BinOp { + location: 55..80, + name: Eq, + left: Var { + location: 55..67, + name: "my_policy_id", + }, + right: ByteArray { + location: 71..80, + bytes: [ + 0, + 170, + 255, + ], + preferred_format: HexadecimalString, + }, + }, + doc: None, + location: 36..48, + name: "foo", + public: true, + return_annotation: None, + return_type: (), + end_position: 81, + can_error: true, + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__block.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__block.snap new file mode 100644 index 00000000..74efb471 --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__block.snap @@ -0,0 +1,99 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n pub fn wow2(a: Int){\n let b = {\n let x = 4\n\n x + 5\n }\n\n b\n }\n " +info: block +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + Fn( + Function { + arguments: [ + Arg { + arg_name: Named { + name: "a", + label: "a", + location: 12..13, + is_validator_param: false, + }, + location: 12..18, + annotation: Some( + Constructor { + location: 15..18, + module: None, + name: "Int", + arguments: [], + }, + ), + tipo: (), + }, + ], + body: Sequence { + location: 23..66, + expressions: [ + Assignment { + location: 23..61, + value: Sequence { + location: 37..57, + expressions: [ + Assignment { + location: 37..46, + value: Int { + location: 45..46, + value: "4", + base: Decimal { + numeric_underscore: false, + }, + }, + pattern: Var { + location: 41..42, + name: "x", + }, + kind: Let, + annotation: None, + }, + BinOp { + location: 52..57, + name: AddInt, + left: Var { + location: 52..53, + name: "x", + }, + right: Int { + location: 56..57, + value: "5", + base: Decimal { + numeric_underscore: false, + }, + }, + }, + ], + }, + pattern: Var { + location: 27..28, + name: "b", + }, + kind: Let, + annotation: None, + }, + Var { + location: 65..66, + name: "b", + }, + ], + }, + doc: None, + location: 0..19, + name: "wow2", + public: true, + return_annotation: None, + return_type: (), + end_position: 67, + can_error: true, + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__call.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__call.snap new file mode 100644 index 00000000..35518d7e --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__call.snap @@ -0,0 +1,182 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n fn calls() {\n let x = add_one(3)\n\n let map_add_x = list.map(_, fn (y) { x + y })\n\n map_add_x([ 1, 2, 3 ])\n }\n " +info: call +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + Fn( + Function { + arguments: [], + body: Sequence { + location: 15..108, + expressions: [ + Assignment { + location: 15..33, + value: Call { + arguments: [ + CallArg { + label: None, + location: 31..32, + value: Int { + location: 31..32, + value: "3", + base: Decimal { + numeric_underscore: false, + }, + }, + }, + ], + fun: Var { + location: 23..30, + name: "add_one", + }, + location: 23..33, + }, + pattern: Var { + location: 19..20, + name: "x", + }, + kind: Let, + annotation: None, + }, + Assignment { + location: 37..82, + value: Fn { + location: 53..82, + fn_style: Capture, + arguments: [ + Arg { + arg_name: Named { + name: "_capture__0", + label: "_capture__0", + location: 0..0, + is_validator_param: false, + }, + location: 0..0, + annotation: None, + tipo: (), + }, + ], + body: Call { + arguments: [ + CallArg { + label: None, + location: 62..63, + value: Var { + location: 62..63, + name: "_capture__0", + }, + }, + CallArg { + label: None, + location: 65..81, + value: Fn { + location: 65..81, + fn_style: Plain, + arguments: [ + Arg { + arg_name: Named { + name: "y", + label: "y", + location: 69..70, + is_validator_param: false, + }, + location: 69..70, + annotation: None, + tipo: (), + }, + ], + body: BinOp { + location: 74..79, + name: AddInt, + left: Var { + location: 74..75, + name: "x", + }, + right: Var { + location: 78..79, + name: "y", + }, + }, + return_annotation: None, + }, + }, + ], + fun: FieldAccess { + location: 53..61, + label: "map", + container: Var { + location: 53..57, + name: "list", + }, + }, + location: 53..82, + }, + return_annotation: None, + }, + pattern: Var { + location: 41..50, + name: "map_add_x", + }, + kind: Let, + annotation: None, + }, + Call { + arguments: [ + CallArg { + label: None, + location: 96..107, + value: List { + location: 96..107, + elements: [ + Int { + location: 98..99, + value: "1", + base: Decimal { + numeric_underscore: false, + }, + }, + Int { + location: 101..102, + value: "2", + base: Decimal { + numeric_underscore: false, + }, + }, + Int { + location: 104..105, + value: "3", + base: Decimal { + numeric_underscore: false, + }, + }, + ], + tail: None, + }, + }, + ], + fun: Var { + location: 86..95, + name: "map_add_x", + }, + location: 86..108, + }, + ], + }, + doc: None, + location: 0..10, + name: "calls", + public: false, + return_annotation: None, + return_type: (), + end_position: 109, + can_error: true, + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__can_handle_comments_at_end_of_file.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__can_handle_comments_at_end_of_file.snap new file mode 100644 index 00000000..0de6c356 --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__can_handle_comments_at_end_of_file.snap @@ -0,0 +1,24 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n use aiken\n\n // some comment\n // more comments" +info: can_handle_comments_at_end_of_file +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + Use( + Use { + as_name: None, + location: 0..9, + module: [ + "aiken", + ], + package: (), + unqualified: [], + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__cargo_create_unlabeled.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__cargo_create_unlabeled.snap new file mode 100644 index 00000000..9f0d8f38 --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__cargo_create_unlabeled.snap @@ -0,0 +1,58 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n fn create() {\n some_module.Thing(1, a)\n }\n " +info: cargo_create_unlabeled +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + Fn( + Function { + arguments: [], + body: Call { + arguments: [ + CallArg { + label: None, + location: 34..35, + value: Int { + location: 34..35, + value: "1", + base: Decimal { + numeric_underscore: false, + }, + }, + }, + CallArg { + label: None, + location: 37..38, + value: Var { + location: 37..38, + name: "a", + }, + }, + ], + fun: FieldAccess { + location: 16..33, + label: "Thing", + container: Var { + location: 16..27, + name: "some_module", + }, + }, + location: 16..39, + }, + doc: None, + location: 0..11, + name: "create", + public: false, + return_annotation: None, + return_type: (), + end_position: 40, + can_error: true, + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__custom_type.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__custom_type.snap new file mode 100644 index 00000000..b8954b8e --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__custom_type.snap @@ -0,0 +1,101 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n type Option {\n Some(a, Int)\n None\n Wow { name: Int, age: Int }\n }\n " +info: custom_type +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + DataType( + DataType { + constructors: [ + RecordConstructor { + location: 19..31, + name: "Some", + arguments: [ + RecordConstructorArg { + label: None, + annotation: Var { + location: 24..25, + name: "a", + }, + location: 24..25, + tipo: (), + doc: None, + }, + RecordConstructorArg { + label: None, + annotation: Constructor { + location: 27..30, + module: None, + name: "Int", + arguments: [], + }, + location: 27..30, + tipo: (), + doc: None, + }, + ], + doc: None, + sugar: false, + }, + RecordConstructor { + location: 34..38, + name: "None", + arguments: [], + doc: None, + sugar: false, + }, + RecordConstructor { + location: 41..68, + name: "Wow", + arguments: [ + RecordConstructorArg { + label: Some( + "name", + ), + annotation: Constructor { + location: 53..56, + module: None, + name: "Int", + arguments: [], + }, + location: 47..56, + tipo: (), + doc: None, + }, + RecordConstructorArg { + label: Some( + "age", + ), + annotation: Constructor { + location: 63..66, + module: None, + name: "Int", + arguments: [], + }, + location: 58..66, + tipo: (), + doc: None, + }, + ], + doc: None, + sugar: false, + }, + ], + doc: None, + location: 0..70, + name: "Option", + opaque: false, + parameters: [ + "a", + ], + public: false, + typed_parameters: [], + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__double_validator.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__double_validator.snap new file mode 100644 index 00000000..68015601 --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__double_validator.snap @@ -0,0 +1,110 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n validator {\n fn foo(datum, rdmr, ctx) {\n True\n }\n\n fn bar(rdmr, ctx) {\n True\n }\n }\n " +info: double_validator +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + Validator( + Validator { + doc: None, + end_position: 90, + fun: Function { + arguments: [ + Arg { + arg_name: Named { + name: "datum", + label: "datum", + location: 21..26, + is_validator_param: false, + }, + location: 21..26, + annotation: None, + tipo: (), + }, + Arg { + arg_name: Named { + name: "rdmr", + label: "rdmr", + location: 28..32, + is_validator_param: false, + }, + location: 28..32, + annotation: None, + tipo: (), + }, + Arg { + arg_name: Named { + name: "ctx", + label: "ctx", + location: 34..37, + is_validator_param: false, + }, + location: 34..37, + annotation: None, + tipo: (), + }, + ], + body: Var { + location: 45..49, + name: "True", + }, + doc: None, + location: 14..38, + name: "foo", + public: false, + return_annotation: None, + return_type: (), + end_position: 52, + can_error: true, + }, + other_fun: Some( + Function { + arguments: [ + Arg { + arg_name: Named { + name: "rdmr", + label: "rdmr", + location: 64..68, + is_validator_param: false, + }, + location: 64..68, + annotation: None, + tipo: (), + }, + Arg { + arg_name: Named { + name: "ctx", + label: "ctx", + location: 70..73, + is_validator_param: false, + }, + location: 70..73, + annotation: None, + tipo: (), + }, + ], + body: Var { + location: 81..85, + name: "True", + }, + doc: None, + location: 57..74, + name: "bar", + public: false, + return_annotation: None, + return_type: (), + end_position: 88, + can_error: true, + }, + ), + location: 0..9, + params: [], + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__empty_function.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__empty_function.snap new file mode 100644 index 00000000..cc09bb21 --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__empty_function.snap @@ -0,0 +1,37 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n pub fn run() {}\n " +info: empty_function +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + Fn( + Function { + arguments: [], + body: Trace { + kind: Todo, + location: 0..15, + then: ErrorTerm { + location: 0..15, + }, + text: String { + location: 0..15, + value: "aiken::todo", + }, + }, + doc: None, + location: 0..12, + name: "run", + public: true, + return_annotation: None, + return_type: (), + end_position: 14, + can_error: true, + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__expect.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__expect.snap new file mode 100644 index 00000000..ffd54e16 --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__expect.snap @@ -0,0 +1,71 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n pub fn run() {\n expect Some(x) = something.field\n x.other_field\n }\n " +info: expect +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + Fn( + Function { + arguments: [], + body: Sequence { + location: 19..69, + expressions: [ + Assignment { + location: 19..51, + value: FieldAccess { + location: 36..51, + label: "field", + container: Var { + location: 36..45, + name: "something", + }, + }, + pattern: Constructor { + is_record: false, + location: 26..33, + name: "Some", + arguments: [ + CallArg { + label: None, + location: 31..32, + value: Var { + location: 31..32, + name: "x", + }, + }, + ], + module: None, + constructor: (), + with_spread: false, + tipo: (), + }, + kind: Expect, + annotation: None, + }, + FieldAccess { + location: 56..69, + label: "other_field", + container: Var { + location: 56..57, + name: "x", + }, + }, + ], + }, + doc: None, + location: 0..12, + name: "run", + public: true, + return_annotation: None, + return_type: (), + end_position: 70, + can_error: true, + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__fail.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__fail.snap new file mode 100644 index 00000000..a4b0dfc8 --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__fail.snap @@ -0,0 +1,54 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n !test invalid_inputs() {\n expect True = False\n\n False\n }\n " +info: test_fail +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + Test( + Function { + arguments: [], + body: Sequence { + location: 27..55, + expressions: [ + Assignment { + location: 27..46, + value: Var { + location: 41..46, + name: "False", + }, + pattern: Constructor { + is_record: false, + location: 34..38, + name: "True", + arguments: [], + module: None, + constructor: (), + with_spread: false, + tipo: (), + }, + kind: Expect, + annotation: None, + }, + Var { + location: 50..55, + name: "False", + }, + ], + }, + doc: None, + location: 0..22, + name: "invalid_inputs", + public: false, + return_annotation: None, + return_type: (), + end_position: 56, + can_error: true, + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__field_access.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__field_access.snap new file mode 100644 index 00000000..6b932afa --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__field_access.snap @@ -0,0 +1,53 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n fn name(user: User) {\n user.name\n }\n " +info: field_access +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + Fn( + Function { + arguments: [ + Arg { + arg_name: Named { + name: "user", + label: "user", + location: 8..12, + is_validator_param: false, + }, + location: 8..18, + annotation: Some( + Constructor { + location: 14..18, + module: None, + name: "User", + arguments: [], + }, + ), + tipo: (), + }, + ], + body: FieldAccess { + location: 24..33, + label: "name", + container: Var { + location: 24..28, + name: "user", + }, + }, + doc: None, + location: 0..19, + name: "name", + public: false, + return_annotation: None, + return_type: (), + end_position: 34, + can_error: true, + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__first_class_binop.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__first_class_binop.snap new file mode 100644 index 00000000..56043b21 --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__first_class_binop.snap @@ -0,0 +1,1212 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n fn foo() {\n compare_with(a, >, b)\n compare_with(a, >=, b)\n compare_with(a, <, b)\n compare_with(a, <=, b)\n compare_with(a, ==, b)\n compare_with(a, !=, b)\n combine_with(a, &&, b)\n combine_with(a, ||, b)\n compute_with(a, +, b)\n compute_with(a, -, b)\n compute_with(a, /, b)\n compute_with(a, *, b)\n compute_with(a, %, b)\n }\n " +info: first_class_binop +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + Fn( + Function { + arguments: [], + body: Sequence { + location: 13..328, + expressions: [ + Call { + arguments: [ + CallArg { + label: None, + location: 26..27, + value: Var { + location: 26..27, + name: "a", + }, + }, + CallArg { + label: None, + location: 29..30, + value: Fn { + location: 29..30, + fn_style: BinOp( + GtInt, + ), + arguments: [ + Arg { + arg_name: Named { + name: "left", + label: "left", + location: 29..30, + is_validator_param: false, + }, + location: 29..30, + annotation: Some( + Constructor { + location: 29..30, + module: None, + name: "Int", + arguments: [], + }, + ), + tipo: (), + }, + Arg { + arg_name: Named { + name: "right", + label: "right", + location: 29..30, + is_validator_param: false, + }, + location: 29..30, + annotation: Some( + Constructor { + location: 29..30, + module: None, + name: "Int", + arguments: [], + }, + ), + tipo: (), + }, + ], + body: BinOp { + location: 29..30, + name: GtInt, + left: Var { + location: 29..30, + name: "left", + }, + right: Var { + location: 29..30, + name: "right", + }, + }, + return_annotation: Some( + Constructor { + location: 29..30, + module: None, + name: "Bool", + arguments: [], + }, + ), + }, + }, + CallArg { + label: None, + location: 32..33, + value: Var { + location: 32..33, + name: "b", + }, + }, + ], + fun: Var { + location: 13..25, + name: "compare_with", + }, + location: 13..34, + }, + Call { + arguments: [ + CallArg { + label: None, + location: 50..51, + value: Var { + location: 50..51, + name: "a", + }, + }, + CallArg { + label: None, + location: 53..55, + value: Fn { + location: 53..55, + fn_style: BinOp( + GtEqInt, + ), + arguments: [ + Arg { + arg_name: Named { + name: "left", + label: "left", + location: 53..55, + is_validator_param: false, + }, + location: 53..55, + annotation: Some( + Constructor { + location: 53..55, + module: None, + name: "Int", + arguments: [], + }, + ), + tipo: (), + }, + Arg { + arg_name: Named { + name: "right", + label: "right", + location: 53..55, + is_validator_param: false, + }, + location: 53..55, + annotation: Some( + Constructor { + location: 53..55, + module: None, + name: "Int", + arguments: [], + }, + ), + tipo: (), + }, + ], + body: BinOp { + location: 53..55, + name: GtEqInt, + left: Var { + location: 53..55, + name: "left", + }, + right: Var { + location: 53..55, + name: "right", + }, + }, + return_annotation: Some( + Constructor { + location: 53..55, + module: None, + name: "Bool", + arguments: [], + }, + ), + }, + }, + CallArg { + label: None, + location: 57..58, + value: Var { + location: 57..58, + name: "b", + }, + }, + ], + fun: Var { + location: 37..49, + name: "compare_with", + }, + location: 37..59, + }, + Call { + arguments: [ + CallArg { + label: None, + location: 75..76, + value: Var { + location: 75..76, + name: "a", + }, + }, + CallArg { + label: None, + location: 78..79, + value: Fn { + location: 78..79, + fn_style: BinOp( + LtInt, + ), + arguments: [ + Arg { + arg_name: Named { + name: "left", + label: "left", + location: 78..79, + is_validator_param: false, + }, + location: 78..79, + annotation: Some( + Constructor { + location: 78..79, + module: None, + name: "Int", + arguments: [], + }, + ), + tipo: (), + }, + Arg { + arg_name: Named { + name: "right", + label: "right", + location: 78..79, + is_validator_param: false, + }, + location: 78..79, + annotation: Some( + Constructor { + location: 78..79, + module: None, + name: "Int", + arguments: [], + }, + ), + tipo: (), + }, + ], + body: BinOp { + location: 78..79, + name: LtInt, + left: Var { + location: 78..79, + name: "left", + }, + right: Var { + location: 78..79, + name: "right", + }, + }, + return_annotation: Some( + Constructor { + location: 78..79, + module: None, + name: "Bool", + arguments: [], + }, + ), + }, + }, + CallArg { + label: None, + location: 81..82, + value: Var { + location: 81..82, + name: "b", + }, + }, + ], + fun: Var { + location: 62..74, + name: "compare_with", + }, + location: 62..83, + }, + Call { + arguments: [ + CallArg { + label: None, + location: 99..100, + value: Var { + location: 99..100, + name: "a", + }, + }, + CallArg { + label: None, + location: 102..104, + value: Fn { + location: 102..104, + fn_style: BinOp( + LtEqInt, + ), + arguments: [ + Arg { + arg_name: Named { + name: "left", + label: "left", + location: 102..104, + is_validator_param: false, + }, + location: 102..104, + annotation: Some( + Constructor { + location: 102..104, + module: None, + name: "Int", + arguments: [], + }, + ), + tipo: (), + }, + Arg { + arg_name: Named { + name: "right", + label: "right", + location: 102..104, + is_validator_param: false, + }, + location: 102..104, + annotation: Some( + Constructor { + location: 102..104, + module: None, + name: "Int", + arguments: [], + }, + ), + tipo: (), + }, + ], + body: BinOp { + location: 102..104, + name: LtEqInt, + left: Var { + location: 102..104, + name: "left", + }, + right: Var { + location: 102..104, + name: "right", + }, + }, + return_annotation: Some( + Constructor { + location: 102..104, + module: None, + name: "Bool", + arguments: [], + }, + ), + }, + }, + CallArg { + label: None, + location: 106..107, + value: Var { + location: 106..107, + name: "b", + }, + }, + ], + fun: Var { + location: 86..98, + name: "compare_with", + }, + location: 86..108, + }, + Call { + arguments: [ + CallArg { + label: None, + location: 124..125, + value: Var { + location: 124..125, + name: "a", + }, + }, + CallArg { + label: None, + location: 127..129, + value: Fn { + location: 127..129, + fn_style: BinOp( + Eq, + ), + arguments: [ + Arg { + arg_name: Named { + name: "left", + label: "left", + location: 127..129, + is_validator_param: false, + }, + location: 127..129, + annotation: None, + tipo: (), + }, + Arg { + arg_name: Named { + name: "right", + label: "right", + location: 127..129, + is_validator_param: false, + }, + location: 127..129, + annotation: None, + tipo: (), + }, + ], + body: BinOp { + location: 127..129, + name: Eq, + left: Var { + location: 127..129, + name: "left", + }, + right: Var { + location: 127..129, + name: "right", + }, + }, + return_annotation: Some( + Constructor { + location: 127..129, + module: None, + name: "Bool", + arguments: [], + }, + ), + }, + }, + CallArg { + label: None, + location: 131..132, + value: Var { + location: 131..132, + name: "b", + }, + }, + ], + fun: Var { + location: 111..123, + name: "compare_with", + }, + location: 111..133, + }, + Call { + arguments: [ + CallArg { + label: None, + location: 149..150, + value: Var { + location: 149..150, + name: "a", + }, + }, + CallArg { + label: None, + location: 152..154, + value: Fn { + location: 152..154, + fn_style: BinOp( + NotEq, + ), + arguments: [ + Arg { + arg_name: Named { + name: "left", + label: "left", + location: 152..154, + is_validator_param: false, + }, + location: 152..154, + annotation: None, + tipo: (), + }, + Arg { + arg_name: Named { + name: "right", + label: "right", + location: 152..154, + is_validator_param: false, + }, + location: 152..154, + annotation: None, + tipo: (), + }, + ], + body: BinOp { + location: 152..154, + name: NotEq, + left: Var { + location: 152..154, + name: "left", + }, + right: Var { + location: 152..154, + name: "right", + }, + }, + return_annotation: Some( + Constructor { + location: 152..154, + module: None, + name: "Bool", + arguments: [], + }, + ), + }, + }, + CallArg { + label: None, + location: 156..157, + value: Var { + location: 156..157, + name: "b", + }, + }, + ], + fun: Var { + location: 136..148, + name: "compare_with", + }, + location: 136..158, + }, + Call { + arguments: [ + CallArg { + label: None, + location: 174..175, + value: Var { + location: 174..175, + name: "a", + }, + }, + CallArg { + label: None, + location: 177..179, + value: Fn { + location: 177..179, + fn_style: BinOp( + And, + ), + arguments: [ + Arg { + arg_name: Named { + name: "left", + label: "left", + location: 177..179, + is_validator_param: false, + }, + location: 177..179, + annotation: Some( + Constructor { + location: 177..179, + module: None, + name: "Bool", + arguments: [], + }, + ), + tipo: (), + }, + Arg { + arg_name: Named { + name: "right", + label: "right", + location: 177..179, + is_validator_param: false, + }, + location: 177..179, + annotation: Some( + Constructor { + location: 177..179, + module: None, + name: "Bool", + arguments: [], + }, + ), + tipo: (), + }, + ], + body: BinOp { + location: 177..179, + name: And, + left: Var { + location: 177..179, + name: "left", + }, + right: Var { + location: 177..179, + name: "right", + }, + }, + return_annotation: Some( + Constructor { + location: 177..179, + module: None, + name: "Bool", + arguments: [], + }, + ), + }, + }, + CallArg { + label: None, + location: 181..182, + value: Var { + location: 181..182, + name: "b", + }, + }, + ], + fun: Var { + location: 161..173, + name: "combine_with", + }, + location: 161..183, + }, + Call { + arguments: [ + CallArg { + label: None, + location: 199..200, + value: Var { + location: 199..200, + name: "a", + }, + }, + CallArg { + label: None, + location: 202..204, + value: Fn { + location: 202..204, + fn_style: BinOp( + Or, + ), + arguments: [ + Arg { + arg_name: Named { + name: "left", + label: "left", + location: 202..204, + is_validator_param: false, + }, + location: 202..204, + annotation: Some( + Constructor { + location: 202..204, + module: None, + name: "Bool", + arguments: [], + }, + ), + tipo: (), + }, + Arg { + arg_name: Named { + name: "right", + label: "right", + location: 202..204, + is_validator_param: false, + }, + location: 202..204, + annotation: Some( + Constructor { + location: 202..204, + module: None, + name: "Bool", + arguments: [], + }, + ), + tipo: (), + }, + ], + body: BinOp { + location: 202..204, + name: Or, + left: Var { + location: 202..204, + name: "left", + }, + right: Var { + location: 202..204, + name: "right", + }, + }, + return_annotation: Some( + Constructor { + location: 202..204, + module: None, + name: "Bool", + arguments: [], + }, + ), + }, + }, + CallArg { + label: None, + location: 206..207, + value: Var { + location: 206..207, + name: "b", + }, + }, + ], + fun: Var { + location: 186..198, + name: "combine_with", + }, + location: 186..208, + }, + Call { + arguments: [ + CallArg { + label: None, + location: 224..225, + value: Var { + location: 224..225, + name: "a", + }, + }, + CallArg { + label: None, + location: 227..228, + value: Fn { + location: 227..228, + fn_style: BinOp( + AddInt, + ), + arguments: [ + Arg { + arg_name: Named { + name: "left", + label: "left", + location: 227..228, + is_validator_param: false, + }, + location: 227..228, + annotation: Some( + Constructor { + location: 227..228, + module: None, + name: "Int", + arguments: [], + }, + ), + tipo: (), + }, + Arg { + arg_name: Named { + name: "right", + label: "right", + location: 227..228, + is_validator_param: false, + }, + location: 227..228, + annotation: Some( + Constructor { + location: 227..228, + module: None, + name: "Int", + arguments: [], + }, + ), + tipo: (), + }, + ], + body: BinOp { + location: 227..228, + name: AddInt, + left: Var { + location: 227..228, + name: "left", + }, + right: Var { + location: 227..228, + name: "right", + }, + }, + return_annotation: Some( + Constructor { + location: 227..228, + module: None, + name: "Int", + arguments: [], + }, + ), + }, + }, + CallArg { + label: None, + location: 230..231, + value: Var { + location: 230..231, + name: "b", + }, + }, + ], + fun: Var { + location: 211..223, + name: "compute_with", + }, + location: 211..232, + }, + Call { + arguments: [ + CallArg { + label: None, + location: 248..249, + value: Var { + location: 248..249, + name: "a", + }, + }, + CallArg { + label: None, + location: 251..252, + value: Fn { + location: 251..252, + fn_style: BinOp( + SubInt, + ), + arguments: [ + Arg { + arg_name: Named { + name: "left", + label: "left", + location: 251..252, + is_validator_param: false, + }, + location: 251..252, + annotation: Some( + Constructor { + location: 251..252, + module: None, + name: "Int", + arguments: [], + }, + ), + tipo: (), + }, + Arg { + arg_name: Named { + name: "right", + label: "right", + location: 251..252, + is_validator_param: false, + }, + location: 251..252, + annotation: Some( + Constructor { + location: 251..252, + module: None, + name: "Int", + arguments: [], + }, + ), + tipo: (), + }, + ], + body: BinOp { + location: 251..252, + name: SubInt, + left: Var { + location: 251..252, + name: "left", + }, + right: Var { + location: 251..252, + name: "right", + }, + }, + return_annotation: Some( + Constructor { + location: 251..252, + module: None, + name: "Int", + arguments: [], + }, + ), + }, + }, + CallArg { + label: None, + location: 254..255, + value: Var { + location: 254..255, + name: "b", + }, + }, + ], + fun: Var { + location: 235..247, + name: "compute_with", + }, + location: 235..256, + }, + Call { + arguments: [ + CallArg { + label: None, + location: 272..273, + value: Var { + location: 272..273, + name: "a", + }, + }, + CallArg { + label: None, + location: 275..276, + value: Fn { + location: 275..276, + fn_style: BinOp( + DivInt, + ), + arguments: [ + Arg { + arg_name: Named { + name: "left", + label: "left", + location: 275..276, + is_validator_param: false, + }, + location: 275..276, + annotation: Some( + Constructor { + location: 275..276, + module: None, + name: "Int", + arguments: [], + }, + ), + tipo: (), + }, + Arg { + arg_name: Named { + name: "right", + label: "right", + location: 275..276, + is_validator_param: false, + }, + location: 275..276, + annotation: Some( + Constructor { + location: 275..276, + module: None, + name: "Int", + arguments: [], + }, + ), + tipo: (), + }, + ], + body: BinOp { + location: 275..276, + name: DivInt, + left: Var { + location: 275..276, + name: "left", + }, + right: Var { + location: 275..276, + name: "right", + }, + }, + return_annotation: Some( + Constructor { + location: 275..276, + module: None, + name: "Int", + arguments: [], + }, + ), + }, + }, + CallArg { + label: None, + location: 278..279, + value: Var { + location: 278..279, + name: "b", + }, + }, + ], + fun: Var { + location: 259..271, + name: "compute_with", + }, + location: 259..280, + }, + Call { + arguments: [ + CallArg { + label: None, + location: 296..297, + value: Var { + location: 296..297, + name: "a", + }, + }, + CallArg { + label: None, + location: 299..300, + value: Fn { + location: 299..300, + fn_style: BinOp( + MultInt, + ), + arguments: [ + Arg { + arg_name: Named { + name: "left", + label: "left", + location: 299..300, + is_validator_param: false, + }, + location: 299..300, + annotation: Some( + Constructor { + location: 299..300, + module: None, + name: "Int", + arguments: [], + }, + ), + tipo: (), + }, + Arg { + arg_name: Named { + name: "right", + label: "right", + location: 299..300, + is_validator_param: false, + }, + location: 299..300, + annotation: Some( + Constructor { + location: 299..300, + module: None, + name: "Int", + arguments: [], + }, + ), + tipo: (), + }, + ], + body: BinOp { + location: 299..300, + name: MultInt, + left: Var { + location: 299..300, + name: "left", + }, + right: Var { + location: 299..300, + name: "right", + }, + }, + return_annotation: Some( + Constructor { + location: 299..300, + module: None, + name: "Int", + arguments: [], + }, + ), + }, + }, + CallArg { + label: None, + location: 302..303, + value: Var { + location: 302..303, + name: "b", + }, + }, + ], + fun: Var { + location: 283..295, + name: "compute_with", + }, + location: 283..304, + }, + Call { + arguments: [ + CallArg { + label: None, + location: 320..321, + value: Var { + location: 320..321, + name: "a", + }, + }, + CallArg { + label: None, + location: 323..324, + value: Fn { + location: 323..324, + fn_style: BinOp( + ModInt, + ), + arguments: [ + Arg { + arg_name: Named { + name: "left", + label: "left", + location: 323..324, + is_validator_param: false, + }, + location: 323..324, + annotation: Some( + Constructor { + location: 323..324, + module: None, + name: "Int", + arguments: [], + }, + ), + tipo: (), + }, + Arg { + arg_name: Named { + name: "right", + label: "right", + location: 323..324, + is_validator_param: false, + }, + location: 323..324, + annotation: Some( + Constructor { + location: 323..324, + module: None, + name: "Int", + arguments: [], + }, + ), + tipo: (), + }, + ], + body: BinOp { + location: 323..324, + name: ModInt, + left: Var { + location: 323..324, + name: "left", + }, + right: Var { + location: 323..324, + name: "right", + }, + }, + return_annotation: Some( + Constructor { + location: 323..324, + module: None, + name: "Int", + arguments: [], + }, + ), + }, + }, + CallArg { + label: None, + location: 326..327, + value: Var { + location: 326..327, + name: "b", + }, + }, + ], + fun: Var { + location: 307..319, + name: "compute_with", + }, + location: 307..328, + }, + ], + }, + doc: None, + location: 0..8, + name: "foo", + public: false, + return_annotation: None, + return_type: (), + end_position: 329, + can_error: true, + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__function_ambiguous_sequence.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__function_ambiguous_sequence.snap new file mode 100644 index 00000000..5eab570c --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__function_ambiguous_sequence.snap @@ -0,0 +1,202 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n fn foo_1() {\n let a = bar\n (40)\n }\n\n fn foo_2() {\n let a = bar\n {40}\n }\n\n fn foo_3() {\n let a = (40+2)\n }\n\n fn foo_4() {\n let a = bar(42)\n (a + 14) * 42\n }\n " +info: function_ambiguous_sequence +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + Fn( + Function { + arguments: [], + body: Sequence { + location: 15..32, + expressions: [ + Assignment { + location: 15..26, + value: Var { + location: 23..26, + name: "bar", + }, + pattern: Var { + location: 19..20, + name: "a", + }, + kind: Let, + annotation: None, + }, + Int { + location: 30..32, + value: "40", + base: Decimal { + numeric_underscore: false, + }, + }, + ], + }, + doc: None, + location: 0..10, + name: "foo_1", + public: false, + return_annotation: None, + return_type: (), + end_position: 34, + can_error: true, + }, + ), + Fn( + Function { + arguments: [], + body: Sequence { + location: 52..69, + expressions: [ + Assignment { + location: 52..63, + value: Var { + location: 60..63, + name: "bar", + }, + pattern: Var { + location: 56..57, + name: "a", + }, + kind: Let, + annotation: None, + }, + Int { + location: 67..69, + value: "40", + base: Decimal { + numeric_underscore: false, + }, + }, + ], + }, + doc: None, + location: 37..47, + name: "foo_2", + public: false, + return_annotation: None, + return_type: (), + end_position: 71, + can_error: true, + }, + ), + Fn( + Function { + arguments: [], + body: Assignment { + location: 89..103, + value: BinOp { + location: 98..102, + name: AddInt, + left: Int { + location: 98..100, + value: "40", + base: Decimal { + numeric_underscore: false, + }, + }, + right: Int { + location: 101..102, + value: "2", + base: Decimal { + numeric_underscore: false, + }, + }, + }, + pattern: Var { + location: 93..94, + name: "a", + }, + kind: Let, + annotation: None, + }, + doc: None, + location: 74..84, + name: "foo_3", + public: false, + return_annotation: None, + return_type: (), + end_position: 104, + can_error: true, + }, + ), + Fn( + Function { + arguments: [], + body: Sequence { + location: 122..153, + expressions: [ + Assignment { + location: 122..137, + value: Call { + arguments: [ + CallArg { + label: None, + location: 134..136, + value: Int { + location: 134..136, + value: "42", + base: Decimal { + numeric_underscore: false, + }, + }, + }, + ], + fun: Var { + location: 130..133, + name: "bar", + }, + location: 130..137, + }, + pattern: Var { + location: 126..127, + name: "a", + }, + kind: Let, + annotation: None, + }, + BinOp { + location: 141..153, + name: MultInt, + left: BinOp { + location: 141..147, + name: AddInt, + left: Var { + location: 141..142, + name: "a", + }, + right: Int { + location: 145..147, + value: "14", + base: Decimal { + numeric_underscore: false, + }, + }, + }, + right: Int { + location: 151..153, + value: "42", + base: Decimal { + numeric_underscore: false, + }, + }, + }, + ], + }, + doc: None, + location: 107..117, + name: "foo_4", + public: false, + return_annotation: None, + return_type: (), + end_position: 154, + can_error: true, + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__function_def.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__function_def.snap new file mode 100644 index 00000000..0ee47d90 --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__function_def.snap @@ -0,0 +1,37 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n fn foo() {}\n " +info: function_def +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + Fn( + Function { + arguments: [], + body: Trace { + kind: Todo, + location: 0..11, + then: ErrorTerm { + location: 0..11, + }, + text: String { + location: 0..11, + value: "aiken::todo", + }, + }, + doc: None, + location: 0..8, + name: "foo", + public: false, + return_annotation: None, + return_type: (), + end_position: 10, + can_error: true, + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__function_invoke.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__function_invoke.snap new file mode 100644 index 00000000..fad161a3 --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__function_invoke.snap @@ -0,0 +1,55 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n fn foo() {\n let a = bar(42)\n }\n " +info: function_invoke +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + Fn( + Function { + arguments: [], + body: Assignment { + location: 15..30, + value: Call { + arguments: [ + CallArg { + label: None, + location: 27..29, + value: Int { + location: 27..29, + value: "42", + base: Decimal { + numeric_underscore: false, + }, + }, + }, + ], + fun: Var { + location: 23..26, + name: "bar", + }, + location: 23..30, + }, + pattern: Var { + location: 19..20, + name: "a", + }, + kind: Let, + annotation: None, + }, + doc: None, + location: 0..8, + name: "foo", + public: false, + return_annotation: None, + return_type: (), + end_position: 31, + can_error: true, + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__if_expression.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__if_expression.snap new file mode 100644 index 00000000..e031484d --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__if_expression.snap @@ -0,0 +1,110 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n fn ifs() {\n if True {\n 1 + 1\n } else if a < 4 {\n 5\n } else if a || b {\n 6\n } else {\n 3\n }\n }\n " +info: if_expression +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + Fn( + Function { + arguments: [], + body: If { + location: 13..106, + branches: [ + IfBranch { + condition: Var { + location: 16..20, + name: "True", + }, + body: BinOp { + location: 27..32, + name: AddInt, + left: Int { + location: 27..28, + value: "1", + base: Decimal { + numeric_underscore: false, + }, + }, + right: Int { + location: 31..32, + value: "1", + base: Decimal { + numeric_underscore: false, + }, + }, + }, + location: 16..36, + }, + IfBranch { + condition: BinOp { + location: 45..50, + name: LtInt, + left: Var { + location: 45..46, + name: "a", + }, + right: Int { + location: 49..50, + value: "4", + base: Decimal { + numeric_underscore: false, + }, + }, + }, + body: Int { + location: 57..58, + value: "5", + base: Decimal { + numeric_underscore: false, + }, + }, + location: 45..62, + }, + IfBranch { + condition: BinOp { + location: 71..77, + name: Or, + left: Var { + location: 71..72, + name: "a", + }, + right: Var { + location: 76..77, + name: "b", + }, + }, + body: Int { + location: 84..85, + value: "6", + base: Decimal { + numeric_underscore: false, + }, + }, + location: 71..89, + }, + ], + final_else: Int { + location: 101..102, + value: "3", + base: Decimal { + numeric_underscore: false, + }, + }, + }, + doc: None, + location: 0..8, + name: "ifs", + public: false, + return_annotation: None, + return_type: (), + end_position: 107, + can_error: true, + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__import.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__import.snap new file mode 100644 index 00000000..bb9e4663 --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__import.snap @@ -0,0 +1,25 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n use std/list\n " +info: import +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + Use( + Use { + as_name: None, + location: 0..12, + module: [ + "std", + "list", + ], + package: (), + unqualified: [], + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__import_alias.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__import_alias.snap new file mode 100644 index 00000000..e61aa49e --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__import_alias.snap @@ -0,0 +1,27 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n use std/tx as t\n " +info: import_alias +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + Use( + Use { + as_name: Some( + "t", + ), + location: 0..15, + module: [ + "std", + "tx", + ], + package: (), + unqualified: [], + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__int_parsing_hex_bytes.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__int_parsing_hex_bytes.snap new file mode 100644 index 00000000..6d8eed84 --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__int_parsing_hex_bytes.snap @@ -0,0 +1,37 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n fn foo() {\n #[ 0x01, 0xa2, 0x03 ]\n }\n " +info: int_parsing_hex_bytes +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + Fn( + Function { + arguments: [], + body: ByteArray { + location: 13..34, + bytes: [ + 1, + 162, + 3, + ], + preferred_format: ArrayOfBytes( + Hexadecimal, + ), + }, + doc: None, + location: 0..8, + name: "foo", + public: false, + return_annotation: None, + return_type: (), + end_position: 35, + can_error: true, + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__let_bindings.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__let_bindings.snap new file mode 100644 index 00000000..aa4e73c7 --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__let_bindings.snap @@ -0,0 +1,137 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n pub fn wow(a: Int) {\n let x =\n a + 2\n |> add_one\n |> add_one\n\n let thing = [ 1, 2, a ]\n\n let idk = thing\n\n y\n }\n " +info: let_bindings +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + Fn( + Function { + arguments: [ + Arg { + arg_name: Named { + name: "a", + label: "a", + location: 11..12, + is_validator_param: false, + }, + location: 11..17, + annotation: Some( + Constructor { + location: 14..17, + module: None, + name: "Int", + arguments: [], + }, + ), + tipo: (), + }, + ], + body: Sequence { + location: 23..121, + expressions: [ + Assignment { + location: 23..70, + value: PipeLine { + expressions: [ + BinOp { + location: 35..40, + name: AddInt, + left: Var { + location: 35..36, + name: "a", + }, + right: Int { + location: 39..40, + value: "2", + base: Decimal { + numeric_underscore: false, + }, + }, + }, + Var { + location: 48..55, + name: "add_one", + }, + Var { + location: 63..70, + name: "add_one", + }, + ], + one_liner: false, + }, + pattern: Var { + location: 27..28, + name: "x", + }, + kind: Let, + annotation: None, + }, + Assignment { + location: 74..97, + value: List { + location: 86..97, + elements: [ + Int { + location: 88..89, + value: "1", + base: Decimal { + numeric_underscore: false, + }, + }, + Int { + location: 91..92, + value: "2", + base: Decimal { + numeric_underscore: false, + }, + }, + Var { + location: 94..95, + name: "a", + }, + ], + tail: None, + }, + pattern: Var { + location: 78..83, + name: "thing", + }, + kind: Let, + annotation: None, + }, + Assignment { + location: 101..116, + value: Var { + location: 111..116, + name: "thing", + }, + pattern: Var { + location: 105..108, + name: "idk", + }, + kind: Let, + annotation: None, + }, + Var { + location: 120..121, + name: "y", + }, + ], + }, + doc: None, + location: 0..18, + name: "wow", + public: true, + return_annotation: None, + return_type: (), + end_position: 122, + can_error: true, + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__opaque_type.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__opaque_type.snap new file mode 100644 index 00000000..5d2546d7 --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__opaque_type.snap @@ -0,0 +1,46 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n pub opaque type User {\n name: _w\n }\n " +info: opaque_type +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + DataType( + DataType { + constructors: [ + RecordConstructor { + location: 21..35, + name: "User", + arguments: [ + RecordConstructorArg { + label: Some( + "name", + ), + annotation: Hole { + location: 31..33, + name: "_w", + }, + location: 25..33, + tipo: (), + doc: None, + }, + ], + doc: None, + sugar: true, + }, + ], + doc: None, + location: 0..35, + name: "User", + opaque: true, + parameters: [], + public: true, + typed_parameters: [], + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__parse_tuple.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__parse_tuple.snap new file mode 100644 index 00000000..5c6d780e --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__parse_tuple.snap @@ -0,0 +1,117 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n fn foo() {\n let tuple = (1, 2, 3, 4)\n tuple.1st + tuple.2nd + tuple.3rd + tuple.4th\n }\n " +info: parse_tuple +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + Fn( + Function { + arguments: [], + body: Sequence { + location: 13..85, + expressions: [ + Assignment { + location: 13..37, + value: Tuple { + location: 25..37, + elems: [ + Int { + location: 26..27, + value: "1", + base: Decimal { + numeric_underscore: false, + }, + }, + Int { + location: 29..30, + value: "2", + base: Decimal { + numeric_underscore: false, + }, + }, + Int { + location: 32..33, + value: "3", + base: Decimal { + numeric_underscore: false, + }, + }, + Int { + location: 35..36, + value: "4", + base: Decimal { + numeric_underscore: false, + }, + }, + ], + }, + pattern: Var { + location: 17..22, + name: "tuple", + }, + kind: Let, + annotation: None, + }, + BinOp { + location: 40..85, + name: AddInt, + left: BinOp { + location: 40..73, + name: AddInt, + left: BinOp { + location: 40..61, + name: AddInt, + left: TupleIndex { + location: 40..49, + index: 0, + tuple: Var { + location: 40..45, + name: "tuple", + }, + }, + right: TupleIndex { + location: 52..61, + index: 1, + tuple: Var { + location: 52..57, + name: "tuple", + }, + }, + }, + right: TupleIndex { + location: 64..73, + index: 2, + tuple: Var { + location: 64..69, + name: "tuple", + }, + }, + }, + right: TupleIndex { + location: 76..85, + index: 3, + tuple: Var { + location: 76..81, + name: "tuple", + }, + }, + }, + ], + }, + doc: None, + location: 0..8, + name: "foo", + public: false, + return_annotation: None, + return_type: (), + end_position: 86, + can_error: true, + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__parse_tuple2.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__parse_tuple2.snap new file mode 100644 index 00000000..5cd5d8f0 --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__parse_tuple2.snap @@ -0,0 +1,76 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n fn foo() {\n let a = foo(14)\n (a, 42)\n }\n " +info: parse_tuple2 +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + Fn( + Function { + arguments: [], + body: Sequence { + location: 13..38, + expressions: [ + Assignment { + location: 13..28, + value: Call { + arguments: [ + CallArg { + label: None, + location: 25..27, + value: Int { + location: 25..27, + value: "14", + base: Decimal { + numeric_underscore: false, + }, + }, + }, + ], + fun: Var { + location: 21..24, + name: "foo", + }, + location: 21..28, + }, + pattern: Var { + location: 17..18, + name: "a", + }, + kind: Let, + annotation: None, + }, + Tuple { + location: 31..38, + elems: [ + Var { + location: 32..33, + name: "a", + }, + Int { + location: 35..37, + value: "42", + base: Decimal { + numeric_underscore: false, + }, + }, + ], + }, + ], + }, + doc: None, + location: 0..8, + name: "foo", + public: false, + return_annotation: None, + return_type: (), + end_position: 39, + can_error: true, + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__parsing_numeric_underscore.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__parsing_numeric_underscore.snap new file mode 100644 index 00000000..0b298984 --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__parsing_numeric_underscore.snap @@ -0,0 +1,83 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n fn foo() {\n let i = 1_234_567\n let j = 1_000_000\n let k = -10_000\n }\n " +info: test_parsing_numeric_underscore +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + Fn( + Function { + arguments: [], + body: Sequence { + location: 17..76, + expressions: [ + Assignment { + location: 17..34, + value: Int { + location: 25..34, + value: "1234567", + base: Decimal { + numeric_underscore: true, + }, + }, + pattern: Var { + location: 21..22, + name: "i", + }, + kind: Let, + annotation: None, + }, + Assignment { + location: 39..56, + value: Int { + location: 47..56, + value: "1000000", + base: Decimal { + numeric_underscore: true, + }, + }, + pattern: Var { + location: 43..44, + name: "j", + }, + kind: Let, + annotation: None, + }, + Assignment { + location: 61..76, + value: UnOp { + op: Negate, + location: 69..76, + value: Int { + location: 70..76, + value: "10000", + base: Decimal { + numeric_underscore: true, + }, + }, + }, + pattern: Var { + location: 65..66, + name: "k", + }, + kind: Let, + annotation: None, + }, + ], + }, + doc: None, + location: 2..10, + name: "foo", + public: false, + return_annotation: None, + return_type: (), + end_position: 77, + can_error: true, + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__pipeline.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__pipeline.snap new file mode 100644 index 00000000..cdeb27a8 --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__pipeline.snap @@ -0,0 +1,73 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n pub fn thing(thing a: Int) {\n a + 2\n |> add_one\n |> add_one\n }\n " +info: pipeline +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + Fn( + Function { + arguments: [ + Arg { + arg_name: Named { + name: "a", + label: "thing", + location: 13..20, + is_validator_param: false, + }, + location: 13..25, + annotation: Some( + Constructor { + location: 22..25, + module: None, + name: "Int", + arguments: [], + }, + ), + tipo: (), + }, + ], + body: PipeLine { + expressions: [ + BinOp { + location: 31..36, + name: AddInt, + left: Var { + location: 31..32, + name: "a", + }, + right: Int { + location: 35..36, + value: "2", + base: Decimal { + numeric_underscore: false, + }, + }, + }, + Var { + location: 42..49, + name: "add_one", + }, + Var { + location: 55..62, + name: "add_one", + }, + ], + one_liner: false, + }, + doc: None, + location: 0..26, + name: "thing", + public: true, + return_annotation: None, + return_type: (), + end_position: 63, + can_error: true, + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__plain_bytearray_literals.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__plain_bytearray_literals.snap new file mode 100644 index 00000000..5178dc9a --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__plain_bytearray_literals.snap @@ -0,0 +1,36 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n pub const my_policy_id = #[0, 170, 255]\n " +info: plain_bytearray_literals +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + ModuleConstant( + ModuleConstant { + doc: None, + location: 0..39, + public: true, + name: "my_policy_id", + annotation: None, + value: ByteArray { + location: 25..39, + bytes: [ + 0, + 170, + 255, + ], + preferred_format: ArrayOfBytes( + Decimal { + numeric_underscore: false, + }, + ), + }, + tipo: (), + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__plus_binop.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__plus_binop.snap new file mode 100644 index 00000000..9ff39e32 --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__plus_binop.snap @@ -0,0 +1,60 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n pub fn add_one(a) -> Int {\n a + 1\n }\n " +info: plus_binop +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + Fn( + Function { + arguments: [ + Arg { + arg_name: Named { + name: "a", + label: "a", + location: 15..16, + is_validator_param: false, + }, + location: 15..16, + annotation: None, + tipo: (), + }, + ], + body: BinOp { + location: 29..34, + name: AddInt, + left: Var { + location: 29..30, + name: "a", + }, + right: Int { + location: 33..34, + value: "1", + base: Decimal { + numeric_underscore: false, + }, + }, + }, + doc: None, + location: 0..24, + name: "add_one", + public: true, + return_annotation: Some( + Constructor { + location: 21..24, + module: None, + name: "Int", + arguments: [], + }, + ), + return_type: (), + end_position: 35, + can_error: true, + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__pub_type_alias.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__pub_type_alias.snap new file mode 100644 index 00000000..0037e397 --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__pub_type_alias.snap @@ -0,0 +1,36 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n pub type Me = Option\n " +info: pub_type_alias +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + TypeAlias( + TypeAlias { + alias: "Me", + annotation: Constructor { + location: 14..28, + module: None, + name: "Option", + arguments: [ + Constructor { + location: 21..27, + module: None, + name: "String", + arguments: [], + }, + ], + }, + doc: None, + location: 0..28, + parameters: [], + public: true, + tipo: (), + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__record_create_labeled.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__record_create_labeled.snap new file mode 100644 index 00000000..ade46c03 --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__record_create_labeled.snap @@ -0,0 +1,75 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n fn create() {\n User { name: \"Aiken\", age, thing: 2 }\n }\n " +info: record_create_labeled +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + Fn( + Function { + arguments: [], + body: Call { + arguments: [ + CallArg { + label: Some( + "name", + ), + location: 23..36, + value: ByteArray { + location: 29..36, + bytes: [ + 65, + 105, + 107, + 101, + 110, + ], + preferred_format: Utf8String, + }, + }, + CallArg { + label: Some( + "age", + ), + location: 38..41, + value: Var { + location: 38..41, + name: "age", + }, + }, + CallArg { + label: Some( + "thing", + ), + location: 43..51, + value: Int { + location: 50..51, + value: "2", + base: Decimal { + numeric_underscore: false, + }, + }, + }, + ], + fun: Var { + location: 16..20, + name: "User", + }, + location: 16..53, + }, + doc: None, + location: 0..11, + name: "create", + public: false, + return_annotation: None, + return_type: (), + end_position: 54, + can_error: true, + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__record_create_labeled_with_field_access.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__record_create_labeled_with_field_access.snap new file mode 100644 index 00000000..4f2351d5 --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__record_create_labeled_with_field_access.snap @@ -0,0 +1,79 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n fn create() {\n some_module.User { name: \"Aiken\", age, thing: 2 }\n }\n " +info: record_create_labeled_with_field_access +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + Fn( + Function { + arguments: [], + body: Call { + arguments: [ + CallArg { + label: Some( + "name", + ), + location: 35..48, + value: ByteArray { + location: 41..48, + bytes: [ + 65, + 105, + 107, + 101, + 110, + ], + preferred_format: Utf8String, + }, + }, + CallArg { + label: Some( + "age", + ), + location: 50..53, + value: Var { + location: 50..53, + name: "age", + }, + }, + CallArg { + label: Some( + "thing", + ), + location: 55..63, + value: Int { + location: 62..63, + value: "2", + base: Decimal { + numeric_underscore: false, + }, + }, + }, + ], + fun: FieldAccess { + location: 16..32, + label: "User", + container: Var { + location: 16..27, + name: "some_module", + }, + }, + location: 16..65, + }, + doc: None, + location: 0..11, + name: "create", + public: false, + return_annotation: None, + return_type: (), + end_position: 66, + can_error: true, + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__record_update.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__record_update.snap new file mode 100644 index 00000000..70cf105f --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__record_update.snap @@ -0,0 +1,109 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n fn update_name(user: User, name: ByteArray) -> User {\n User { ..user, name: \"Aiken\", age }\n }\n " +info: record_update +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + Fn( + Function { + arguments: [ + Arg { + arg_name: Named { + name: "user", + label: "user", + location: 15..19, + is_validator_param: false, + }, + location: 15..25, + annotation: Some( + Constructor { + location: 21..25, + module: None, + name: "User", + arguments: [], + }, + ), + tipo: (), + }, + Arg { + arg_name: Named { + name: "name", + label: "name", + location: 27..31, + is_validator_param: false, + }, + location: 27..42, + annotation: Some( + Constructor { + location: 33..42, + module: None, + name: "ByteArray", + arguments: [], + }, + ), + tipo: (), + }, + ], + body: RecordUpdate { + location: 56..91, + constructor: Var { + location: 56..60, + name: "User", + }, + spread: RecordUpdateSpread { + base: Var { + location: 65..69, + name: "user", + }, + location: 63..69, + }, + arguments: [ + UntypedRecordUpdateArg { + label: "name", + location: 71..84, + value: ByteArray { + location: 77..84, + bytes: [ + 65, + 105, + 107, + 101, + 110, + ], + preferred_format: Utf8String, + }, + }, + UntypedRecordUpdateArg { + label: "age", + location: 86..89, + value: Var { + location: 86..89, + name: "age", + }, + }, + ], + }, + doc: None, + location: 0..51, + name: "update_name", + public: false, + return_annotation: Some( + Constructor { + location: 47..51, + module: None, + name: "User", + arguments: [], + }, + ), + return_type: (), + end_position: 92, + can_error: true, + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__tuple_type_alias.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__tuple_type_alias.snap new file mode 100644 index 00000000..d0bb9780 --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__tuple_type_alias.snap @@ -0,0 +1,40 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n type RoyaltyToken = (PolicyId, AssetName)\n " +info: tuple_type_alias +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + TypeAlias( + TypeAlias { + alias: "RoyaltyToken", + annotation: Tuple { + location: 20..41, + elems: [ + Constructor { + location: 21..29, + module: None, + name: "PolicyId", + arguments: [], + }, + Constructor { + location: 31..40, + module: None, + name: "AssetName", + arguments: [], + }, + ], + }, + doc: None, + location: 0..41, + parameters: [], + public: false, + tipo: (), + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__type_alias.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__type_alias.snap new file mode 100644 index 00000000..e36b18a5 --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__type_alias.snap @@ -0,0 +1,36 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n type Thing = Option\n " +info: type_alias +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + TypeAlias( + TypeAlias { + alias: "Thing", + annotation: Constructor { + location: 13..24, + module: None, + name: "Option", + arguments: [ + Constructor { + location: 20..23, + module: None, + name: "Int", + arguments: [], + }, + ], + }, + doc: None, + location: 0..24, + parameters: [], + public: false, + tipo: (), + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__type_annotation_with_module_prefix.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__type_annotation_with_module_prefix.snap new file mode 100644 index 00000000..140a0ba3 --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__type_annotation_with_module_prefix.snap @@ -0,0 +1,57 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n use aiken\n\n pub fn go() -> aiken.Option {\n False\n }\n " +info: type_annotation_with_module_prefix +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + Use( + Use { + as_name: None, + location: 0..9, + module: [ + "aiken", + ], + package: (), + unqualified: [], + }, + ), + Fn( + Function { + arguments: [], + body: Var { + location: 48..53, + name: "False", + }, + doc: None, + location: 11..43, + name: "go", + public: true, + return_annotation: Some( + Constructor { + location: 26..43, + module: Some( + "aiken", + ), + name: "Option", + arguments: [ + Constructor { + location: 39..42, + module: None, + name: "Int", + arguments: [], + }, + ], + }, + ), + return_type: (), + end_position: 54, + can_error: true, + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__unqualified_imports.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__unqualified_imports.snap new file mode 100644 index 00000000..3f155926 --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__unqualified_imports.snap @@ -0,0 +1,42 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n use std/address.{Address as A, thing as w}\n " +info: unqualified_imports +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + Use( + Use { + as_name: None, + location: 0..42, + module: [ + "std", + "address", + ], + package: (), + unqualified: [ + UnqualifiedImport { + location: 17..29, + name: "Address", + as_name: Some( + "A", + ), + layer: Value, + }, + UnqualifiedImport { + location: 31..41, + name: "thing", + as_name: Some( + "w", + ), + layer: Value, + }, + ], + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__validator.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__validator.snap new file mode 100644 index 00000000..c3bb017a --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__validator.snap @@ -0,0 +1,71 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n validator {\n fn foo(datum, rdmr, ctx) {\n True\n }\n }\n " +info: validator +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + Validator( + Validator { + doc: None, + end_position: 54, + fun: Function { + arguments: [ + Arg { + arg_name: Named { + name: "datum", + label: "datum", + location: 21..26, + is_validator_param: false, + }, + location: 21..26, + annotation: None, + tipo: (), + }, + Arg { + arg_name: Named { + name: "rdmr", + label: "rdmr", + location: 28..32, + is_validator_param: false, + }, + location: 28..32, + annotation: None, + tipo: (), + }, + Arg { + arg_name: Named { + name: "ctx", + label: "ctx", + location: 34..37, + is_validator_param: false, + }, + location: 34..37, + annotation: None, + tipo: (), + }, + ], + body: Var { + location: 45..49, + name: "True", + }, + doc: None, + location: 14..38, + name: "foo", + public: false, + return_annotation: None, + return_type: (), + end_position: 52, + can_error: true, + }, + other_fun: None, + location: 0..9, + params: [], + }, + ), + ], + kind: Validator, +} diff --git a/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__when.snap b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__when.snap new file mode 100644 index 00000000..48653cbe --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/aiken_lang__tests__parser__when.snap @@ -0,0 +1,163 @@ +--- +source: crates/aiken-lang/src/tests/parser.rs +description: "\n pub fn wow2(a: Int){\n when a is {\n 2 -> 3\n 1 | 4 | 5 -> {\n let amazing = 5\n amazing\n }\n 3 -> 9\n _ -> 4\n }\n }\n " +info: when +--- +Module { + name: "", + docs: [], + type_info: (), + definitions: [ + Fn( + Function { + arguments: [ + Arg { + arg_name: Named { + name: "a", + label: "a", + location: 12..13, + is_validator_param: false, + }, + location: 12..18, + annotation: Some( + Constructor { + location: 15..18, + module: None, + name: "Int", + arguments: [], + }, + ), + tipo: (), + }, + ], + body: When { + location: 23..132, + subject: Var { + location: 28..29, + name: "a", + }, + clauses: [ + UntypedClause { + location: 39..45, + patterns: [ + Int { + location: 39..40, + value: "2", + base: Decimal { + numeric_underscore: false, + }, + }, + ], + guard: None, + then: Int { + location: 44..45, + value: "3", + base: Decimal { + numeric_underscore: false, + }, + }, + }, + UntypedClause { + location: 50..106, + patterns: [ + Int { + location: 50..51, + value: "1", + base: Decimal { + numeric_underscore: false, + }, + }, + Int { + location: 54..55, + value: "4", + base: Decimal { + numeric_underscore: false, + }, + }, + Int { + location: 58..59, + value: "5", + base: Decimal { + numeric_underscore: false, + }, + }, + ], + guard: None, + then: Sequence { + location: 71..100, + expressions: [ + Assignment { + location: 71..86, + value: Int { + location: 85..86, + value: "5", + base: Decimal { + numeric_underscore: false, + }, + }, + pattern: Var { + location: 75..82, + name: "amazing", + }, + kind: Let, + annotation: None, + }, + Var { + location: 93..100, + name: "amazing", + }, + ], + }, + }, + UntypedClause { + location: 111..117, + patterns: [ + Int { + location: 111..112, + value: "3", + base: Decimal { + numeric_underscore: false, + }, + }, + ], + guard: None, + then: Int { + location: 116..117, + value: "9", + base: Decimal { + numeric_underscore: false, + }, + }, + }, + UntypedClause { + location: 122..128, + patterns: [ + Discard { + name: "_", + location: 122..123, + }, + ], + guard: None, + then: Int { + location: 127..128, + value: "4", + base: Decimal { + numeric_underscore: false, + }, + }, + }, + ], + }, + doc: None, + location: 0..19, + name: "wow2", + public: true, + return_annotation: None, + return_type: (), + end_position: 133, + can_error: true, + }, + ), + ], + kind: Validator, +}