From 1a365481abf1f3013256327167a3c1b71e1960e1 Mon Sep 17 00:00:00 2001 From: Jesse Brault Date: Wed, 7 May 2025 15:05:39 -0500 Subject: [PATCH] Add smoke screen tests for parser; add some function grammar rules. --- src/parser/deimos.pest | 49 ++++++++++++++++++++++++++++++++++++------ src/parser/mod.rs | 33 ++++++++++++++++++++++++++-- 2 files changed, 74 insertions(+), 8 deletions(-) diff --git a/src/parser/deimos.pest b/src/parser/deimos.pest index 137a88a..5a23a88 100644 --- a/src/parser/deimos.pest +++ b/src/parser/deimos.pest @@ -2,7 +2,7 @@ CompilationUnit = { SOI ~ Namespace? ~ ModuleLevelDeclaration* ~ EOI } Namespace = { "ns" ~ FullyQualifiedName } -CommonDeclaration = { Interface | Class | Module | Function } +CommonDeclaration = { Interface | Class | Module | Function | OperatorFunction } ModuleLevelDeclaration = { Declare? ~ Public? ~ CommonDeclaration } InterfaceLevelDeclaration = { CommonDeclaration } ClassLevelDeclaration = { Declare? ~ Public? ~ ( CommonDeclaration | ClassMember ) } @@ -27,6 +27,9 @@ Public = { "pub" } Field = { "fld" } Implementation = { "impl" } Mutable = { "mut" } +Consume = { "cons" } +Reference = { "ref" } +Define = { "def" } // Fqn and identifier FullyQualifiedName = { Identifier ~ ( "::" ~ Identifier )* } @@ -47,13 +50,45 @@ GenericArguments = { "<" ~ FullyQualifiedName ~ ( "," ~ FullyQualifiedName )* ~ GenericParameters = { "<" ~ Identifier ~ ( "," ~ Identifier )* ~ ">" } // Function -Function = { Implementation? +Function = { ( Implementation | Define )? + ~ ( Consume | Mutable )? + ~ Reference? ~ "fn" - ~ Identifier ~ GenericParameters? + ~ Identifier ~ "(" ~ Parameters? ~ ")" - ~ TypeAnnotation? ~ ( FunctionEqualsBody | BlockStatement ) + ~ ReturnType? + ~ ( FunctionAlias | FunctionEqualsBody | BlockStatement )? } +ReturnType = { "->" ~ Reference? ~ TypeUse } +FunctionAlias = { "alias" ~ FullyQualifiedName } + +OperatorFunction = { ( Implementation | Define )? + ~ ( Consume | Mutable )? + ~ Reference? + ~ "op" + ~ Operator + ~ "(" ~ Parameters? ~ ")" + ~ ReturnType? + ~ ( FunctionAlias | FunctionEqualsBody | BlockStatement )? +} +Operator = { Or + | And + | EqualTo + | NotEqualTo + | Greater + | Less + | GreaterEqual + | LessEqual + | Add + | Subtract + | Multiply + | Divide + | Modulo + | CallOp +} + +CallOp = { "()" } Parameters = { Parameter ~ ( "," ~ Parameter )* } Parameter = { Identifier ~ TypeAnnotation? } @@ -69,8 +104,10 @@ VariableDeclaration = { "let" ~ Mutable? ~ Identifier ~ TypeAnnotation? ~ ( "=" // Expressions Expression = { OrExpression } -OrExpression = { AndExpression ~ ( "||" ~ AndExpression )* } -AndExpression = { EqualityExpression ~ ( "&&" ~ EqualityExpression )* } +OrExpression = { AndExpression ~ ( Or ~ AndExpression )* } +AndExpression = { EqualityExpression ~ ( And ~ EqualityExpression )* } +Or = { "||" } +And = { "&&" } EqualityExpression = { ComparisonExpression ~ ( ( EqualTo | NotEqualTo ) ~ ComparisonExpression )* } EqualTo = { "==" } diff --git a/src/parser/mod.rs b/src/parser/mod.rs index d341bda..4b50e29 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -51,7 +51,10 @@ mod deimos_parser_tests { } fn parse(rule: Rule, input: &str) -> Pair { - let pair = DeimosParser::parse(rule, input).unwrap().next().unwrap(); + let pair = DeimosParser::parse(rule, input) + .expect("Parsing failed.") + .next() + .unwrap(); dbg!(&pair); pair } @@ -83,7 +86,7 @@ mod deimos_parser_tests { match_rule!(call; Rule::Call); }); } - + #[test] fn identifier_call_as_call_expression() { let pair = parse(Rule::CallExpression, "foo()"); @@ -94,4 +97,30 @@ mod deimos_parser_tests { let call = call_expression_pairs.next().unwrap(); match_rule!(call; Rule::Call); } + + mod smoke_screen_tests { + use crate::parser::deimos_parser_tests::parse; + use crate::parser::Rule; + + #[test] + fn simple_interface() { + parse(Rule::CompilationUnit, "pub int Simple { fn foo() -> Void }"); + } + + #[test] + fn interface_with_op() { + parse( + Rule::CompilationUnit, + "pub int Callable { op () () -> Void }", + ); + } + + #[test] + fn interface_with_alias() { + parse( + Rule::CompilationUnit, + "pub int Callable {\n fn call() -> Void\n op () () -> Void alias call\n}", + ); + } + } }