Parse mutable interface functions

This commit is contained in:
mars 2022-03-02 10:21:10 -07:00
parent 79b8b8ea3d
commit 4c297eb957
1 changed files with 62 additions and 30 deletions

View File

@ -23,7 +23,8 @@ impl<'a> ParseTree<'a> {
} }
declarations.push(Definition::build_function( declarations.push(Definition::build_function(
Some((struct_name, mutable)), mutable,
Some(struct_name),
lexer, lexer,
)); ));
@ -31,7 +32,9 @@ impl<'a> ParseTree<'a> {
} else { } else {
match tok { match tok {
Token::Struct => declarations.push(Definition::build_structure(lexer)), 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::Interface => declarations.push(Definition::build_interface(lexer)),
Token::Impl => declarations.push(Definition::build_impl(lexer)), Token::Impl => declarations.push(Definition::build_impl(lexer)),
Token::Identifier => associated_struct = Some(lexer.slice()), Token::Identifier => associated_struct = Some(lexer.slice()),
@ -51,12 +54,12 @@ pub enum Definition<'a> {
members: Vec<StructMember<'a>>, members: Vec<StructMember<'a>>,
}, },
Function { Function {
associated_struct: Option<(&'a str, bool)>, associated_struct: Option<&'a str>,
implementation: FnImpl<'a>, implementation: FnImpl<'a>,
}, },
Interface { Interface {
name: &'a str, name: &'a str,
functions: Vec<(&'a str, FnSig<'a>)>, functions: Vec<FnDef<'a>>,
}, },
Impl { Impl {
structure: &'a str, structure: &'a str,
@ -91,10 +94,11 @@ impl<'a> Definition<'a> {
} }
pub fn build_function( pub fn build_function(
associated_struct: Option<(&'a str, bool)>, mutable: bool,
associated_struct: Option<&'a str>,
lexer: &mut Lexer<'a>, lexer: &mut Lexer<'a>,
) -> Self { ) -> Self {
let implementation = FnImpl::build(lexer); let implementation = FnImpl::build(mutable, lexer);
Self::Function { Self::Function {
associated_struct, associated_struct,
@ -109,17 +113,13 @@ impl<'a> Definition<'a> {
let mut functions = Vec::new(); let mut functions = Vec::new();
loop { loop {
match lexer.next().unwrap() { match lexer.next().unwrap() {
Token::Function => { Token::Function => functions.push(FnDef::eat_with_semicolon(false, lexer)),
let name = lexer.eat_expect_id(); Token::Mut => {
let (signature, next) = FnSig::build(lexer); lexer.eat_expect(Token::Function);
if next != Token::Semicolon { functions.push(FnDef::eat_with_semicolon(true, lexer));
lexer.panic_message("Expected semicolon");
}
functions.push((name, signature));
} }
Token::BraceClose => break, 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 { loop {
match lexer.next().unwrap() { match lexer.next().unwrap() {
Token::BraceClose => break, 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"), _ => lexer.panic_message("Expected function implementation or closing brace"),
} }
} }
@ -157,27 +161,55 @@ impl<'a> Definition<'a> {
#[derive(Debug)] #[derive(Debug)]
pub struct FnImpl<'a> { pub struct FnImpl<'a> {
pub name: &'a str, pub def: FnDef<'a>,
pub signature: FnSig<'a>,
pub body: BranchBody<'a>, pub body: BranchBody<'a>,
} }
impl<'a> FnImpl<'a> { impl<'a> FnImpl<'a> {
pub fn build(lexer: &mut Lexer<'a>) -> Self { pub fn build(mutable: bool, lexer: &mut Lexer<'a>) -> Self {
let name = lexer.eat_expect_id(); let def = FnDef::eat_with_brace(mutable, lexer);
let (signature, tok) = FnSig::build(lexer);
if tok != Token::BraceOpen {
lexer.panic_message("Expected open brace");
}
let body = BranchBody::build(lexer); let body = BranchBody::build(lexer);
Self { def, body }
}
}
Self { #[derive(Debug)]
name, pub struct FnDef<'a> {
signature, pub mutable: bool,
body, 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
} }
} }