type declarations
This commit is contained in:
parent
02fc76c8fc
commit
d46f40bc0f
@ -2,6 +2,10 @@ use std::rc::Rc;
|
||||
|
||||
use crate::ast::*;
|
||||
|
||||
fn rc_string(s: &str) -> Rc<String> {
|
||||
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<TypeIdentifier> =
|
||||
"<" _ 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<String>, 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 =
|
||||
|
@ -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<T> = 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<T, U> = Unit | Record { field: AnotherType<Bool>, field2: (Nat, Int), field3: T } | Tuple(Int, (String, T))",
|
||||
assert_ast2!("type Complex<T, U> = Unit | Record { field: AnotherType<Bool>, 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"),
|
||||
|
Loading…
Reference in New Issue
Block a user