| /*============================================================================= |
| Copyright (c) 2001-2010 Joel de Guzman |
| |
| Distributed under the Boost Software License, Version 1.0. (See accompanying |
| file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
| =============================================================================*/ |
| #include "calc7.hpp" |
| |
| # pragma warning(disable: 4800) // forcing value to bool 'true' or 'false' |
| // (performance warning) |
| |
| void vmachine::execute(std::vector<int> const& code, int nvars) |
| { |
| std::vector<int>::const_iterator pc = code.begin(); |
| std::vector<int>::iterator locals = stack.begin(); |
| stack_ptr = stack.begin() + nvars; |
| |
| while (pc != code.end()) |
| { |
| switch (*pc++) |
| { |
| case op_neg: |
| stack_ptr[-1] = -stack_ptr[-1]; |
| break; |
| |
| case op_not: |
| stack_ptr[-1] = !bool(stack_ptr[-1]); |
| break; |
| |
| case op_add: |
| --stack_ptr; |
| stack_ptr[-1] += stack_ptr[0]; |
| break; |
| |
| case op_sub: |
| --stack_ptr; |
| stack_ptr[-1] -= stack_ptr[0]; |
| break; |
| |
| case op_mul: |
| --stack_ptr; |
| stack_ptr[-1] *= stack_ptr[0]; |
| break; |
| |
| case op_div: |
| --stack_ptr; |
| stack_ptr[-1] /= stack_ptr[0]; |
| break; |
| |
| case op_eq: |
| --stack_ptr; |
| stack_ptr[-1] = bool(stack_ptr[-1] == stack_ptr[0]); |
| break; |
| |
| case op_neq: |
| --stack_ptr; |
| stack_ptr[-1] = bool(stack_ptr[-1] != stack_ptr[0]); |
| break; |
| |
| case op_lt: |
| --stack_ptr; |
| stack_ptr[-1] = bool(stack_ptr[-1] < stack_ptr[0]); |
| break; |
| |
| case op_lte: |
| --stack_ptr; |
| stack_ptr[-1] = bool(stack_ptr[-1] <= stack_ptr[0]); |
| break; |
| |
| case op_gt: |
| --stack_ptr; |
| stack_ptr[-1] = bool(stack_ptr[-1] > stack_ptr[0]); |
| break; |
| |
| case op_gte: |
| --stack_ptr; |
| stack_ptr[-1] = bool(stack_ptr[-1] >= stack_ptr[0]); |
| break; |
| |
| case op_and: |
| --stack_ptr; |
| stack_ptr[-1] = bool(stack_ptr[-1]) && bool(stack_ptr[0]); |
| break; |
| |
| case op_or: |
| --stack_ptr; |
| stack_ptr[-1] = bool(stack_ptr[-1]) || bool(stack_ptr[0]); |
| break; |
| |
| case op_load: |
| *stack_ptr++ = locals[*pc++]; |
| break; |
| |
| case op_store: |
| --stack_ptr; |
| locals[*pc++] = stack_ptr[0]; |
| break; |
| |
| case op_int: |
| *stack_ptr++ = *pc++; |
| break; |
| |
| case op_true: |
| *stack_ptr++ = true; |
| break; |
| |
| case op_false: |
| *stack_ptr++ = false; |
| break; |
| |
| case op_jump: |
| pc = code.begin() + *pc; |
| break; |
| |
| case op_jump_if: |
| if (!bool(stack_ptr[-1])) |
| pc = code.begin() + *pc; |
| else |
| ++pc; |
| --stack_ptr; |
| break; |
| } |
| } |
| } |
| |