diff --git a/src/ast/file.rs b/src/ast/file.rs index 1706962..3adfeca 100644 --- a/src/ast/file.rs +++ b/src/ast/file.rs @@ -1,6 +1,6 @@ use super::{ enumeration::Enum, global_variable::GlobalVar, implementation::Impl, structure::Structure, - type_alias::TypeAlias, Function, Given, HelperExpr, SettingsId, Trait, + type_alias::TypeAlias, Function, HelperExpr, SettingsId, Trait, }; #[derive(Clone, Debug)] @@ -13,7 +13,6 @@ pub struct AstFile { pub helper_exprs: Vec, pub traits: Vec, pub impls: Vec, - pub givens: Vec, pub settings: Option, } @@ -28,7 +27,6 @@ impl AstFile { helper_exprs: vec![], traits: vec![], impls: vec![], - givens: vec![], settings: None, } } diff --git a/src/ast/given.rs b/src/ast/given.rs deleted file mode 100644 index 5930666..0000000 --- a/src/ast/given.rs +++ /dev/null @@ -1,10 +0,0 @@ -use super::{Function, Type}; -use crate::source_files::Source; - -#[derive(Clone, Debug)] -pub struct Given { - pub name: Option, - pub target: Type, - pub source: Source, - pub body: Vec, -} diff --git a/src/ast/implementation.rs b/src/ast/implementation.rs index ea61db3..3854eb1 100644 --- a/src/ast/implementation.rs +++ b/src/ast/implementation.rs @@ -3,8 +3,8 @@ use crate::source_files::Source; #[derive(Clone, Debug)] pub struct Impl { - pub for_type: Type, - pub target_trait: Type, + pub name: Option, + pub target: Type, pub source: Source, pub body: Vec, } diff --git a/src/ast/mod.rs b/src/ast/mod.rs index fe98fce..826ecbe 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -5,7 +5,6 @@ mod enumeration; mod expr; mod file; mod function; -mod given; mod global_variable; mod helper_expr; mod implementation; @@ -23,7 +22,6 @@ pub use enumeration::*; pub use expr::*; pub use file::*; pub use function::*; -pub use given::*; pub use global_variable::*; pub use helper_expr::*; pub use implementation::*; diff --git a/src/lexer/identifier_state.rs b/src/lexer/identifier_state.rs index c187c1c..e77ab3a 100644 --- a/src/lexer/identifier_state.rs +++ b/src/lexer/identifier_state.rs @@ -47,7 +47,6 @@ impl IdentifierState { "impl" => TokenKind::ImplKeyword, "for" => TokenKind::ForKeyword, "is" => TokenKind::IsKeyword, - "given" => TokenKind::GivenKeyword, _ => TokenKind::Identifier(identifier), } .at(self.start_source) diff --git a/src/parser/annotation.rs b/src/parser/annotation.rs index d0e9b08..de5716f 100644 --- a/src/parser/annotation.rs +++ b/src/parser/annotation.rs @@ -21,11 +21,11 @@ pub enum AnnotationKind { AbideAbi, Public, Template, - Using(Using), + Given(Given), } #[derive(Clone, Debug)] -pub struct Using { +pub struct Given { pub name: Option, pub ty: ast::Type, } @@ -45,7 +45,7 @@ impl Display for AnnotationKind { Self::AbideAbi => "abide_abi", Self::Public => "public", Self::Template => "template", - Self::Using(_) => "using", + Self::Given(_) => "given", }) } } diff --git a/src/parser/input.rs b/src/parser/input.rs index 4a0c9e5..e2a7602 100644 --- a/src/parser/input.rs +++ b/src/parser/input.rs @@ -78,6 +78,13 @@ where .then(|| self.advance().kind.unwrap_identifier()) } + pub fn eat_polymorph(&mut self) -> Option { + self.peek() + .kind + .is_polymorph() + .then(|| self.advance().kind.unwrap_polymorph()) + } + pub fn ignore_newlines(&mut self) { while self.eat(TokenKind::Newline) {} } diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 11512b1..2f82585 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -8,7 +8,6 @@ mod parse_enum; mod parse_expr; mod parse_function; mod parse_function_parameters; -mod parse_given; mod parse_global_variable; mod parse_helper_expr; mod parse_impl; diff --git a/src/parser/parse_annotation.rs b/src/parser/parse_annotation.rs index d0f88b5..0013e3d 100644 --- a/src/parser/parse_annotation.rs +++ b/src/parser/parse_annotation.rs @@ -1,5 +1,5 @@ use super::{ - annotation::{Annotation, AnnotationKind, Using}, + annotation::{Annotation, AnnotationKind, Given}, error::{ParseError, ParseErrorKind}, Parser, }; @@ -28,10 +28,7 @@ impl<'a, I: Inflow> Parser<'a, I> { "abide_abi" => AnnotationKind::AbideAbi, "public" => AnnotationKind::Public, "template" => AnnotationKind::Template, - "using" => AnnotationKind::Using(Using { - name: self.parse_optional_name(), - ty: self.parse_type(None::<&str>, Some("for context"))?, - }), + "given" => AnnotationKind::Given(self.parse_given()?), _ => { return Err(ParseErrorKind::UnrecognizedAnnotation { name: annotation_name, @@ -52,6 +49,15 @@ impl<'a, I: Inflow> Parser<'a, I> { Ok(annotations) } + fn parse_given(&mut self) -> Result { + let name = self.input.eat_polymorph(); + + Ok(Given { + name, + ty: self.parse_type(None::<&str>, Some("for context"))?, + }) + } + pub fn parse_optional_name(&mut self) -> Option { (self.input.peek().is_identifier() && self.input.peek_nth(1).is_identifier()) .then(|| self.input.advance().kind.unwrap_identifier()) diff --git a/src/parser/parse_function.rs b/src/parser/parse_function.rs index a257b19..2f2c852 100644 --- a/src/parser/parse_function.rs +++ b/src/parser/parse_function.rs @@ -15,6 +15,16 @@ impl<'a, I: Inflow> Parser<'a, I> { // func functionName { // ^ + if !self.input.peek().is_func_keyword() { + return Err(ParseError::expected( + "function", + None::<&str>, + self.input.peek(), + )); + } + + let source = self.input.advance().source; + let mut is_foreign = false; let mut abide_abi = false; let mut privacy = Privacy::Private; @@ -25,8 +35,8 @@ impl<'a, I: Inflow> Parser<'a, I> { AnnotationKind::Foreign => is_foreign = true, AnnotationKind::AbideAbi => abide_abi = true, AnnotationKind::Public => privacy = Privacy::Public, - AnnotationKind::Using(using) => { - contextual_parameters.push(using); + AnnotationKind::Given(given) => { + contextual_parameters.push(given); } _ => return Err(self.unexpected_annotation(&annotation, Some("for function"))), } @@ -37,8 +47,6 @@ impl<'a, I: Inflow> Parser<'a, I> { abide_abi = true; } - let source = self.input.advance().source; - let name = self.parse_identifier(Some("after 'func' keyword"))?; self.ignore_newlines(); diff --git a/src/parser/parse_given.rs b/src/parser/parse_given.rs deleted file mode 100644 index fce7447..0000000 --- a/src/parser/parse_given.rs +++ /dev/null @@ -1,65 +0,0 @@ -use super::{ - annotation::Annotation, - error::{ParseError, ParseErrorKind}, - Parser, -}; -use crate::{ - ast::Given, - inflow::Inflow, - token::{Token, TokenKind}, -}; - -impl<'a, I: Inflow> Parser<'a, I> { - pub fn parse_given(&mut self, annotations: Vec) -> Result { - let source = self.input.peek().source; - self.input.advance().kind.unwrap_given_keyword(); - - for annotation in annotations { - match annotation.kind { - _ => { - return Err(self.unexpected_annotation(&annotation, Some("for implementation"))) - } - } - } - - let name = self.parse_optional_name(); - let target = self.parse_type(None::<&str>, Some("trait"))?; - - let mut body = vec![]; - - if self.input.eat(TokenKind::OpenCurly) { - self.input.ignore_newlines(); - - while !self.input.peek_is_or_eof(TokenKind::CloseCurly) { - // Ignore preceeding newlines - self.ignore_newlines(); - - // Parse annotations - let mut annotations = vec![]; - while self.input.peek().is_hash() { - annotations.extend(self.parse_annotation()?); - self.ignore_newlines(); - } - - body.push(self.parse_function(annotations)?); - self.input.ignore_newlines(); - } - - if !self.input.eat(TokenKind::CloseCurly) { - return Err(ParseErrorKind::Expected { - expected: TokenKind::CloseCurly.to_string(), - for_reason: Some("to close implementation body".into()), - got: self.input.peek().to_string(), - } - .at(self.input.peek().source)); - } - } - - Ok(Given { - name, - target, - source, - body, - }) - } -} diff --git a/src/parser/parse_impl.rs b/src/parser/parse_impl.rs index 1fb18c9..0708cdd 100644 --- a/src/parser/parse_impl.rs +++ b/src/parser/parse_impl.rs @@ -16,22 +16,14 @@ impl<'a, I: Inflow> Parser<'a, I> { for annotation in annotations { match annotation.kind { - _ => return Err(self.unexpected_annotation(&annotation, Some("for impl"))), - } - } - - let target_trait = self.parse_type(None::<&str>, Some("trait"))?; - - if !self.input.eat(TokenKind::ForKeyword) { - return Err(ParseErrorKind::Expected { - expected: TokenKind::ForKeyword.to_string(), - for_reason: Some("after trait to implement".into()), - got: self.input.peek().to_string(), + _ => { + return Err(self.unexpected_annotation(&annotation, Some("for implementation"))) + } } - .at(self.input.peek().source)); } - let for_type = self.parse_type(None::<&str>, Some("impl target"))?; + let name = self.parse_optional_name(); + let target = self.parse_type(None::<&str>, Some("trait"))?; let mut body = vec![]; @@ -64,8 +56,8 @@ impl<'a, I: Inflow> Parser<'a, I> { } Ok(Impl { - for_type, - target_trait, + name, + target, source, body, }) diff --git a/src/parser/parse_top_level.rs b/src/parser/parse_top_level.rs index aff9712..73a6301 100644 --- a/src/parser/parse_top_level.rs +++ b/src/parser/parse_top_level.rs @@ -76,11 +76,7 @@ impl<'a, I: Inflow> Parser<'a, I> { ast_file.traits.push(trait_decl); } TokenKind::ImplKeyword => { - let impl_decl = self.parse_impl(annotations)?; - ast_file.impls.push(impl_decl); - } - TokenKind::GivenKeyword => { - ast_file.givens.push(self.parse_given(annotations)?); + ast_file.impls.push(self.parse_impl(annotations)?); } TokenKind::EndOfFile => { // End-of-file is only okay if no preceeding annotations