test(parser): rename definitions to definition and more tests
This commit is contained in:
parent
baf807ca2d
commit
6b05d6a91e
|
@ -1,5 +1,5 @@
|
|||
mod annotation;
|
||||
pub mod definitions;
|
||||
pub mod definition;
|
||||
pub mod error;
|
||||
pub mod expr;
|
||||
pub mod extra;
|
||||
|
@ -9,7 +9,7 @@ pub mod token;
|
|||
mod utils;
|
||||
|
||||
pub use annotation::parser as annotation;
|
||||
pub use definitions::parser as definitions;
|
||||
pub use definition::parser as definition;
|
||||
pub use expr::parser as expression;
|
||||
pub use pattern::parser as pattern;
|
||||
|
||||
|
@ -26,7 +26,7 @@ pub fn module(
|
|||
|
||||
let stream = chumsky::Stream::from_iter(ast::Span::create(tokens.len()), tokens.into_iter());
|
||||
|
||||
let definitions = definitions().parse(stream)?;
|
||||
let definitions = definition().repeated().then_ignore(end()).parse(stream)?;
|
||||
|
||||
let module = ast::UntypedModule {
|
||||
kind,
|
||||
|
|
|
@ -55,3 +55,29 @@ pub fn parser() -> impl Parser<Token, ast::UntypedDefinition, Error = ParseError
|
|||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use chumsky::Parser;
|
||||
|
||||
use crate::assert_definition;
|
||||
|
||||
#[test]
|
||||
fn import_basic() {
|
||||
assert_definition!("use aiken/list");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn import_unqualified() {
|
||||
assert_definition!(
|
||||
r#"
|
||||
use std/address.{Address as A, thing as w}
|
||||
"#
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn import_alias() {
|
||||
assert_definition!("use aiken/list as foo");
|
||||
}
|
||||
}
|
|
@ -19,7 +19,7 @@ pub use validator::parser as validator;
|
|||
use super::{error::ParseError, token::Token};
|
||||
use crate::ast;
|
||||
|
||||
pub fn parser() -> impl Parser<Token, Vec<ast::UntypedDefinition>, Error = ParseError> {
|
||||
pub fn parser() -> impl Parser<Token, ast::UntypedDefinition, Error = ParseError> {
|
||||
choice((
|
||||
import(),
|
||||
data_type(),
|
||||
|
@ -29,6 +29,4 @@ pub fn parser() -> impl Parser<Token, Vec<ast::UntypedDefinition>, Error = Parse
|
|||
test(),
|
||||
constant(),
|
||||
))
|
||||
.repeated()
|
||||
.then_ignore(end())
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
---
|
||||
source: crates/aiken-lang/src/parser/definition/import.rs
|
||||
description: "Code:\n\nuse aiken/list as foo"
|
||||
---
|
||||
Use(
|
||||
Use {
|
||||
as_name: Some(
|
||||
"foo",
|
||||
),
|
||||
location: 0..21,
|
||||
module: [
|
||||
"aiken",
|
||||
"list",
|
||||
],
|
||||
package: (),
|
||||
unqualified: [],
|
||||
},
|
||||
)
|
|
@ -0,0 +1,16 @@
|
|||
---
|
||||
source: crates/aiken-lang/src/parser/definition/import.rs
|
||||
description: "Code:\n\nuse aiken/list"
|
||||
---
|
||||
Use(
|
||||
Use {
|
||||
as_name: None,
|
||||
location: 0..14,
|
||||
module: [
|
||||
"aiken",
|
||||
"list",
|
||||
],
|
||||
package: (),
|
||||
unqualified: [],
|
||||
},
|
||||
)
|
|
@ -0,0 +1,33 @@
|
|||
---
|
||||
source: crates/aiken-lang/src/parser/definition/import.rs
|
||||
description: "Code:\n\nuse std/address.{Address as A, thing as w}\n"
|
||||
---
|
||||
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,
|
||||
},
|
||||
],
|
||||
},
|
||||
)
|
|
@ -46,3 +46,25 @@ pub fn parser<'a>(
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use chumsky::Parser;
|
||||
|
||||
use crate::assert_expr;
|
||||
|
||||
#[test]
|
||||
fn if_else_basic() {
|
||||
assert_expr!(
|
||||
r#"
|
||||
if True {
|
||||
1 + 1
|
||||
} else if a < 1 {
|
||||
3
|
||||
} else {
|
||||
4
|
||||
}
|
||||
"#
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,3 +14,38 @@ pub fn parser() -> impl Parser<Token, UntypedExpr, Error = ParseError> {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use chumsky::Parser;
|
||||
|
||||
use crate::assert_expr;
|
||||
|
||||
#[test]
|
||||
fn int_literal() {
|
||||
assert_expr!("1");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn int_negative() {
|
||||
assert_expr!("-1");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn int_numeric_underscore() {
|
||||
assert_expr!(
|
||||
r#"
|
||||
{
|
||||
let i = 1_234_567
|
||||
let j = 1_000_000
|
||||
let k = -10_000
|
||||
}
|
||||
"#
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn int_hex_bytes() {
|
||||
assert_expr!(r#"0x01"#);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,6 @@ pub fn parser(
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use chumsky::Parser;
|
||||
|
||||
use crate::assert_expr;
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
---
|
||||
source: crates/aiken-lang/src/parser/expr/if_else.rs
|
||||
description: "Code:\n\nif True {\n 1 + 1\n} else if a < 1 {\n 3\n} else {\n 4\n}\n"
|
||||
---
|
||||
If {
|
||||
location: 0..54,
|
||||
branches: [
|
||||
IfBranch {
|
||||
condition: Var {
|
||||
location: 3..7,
|
||||
name: "True",
|
||||
},
|
||||
body: BinOp {
|
||||
location: 12..17,
|
||||
name: AddInt,
|
||||
left: Int {
|
||||
location: 12..13,
|
||||
value: "1",
|
||||
base: Decimal {
|
||||
numeric_underscore: false,
|
||||
},
|
||||
},
|
||||
right: Int {
|
||||
location: 16..17,
|
||||
value: "1",
|
||||
base: Decimal {
|
||||
numeric_underscore: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
location: 3..19,
|
||||
},
|
||||
IfBranch {
|
||||
condition: BinOp {
|
||||
location: 28..33,
|
||||
name: LtInt,
|
||||
left: Var {
|
||||
location: 28..29,
|
||||
name: "a",
|
||||
},
|
||||
right: Int {
|
||||
location: 32..33,
|
||||
value: "1",
|
||||
base: Decimal {
|
||||
numeric_underscore: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
body: Int {
|
||||
location: 38..39,
|
||||
value: "3",
|
||||
base: Decimal {
|
||||
numeric_underscore: false,
|
||||
},
|
||||
},
|
||||
location: 28..41,
|
||||
},
|
||||
],
|
||||
final_else: Int {
|
||||
location: 51..52,
|
||||
value: "4",
|
||||
base: Decimal {
|
||||
numeric_underscore: false,
|
||||
},
|
||||
},
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
source: crates/aiken-lang/src/parser/expr/int.rs
|
||||
description: "Code:\n\n0x01"
|
||||
---
|
||||
Int {
|
||||
location: 0..4,
|
||||
value: "1",
|
||||
base: Hexadecimal,
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
---
|
||||
source: crates/aiken-lang/src/parser/expr/int.rs
|
||||
description: "Code:\n\n1"
|
||||
---
|
||||
Int {
|
||||
location: 0..1,
|
||||
value: "1",
|
||||
base: Decimal {
|
||||
numeric_underscore: false,
|
||||
},
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
source: crates/aiken-lang/src/parser/expr/int.rs
|
||||
description: "Code:\n\n-1"
|
||||
---
|
||||
UnOp {
|
||||
op: Negate,
|
||||
location: 0..2,
|
||||
value: Int {
|
||||
location: 1..2,
|
||||
value: "1",
|
||||
base: Decimal {
|
||||
numeric_underscore: false,
|
||||
},
|
||||
},
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
---
|
||||
source: crates/aiken-lang/src/parser/expr/int.rs
|
||||
description: "Code:\n\n{\n let i = 1_234_567\n let j = 1_000_000\n let k = -10_000\n}\n"
|
||||
---
|
||||
Sequence {
|
||||
location: 4..59,
|
||||
expressions: [
|
||||
Assignment {
|
||||
location: 4..21,
|
||||
value: Int {
|
||||
location: 12..21,
|
||||
value: "1234567",
|
||||
base: Decimal {
|
||||
numeric_underscore: true,
|
||||
},
|
||||
},
|
||||
pattern: Var {
|
||||
location: 8..9,
|
||||
name: "i",
|
||||
},
|
||||
kind: Let,
|
||||
annotation: None,
|
||||
},
|
||||
Assignment {
|
||||
location: 24..41,
|
||||
value: Int {
|
||||
location: 32..41,
|
||||
value: "1000000",
|
||||
base: Decimal {
|
||||
numeric_underscore: true,
|
||||
},
|
||||
},
|
||||
pattern: Var {
|
||||
location: 28..29,
|
||||
name: "j",
|
||||
},
|
||||
kind: Let,
|
||||
annotation: None,
|
||||
},
|
||||
Assignment {
|
||||
location: 44..59,
|
||||
value: UnOp {
|
||||
op: Negate,
|
||||
location: 52..59,
|
||||
value: Int {
|
||||
location: 53..59,
|
||||
value: "10000",
|
||||
base: Decimal {
|
||||
numeric_underscore: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
pattern: Var {
|
||||
location: 48..49,
|
||||
name: "k",
|
||||
},
|
||||
kind: Let,
|
||||
annotation: None,
|
||||
},
|
||||
],
|
||||
}
|
|
@ -2,7 +2,7 @@ use chumsky::prelude::*;
|
|||
|
||||
use crate::{
|
||||
ast,
|
||||
parser::{definitions, error::ParseError, token::Token},
|
||||
parser::{definition, error::ParseError, token::Token},
|
||||
};
|
||||
|
||||
pub fn parser() -> impl Parser<Token, ast::UntypedClauseGuard, Error = ParseError> {
|
||||
|
@ -17,7 +17,7 @@ pub fn parser() -> impl Parser<Token, ast::UntypedClauseGuard, Error = ParseErro
|
|||
location: span,
|
||||
});
|
||||
|
||||
let constant_parser = definitions::constant::value().map(ast::ClauseGuard::Constant);
|
||||
let constant_parser = definition::constant::value().map(ast::ClauseGuard::Constant);
|
||||
|
||||
let block_parser = r
|
||||
.clone()
|
||||
|
|
|
@ -128,3 +128,22 @@ macro_rules! assert_module {
|
|||
});
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! assert_definition {
|
||||
($code:expr) => {
|
||||
let $crate::parser::lexer::LexInfo { tokens, .. } = $crate::parser::lexer::run(indoc::indoc! { $code }).unwrap();
|
||||
|
||||
let stream = chumsky::Stream::from_iter($crate::ast::Span::create(tokens.len()), tokens.into_iter());
|
||||
|
||||
let result = $crate::parser::definition().parse(stream).unwrap();
|
||||
|
||||
insta::with_settings!({
|
||||
description => concat!("Code:\n\n", indoc::indoc! { $code }),
|
||||
prepend_module_to_snapshot => false,
|
||||
omit_expression => true
|
||||
}, {
|
||||
insta::assert_debug_snapshot!(result);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
|
|
@ -72,24 +72,6 @@ fn double_validator() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn import() {
|
||||
assert_module!(
|
||||
r#"
|
||||
use std/list
|
||||
"#
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unqualified_imports() {
|
||||
assert_module!(
|
||||
r#"
|
||||
use std/address.{Address as A, thing as w}
|
||||
"#
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn import_alias() {
|
||||
assert_module!(
|
||||
|
@ -186,25 +168,6 @@ fn pipeline() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn if_expression() {
|
||||
assert_module!(
|
||||
r#"
|
||||
fn ifs() {
|
||||
if True {
|
||||
1 + 1
|
||||
} else if a < 4 {
|
||||
5
|
||||
} else if a || b {
|
||||
6
|
||||
} else {
|
||||
3
|
||||
}
|
||||
}
|
||||
"#
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn let_bindings() {
|
||||
assert_module!(
|
||||
|
@ -445,30 +408,6 @@ fn tuple_type_alias() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn int_parsing_hex_bytes() {
|
||||
assert_module!(
|
||||
r#"
|
||||
fn foo() {
|
||||
#[ 0x01, 0xa2, 0x03 ]
|
||||
}
|
||||
"#
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parsing_numeric_underscore() {
|
||||
assert_module!(
|
||||
r#"
|
||||
fn foo() {
|
||||
let i = 1_234_567
|
||||
let j = 1_000_000
|
||||
let k = -10_000
|
||||
}
|
||||
"#
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn first_class_binop() {
|
||||
assert_module!(
|
||||
|
|
|
@ -1,109 +0,0 @@
|
|||
---
|
||||
source: crates/aiken-lang/src/tests/parser.rs
|
||||
description: "Code:\n\nfn 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"
|
||||
---
|
||||
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,
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
---
|
||||
source: crates/aiken-lang/src/tests/parser.rs
|
||||
description: "Code:\n\nuse std/list\n"
|
||||
---
|
||||
Module {
|
||||
name: "",
|
||||
docs: [],
|
||||
type_info: (),
|
||||
definitions: [
|
||||
Use(
|
||||
Use {
|
||||
as_name: None,
|
||||
location: 0..12,
|
||||
module: [
|
||||
"std",
|
||||
"list",
|
||||
],
|
||||
package: (),
|
||||
unqualified: [],
|
||||
},
|
||||
),
|
||||
],
|
||||
kind: Validator,
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
---
|
||||
source: crates/aiken-lang/src/tests/parser.rs
|
||||
description: "Code:\n\nfn foo() {\n #[ 0x01, 0xa2, 0x03 ]\n}\n"
|
||||
---
|
||||
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,
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
---
|
||||
source: crates/aiken-lang/src/tests/parser.rs
|
||||
description: "Code:\n\nfn foo() {\n let i = 1_234_567\n let j = 1_000_000\n let k = -10_000\n}\n"
|
||||
---
|
||||
Module {
|
||||
name: "",
|
||||
docs: [],
|
||||
type_info: (),
|
||||
definitions: [
|
||||
Fn(
|
||||
Function {
|
||||
arguments: [],
|
||||
body: Sequence {
|
||||
location: 13..68,
|
||||
expressions: [
|
||||
Assignment {
|
||||
location: 13..30,
|
||||
value: Int {
|
||||
location: 21..30,
|
||||
value: "1234567",
|
||||
base: Decimal {
|
||||
numeric_underscore: true,
|
||||
},
|
||||
},
|
||||
pattern: Var {
|
||||
location: 17..18,
|
||||
name: "i",
|
||||
},
|
||||
kind: Let,
|
||||
annotation: None,
|
||||
},
|
||||
Assignment {
|
||||
location: 33..50,
|
||||
value: Int {
|
||||
location: 41..50,
|
||||
value: "1000000",
|
||||
base: Decimal {
|
||||
numeric_underscore: true,
|
||||
},
|
||||
},
|
||||
pattern: Var {
|
||||
location: 37..38,
|
||||
name: "j",
|
||||
},
|
||||
kind: Let,
|
||||
annotation: None,
|
||||
},
|
||||
Assignment {
|
||||
location: 53..68,
|
||||
value: UnOp {
|
||||
op: Negate,
|
||||
location: 61..68,
|
||||
value: Int {
|
||||
location: 62..68,
|
||||
value: "10000",
|
||||
base: Decimal {
|
||||
numeric_underscore: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
pattern: Var {
|
||||
location: 57..58,
|
||||
name: "k",
|
||||
},
|
||||
kind: Let,
|
||||
annotation: None,
|
||||
},
|
||||
],
|
||||
},
|
||||
doc: None,
|
||||
location: 0..8,
|
||||
name: "foo",
|
||||
public: false,
|
||||
return_annotation: None,
|
||||
return_type: (),
|
||||
end_position: 69,
|
||||
can_error: true,
|
||||
},
|
||||
),
|
||||
],
|
||||
kind: Validator,
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
---
|
||||
source: crates/aiken-lang/src/tests/parser.rs
|
||||
description: "Code:\n\nuse std/address.{Address as A, thing as w}\n"
|
||||
---
|
||||
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,
|
||||
}
|
Loading…
Reference in New Issue