summaryrefslogtreecommitdiffstats
path: root/src/forth/parser.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/forth/parser.rs')
-rw-r--r--src/forth/parser.rs35
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);