#[derive(Parser)]
#[grammar = "sway.pest"]
pub struct SwayParser;
#[cfg(test)]
mod test {
use super::{Rule, SwayParser};
use pest::Parser;
#[test]
fn test_var_decl() {
let parsed = SwayParser::parse(Rule::var_decl, r#"let x = 2;"#.into());
if let Err(e) = parsed {
panic!("{:#?}", e);
}
}
#[test]
fn test_comment() {
let parsed = SwayParser::parse(
Rule::var_decl,
r#"let x = 2; // and a comment
/* and a multiline comment
* second line */"#
.into(),
);
if let Err(e) = parsed {
panic!("{:#?}", e);
}
}
#[test]
fn test_fn_decl() {
let parsed = SwayParser::parse(
Rule::fn_decl,
r#"fn myfunc(x: i32, y: i32) -> i32 {
// a function body
let x = 5;
let y = 10;
return 10;
}"#
.into(),
);
if let Err(e) = parsed {
panic!("{:#?}", e);
}
}
#[test]
fn test_if_else_expr() {
let parsed = SwayParser::parse(
Rule::fn_decl,
r#"fn myfunc(x: i32, y: i32) -> i32 {
// a function body
let x = if
true
{ 5 }
else { 6 };
let y = 10;
return 10;
}"#
.into(),
);
if let Err(e) = parsed {
panic!("{:#?}", e);
}
}
#[test]
fn test_if_expr() {
let parsed = SwayParser::parse(
Rule::fn_decl,
r#"fn myfunc(x: i32, y: i32) -> i32 {
// a function body
if true { /* comment */ 5 /*comment test*/ };
/* some comments */
}"#
.into(),
);
if let Err(e) = parsed {
panic!("{:#?}", e);
}
}
#[test]
fn test_if_else_expr_2() {
let parsed = SwayParser::parse(
Rule::fn_decl,
r#"fn myfunc(x: i32, y: i32) -> i32 {
// a function body
if ((true)) { /* comment */ (((5))) /*comment test*/ };
/* some comments */
}"#
.into(),
);
if let Err(e) = parsed {
panic!("{:#?}", e);
}
}
#[test]
fn mismatched_parens() {
let parsed = SwayParser::parse(
Rule::fn_decl,
r#"fn myfunc(x: i32, y: i32) -> i32 {
// a function body
if ((true)) { /* comment */ (((5)) };
}"#
.into(),
);
match parsed {
Err(_) => (),
Ok(o) => {
panic!("{:?}", o)
}
}
}
#[test]
fn parse_infix_op() {
let parsed = SwayParser::parse(
Rule::fn_decl,
r#"fn myfunc(x: i32, y: i32) -> i32 {
let x = 5 + 10;
}"#
.into(),
);
if let Err(e) = parsed {
panic!("{:#?}", e);
}
}
#[test]
fn var_exp() {
let parsed = SwayParser::parse(
Rule::fn_decl,
r#"fn myfunc(x: i32, y: i32) -> i32 {
let x = 5 + 10;
let foo = 20;
let y = (x + foo) - x ;
return y;
}"#
.into(),
);
if let Err(e) = parsed {
panic!("{:#?}", e);
}
}
#[test]
fn var_exp_triple_op() {
let parsed = SwayParser::parse(
Rule::fn_decl,
r#"fn myfunc(x: i32, y: i32) -> i32 {
let x = 5 + 10;
let foo = 20;
let y = (x + foo + 3) - x ;
return y;
}"#
.into(),
);
if let Err(e) = parsed {
panic!("{:#?}", e);
}
}
#[test]
fn trait_decl_unimplemented_method() {
let parsed = SwayParser::parse(
Rule::program,
r#"script;
trait MyTrait {
fn some_method_you_need_to_implement(x: i32) -> i32;
}"#
.into(),
);
if let Err(e) = parsed {
panic!("{:#?}", e);
}
}
#[test]
fn trait_decl_unimplemented_and_implemented() {
let parsed = SwayParser::parse(
Rule::program,
r#"
predicate;
trait MyTrait {
fn some_method_you_need_to_implement(x: i32) -> i32;
} {
fn some_method_that_the_trait_implements(x: i32) -> i32 {
let x = 5;
return x;
}
}
"#
.into(),
);
if let Err(e) = parsed {
panic!("{:#?}", e);
}
}
#[test]
fn import_statement() {
let parsed = SwayParser::parse(
Rule::use_statement,
r#"use otherlibrary::packagename;
"#
.into(),
);
if let Err(e) = parsed {
panic!("{:#?}", e);
}
}
#[test]
fn import_statement_2() {
let parsed = SwayParser::parse(
Rule::program,
r#"
contract;
use otherlibrary::packagename;
fn main(){
let x = 5;
return x;
}
"#
.into(),
);
if let Err(e) = parsed {
panic!("{:#?}", e);
}
}
#[test]
fn byte_literals() {
let parsed = SwayParser::parse(
Rule::program,
r#"
script;
fn main(){
let x = 0b01011010;
let y = 0xAF;
return 0;
}"#
.into(),
);
parsed.unwrap();
}
#[test]
fn bytes_literals() {
let parsed = SwayParser::parse(
Rule::program,
r#"
predicate;
fn main(){
let x = 0b01011010;
// 32 bytes in a bytes32
let y = 0xAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAF;
return x;
}
"#
.into(),
);
parsed.unwrap();
}
#[test]
#[should_panic]
fn multiple_programs() {
let parsed = SwayParser::parse(
Rule::program,
r#"
predicate;
fn main(){
let x = 0b01011010;
// 32 bytes in a bytes32
let y = 0xAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAF;
return x;
}
predicate;
fn main(){
let x = 0b01011010;
// 32 bytes in a bytes32
let y = 0xAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAF;
return x;
}
"#
.into(),
);
parsed.unwrap();
}
#[test]
fn test_filename() {
let parsed = SwayParser::parse(
Rule::fn_decl,
r#"fn myfunc(x: i32, y: i32) -> i32 {
// a function body
let x = 5;
let y = 10;
return 10;
}"#
.into(),
);
parsed.unwrap();
}
}