diff options
| author | Jonas Maier <> | 2026-03-07 09:00:24 +0100 |
|---|---|---|
| committer | Jonas Maier <> | 2026-03-07 09:00:24 +0100 |
| commit | 2d922be2b47bb789fd2903fe48fe2ba920775114 (patch) | |
| tree | 93ba9b2f8508f61527638ebb021fcc208872423e /src/parse.rs | |
| parent | 1385db90739f92f3d33ba6855d383f2a0f34b307 (diff) | |
| download | pish-2d922be2b47bb789fd2903fe48fe2ba920775114.tar.gz | |
some more parsing
Diffstat (limited to 'src/parse.rs')
| -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; |
