From ee7861cbd09e1f7e32ed0d9fca2b2346f50fc696 Mon Sep 17 00:00:00 2001 From: greg Date: Tue, 8 Jan 2019 00:51:56 -0800 Subject: [PATCH] Fix how impl blocks work This gets rid of a token-less parseerror --- schala-lang/language/src/ast.rs | 3 +-- schala-lang/language/src/parsing.rs | 36 +++++++++++++++-------------- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/schala-lang/language/src/ast.rs b/schala-lang/language/src/ast.rs index 32b2ae7..e937c48 100644 --- a/schala-lang/language/src/ast.rs +++ b/schala-lang/language/src/ast.rs @@ -41,7 +41,6 @@ pub enum Statement { pub type Block = Vec>; pub type ParamName = Rc; -pub type InterfaceName = Rc; //should be a singleton I think?? pub type FormalParam = (ParamName, Option); #[derive(Debug, PartialEq, Clone)] @@ -61,7 +60,7 @@ pub enum Declaration { }, Impl { type_name: TypeIdentifier, - interface_name: Option, + interface_name: Option, block: Vec, }, Interface { diff --git a/schala-lang/language/src/parsing.rs b/schala-lang/language/src/parsing.rs index 484295c..db90762 100644 --- a/schala-lang/language/src/parsing.rs +++ b/schala-lang/language/src/parsing.rs @@ -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 { 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 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 { fn oi() }", AST(vec![ Node::new( Declaration(Impl {