fourth/src/backend.rs~

152 lines
3.9 KiB
Rust

use std::collections::HashMap;
use crate::parse::Parser;
use crate::parse::TokenType::*;
#[derive(Debug)]
pub struct Vm {
stack: Vec<u64>,
dictionary: Dictionary
}
#[derive(Debug, Default)]
struct Dictionary {
dp: u64,
data: HashMap<u64, u64>,
words: HashMap<String, String>
}
impl<'a> Vm {
pub fn new() -> Self {
Self {
stack: Vec::new(),
dictionary: Default::default()
}
}
pub fn vmrun(&mut self, parser: &mut Parser) {
macro_rules! unwrap {
() => {
match self.stack.pop() {
Some(v) => {
v
},
None => {
println!("ERROR: stack empty");
std::process::exit(1);
}
}
}
}
while let Some(item) = parser.next() {
match item {
Number(n) => self.stack.push(n),
Word(w) => {
match w {
"." => {
println!("{:?} ok", unwrap!());
},
"+" => {
let sum = unwrap!().wrapping_add(unwrap!());
self.stack.push(sum);
},
"*" => {
let prod = unwrap!().wrapping_mul(unwrap!());
self.stack.push(prod);
},
"/" => {
let stack_top = unwrap!();
let stack_second = unwrap!();
let quo = stack_second.wrapping_div(stack_top);
self.stack.push(quo);
},
"=" => {
if unwrap!() == unwrap!() {
self.stack.push(1);
} else {
self.stack.push(0);
}
},
"MOD"|"mod" => {
let stack_top = unwrap!();
let stack_second = unwrap!();
let rem = stack_second.wrapping_rem(stack_top);
self.stack.push(rem);
},
"/MOD"|"/mod" => {
let stack_top = unwrap!();
let stack_second = unwrap!();
let rem = stack_second.wrapping_rem(stack_top);
let quo = stack_second.wrapping_div(stack_top);
self.stack.push(rem);
self.stack.push(quo);
},
"SWAP"|"swap" => {
let stack_top = unwrap!();
let stack_second = unwrap!();
self.stack.push(stack_top);
self.stack.push(stack_second);
},
"HERE"|"here" => {
self.stack.push(self.dictionary.dp);
},
"@" => {
let addr = unwrap!();
self.stack.push(*self.dictionary.data.get(&addr).unwrap_or(&0));
},
"!" => {
let addr = unwrap!();
let content = unwrap!();
self.dictionary.data.insert(addr, content);
},
"," => {
let content = unwrap!();
self.dictionary.dp += 1;
self.dictionary.data.insert(self.dictionary.dp, content);
},
"ALLOT"|"allot" => {
self.dictionary.dp += unwrap!();
},
"CREATE"|"create" => {
self.dictionary.dp += 1;
let Some(Word(word_name)) = parser.next() else { println!("ERROR: Word name not given."); std::process::exit(1) };
self.dictionary.words.insert(word_name.to_string(), self.dictionary.dp.to_string());
},
"VARIABLE"|"variable" => {
self.dictionary.dp += 1;
let Some(Word(word_name)) = parser.next() else { println!("ERROR: Word name not given."); std::process::exit(1) };
self.dictionary.words.insert(word_name.to_string(), self.dictionary.dp.to_string());
},
"DUP"|"dup" => {
let stack_top = unwrap!();
self.stack.push(stack_top);
self.stack.push(stack_top);
},
":" => {
let mut word_content = String::new();
let Some(Word(word_name)) = parser.next() else { println!("ERROR: Word name not given."); std::process::exit(1); };
let mut next = parser.inner_next();
while next != Some(";") && next != None {
word_content.push_str(next.unwrap());
word_content.push_str(" ");
next = parser.inner_next();
}
self.dictionary.words.insert(word_name.to_string(), word_content);
},
word => {
let words = self.dictionary.words.clone();
let Some(word_content) = words.get(word) else {
println!("word {:?} does not exist", word);
std::process::exit(1);
};
self.vmrun(&mut Parser::new(word_content));
}
}
}
}
}
}
}