Fix how impl blocks work
This gets rid of a token-less parseerror
This commit is contained in:
parent
b88def8a2e
commit
ee7861cbd0
@ -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 {
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user