From 63747d1666afebc81b32a1e4cf5592d7dc614c11 Mon Sep 17 00:00:00 2001 From: IsaacShelton Date: Sat, 14 Dec 2024 22:31:06 -0600 Subject: [PATCH] Implemented parsing for trait bodies in preparation for user-defined traits --- src/parser/parse_trait.rs | 48 ++++++++++++++++++++++++++++++++++-- src/resolve/function_head.rs | 7 ++---- 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/src/parser/parse_trait.rs b/src/parser/parse_trait.rs index 0609c4e6..1e202793 100644 --- a/src/parser/parse_trait.rs +++ b/src/parser/parse_trait.rs @@ -4,11 +4,19 @@ use super::{ Parser, }; use crate::{ - ast::{Privacy, Trait}, + ast::{Parameters, Privacy, Trait, Type}, inflow::Inflow, + source_files::Source, token::{Token, TokenKind}, }; +pub struct TraitMethod { + pub name: String, + pub parameters: Parameters, + pub return_type: Type, + pub source: Source, +} + impl<'a, I: Inflow> Parser<'a, I> { pub fn parse_trait(&mut self, annotations: Vec) -> Result { let source = self.source_here(); @@ -28,9 +36,13 @@ impl<'a, I: Inflow> Parser<'a, I> { self.ignore_newlines(); self.parse_token(TokenKind::OpenCurly, Some("to begin trait body"))?; + self.ignore_newlines(); + + let mut methods = vec![]; while !self.input.peek_is_or_eof(TokenKind::CloseCurly) { - todo!("parse trait body"); + methods.push(self.parse_trait_method()?); + self.ignore_newlines(); } self.parse_token(TokenKind::CloseCurly, Some("to end trait body"))?; @@ -41,4 +53,36 @@ impl<'a, I: Inflow> Parser<'a, I> { privacy, }) } + + fn parse_trait_method(&mut self) -> Result { + let source = self.input.peek().source; + + if !self.input.eat(TokenKind::FuncKeyword) { + return Err(ParseError::expected( + "'func' keyword", + Some("to begin trait method"), + self.input.peek(), + )); + } + + let name = self.parse_identifier(Some("after 'func' keyword"))?; + self.ignore_newlines(); + + let parameters = if self.input.peek_is(TokenKind::OpenParen) { + self.parse_function_parameters()? + } else { + Parameters::default() + }; + + self.ignore_newlines(); + + let return_type = self.parse_type(Some("return "), Some("for trait method"))?; + + Ok(TraitMethod { + name, + parameters, + return_type, + source, + }) + } } diff --git a/src/resolve/function_head.rs b/src/resolve/function_head.rs index 2a5a5f88..3387c1ab 100644 --- a/src/resolve/function_head.rs +++ b/src/resolve/function_head.rs @@ -25,17 +25,14 @@ pub fn create_function_heads( for (function_i, function) in file.functions.iter().enumerate() { let name = ResolvedName::new(module_file_id, &function.name); - - let fake_constraints = CurrentConstraints { - constraints: Default::default(), - }; + let pre_parameters_constraints = CurrentConstraints::default(); let type_ctx = ResolveTypeCtx::new( &resolved_ast, module_file_id, *physical_file_id, &ctx.types_in_modules, - &fake_constraints, + &pre_parameters_constraints, ); let is_generic = function.return_type.contains_polymorph().is_some()