From 2d922be2b47bb789fd2903fe48fe2ba920775114 Mon Sep 17 00:00:00 2001 From: Jonas Maier <> Date: Sat, 7 Mar 2026 09:00:24 +0100 Subject: some more parsing --- src/parse.rs | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) (limited to 'src') diff --git a/src/parse.rs b/src/parse.rs index 45bfdc0..8501963 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -40,6 +40,66 @@ impl Ast { } } +#[derive(Debug, Clone)] +pub struct FunBody { + pub body: Ast, +} + +impl Parse for FunBody { + fn parse(b: &mut Cursor<'_>) -> Result { + b.spaces(); + + if b.is_empty() { + return Err(ParseError::Eof); + } + + if b.peek() != b'{' { + return Err(ParseError::Expected('{')); + } + + b.adv(); + let body = Ast::parse(b)?; + if b.is_empty() { + if b.is_completion() { + Ok(Self { body }) + } else { + Err(ParseError::Eof) + } + } else if b.peek() == b'}' { + Ok(Self { body }) + } else { + Err(ParseError::Expected('}')) + } + } +} + +#[derive(Debug, Clone)] +pub struct FunDecl { + pub name: S::Str, + pub body: FunBody, +} + +impl Parse for FunDecl { + fn parse(b: &mut Cursor<'_>) -> Result { + b.spaces(); + // TODO allow funname() {} + if !b.buf.starts_with(b"fun ") { + return Err(ParseError::NotAFunDecl); + } + b.advance(4); + b.spaces(); + let name = ExpString::parse(b)?; + let body = FunBody::parse(b)?; + Ok(Self { name, body }) + } +} + +#[derive(Debug, Clone)] +pub struct VarDecl { + pub name: S::Str, + pub val: S::Str, +} + #[derive(Debug, Clone)] pub struct AssignVar { pub to: String, @@ -303,6 +363,8 @@ pub enum ParseError { Expected(char), NotAString, + + NotAFunDecl, } type Result = std::result::Result; @@ -428,6 +490,14 @@ impl<'a> Cursor<'a> { out } + fn advance(&mut self, amt: usize) -> &[u8] { + self.bt(&format!("adv({amt})")); + let out = &self.buf[..amt]; + self.buf = &self.buf[amt..]; + self.spaced = false; + out + } + fn peek_space(&self) -> bool { if self.buf.is_empty() { return false; -- cgit v1.2.3