1extern crate hibitset;
2extern crate rtforth;
3
4use self::hibitset::BitSet;
5use rtforth::core::{Control, Core, ForwardReferences, Stack, State, Wordlist};
6use rtforth::env::Environment;
7use rtforth::exception::Exception;
8use rtforth::facility::Facility;
9use rtforth::file_access::FileAccess;
10use rtforth::float::Float;
11use rtforth::loader::{HasLoader, Source};
12use rtforth::memory::DataSpace;
13use rtforth::output::Output;
14use rtforth::tools::Tools;
15use rtforth::units::Units;
16use rtforth::NUM_TASKS;
17use std::fs::File;
18use std::time::Instant;
19
20const BUFFER_SIZE: usize = 0x400;
21const LABEL_COUNT: u32 = 1000;
22
23pub struct Task {
28 awake: bool,
29 state: State,
30 s_stk: Stack<isize>,
31 r_stk: Stack<isize>,
32 c_stk: Stack<Control>,
33 f_stk: Stack<f64>,
34 inbuf: Option<String>,
35 files: Vec<Option<File>>,
36 sources: Vec<Option<Source>>,
37 lines: Vec<Option<String>>,
38}
39
40impl Task {
41 pub fn new_background() -> Task {
43 Task {
44 awake: false,
45 state: State::new(),
46 s_stk: Stack::new(0x12345678),
47 r_stk: Stack::new(0x12345678),
48 c_stk: Stack::new(Control::Canary),
49 f_stk: Stack::new(1.234567890),
50 inbuf: None,
51 files: Vec::new(),
52 sources: Vec::new(),
53 lines: Vec::new(),
54 }
55 }
56
57 pub fn new_terminal() -> Task {
59 let mut task = Task::new_background();
60 task.inbuf = Some(String::with_capacity(BUFFER_SIZE));
61 task
62 }
63}
64
65pub struct VM {
67 current_task: usize,
68 tasks: [Task; NUM_TASKS],
69 last_error: Option<Exception>,
70 handler: usize,
71 wordlist: Wordlist<VM>,
72 data_space: DataSpace,
73 tkn: Option<String>,
74 outbuf: Option<String>,
75 hldbuf: String,
76 references: ForwardReferences,
77 now: Instant,
78 forward_bitset: BitSet,
79 resolved_bitset: BitSet,
80 labels: Vec<usize>,
81}
82
83impl VM {
84 pub fn new(data_pages: usize) -> VM {
86 let mut labels = Vec::with_capacity(LABEL_COUNT as _);
87 labels.resize(LABEL_COUNT as _, 0);
88 let mut vm = VM {
89 current_task: 0,
90 tasks: [
91 Task::new_terminal(),
93 Task::new_background(),
94 Task::new_background(),
95 Task::new_background(),
96 Task::new_background(),
97 ],
98 last_error: None,
99 handler: 0,
100 wordlist: Wordlist::with_capacity(1000),
101 data_space: DataSpace::new(data_pages),
102 tkn: Some(String::with_capacity(64)),
103 outbuf: Some(String::with_capacity(128)),
104 hldbuf: String::with_capacity(128),
105 references: ForwardReferences::new(),
106 now: Instant::now(),
107 forward_bitset: BitSet::with_capacity(LABEL_COUNT),
108 resolved_bitset: BitSet::with_capacity(LABEL_COUNT),
109 labels,
110 };
111 vm.add_core();
112 vm.add_output();
113 vm.add_tools();
114 vm.add_environment();
115 vm.add_facility();
116 vm.add_float();
117 vm.add_units();
118 vm.add_file_access();
119 vm.add_loader();
120
121 vm.load_core_fth();
122
123 vm
124 }
125}
126
127impl Core for VM {
128 fn last_error(&self) -> Option<Exception> {
129 self.last_error
130 }
131 fn set_error(&mut self, e: Option<Exception>) {
132 self.last_error = e;
133 }
134 fn handler(&self) -> usize {
135 self.handler
136 }
137 fn set_handler(&mut self, h: usize) {
138 self.handler = h;
139 }
140 fn data_space(&mut self) -> &mut DataSpace {
141 &mut self.data_space
142 }
143 fn data_space_const(&self) -> &DataSpace {
144 &self.data_space
145 }
146 fn hold_buffer(&mut self) -> &mut String {
147 &mut self.hldbuf
148 }
149 fn output_buffer(&mut self) -> &mut Option<String> {
150 &mut self.outbuf
151 }
152 fn set_output_buffer(&mut self, buffer: String) {
153 self.outbuf = Some(buffer);
154 }
155 fn source_id(&self) -> isize {
156 self.tasks[self.current_task].state.source_id
157 }
158 fn input_buffer(&mut self) -> &mut Option<String> {
159 let source_id = self.source_id();
160 if source_id > 0 {
161 &mut self.lines_mut()[source_id as usize - 1]
162 } else {
163 &mut self.tasks[self.current_task].inbuf
164 }
165 }
166 fn set_input_buffer(&mut self, buffer: String) {
167 *self.input_buffer() = Some(buffer);
168 }
169 fn files(&self) -> &Vec<Option<File>> {
170 &self.tasks[self.current_task].files
171 }
172 fn files_mut(&mut self) -> &mut Vec<Option<File>> {
173 &mut self.tasks[self.current_task].files
174 }
175 fn sources(&self) -> &Vec<Option<Source>> {
176 &self.tasks[self.current_task].sources
177 }
178 fn sources_mut(&mut self) -> &mut Vec<Option<Source>> {
179 &mut self.tasks[self.current_task].sources
180 }
181 fn lines(&self) -> &Vec<Option<String>> {
182 &self.tasks[self.current_task].lines
183 }
184 fn lines_mut(&mut self) -> &mut Vec<Option<String>> {
185 &mut self.tasks[self.current_task].lines
186 }
187 fn last_token(&mut self) -> &mut Option<String> {
188 &mut self.tkn
189 }
190 fn set_last_token(&mut self, buffer: String) {
191 self.tkn = Some(buffer);
192 }
193 fn s_stack(&mut self) -> &mut Stack<isize> {
194 &mut self.tasks[self.current_task].s_stk
195 }
196 fn r_stack(&mut self) -> &mut Stack<isize> {
197 &mut self.tasks[self.current_task].r_stk
198 }
199 fn c_stack(&mut self) -> &mut Stack<Control> {
200 &mut self.tasks[self.current_task].c_stk
201 }
202 fn f_stack(&mut self) -> &mut Stack<f64> {
203 &mut self.tasks[self.current_task].f_stk
204 }
205 fn wordlist_mut(&mut self) -> &mut Wordlist<Self> {
206 &mut self.wordlist
207 }
208 fn wordlist(&self) -> &Wordlist<Self> {
209 &self.wordlist
210 }
211 fn state(&mut self) -> &mut State {
212 &mut self.tasks[self.current_task].state
213 }
214 fn references(&mut self) -> &mut ForwardReferences {
215 &mut self.references
216 }
217 fn system_time_ns(&self) -> u64 {
218 let elapsed = self.now.elapsed();
219 elapsed.as_nanos() as _
220 }
221 fn current_task(&self) -> usize {
222 self.current_task
223 }
224 fn set_current_task(&mut self, i: usize) {
225 if i < NUM_TASKS {
226 self.current_task = i;
227 } else {
228 }
230 }
231 fn awake(&self, i: usize) -> bool {
232 if i < NUM_TASKS {
233 self.tasks[i].awake
234 } else {
235 false
236 }
237 }
238 fn set_awake(&mut self, i: usize, v: bool) {
239 if i < NUM_TASKS {
240 self.tasks[i].awake = v;
241 } else {
242 }
244 }
245 fn forward_bitset(&self) -> &BitSet {
246 &self.forward_bitset
247 }
248 fn forward_bitset_mut(&mut self) -> &mut BitSet {
249 &mut self.forward_bitset
250 }
251 fn resolved_bitset(&self) -> &BitSet {
252 &self.resolved_bitset
253 }
254 fn resolved_bitset_mut(&mut self) -> &mut BitSet {
255 &mut self.resolved_bitset
256 }
257 fn labels(&self) -> &Vec<usize> {
258 &self.labels
259 }
260 fn labels_mut(&mut self) -> &mut Vec<usize> {
261 &mut self.labels
262 }
263}
264
265impl Environment for VM {}
266impl Facility for VM {}
267impl Float for VM {}
268impl Units for VM {}
269impl FileAccess for VM {}
270impl HasLoader for VM {}
271impl Output for VM {}
272impl Tools for VM {}