From a1c946b747325b4d7df778ebc70112338482f143 Mon Sep 17 00:00:00 2001 From: Brian Cully Date: Thu, 21 Aug 2025 15:26:44 -0400 Subject: factorial working --- src/forth/parser.rs | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'src/forth/parser.rs') diff --git a/src/forth/parser.rs b/src/forth/parser.rs index ddc48a9..55ad64b 100644 --- a/src/forth/parser.rs +++ b/src/forth/parser.rs @@ -1,4 +1,4 @@ -use super::interp::{ByteCode, OpCode, WordCatalog, WordList}; +use super::interp::{ByteCode, OpCode, WordList}; use std::collections::HashMap; use std::iter::{Enumerate, Iterator}; @@ -27,6 +27,9 @@ impl std::error::Error for ParseError {} type ParseResult = Result; +#[derive(Debug)] +pub struct WordCatalog<'a>(pub(super) HashMap<&'a str, usize>); + #[derive(Debug)] pub enum IfClauses { True(usize), @@ -39,7 +42,8 @@ pub struct Parser<'a> { enumerator: Enumerate>, // list of all word definitions, in the order defined. the main // routine is always in the first entry. - wordlist: WordList, + // todo: don't be pub, have a method to extract a wordlist + pub wordlist: WordList, // catalog of word to word index in `wordlist` wordalog: WordCatalog<'a>, // holds a stack of indices into `wordlist` that are currently @@ -74,7 +78,7 @@ impl<'a> Parser<'a> { let (end, _c) = self.enumerator.by_ref() .find(|(_i, c)| c.is_whitespace())?; - let word = self.text.get(start..end).unwrap(); + let word = &self.text[start..end]; Some((word, start, end)) } @@ -98,7 +102,7 @@ impl<'a> Parser<'a> { Ok(()) } - fn parse(&mut self) -> ParseResult<()> { + pub fn parse(&mut self) -> ParseResult<()> { while let Some((word, _start, end)) = self.next_word() { if let Ok(i) = word.parse::() { self.bc_push(OpCode::Num(i))?; @@ -139,7 +143,6 @@ impl<'a> Parser<'a> { self.defstack.pop().ok_or(ParseError::DefStackEmpty)?; }, "if" => { - eprintln!("got if, if_stack: {:?}", self.if_stack); let i = self.wordlist.0.len(); self.wordlist.0.push(ByteCode(vec![])); self.defstack.push(i); @@ -147,7 +150,6 @@ impl<'a> Parser<'a> { self.if_stack.push(IfClauses::True(i)); }, "else" => { - eprintln!("got else, if_stack: {:?}", self.if_stack); self.bc_push(OpCode::Ret)?; self.defstack.pop(); @@ -163,24 +165,30 @@ impl<'a> Parser<'a> { self.if_stack.push(IfClauses::TrueFalse(true_clause, i)); }, "then" => { - eprintln!("got then, if_stack: {:?}", self.if_stack); self.bc_push(OpCode::Ret)?; self.defstack.pop(); match self.if_stack.pop() { None => return Err(ParseError::MissingIf), Some(IfClauses::True(true_clause)) => { - eprintln!("single clause true at {}", true_clause); self.bc_push(OpCode::If(true_clause, None))?; }, Some(IfClauses::TrueFalse(true_clause, false_clause)) => { - eprintln!("two clause true at {} and {}", true_clause, false_clause); self.bc_push(OpCode::If(true_clause, Some(false_clause)))?; } } }, "+" => self.bc_push(OpCode::Add)?, "-" => self.bc_push(OpCode::Sub)?, + "*" => self.bc_push(OpCode::Mul)?, + "/" => self.bc_push(OpCode::Div)?, + "dup" => self.bc_push(OpCode::Dup)?, + "drop" => self.bc_push(OpCode::Drop)?, + "=" => self.bc_push(OpCode::EQ)?, + ">" => self.bc_push(OpCode::GT)?, + ">=" => self.bc_push(OpCode::GTE)?, + "<" => self.bc_push(OpCode::LT)?, + "<=" => self.bc_push(OpCode::LTE)?, other => return Err(ParseError::UnknownWord(String::from(other))), } } -- cgit v1.3