]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/example/x3/calc/calc8/compiler.cpp
1 /*=============================================================================
2 Copyright (c) 2001-2014 Joel de Guzman
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 "compiler.hpp"
9 #include <boost/variant/apply_visitor.hpp>
10 #include <boost/assert.hpp>
13 namespace client
{ namespace code_gen
15 void program::op(int a
)
20 void program::op(int a
, int b
)
26 void program::op(int a
, int b
, int c
)
33 int const* program::find_var(std::string
const& name
) const
35 auto i
= variables
.find(name
);
36 if (i
== variables
.end())
41 void program::add_var(std::string
const& name
)
43 std::size_t n
= variables
.size();
44 variables
[name
] = int(n
);
47 void program::print_variables(std::vector
<int> const& stack
) const
49 for (auto const& p
: variables
)
51 std::cout
<< " " << p
.first
<< ": " << stack
[p
.second
] << std::endl
;
55 void program::print_assembler() const
57 auto pc
= code
.begin();
59 std::vector
<std::string
> locals(variables
.size());
60 typedef std::pair
<std::string
, int> pair
;
61 for (pair
const& p
: variables
)
63 locals
[p
.second
] = p
.first
;
65 << p
.first
<< ", @" << p
.second
<< std::endl
;
68 while (pc
!= code
.end())
73 std::cout
<< "op_neg" << std::endl
;
77 std::cout
<< "op_add" << std::endl
;
81 std::cout
<< "op_sub" << std::endl
;
85 std::cout
<< "op_mul" << std::endl
;
89 std::cout
<< "op_div" << std::endl
;
93 std::cout
<< "op_load " << locals
[*pc
++] << std::endl
;
97 std::cout
<< "op_store " << locals
[*pc
++] << std::endl
;
101 std::cout
<< "op_int " << *pc
++ << std::endl
;
105 std::cout
<< "op_stk_adj " << *pc
++ << std::endl
;
111 bool compiler::operator()(unsigned int x
) const
113 program
.op(op_int
, x
);
117 bool compiler::operator()(ast::variable
const& x
) const
119 int const* p
= program
.find_var(x
.name
);
122 error_handler(x
, "Undeclared variable: " + x
.name
);
125 program
.op(op_load
, *p
);
129 bool compiler::operator()(ast::operation
const& x
) const
131 if (!boost::apply_visitor(*this, x
.operand_
))
135 case '+': program
.op(op_add
); break;
136 case '-': program
.op(op_sub
); break;
137 case '*': program
.op(op_mul
); break;
138 case '/': program
.op(op_div
); break;
139 default: BOOST_ASSERT(0); return false;
144 bool compiler::operator()(ast::signed_
const& x
) const
146 if (!boost::apply_visitor(*this, x
.operand_
))
150 case '-': program
.op(op_neg
); break;
152 default: BOOST_ASSERT(0); return false;
157 bool compiler::operator()(ast::expression
const& x
) const
159 if (!boost::apply_visitor(*this, x
.first
))
161 for (ast::operation
const& oper
: x
.rest
)
169 bool compiler::operator()(ast::assignment
const& x
) const
173 int const* p
= program
.find_var(x
.lhs
.name
);
176 error_handler(x
.lhs
, "Undeclared variable: " + x
.lhs
.name
);
179 program
.op(op_store
, *p
);
183 bool compiler::operator()(ast::variable_declaration
const& x
) const
185 int const* p
= program
.find_var(x
.assign
.lhs
.name
);
188 error_handler(x
.assign
.lhs
, "Duplicate variable: " + x
.assign
.lhs
.name
);
191 bool r
= (*this)(x
.assign
.rhs
);
192 if (r
) // don't add the variable if the RHS fails
194 program
.add_var(x
.assign
.lhs
.name
);
195 program
.op(op_store
, *program
.find_var(x
.assign
.lhs
.name
));
200 bool compiler::operator()(ast::statement_list
const& x
) const
204 // op_stk_adj 0 for now. we'll know how many variables we'll have later
205 program
.op(op_stk_adj
, 0);
206 for (ast::statement
const& s
: x
)
208 if (!boost::apply_visitor(*this, s
))
214 program
[1] = int(program
.nvars()); // now store the actual number of variables