diff options
| author | Brian Cully <bjc@spork.org> | 2025-08-19 13:07:41 -0400 |
|---|---|---|
| committer | Brian Cully <bjc@spork.org> | 2025-08-19 13:07:41 -0400 |
| commit | bd33129b72372512a4b8a570c101da01e8877fff (patch) | |
| tree | 0e9adf39ec292a4e6ce23d017e9accf185038710 /src/forth/parser.rs | |
| parent | 2eecdb1a4bae0fbced05f4c375cd6126929fb1fb (diff) | |
| download | automathon-bd33129b72372512a4b8a570c101da01e8877fff.tar.gz automathon-bd33129b72372512a4b8a570c101da01e8877fff.zip | |
interpreter now uses same structure as parser
Diffstat (limited to 'src/forth/parser.rs')
| -rw-r--r-- | src/forth/parser.rs | 35 |
1 files changed, 16 insertions, 19 deletions
diff --git a/src/forth/parser.rs b/src/forth/parser.rs index 26a5686..9e444c9 100644 --- a/src/forth/parser.rs +++ b/src/forth/parser.rs @@ -1,4 +1,4 @@ -use super::interp::{ByteCode, OpCode, WordCatalog}; +use super::interp::{ByteCode, OpCode, WordCatalog, WordList}; use std::collections::HashMap; use std::iter::{Enumerate, Iterator}; @@ -25,14 +25,11 @@ impl std::error::Error for ParseError {} type ParseResult<T> = Result<T, ParseError>; -// a list of all bytecode defs, with the main routine at ‘0’. -type ParserWordList = Vec<ByteCode>; - #[derive(Debug)] pub struct Parser<'a> { text: &'a str, enumerator: Enumerate<Chars<'a>>, - wordlist: ParserWordList, + wordlist: WordList, wordalog: WordCatalog<'a>, namestack: Vec<&'a str>, } @@ -40,13 +37,13 @@ pub struct Parser<'a> { impl<'a> Parser<'a> { pub fn new(text: &'a str) -> Self { let enumerator = text.chars().enumerate(); - let mut wordlist = vec![]; + let mut wl = vec![]; // main routine is always the first entry. - wordlist.push(ByteCode(vec![])); + wl.push(ByteCode(vec![])); Self { text, enumerator, - wordlist, + wordlist: WordList(wl), wordalog: WordCatalog(HashMap::new()), namestack: vec![], } @@ -78,7 +75,7 @@ impl<'a> Parser<'a> { None => &0, Some(name) => self.wordalog.0.get(name).ok_or(ParseError::NameStackEmpty)?, }; - self.wordlist[*word_index].0.push(op); + self.wordlist.0[*word_index].0.push(op); Ok(()) } @@ -87,7 +84,7 @@ impl<'a> Parser<'a> { if let Ok(i) = word.parse::<i32>() { self.bc_push(OpCode::Num(i))?; } else if let Some(i) = self.wordalog.0.get(word) { - self.bc_push(OpCode::WordI(*i))?; + self.bc_push(OpCode::Call(*i))?; } else { match word { r#"s""# => { @@ -100,8 +97,8 @@ impl<'a> Parser<'a> { ":" => { let (name, _, _) = self.next_word().ok_or(ParseError::EOF)?; self.namestack.push(name); - self.wordalog.0.insert(name, self.wordlist.len()); - self.wordlist.push(ByteCode(vec![])); + self.wordalog.0.insert(name, self.wordlist.0.len()); + self.wordlist.0.push(ByteCode(vec![])); }, ";" => { self.bc_push(OpCode::Ret)?; @@ -131,7 +128,7 @@ mod tests { #[test] fn literal_num() { let p = parser_for("1\n"); - let main = &p.wordlist[0]; + let main = &p.wordlist.0[0]; assert_eq!(main.len(), 1); assert_eq!(main[0], OpCode::Num(1)); } @@ -139,7 +136,7 @@ mod tests { #[test] fn literal_string() { let p = parser_for(r#"s" hello there""#); - let main = &p.wordlist[0]; + let main = &p.wordlist.0[0]; assert_eq!(main.len(), 1); assert_eq!(main[0], OpCode::Str(3, 14)); } @@ -147,7 +144,7 @@ mod tests { #[test] fn add_opcode() { let p = parser_for("+\n"); - let main = &p.wordlist[0]; + let main = &p.wordlist.0[0]; eprintln!("main {:?}", main); assert_eq!(main.len(), 1); assert_eq!(main[0], OpCode::Add); @@ -156,7 +153,7 @@ mod tests { #[test] fn sub_opcode() { let p = parser_for("-\n"); - let main = &p.wordlist[0]; + let main = &p.wordlist.0[0]; eprintln!("main {:?}", main); assert_eq!(main.len(), 1); assert_eq!(main[0], OpCode::Sub); @@ -165,16 +162,16 @@ mod tests { #[test] fn def_word() { let p = parser_for(": add2 2 + ; 3 add2\n"); - let main = &p.wordlist[0]; + let main = &p.wordlist.0[0]; eprintln!("main {:?}", main); let add2_index = p.wordalog.0.get("add2").expect("add2 has entry in wordlist"); - let add2 = &p.wordlist[*add2_index]; + let add2 = &p.wordlist.0[*add2_index]; eprintln!("add2 {:?}", add2); assert_eq!(main.len(), 2); assert_eq!(main[0], OpCode::Num(3)); - assert_eq!(main[1], OpCode::WordI(*add2_index)); + assert_eq!(main[1], OpCode::Call(*add2_index)); assert_eq!(add2.len(), 3); assert_eq!(add2[0], OpCode::Num(2)); assert_eq!(add2[1], OpCode::Add); |
