Interface, impls

This commit is contained in:
Greg Shuflin 2021-11-11 22:00:04 -08:00
parent 7bd6072dae
commit c3d36ab320
2 changed files with 46 additions and 24 deletions

View File

@ -37,15 +37,37 @@ peg::parser! {
__ expr:expression() { StatementKind::Expression(expr) }
rule declaration() -> Declaration =
binding() / type_decl() / annotation() / func()
binding() / type_decl() / annotation() / func() / interface() / implementation()
rule implementation() -> Declaration =
"impl" _ interface:type_singleton_name() _ "for" _ type_name:type_identifier() _ block:decl_block() {
Declaration::Impl { type_name, interface_name: Some(interface), block }
} /
"impl" _ type_name:type_identifier() _ block:decl_block() {
Declaration::Impl { type_name, interface_name: None, block }
}
rule decl_block() -> Vec<Declaration> =
"{" __ decls:(func_declaration() ** (delimiter()+)) __ "}" { decls }
rule interface() -> Declaration =
"interface" _ name:identifier() _ signatures:signature_block() { Declaration::Interface { name: rc_string(name), signatures } }
rule signature_block() -> Vec<Signature> =
"{" __ signatures:(func_signature() ** (delimiter()+)) __ "}" { signatures }
rule func() -> Declaration =
sig:func_signature() __ body:block() { Declaration::FuncDecl(sig, body) } /
decl:func_declaration() { decl } /
sig:func_signature() { Declaration::FuncSig(sig) }
rule func_declaration() -> Declaration =
sig:func_signature() __ body:block() { Declaration::FuncDecl(sig, body) }
//TODO handle operators
rule func_signature() -> Signature =
"fn" _ name:identifier() "(" _ params:formal_params() _ ")" _ type_anno:type_anno()? { Signature {
_ "fn" _ name:identifier() "(" _ params:formal_params() _ ")" _ type_anno:type_anno()? { Signature {
name: rc_string(name), operator: false, params, type_anno
} }

View File

@ -904,7 +904,7 @@ fn functions_with_default_args() {
#[test]
fn interface() {
let glue = TypeIdentifier::Singleton(TypeSingletonName { name: rc("Glue"), params: vec![] });
assert_ast!(
assert_ast2!(
"interface Unglueable { fn unglue(a: Glue); fn mar(): Glue }",
vec![decl(Declaration::Interface {
name: rc("Unglueable"),
@ -923,48 +923,48 @@ fn interface() {
#[test]
fn impls() {
use Declaration::{FuncSig, Impl};
use Declaration::{FuncDecl, Impl};
assert_ast!(
"impl Heh { fn yolo(); fn swagg(); }",
let block = vec![
FuncDecl(Signature { name: rc("yolo"), operator: false, params: vec![], type_anno: None },
vec![].into()),
FuncDecl(Signature { name: rc("swagg"), operator: false, params: vec![], type_anno: None },
vec![].into()
)
];
assert_ast2!(
"impl Heh { fn yolo() { }; fn swagg() { } }",
vec![decl(Impl {
type_name: ty_simple("Heh"),
interface_name: None,
block: vec![
FuncSig(Signature { name: rc("yolo"), operator: false, params: vec![], type_anno: None }),
FuncSig(Signature { name: rc("swagg"), operator: false, params: vec![], type_anno: None })
]
block: block.clone(),
})]
);
assert_ast!(
"impl Heh<X> { fn yolo(); fn swagg(); }",
//TODO `"impl Heh<X> { fn yolo() { }; fn swagg() { }; }"` ought to work
assert_ast2!(
"impl Heh<X> { fn yolo() { }; fn swagg() { } }",
vec![decl(Impl {
type_name: TypeIdentifier::Singleton(TypeSingletonName {
name: rc("Heh"),
params: vec![ty_simple("X")]
}),
interface_name: None,
block: vec![
FuncSig(Signature { name: rc("yolo"), operator: false, params: vec![], type_anno: None }),
FuncSig(Signature { name: rc("swagg"), operator: false, params: vec![], type_anno: None })
]
block: block.clone(),
})]
);
assert_ast!(
"impl Heh for Saraz { fn yolo(); fn swagg(); }",
assert_ast2!(
"impl Heh for Saraz { fn yolo() {}; fn swagg() {} }",
vec![decl(Impl {
type_name: ty_simple("Saraz"),
interface_name: Some(TypeSingletonName { name: rc("Heh"), params: vec![] }),
block: vec![
FuncSig(Signature { name: rc("yolo"), operator: false, params: vec![], type_anno: None }),
FuncSig(Signature { name: rc("swagg"), operator: false, params: vec![], type_anno: None })
]
block: block.clone(),
})]
);
assert_ast!(
assert_ast2!(
"impl Heh<T> for (Int, Codepoint) {}",
vec![decl(Impl {
type_name: TypeIdentifier::Tuple(vec![ty_simple("Int"), ty_simple("Codepoint")]),