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

View File

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