1/*=============================================================================
2 Copyright (c) 2001-2011 Joel de Guzman
3
4 Distributed under the Boost Software License, Version 1.0. (See accompanying
5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6=============================================================================*/
7#include "vm.hpp"
8
9#if defined(_MSC_VER)
10# pragma warning(disable: 4800) // forcing value to bool 'true' or 'false'
11 // (performance warning)
12#endif
13
14namespace client
15{
16 int vmachine::execute(
17 std::vector<int> const& code
18 , std::vector<int>::const_iterator pc
19 , std::vector<int>::iterator frame_ptr
20 )
21 {
22 std::vector<int>::iterator stack_ptr = frame_ptr;
23
24 while (true)
25 {
26 switch (*pc++)
27 {
28 case op_neg:
29 stack_ptr[-1] = -stack_ptr[-1];
30 break;
31
32 case op_not:
33 stack_ptr[-1] = !bool(stack_ptr[-1]);
34 break;
35
36 case op_add:
37 --stack_ptr;
38 stack_ptr[-1] += stack_ptr[0];
39 break;
40
41 case op_sub:
42 --stack_ptr;
43 stack_ptr[-1] -= stack_ptr[0];
44 break;
45
46 case op_mul:
47 --stack_ptr;
48 stack_ptr[-1] *= stack_ptr[0];
49 break;
50
51 case op_div:
52 --stack_ptr;
53 stack_ptr[-1] /= stack_ptr[0];
54 break;
55
56 case op_eq:
57 --stack_ptr;
58 stack_ptr[-1] = bool(stack_ptr[-1] == stack_ptr[0]);
59 break;
60
61 case op_neq:
62 --stack_ptr;
63 stack_ptr[-1] = bool(stack_ptr[-1] != stack_ptr[0]);
64 break;
65
66 case op_lt:
67 --stack_ptr;
68 stack_ptr[-1] = bool(stack_ptr[-1] < stack_ptr[0]);
69 break;
70
71 case op_lte:
72 --stack_ptr;
73 stack_ptr[-1] = bool(stack_ptr[-1] <= stack_ptr[0]);
74 break;
75
76 case op_gt:
77 --stack_ptr;
78 stack_ptr[-1] = bool(stack_ptr[-1] > stack_ptr[0]);
79 break;
80
81 case op_gte:
82 --stack_ptr;
83 stack_ptr[-1] = bool(stack_ptr[-1] >= stack_ptr[0]);
84 break;
85
86 case op_and:
87 --stack_ptr;
88 stack_ptr[-1] = bool(stack_ptr[-1]) && bool(stack_ptr[0]);
89 break;
90
91 case op_or:
92 --stack_ptr;
93 stack_ptr[-1] = bool(stack_ptr[-1]) || bool(stack_ptr[0]);
94 break;
95
96 case op_load:
97 *stack_ptr++ = frame_ptr[*pc++];
98 break;
99
100 case op_store:
101 --stack_ptr;
102 frame_ptr[*pc++] = stack_ptr[0];
103 break;
104
105 case op_int:
106 *stack_ptr++ = *pc++;
107 break;
108
109 case op_true:
110 *stack_ptr++ = true;
111 break;
112
113 case op_false:
114 *stack_ptr++ = false;
115 break;
116
117 case op_jump:
118 pc += *pc;
119 break;
120
121 case op_jump_if:
122 if (!bool(stack_ptr[-1]))
123 pc += *pc;
124 else
125 ++pc;
126 --stack_ptr;
127 break;
128
129 case op_stk_adj:
130 stack_ptr += *pc++;
131 break;
132
133 case op_call:
134 {
135 int nargs = *pc++;
136 int jump = *pc++;
137
138 // a function call is a recursive call to execute
139 int r = execute(
140 code
141 , pc: code.begin() + jump
142 , frame_ptr: stack_ptr - nargs
143 );
144
145 // cleanup after return from function
146 stack_ptr[-nargs] = r; // get return value
147 stack_ptr -= (nargs - 1); // the stack will now contain
148 // the return value
149 }
150 break;
151
152 case op_return:
153 return stack_ptr[-1];
154 }
155 }
156 }
157}
158
159
160

source code of boost/libs/spirit/example/qi/compiler_tutorial/mini_c/vm.cpp