stackr_rs/interpreter/
evaluate.rs1use super::*;
2
3impl<State> Interpreter<State> {
4 #[allow(dead_code)]
6 pub fn reset_program(&mut self) {
7 self.program_counter = 0;
8 self.program.clear();
9 self.program_debug_locations.clear();
10 }
11
12 pub(crate) fn load_program(&mut self, code: &str, path: Option<PathBuf>) -> Result<(), Err> {
14 let mut location = Location::new(path);
15
16 let mut maybe_make_word = |buffer: &mut String, word_location: &Location| {
17 if !buffer.is_empty() {
18 let word = buffer.trim();
19 let location = word_location.clone();
20 self.program_debug_locations.push(location);
21
22 let instruction = if let Ok(number) = word.parse::<Number>() {
24 Instruction::PushNumber(number)
25 } else if word.starts_with('"') {
26 let mut word = word.to_string();
28 word.remove(0);
29 word.pop();
30 Instruction::PushString(word)
31 } else {
32 Instruction::Address(self.get_address(word))
33 };
34 self.program.push(instruction);
35 *buffer = String::new();
36 }
37 };
38
39 let mut buffer = String::new();
40 let mut word_location = location.clone();
41 let mut making_string = false;
42 let mut made_string = false;
43
44 for c in code.chars() {
45 if c == '"' {
46 if !making_string {
47 making_string = true;
48 } else {
49 let last_char = buffer.chars().last();
50 if last_char != Some('\\') {
51 making_string = false;
52 made_string = true;
53 buffer.push(c);
54 }
55 }
56 }
57 if !making_string && c.is_whitespace() || made_string {
58 made_string = false;
59 maybe_make_word(&mut buffer, &word_location);
60 } else {
61 if buffer.is_empty() {
64 word_location = location.clone();
65 }
66 buffer.push(c);
67 }
68
69 if c == '\n' {
71 location.new_line();
72 } else {
73 location.next();
74 }
75 }
76
77 if making_string {
78 return Err(("Unclosed string".into(), word_location));
79 }
80
81 maybe_make_word(&mut buffer, &word_location);
83
84 Ok(())
85 }
86
87 pub(crate) fn execute(&mut self) -> Result<(), Err> {
89 while self.program_counter < self.program.len() {
90 let instruction = self.program[self.program_counter].clone();
91 self.execute_instruction(instruction)?;
92 self.program_counter += 1;
93 }
94
95 Ok(())
96 }
97
98 pub(crate) fn execute_instruction(&mut self, instruction: Instruction) -> Result<(), Err> {
100 match instruction {
101 Instruction::PushString(string) => self.push_string(string),
102 Instruction::PushNumber(number) => self.push_number(number),
103 Instruction::Address(address) => {
104 if self.read_mode != ReadMode::Off && address != self.address_cache.read_mode_end {
106 if self.read_mode == ReadMode::SingleWord {
107 self.read_mode = ReadMode::Off;
108
109 if !self.ram.contains_key(&address) {
111 let variable_location = self.next_address;
112 self.next_address = self.next_address.next();
113 self.ram
114 .insert(address, RamValue::Address(variable_location));
115 }
116 } else {
117 self.push_address(address);
118 }
119 } else {
120 let contents = self.ram.get(&address).ok_or((
122 format!("Address not found: {}", self.get_name(address)),
123 self.location(),
124 ))?;
125 let ops_to_execute = match contents {
126 RamValue::Compiled(ops) => Some(ops.clone()),
127 RamValue::BuiltIn(method) => {
128 method(self)?;
129 None
130 }
131 RamValue::Value(value) => {
132 self.stack.push(StackValue::Value(value.clone()));
133 None
134 }
135 RamValue::Address(address) => {
136 self.stack.push(address.into());
137 None
138 }
139 };
140 if let Some(ops) = ops_to_execute {
141 for op in ops {
142 self.execute_instruction(op)?;
143 }
144 }
145 }
146 }
147 }
148 Ok(())
149 }
150}