Impl, interface

This commit is contained in:
Greg Shuflin 2021-11-18 18:58:46 -08:00
parent 65c745fb30
commit d5cd0dada7
2 changed files with 64 additions and 9 deletions

View File

@ -105,14 +105,16 @@ pub fn block(input: Span) -> ParseResult<Block> {
context( context(
"block", "block",
map( map(
tuple(( delimited(
tok(char('{')), tok(char('{')),
tuple((
many0(statement_delimiter), many0(statement_delimiter),
separated_list0(statement_delimiter, statement), separated_list0(statement_delimiter, statement),
many0(statement_delimiter), many0(statement_delimiter),
)),
tok(char('}')), tok(char('}')),
)), ),
|(_, _, items, _, _)| items.into(), |(_, items, _)| items.into(),
), ),
)(input) )(input)
} }
@ -129,7 +131,60 @@ fn statement(input: Span) -> ParseResult<Statement> {
} }
fn declaration(input: Span) -> ParseResult<Declaration> { fn declaration(input: Span) -> ParseResult<Declaration> {
alt((binding, type_decl, func, annotation, module))(input) alt((binding, type_decl, func, annotation, module, interface, implementation))(input)
}
fn implementation(input: Span) -> ParseResult<Declaration> {
alt((
map(
preceded(kw("impl"), tuple((type_singleton_name, kw("for"), type_identifier, decl_block))),
|(if_name, _, type_name, block)| Declaration::Impl {
type_name,
interface_name: Some(if_name),
block,
},
),
map(preceded(kw("impl"), pair(type_identifier, decl_block)), |(type_name, block)| {
Declaration::Impl { type_name, interface_name: None, block }
}),
))(input)
}
fn decl_block(input: Span) -> ParseResult<Vec<Declaration>> {
delimited(
tok(char('{')),
map(
tuple((
many0(statement_delimiter),
separated_list0(statement_delimiter, func_decl),
many0(statement_delimiter),
)),
|(_, signatures, _)| signatures,
),
tok(char('}')),
)(input)
}
fn interface(input: Span) -> ParseResult<Declaration> {
map(preceded(kw("interface"), pair(tok(identifier), signature_block)), |(name, signatures)| {
Declaration::Interface { name: rc_string(name.fragment()), signatures }
})(input)
}
//TODO make the blocks parameterizable
fn signature_block(input: Span) -> ParseResult<Vec<Signature>> {
delimited(
tok(char('{')),
map(
tuple((
many0(statement_delimiter),
separated_list0(statement_delimiter, func_signature),
many0(statement_delimiter),
)),
|(_, signatures, _)| signatures,
),
tok(char('}')),
)(input)
} }
fn annotation(input: Span) -> ParseResult<Declaration> { fn annotation(input: Span) -> ParseResult<Declaration> {

View File

@ -921,7 +921,7 @@ fn functions_with_default_args() {
#[test] #[test]
fn interface() { fn interface() {
let glue = TypeIdentifier::Singleton(TypeSingletonName { name: rc("Glue"), params: vec![] }); let glue = TypeIdentifier::Singleton(TypeSingletonName { name: rc("Glue"), params: vec![] });
assert_ast!( assert_ast_comb!(
"interface Unglueable { fn unglue(a: Glue); fn mar(): Glue }", "interface Unglueable { fn unglue(a: Glue); fn mar(): Glue }",
vec![decl(Declaration::Interface { vec![decl(Declaration::Interface {
name: rc("Unglueable"), name: rc("Unglueable"),
@ -953,13 +953,13 @@ fn impls() {
), ),
]; ];
assert_ast!( assert_ast_comb!(
"impl Heh { fn yolo() { }; fn swagg() { } }", "impl Heh { fn yolo() { }; fn swagg() { } }",
vec![decl(Impl { type_name: ty_simple("Heh"), interface_name: None, block: block.clone() })] vec![decl(Impl { type_name: ty_simple("Heh"), interface_name: None, block: block.clone() })]
); );
//TODO `"impl Heh<X> { fn yolo() { }; fn swagg() { }; }"` ought to work //TODO `"impl Heh<X> { fn yolo() { }; fn swagg() { }; }"` ought to work
assert_ast!( assert_ast_comb!(
"impl Heh<X> { fn yolo() { }; fn swagg() { } }", "impl Heh<X> { fn yolo() { }; fn swagg() { } }",
vec![decl(Impl { vec![decl(Impl {
type_name: TypeIdentifier::Singleton(TypeSingletonName { type_name: TypeIdentifier::Singleton(TypeSingletonName {
@ -971,7 +971,7 @@ fn impls() {
})] })]
); );
assert_ast!( assert_ast_comb!(
"impl Heh for Saraz { fn yolo() {}; fn swagg() {} }", "impl Heh for Saraz { fn yolo() {}; fn swagg() {} }",
vec![decl(Impl { vec![decl(Impl {
type_name: ty_simple("Saraz"), type_name: ty_simple("Saraz"),
@ -980,7 +980,7 @@ fn impls() {
})] })]
); );
assert_ast!( assert_ast_comb!(
"impl Heh<T> for (Int, Codepoint) {}", "impl Heh<T> for (Int, Codepoint) {}",
vec![decl(Impl { vec![decl(Impl {
type_name: TypeIdentifier::Tuple(vec![ty_simple("Int"), ty_simple("Codepoint")]), type_name: TypeIdentifier::Tuple(vec![ty_simple("Int"), ty_simple("Codepoint")]),