From 4c297eb957a5beb05b6d3dff94bfaf7545181887 Mon Sep 17 00:00:00 2001 From: mars Date: Wed, 2 Mar 2022 10:21:10 -0700 Subject: [PATCH] Parse mutable interface functions --- src/parse.rs | 92 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 62 insertions(+), 30 deletions(-) diff --git a/src/parse.rs b/src/parse.rs index 7dac029..ee65e2a 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -23,7 +23,8 @@ impl<'a> ParseTree<'a> { } declarations.push(Definition::build_function( - Some((struct_name, mutable)), + mutable, + Some(struct_name), lexer, )); @@ -31,7 +32,9 @@ impl<'a> ParseTree<'a> { } else { match tok { Token::Struct => declarations.push(Definition::build_structure(lexer)), - Token::Function => declarations.push(Definition::build_function(None, lexer)), + Token::Function => { + declarations.push(Definition::build_function(false, None, lexer)) + } Token::Interface => declarations.push(Definition::build_interface(lexer)), Token::Impl => declarations.push(Definition::build_impl(lexer)), Token::Identifier => associated_struct = Some(lexer.slice()), @@ -51,12 +54,12 @@ pub enum Definition<'a> { members: Vec>, }, Function { - associated_struct: Option<(&'a str, bool)>, + associated_struct: Option<&'a str>, implementation: FnImpl<'a>, }, Interface { name: &'a str, - functions: Vec<(&'a str, FnSig<'a>)>, + functions: Vec>, }, Impl { structure: &'a str, @@ -91,10 +94,11 @@ impl<'a> Definition<'a> { } pub fn build_function( - associated_struct: Option<(&'a str, bool)>, + mutable: bool, + associated_struct: Option<&'a str>, lexer: &mut Lexer<'a>, ) -> Self { - let implementation = FnImpl::build(lexer); + let implementation = FnImpl::build(mutable, lexer); Self::Function { associated_struct, @@ -109,17 +113,13 @@ impl<'a> Definition<'a> { let mut functions = Vec::new(); loop { match lexer.next().unwrap() { - Token::Function => { - let name = lexer.eat_expect_id(); - let (signature, next) = FnSig::build(lexer); - if next != Token::Semicolon { - lexer.panic_message("Expected semicolon"); - } - - functions.push((name, signature)); + Token::Function => functions.push(FnDef::eat_with_semicolon(false, lexer)), + Token::Mut => { + lexer.eat_expect(Token::Function); + functions.push(FnDef::eat_with_semicolon(true, lexer)); } Token::BraceClose => break, - _ => lexer.panic_message("Expected fn or closing bracket"), + _ => lexer.panic_message("Expected function definition or closing bracket"), } } @@ -142,7 +142,11 @@ impl<'a> Definition<'a> { loop { match lexer.next().unwrap() { Token::BraceClose => break, - Token::Function => functions.push(FnImpl::build(lexer)), + Token::Function => functions.push(FnImpl::build(false, lexer)), + Token::Mut => { + lexer.eat_expect(Token::Function); + functions.push(FnImpl::build(true, lexer)); + } _ => lexer.panic_message("Expected function implementation or closing brace"), } } @@ -157,27 +161,55 @@ impl<'a> Definition<'a> { #[derive(Debug)] pub struct FnImpl<'a> { - pub name: &'a str, - pub signature: FnSig<'a>, + pub def: FnDef<'a>, pub body: BranchBody<'a>, } impl<'a> FnImpl<'a> { - pub fn build(lexer: &mut Lexer<'a>) -> Self { - let name = lexer.eat_expect_id(); - let (signature, tok) = FnSig::build(lexer); - - if tok != Token::BraceOpen { - lexer.panic_message("Expected open brace"); - } - + pub fn build(mutable: bool, lexer: &mut Lexer<'a>) -> Self { + let def = FnDef::eat_with_brace(mutable, lexer); let body = BranchBody::build(lexer); + Self { def, body } + } +} - Self { - name, - signature, - body, +#[derive(Debug)] +pub struct FnDef<'a> { + pub mutable: bool, + pub name: &'a str, + pub signature: FnSig<'a>, +} + +impl<'a> FnDef<'a> { + pub fn build(mutable: bool, lexer: &mut Lexer<'a>) -> (Self, Token) { + let name = lexer.eat_expect_id(); + let (signature, tail) = FnSig::build(lexer); + ( + Self { + mutable, + name, + signature, + }, + tail, + ) + } + + pub fn eat_with_semicolon(mutable: bool, lexer: &mut Lexer<'a>) -> Self { + let (fn_def, tail) = Self::build(mutable, lexer); + if tail != Token::Semicolon { + lexer.panic_message("Expected semicolon"); } + + fn_def + } + + pub fn eat_with_brace(mutable: bool, lexer: &mut Lexer<'a>) -> Self { + let (fn_def, tail) = Self::build(mutable, lexer); + if tail != Token::BraceOpen { + lexer.panic_message("Expected opening brace"); + } + + fn_def } }