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(
"block",
map(
tuple((
delimited(
tok(char('{')),
tuple((
many0(statement_delimiter),
separated_list0(statement_delimiter, statement),
many0(statement_delimiter),
tok(char('}')),
)),
|(_, _, items, _, _)| items.into(),
tok(char('}')),
),
|(_, items, _)| items.into(),
),
)(input)
}
@ -129,7 +131,60 @@ fn statement(input: Span) -> ParseResult<Statement> {
}
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> {

View File

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