From 6a4a602391df0e2bd74811513afd6db2d1327704 Mon Sep 17 00:00:00 2001 From: KtorZ Date: Sun, 16 Mar 2025 13:17:05 +0100 Subject: [PATCH] have namespaces work also for calls to record-like constructors. Signed-off-by: KtorZ --- crates/aiken-lang/src/parser/chain/mod.rs | 1 + crates/aiken-lang/src/parser/expr/record.rs | 79 +++++++++++++++------ crates/aiken-lang/src/tests/check.rs | 55 +++++++------- 3 files changed, 87 insertions(+), 48 deletions(-) diff --git a/crates/aiken-lang/src/parser/chain/mod.rs b/crates/aiken-lang/src/parser/chain/mod.rs index c56ff929..a791c5ae 100644 --- a/crates/aiken-lang/src/parser/chain/mod.rs +++ b/crates/aiken-lang/src/parser/chain/mod.rs @@ -4,6 +4,7 @@ pub(crate) mod call; pub(crate) mod field_access; pub(crate) mod tuple_index; +#[derive(Debug)] pub(crate) enum Chain { Call(Vec, Span), FieldAccess(String, Span), diff --git a/crates/aiken-lang/src/parser/expr/record.rs b/crates/aiken-lang/src/parser/expr/record.rs index d947d7f7..2e654f69 100644 --- a/crates/aiken-lang/src/parser/expr/record.rs +++ b/crates/aiken-lang/src/parser/expr/record.rs @@ -16,6 +16,12 @@ pub fn parser( .map_with_span(|module, span: ast::Span| (module, span)) .then_ignore(just(Token::Dot)) .or_not() + .then( + select! {Token::UpName { name } => name} + .map_with_span(|name, span| (name, span)) + .then_ignore(just(Token::Dot)) + .or_not(), + ) .then(select! {Token::UpName { name } => name}.map_with_span(|name, span| (name, span))) .then( choice(( @@ -117,6 +123,12 @@ pub fn parser( .map_with_span(|module, span| (module, span)) .then_ignore(just(Token::Dot)) .or_not() + .then( + select! {Token::UpName { name } => name} + .map_with_span(|name, span| (name, span)) + .then_ignore(just(Token::Dot)) + .or_not(), + ) .then(select! {Token::UpName { name } => name}.map_with_span(|name, span| (name, span))) .then( select! {Token::Name {name} => name} @@ -157,29 +169,52 @@ pub fn parser( .delimited_by(just(Token::LeftParen), just(Token::RightParen)), ), )) - .map_with_span(|((module, (name, n_span)), arguments), span| { - let fun = if let Some((module, m_span)) = module { - UntypedExpr::FieldAccess { - location: m_span.union(n_span), - label: name, - container: Box::new(UntypedExpr::Var { - location: m_span, - name: module, - }), - } - } else { - UntypedExpr::Var { - location: n_span, - name, - } - }; + .map_with_span( + |(((module, namespace), (label, label_span)), arguments), span| { + let fun = match (module, namespace) { + (Some((module, module_span)), Some((namespace, namespace_span))) => { + UntypedExpr::FieldAccess { + location: module_span.union(namespace_span).union(label_span), + label, + container: Box::new(UntypedExpr::FieldAccess { + location: module_span.union(namespace_span), + label: namespace, + container: Box::new(UntypedExpr::Var { + location: module_span, + name: module, + }), + }), + } + } + (None, Some((namespace, namespace_span))) => UntypedExpr::FieldAccess { + location: namespace_span.union(label_span), + label, + container: Box::new(UntypedExpr::Var { + location: namespace_span, + name: namespace, + }), + }, + (Some((module, module_span)), None) => UntypedExpr::FieldAccess { + location: module_span.union(label_span), + label, + container: Box::new(UntypedExpr::Var { + location: module_span, + name: module, + }), + }, + (None, None) => UntypedExpr::Var { + location: label_span, + name: label, + }, + }; - UntypedExpr::Call { - arguments, - fun: Box::new(fun), - location: span, - } - }) + UntypedExpr::Call { + arguments, + fun: Box::new(fun), + location: span, + } + }, + ) } #[cfg(test)] diff --git a/crates/aiken-lang/src/tests/check.rs b/crates/aiken-lang/src/tests/check.rs index 05753ef3..557d0495 100644 --- a/crates/aiken-lang/src/tests/check.rs +++ b/crates/aiken-lang/src/tests/check.rs @@ -2307,7 +2307,7 @@ fn use_imported_type_as_namespace_for_patterns() { fn use_type_as_namespace_for_patterns() { let dependency = r#" pub type Foo { - A + A { a: Int } B } "#; @@ -2317,7 +2317,7 @@ fn use_type_as_namespace_for_patterns() { fn bar(foo: Foo) { when foo is { - Foo.A -> True + Foo.A { a } -> a > 10 Foo.B -> False } } @@ -2332,7 +2332,7 @@ fn use_type_as_namespace_for_patterns() { fn use_nested_type_as_namespace_for_patterns() { let dependency = r#" pub type Foo { - A + A { a: Int } B } "#; @@ -2342,7 +2342,7 @@ fn use_nested_type_as_namespace_for_patterns() { fn bar(x: Foo) { when x is { - foo.Foo.A -> True + foo.Foo.A { a } -> a > 10 foo.Foo.B -> False } } @@ -2357,7 +2357,7 @@ fn use_nested_type_as_namespace_for_patterns() { fn use_opaque_type_as_namespace_for_patterns_fails() { let dependency = r#" pub opaque type Foo { - A + A { a: Int } B } "#; @@ -2367,7 +2367,7 @@ fn use_opaque_type_as_namespace_for_patterns_fails() { fn bar(foo: Foo) { when foo is { - Foo.A -> True + Foo.A { a } -> a > 10 Foo.B -> False } } @@ -2388,7 +2388,7 @@ fn use_opaque_type_as_namespace_for_patterns_fails() { fn use_wrong_type_as_namespace_for_patterns_fails() { let dependency = r#" pub type Foo { - A + A { a: Int } B } @@ -2403,7 +2403,7 @@ fn use_wrong_type_as_namespace_for_patterns_fails() { fn bar(foo: Foo) { when foo is { - Foo.A -> True + Foo.A { .. } -> True Foo.D -> False } } @@ -2424,7 +2424,7 @@ fn use_wrong_type_as_namespace_for_patterns_fails() { fn use_type_as_namespace_for_constructors() { let dependency = r#" pub type Foo { - I(Int) + I { i: Int } B(Bool) } "#; @@ -2434,7 +2434,7 @@ fn use_type_as_namespace_for_constructors() { test my_test() { and { - Foo.I(42) == foo.I(42), + Foo.I { i: 42 } == foo.I(42), foo.B(True) == Foo.B(True), } } @@ -2449,7 +2449,7 @@ fn use_type_as_namespace_for_constructors() { fn use_type_as_nested_namespace_for_constructors() { let dependency = r#" pub type Foo { - I(Int) + I { i: Int } B(Bool) } "#; @@ -2458,7 +2458,8 @@ fn use_type_as_nested_namespace_for_constructors() { use foo test my_test() { - trace foo.Foo.I(42) + trace foo.Foo.I { i: 42 } + trace foo.Foo.B(False) Void } "#; @@ -2472,7 +2473,7 @@ fn use_type_as_nested_namespace_for_constructors() { fn use_type_as_nested_namespace_for_constructors_from_multi_level_module() { let dependency = r#" pub type Foo { - I(Int) + I { i: Int } B(Bool) } "#; @@ -2481,7 +2482,8 @@ fn use_type_as_nested_namespace_for_constructors_from_multi_level_module() { use foo/bar test my_test() { - trace bar.Foo.I(42) + trace bar.Foo.I { i: 42 } + trace bar.Foo.B(True) Void } "#; @@ -2495,7 +2497,7 @@ fn use_type_as_nested_namespace_for_constructors_from_multi_level_module() { fn use_type_as_nested_namespace_for_constructors_from_module_alias() { let dependency = r#" pub type Foo { - I(Int) + I { i: Int } B(Bool) } "#; @@ -2504,7 +2506,8 @@ fn use_type_as_nested_namespace_for_constructors_from_module_alias() { use foo as bar test my_test() { - trace bar.Foo.I(42) + trace bar.Foo.I { i: 42 } + trace bar.Foo.B(True) Void } "#; @@ -2518,7 +2521,7 @@ fn use_type_as_nested_namespace_for_constructors_from_module_alias() { fn use_type_as_namespace_unknown_constructor() { let dependency = r#" pub type Foo { - I(Int) + I { i: Int } B(Bool) } "#; @@ -2527,7 +2530,7 @@ fn use_type_as_namespace_unknown_constructor() { use foo.{Foo} test my_test() { - Foo.A == Foo.I(42) + Foo.I(42) == Foo.A } "#; @@ -2546,12 +2549,12 @@ fn use_type_as_namespace_unknown_constructor() { fn use_wrong_type_as_namespace() { let dependency = r#" pub type Foo { - I(Int) + I { i: Int } B(Bool) } pub type Bar { - S(String) + S { s: String } L(List) } "#; @@ -2580,12 +2583,12 @@ fn use_wrong_type_as_namespace() { fn use_wrong_nested_type_as_namespace() { let dependency = r#" pub type Foo { - I(Int) + I { i: Int } B(Bool) } pub type Bar { - S(String) + S { s: String } L(List) } "#; @@ -2614,7 +2617,7 @@ fn use_wrong_nested_type_as_namespace() { fn use_private_type_as_nested_namespace_fails() { let dependency = r#" type Foo { - I(Int) + I { i: Int } B(Bool) } "#; @@ -2623,7 +2626,7 @@ fn use_private_type_as_nested_namespace_fails() { use foo test my_test() { - trace foo.Foo.I(42) + trace foo.Foo.I { i: 42 } Void } "#; @@ -2643,7 +2646,7 @@ fn use_private_type_as_nested_namespace_fails() { fn use_opaque_type_as_namespace_for_constructors_fails() { let dependency = r#" pub opaque type Foo { - I(Int) + I { i: Int } B(Bool) } "#; @@ -2672,7 +2675,7 @@ fn use_opaque_type_as_namespace_for_constructors_fails() { fn use_opaque_type_as_nested_namespace_for_constructors_fails() { let dependency = r#" pub opaque type Foo { - I(Int) + I { i: Int } B(Bool) } "#;