1use crate::{
2 Instruction,
3 TypeFlag,
4 Value,
5};
6
7const STACK_SIZE: usize = 1024;
8
9macro_rules! binop_helper {
10 ($fn_name:ident, $op:tt) => {
11 fn $fn_name(&mut self) {
12 let lhs = self.value_pop();
13 let rhs = self.value_pop();
14 self.value_push(lhs $op rhs);
15 }
16 };
17}
18
19macro_rules! comp_helper {
20 ($fn_name:ident, $op:tt) => {
21 fn $fn_name(&mut self) {
22 let lhs = self.value_pop();
23 let rhs = self.value_pop();
24 let curr_ty = self.ty_flag;
25 self.ty_flag = TypeFlag::Bool;
26 self.value_push((lhs $op rhs).into());
27 self.ty_flag = curr_ty;
28 }
29 };
30}
31
32
33macro_rules! bytecode {
34 ( $( $item:expr ),* ) => {
35 {
36 let mut tmp_vec: Vec<u8> = vec![];
37
38 $(
39 tmp_vec.push($item as u8);
40 )*
41
42 tmp_vec
43 }
44 }
45}
46
47#[derive(Clone)]
48pub struct Machine {
49 stack: [u64; STACK_SIZE],
50 sp: usize,
51 code: Vec<u8>,
52 ip: usize,
53 heap: Vec<u8>,
54 ty_flag: TypeFlag, stream: String,
56 read_wait: bool,halt: bool,
58}
59
60impl Machine {
61 pub fn new() -> Self {
62 Self {
63 stack: [0; STACK_SIZE],
64 sp: 0,
65 code: Vec::new(),
66 ip: 0,
67 heap: Vec::new(),
68 ty_flag: 11.into(), stream: String::new(),
70 read_wait: false,
71 halt: false,
72 }
73 }
74
75 fn push_stream(&mut self) {
76 let mut stream = self.stream.clone();
77
78 loop {
79 match stream.pop() {
80 Some(ch) => self.value_push(ch.into()),
81 None => break,
82 }
83 }
84 }
85
86 pub fn set_stream(&mut self, input: &str) {
87 self.stream = input.to_string();
88
89 if self.read_wait {
90 self.push_stream();
91 self.read_wait = false;
92 }
93 }
94
95 pub fn get_stream(&self) -> Option<String> {
96 if self.stream.len() > 0 {
97 return Some(self.stream.clone());
98 }else{
99 return None;
100 }
101 }
102
103 pub fn clear_stream(&mut self) {
104 self.stream = String::new();
105 }
106
107 fn zero(&mut self) {
108 self.stack.fill(0);
109 self.sp = 0;
110 self.code = vec![];
111 self.ip = 0;
112 self.heap = vec![];
113 self.ty_flag = 11.into();
114 self.clear_stream();
115 self.read_wait = false;
116 self.halt = false;
117 }
118
119 pub fn push_code(&mut self, code: &[u8]) {
120 self.code.extend_from_slice(code)
121 }
122
123 fn stack_push(&mut self, raw: u64) {
124 self.stack[self.sp] = raw;
126 self.sp += 1;
127 }
128
129 fn stack_pop(&mut self) -> u64 {
130 match self.sp.checked_sub(1) {
132 Some(n) => self.sp = n,
133 None => panic!("Error: Stack underflow has occured."),
134 };
135 self.stack[self.sp]
136 }
137
138 fn value_pop(&mut self) -> Value {
139 Value::from_stack(self.ty_flag, self.stack_pop())
141 }
142
143 fn value_push(&mut self, value: Value) {
144 self.stack_push(value.to_stack());
146 }
147
148 fn halt(&mut self) {
149 self.halt = true;
150 }
151
152 fn set_ty_flag(&mut self) {
153 self.ty_flag = self.code[self.ip].into();
156 self.ip += 1;
157 }
158
159 fn get_ty_flag(&mut self) {
160 self.stack_push(self.ty_flag.into());
161 }
162
163 binop_helper!(add, +);
164
165 binop_helper!(sub, -);
166
167 binop_helper!(mul, *);
168
169 binop_helper!(div, /);
170
171 binop_helper!(rem, %);
172
173 fn neg(&mut self) {
174 self.stack[self.sp - 1] =
175 (-(Value::from_stack(self.ty_flag, self.stack[self.sp - 1]))).to_stack();
176 }
177
178 fn incr(&mut self) {
179 let value = Value::from_stack(self.ty_flag, self.stack[self.sp - 1]);
180 self.stack[self.sp - 1] = (value + Value::from_stack(self.ty_flag, 1)).to_stack();
181 }
182
183 fn decr(&mut self) {
184 let value = Value::from_stack(self.ty_flag, self.stack[self.sp - 1]);
185 self.stack[self.sp - 1] = (value - Value::from_stack(self.ty_flag, 1)).to_stack();
186 }
187
188 comp_helper!(eq, ==);
189 comp_helper!(neq, !=);
190 comp_helper!(lt, <);
191 comp_helper!(gt, >);
192 comp_helper!(lte, <=);
193 comp_helper!(gte, >=);
194
195 binop_helper!(and, &);
196 binop_helper!(or, |);
197 binop_helper!(xor, ^);
198 binop_helper!(shl, <<);
199 binop_helper!(shr, >>);
200
201 fn not(&mut self) {
202 self.stack[self.sp - 1] =
203 (!Value::from_stack(self.ty_flag, self.stack[self.sp - 1])).to_stack();
204 }
205
206 fn jmp(&mut self) {
207 let addr = self.stack_pop() as usize;
208 self.ip = addr;
209 }
210
211 fn jmp_if(&mut self) {
212 let cond = self.value_pop();
213 let addr = self.stack_pop() as usize;
214
215 if cond.to_stack() != 0 {
216 self.ip = addr;
217 }
218 }
219
220 fn jmp_if_not(&mut self) {
221 let cond = self.value_pop();
222 let addr = self.stack_pop() as usize;
223
224 if cond.to_stack() == 0 {
225 self.ip = addr;
226 }
227 }
228
229 fn call(&mut self) {
230 let addr = self.stack_pop() as usize;
231 self.stack_push(self.ip as u64);
232 self.ip = addr;
233 }
234
235 fn ret(&mut self) {
236 self.ip = self.stack_pop() as usize;
237 }
238
239 fn push(&mut self) {
240 let value = Value::from_code(
241 self.ty_flag,
242 &self.code[self.ip..self.ip + self.ty_flag.size()],
243 );
244 self.value_push(value);
245 self.ip += self.ty_flag.size();
246 }
247
248 fn dup(&mut self) {
249 self.stack[self.sp] = self.stack[self.sp - 1];
250 self.sp += 1;
251 }
252
253 fn drop(&mut self) {
254 self.sp -= 1;
255 }
256
257 fn swap(&mut self) {
258 let tmp = self.stack[self.sp - 1];
259 self.stack[self.sp - 1] = self.stack[self.sp - 2];
260 self.stack[self.sp - 2] = tmp;
261 }
262
263 fn load(&mut self) {
264 let addr = self.stack_pop() as usize;
265 let value = Value::from_code(self.ty_flag, &self.heap[addr..addr + self.ty_flag.size()]);
266 self.value_push(value);
267 }
268
269 fn store(&mut self) {
270 let addr = self.stack_pop() as usize;
271 let value = self.value_pop();
272 let raw = value.to_code();
273 for i in 0..self.ty_flag.size() {
274 self.heap[addr + i] = raw[i];
275 }
276 }
277
278 fn alloc(&mut self) {
279 let size = self.stack_pop() as usize;
280 let addr = self.heap.len();
281 self.heap.resize(addr + size, 0);
282 self.stack_push(addr as u64);
283 }
284
285 fn free(&mut self) {
286 let addr = self.stack_pop() as usize;
287 let size = self.stack_pop() as usize;
288 self.heap.resize(addr + size, 0);
289 }
290
291 fn heap_size(&mut self) {
292 self.stack_push(self.heap.len() as u64);
293 }
294
295 fn stack_size(&mut self) {
296 self.stack_push(self.sp as u64);
297 }
298
299 fn load_code(&mut self) {
300 let addr = self.stack_pop() as usize;
301 let size = self.stack_pop() as usize;
302 let new_code_start = self.code.len();
303 self.code.extend_from_slice(&self.heap[addr..addr + size]);
304 self.stack_push(new_code_start as u64);
305 }
306
307 fn save_code(&mut self) {
308 let addr = self.stack_pop() as usize;
309 let size = self.stack_pop() as usize;
310 let code_seg = &self.code[addr..addr + size];
311 let heap_len = self.heap.len();
312 self.heap.extend_from_slice(code_seg);
313 self.stack_push(heap_len as u64);
314 }
315
316 fn write(&mut self) {
317 let value = self.value_pop().to_string();
318 self.stream += &value;
319 }
320
321 fn read(&mut self) {
322 self.read_wait = true;
323 }
324
325 fn print(&mut self) {
326 println!("{}", self.stream)
327 }
328
329 fn fetch_instr(&mut self) -> Instruction {
330 if self.ip >= self.code.len() {
331 panic!("Error: Instruction pointer has gone out of bounds")
332 }else{
333 self.ip += 1;
334 return self.code[self.ip - 1].into()
335 }
336 }
337
338 fn dispatch(&mut self) {
339 use Instruction::*;
340
341 let instr = self.fetch_instr();
342
343 match instr {
344 Halt => self.halt(),
345 SetType => self.set_ty_flag(),
346 GetType => self.get_ty_flag(),
347 Add => self.add(),
348 Sub => self.sub(),
349 Mul => self.mul(),
350 Div => self.div(),
351 Rem => self.rem(),
352 Neg => self.neg(),
353 Incr => self.incr(),
354 Decr => self.decr(),
355 Eq => self.eq(),
356 Neq => self.neq(),
357 Lt => self.lt(),
358 Gt => self.gt(),
359 Lte => self.lte(),
360 Gte => self.gte(),
361 And => self.and(),
362 Or => self.or(),
363 Xor => self.xor(),
364 Shl => self.shl(),
365 Shr => self.shr(),
366 Not => self.not(),
367 Jmp => self.jmp(),
368 JmpIf => self.jmp_if(),
369 JmpIfNot => self.jmp_if_not(),
370 Call => self.call(),
371 Ret => self.ret(),
372 Push => self.push(),Dup => self.dup(),
374 Drop => self.drop(),
375 Swap => self.swap(),
376 Load => self.load(),
377 Store => self.store(),
378 Alloc => self.alloc(),
379 Free => self.free(),
380 HeapSize => self.heap_size(),
381 StackSize => self.stack_size(),
382 LoadCode => self.load_code(),
383 SaveCode => self.save_code(),
384 Read => self.read(),
385 Write => self.write(),
386 Print => self.print(),
387 Clear => self.clear_stream(),
388 }
389 }
390
391 fn run(&mut self) {
392 while self.ip <= self.code.len() && !self.halt {
393 if !self.read_wait {
394 self.dispatch()
395 }
396 }
397 }
398
399 pub fn execute(&mut self) {
400 self.run()
401 }
402
403 pub fn execute_code(&mut self, code: Vec<u8>) {
404 self.code = code;
405 self.run();
406 }
407}
408
409#[cfg(test)]
410mod tests {
411 use std::vec;
412
413 use super::*;
414
415 #[test]
416 fn test_internal_stack_ops() {
417 let mut machine = Machine::new();
418
419 machine.stack_push(10);
420 assert_eq!(machine.sp, 1);
421
422 let pop = machine.stack_pop();
423 assert_eq!(pop, 10u64);
424 assert_eq!(machine.sp, 0);
425 }
426
427 #[test]
428 fn test_push_instr() {
429 use Instruction::*;
430 use TypeFlag::*;
431 let mut machine = Machine::new();
432
433 let value: Value = 11i8.into();
434
435 machine.code = bytecode!(SetType, I8, Push);
436 machine.code.extend_from_slice(&value.to_code());
437 machine.push_code(&bytecode!(Halt));
438 machine.run();
439 assert_eq!(machine.stack[machine.sp - 1], 11);
440 }
441
442 #[test]
443 fn test_arith_instrs() {
444 use Instruction::*;
445 use TypeFlag::*;
446
447 let mut machine = Machine::new();
448
449 let lhs: Value = 1000i64.into();
450 let rhs: Value = 500i64.into();
451 let mut start = vec![];
452 start = bytecode!(SetType, I64, Push);
453 start.extend_from_slice(&rhs.to_code());
454 start.extend_from_slice(&bytecode![Push]);
455 start.extend_from_slice(&lhs.to_code());
456
457 let mut add_test = start.clone();
458 add_test.extend_from_slice(&bytecode!(Add, Halt));
459 machine.code = add_test;
460 machine.run();
461 assert_eq!(Value::from(1500i64), machine.value_pop());
462 machine.zero();
463
464 let mut sub_test = start.clone();
465 sub_test.extend_from_slice(&bytecode!(Sub, Halt));
466 machine.code = sub_test;
467 machine.run();
468 assert_eq!(Value::from(500i64), machine.value_pop());
469 machine.zero();
470
471 let mut mul_test = start.clone();
472 mul_test.extend_from_slice(&bytecode!(Mul, Halt));
473 machine.code = mul_test;
474 machine.run();
475 assert_eq!(Value::from(500000i64), machine.value_pop());
476 machine.zero();
477
478 let mut div_test = start.clone();
479 div_test.extend_from_slice(&bytecode!(Div, Halt));
480 machine.code = div_test;
481 machine.run();
482 assert_eq!(Value::from(2i64), machine.value_pop());
483 machine.zero();
484
485 let mut rem_test = start;
486 rem_test.extend_from_slice(&bytecode!(Rem, Halt));
487 machine.code = rem_test;
488 machine.run();
489 assert_eq!(Value::from(0i64), machine.value_pop());
490 }
491
492 #[test]
493 fn test_write() {
494 let mut machine = Machine::new();
495 machine.code = vec![Instruction::SetType as u8, TypeFlag::Char as u8, Instruction::Push as u8];
496 machine.code.extend_from_slice(&Value::from('c').to_code());
497 machine.code.extend_from_slice(&vec![Instruction::Write as u8, Instruction::Halt as u8]);
498 machine.execute();
499 let out = machine.get_stream().unwrap();
500 assert_eq!(out, 'c'.to_string());
501 }
502}