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 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 {
|
||||||
|
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user