From d46f40bc0fd0f9eba6ed9ea6699d9d0cf35fa68f Mon Sep 17 00:00:00 2001 From: Greg Shuflin Date: Sun, 7 Nov 2021 01:30:26 -0800 Subject: [PATCH] type declarations --- schala-lang/language/src/parsing/new.rs | 62 +++++++++++++++++++++--- schala-lang/language/src/parsing/test.rs | 22 ++++----- 2 files changed, 67 insertions(+), 17 deletions(-) diff --git a/schala-lang/language/src/parsing/new.rs b/schala-lang/language/src/parsing/new.rs index bc05a26..06986a1 100644 --- a/schala-lang/language/src/parsing/new.rs +++ b/schala-lang/language/src/parsing/new.rs @@ -2,6 +2,10 @@ use std::rc::Rc; use crate::ast::*; +fn rc_string(s: &str) -> Rc { + Rc::new(s.to_string()) +} + peg::parser! { pub grammar schala_parser() for str { @@ -14,11 +18,6 @@ peg::parser! { rule delimiter() = (";" / "\n")+ - rule statement() -> Statement = - _ expr:expression() { Statement { - id: Default::default(), location: Default::default(), kind: StatementKind::Expression(expr) } - } - //Note - this is a hack, ideally the rule `rule block() -> Block = "{" _ items:(statement() ** //delimiter()) _ "}" { items.into() }` would've worked, but it doesn't. pub rule block() -> Block = "{" _ items:block_item()* _ "}" { items.into() } / @@ -27,10 +26,61 @@ peg::parser! { rule block_item() -> Statement = stmt:statement() delimiter()+ { stmt } + rule statement() -> Statement = + _ decl:declaration() { Statement { id: Default::default(), location: Default::default(), kind: StatementKind::Declaration(decl) } } / + _ expr:expression() { Statement { id: Default::default(), location: Default::default(), kind: StatementKind::Expression(expr) } } + + rule declaration() -> Declaration = + binding() / type_decl() + + rule binding() -> Declaration = + "let" _ mutable:"mut"? _ ident:identifier() _ type_anno:type_anno()? _ "=" _ expr:expression() { + Declaration::Binding { name: Rc::new(ident.to_string()), constant: mutable.is_none(), + type_anno, expr } + } + + + rule type_decl() -> Declaration = + "type" _ "alias" _ alias:type_alias() { alias } / + "type" _ mutable:"mut"? _ name:type_singleton_name() _ "=" _ body:type_body() { + Declaration::TypeDecl { name, body, mutable: mutable.is_some() } + } + + rule type_singleton_name() -> TypeSingletonName = + name:identifier() params:type_params()? { TypeSingletonName { name: rc_string(name), params: if let Some(params) = params { params } else { vec![] } } } + + rule type_params() -> Vec = + "<" _ idents:(type_identifier() ** (_ "," _)) _ ">" { idents } + + rule type_identifier() -> TypeIdentifier = + "(" _ items:(type_identifier() ** (_ "," _)) _ ")" { TypeIdentifier::Tuple(items) } / + singleton:type_singleton_name() { TypeIdentifier::Singleton(singleton) } + + rule type_body() -> TypeBody = + "{" _ items:(record_variant_item() ++ (_ "," _)) _ "}" { TypeBody::ImmediateRecord(Default::default(), items) } / + variants:(variant_spec() ** (_ "|" _)) { TypeBody::Variants(variants) } + + rule variant_spec() -> Variant = + name:identifier() _ "{" _ typed_identifier_list:(record_variant_item() ++ (_ "," _)) _ "}" { Variant { + id: Default::default(), name: rc_string(name), kind: VariantKind::Record(typed_identifier_list) + } } / + name:identifier() "(" tuple_members:(type_identifier() ++ (_ "," _)) ")" { Variant { + id: Default::default(), name: rc_string(name), kind: VariantKind::TupleStruct(tuple_members) } } / + name:identifier() { Variant { id: Default::default(), name: rc_string(name), kind: VariantKind::UnitStruct } } + + rule record_variant_item() -> (Rc, TypeIdentifier) = + name:identifier() _ ":" _ ty:type_identifier() { (rc_string(name), ty) } + + rule type_alias() -> Declaration = + alias:identifier() _ "=" _ name:identifier() { Declaration::TypeAlias { alias: rc_string(alias), original: rc_string(name), } } + + rule type_anno() -> TypeIdentifier = + ":" _ ident:identifier() { TypeIdentifier::Singleton(TypeSingletonName { name: Rc::new(ident.to_string()), params: vec![] }) } + pub rule expression() -> Expression = _ kind:expression_kind() { Expression { id: Default::default(), type_anno: None, kind: kind } } - pub rule expression_no_struct() -> Expression = + rule expression_no_struct() -> Expression = _ kind:expression_kind_no_struct() { Expression { id: Default::default(), type_anno: None, kind: kind } } rule expression_kind() -> ExpressionKind = diff --git a/schala-lang/language/src/parsing/test.rs b/schala-lang/language/src/parsing/test.rs index ec9593f..dad6ff8 100644 --- a/schala-lang/language/src/parsing/test.rs +++ b/schala-lang/language/src/parsing/test.rs @@ -597,7 +597,7 @@ fn type_annotations() { #[test] fn type_declarations() { use Declaration::TypeDecl; - assert_ast! { + assert_ast2! { "type Alpha = Alpha", vec![ decl(TypeDecl { name: TypeSingletonName { name: rc("Alpha"), params: vec![] }, @@ -613,7 +613,7 @@ fn type_declarations() { ] }; - assert_ast!( + assert_ast2!( "type mut Kuah = Kuah", decl(TypeDecl { name: TypeSingletonName { name: rc("Kuah"), params: vec![] }, @@ -626,7 +626,7 @@ fn type_declarations() { }) ); - assert_ast! { + assert_ast2! { "type Alpha = Alpha { a: Int, b: Int }", vec![decl(TypeDecl { name: TypeSingletonName { name: rc("Alpha"), params: vec![] }, @@ -644,7 +644,7 @@ fn type_declarations() { })] }; - assert_ast! { + assert_ast2! { "type Alpha = { a: Int, b: Int }", vec![decl(TypeDecl { name: TypeSingletonName { name: rc("Alpha"), params: vec![] }, @@ -657,7 +657,7 @@ fn type_declarations() { })] }; - assert_ast!( + assert_ast2!( "type Option = None | Some(T)", vec![decl(TypeDecl { name: TypeSingletonName { @@ -679,12 +679,12 @@ fn type_declarations() { })] ); - assert_ast!( + assert_ast2!( "type alias Alpha = Beta", decl(Declaration::TypeAlias { alias: rc("Alpha"), original: rc("Beta") }) ); - assert_ast!("type Complex = Unit | Record { field: AnotherType, field2: (Nat, Int), field3: T } | Tuple(Int, (String, T))", + assert_ast2!("type Complex = Unit | Record { field: AnotherType, field2: (Nat, Int), field3: T } | Tuple(Int, (String, T))", decl(TypeDecl { name: TypeSingletonName { name: rc("Complex"), params: vec![ TypeIdentifier::Singleton(TypeSingletonName { name: rc("T"), params: vec![] }), @@ -721,7 +721,7 @@ fn type_declarations() { fn declarations() { use ExpressionKind::*; - assert_ast!( + assert_ast2!( "let q_q = Yolo::Swaggins", vec![decl(Declaration::Binding { name: rc("q_q"), @@ -736,7 +736,7 @@ fn declarations() { fn bindings() { use ExpressionKind::*; - assert_ast!( + assert_ast2!( "let mut a = 10", vec![decl(Declaration::Binding { name: rc("a"), @@ -746,7 +746,7 @@ fn bindings() { })] ); - assert_ast!( + assert_ast2!( "let a = 2 + a", vec![stmt(StatementKind::Declaration(Declaration::Binding { name: rc("a"), @@ -756,7 +756,7 @@ fn bindings() { }))] ); - assert_ast!( + assert_ast2!( "let a: Nat = 2", vec![stmt(StatementKind::Declaration(Declaration::Binding { name: rc("a"),