diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/parse.rs | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/src/parse.rs b/src/parse.rs index 45bfdc0..8501963 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -41,6 +41,66 @@ impl Ast<PreExpansion> { } #[derive(Debug, Clone)] +pub struct FunBody { + pub body: Ast<PreExpansion>, +} + +impl Parse for FunBody { + fn parse(b: &mut Cursor<'_>) -> Result<Self> { + 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<S: Stage> { + pub name: S::Str, + pub body: FunBody, +} + +impl Parse for FunDecl<PreExpansion> { + fn parse(b: &mut Cursor<'_>) -> Result<Self> { + b.spaces(); + // TODO allow fun<tab>name() {} + 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<S: Stage> { + pub name: S::Str, + pub val: S::Str, +} + +#[derive(Debug, Clone)] pub struct AssignVar { pub to: String, // TODO: body @@ -303,6 +363,8 @@ pub enum ParseError { Expected(char), NotAString, + + NotAFunDecl, } type Result<T> = std::result::Result<T, ParseError>; @@ -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; |
