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