aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJonas Maier <>2026-03-07 09:00:24 +0100
committerJonas Maier <>2026-03-07 09:00:24 +0100
commit2d922be2b47bb789fd2903fe48fe2ba920775114 (patch)
tree93ba9b2f8508f61527638ebb021fcc208872423e /src
parent1385db90739f92f3d33ba6855d383f2a0f34b307 (diff)
downloadpish-2d922be2b47bb789fd2903fe48fe2ba920775114.tar.gz
some more parsing
Diffstat (limited to 'src')
-rw-r--r--src/parse.rs70
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;