Fix how impl blocks work

This gets rid of a token-less parseerror
This commit is contained in:
greg 2019-01-08 00:51:56 -08:00
parent b88def8a2e
commit ee7861cbd0
2 changed files with 20 additions and 19 deletions

View File

@ -41,7 +41,6 @@ pub enum Statement {
pub type Block = Vec<Node<Statement>>;
pub type ParamName = Rc<String>;
pub type InterfaceName = Rc<String>; //should be a singleton I think??
pub type FormalParam = (ParamName, Option<TypeIdentifier>);
#[derive(Debug, PartialEq, Clone)]
@ -61,7 +60,7 @@ pub enum Declaration {
},
Impl {
type_name: TypeIdentifier,
interface_name: Option<InterfaceName>,
interface_name: Option<TypeSingletonName>,
block: Vec<Declaration>,
},
Interface {

View File

@ -203,11 +203,10 @@ binding_declaration := 'let' 'mut'? IDENTIFIER '=' expresion
/* Declaration - Interface */
interface_declaration := 'interface' interface_name signature_block
impl_declaration := 'impl' IDENTIFIER decl_block | 'impl' interface_name 'for' IDENTIFIER decl_block
interface_declaration := 'interface' type_singleton_name signature_block
impl_declaration := 'impl' type_singleton_name decl_block | 'impl' type_singleton_name 'for' type_name decl_block
decl_block := '{' (func_declaration)* '}'
signature_block := '{' (func_signature)* '}'
interface_name := IDENTIFIER
/* Type annotations */
@ -477,7 +476,7 @@ impl Parser {
#[recursive_descent_method]
fn impl_declaration(&mut self) -> ParseResult<Declaration> {
expect!(self, Keyword(Impl));
let first = self.type_name()?;
let first = self.type_singleton_name()?;
let second = if let Keyword(For) = self.token_handler.peek_kind() {
self.token_handler.next();
Some(self.type_name()?)
@ -486,18 +485,12 @@ impl Parser {
};
let block = self.decl_block()?;
let result = match (first, second) {
(first, Some(second)) => {
match first {
TypeIdentifier::Singleton(TypeSingletonName { ref name, ref params }) if params.len() == 0 =>
Declaration::Impl { type_name: second, interface_name: Some(name.clone()), block },
_ => return ParseError::new(&format!("Invalid name for an interface")),
}
},
(first, None) => Declaration::Impl { type_name: first, interface_name: None, block }
};
Ok(result)
Ok(match (first, second) {
(interface_name, Some(type_name)) =>
Declaration::Impl { type_name, interface_name: Some(interface_name), block },
(type_singleton_name, None) =>
Declaration::Impl { type_name: TypeIdentifier::Singleton(type_singleton_name), interface_name: None, block }
})
}
#[recursive_descent_method]
@ -1471,11 +1464,20 @@ fn a(x) {
parse_test!("impl Mondai for Lollerino { fn yolo(); fn swagg(); }", AST(vec![
Node::new(Declaration(Impl {
type_name: ty!("Lollerino"),
interface_name: Some(rc!(Mondai)),
interface_name: Some(TypeSingletonName { name: rc!(Mondai), 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 })
] }))]));
parse_test!("impl Hella<T> for (Alpha, Omega) { }", AST(vec![
Node::new(Declaration(Impl {
type_name: Tuple(vec![ty!("Alpha"), ty!("Omega")]),
interface_name: Some(TypeSingletonName { name: rc!(Hella), params: vec![ty!("T")] }),
block: vec![]
}))
]));
parse_test!("impl Option<WTFMate> { fn oi() }", AST(vec![
Node::new(
Declaration(Impl {