| 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 | #if !defined(BOOST_SPIRIT_CONJURE_COMPILER_HPP) |
| 8 | #define BOOST_SPIRIT_CONJURE_COMPILER_HPP |
| 9 | |
| 10 | #include "ast.hpp" |
| 11 | #include "error_handler.hpp" |
| 12 | #include <vector> |
| 13 | #include <map> |
| 14 | #include <boost/function.hpp> |
| 15 | #include <boost/shared_ptr.hpp> |
| 16 | #include <boost/phoenix/core.hpp> |
| 17 | #include <boost/phoenix/function.hpp> |
| 18 | #include <boost/phoenix/operator.hpp> |
| 19 | |
| 20 | namespace client { namespace code_gen |
| 21 | { |
| 22 | /////////////////////////////////////////////////////////////////////////// |
| 23 | // The Function |
| 24 | /////////////////////////////////////////////////////////////////////////// |
| 25 | struct function |
| 26 | { |
| 27 | function(std::vector<int>& code, int nargs) |
| 28 | : code(code), address(code.size()), size_(0), nargs_(nargs) {} |
| 29 | |
| 30 | void op(int a); |
| 31 | void op(int a, int b); |
| 32 | void op(int a, int b, int c); |
| 33 | |
| 34 | int& operator[](std::size_t i) { return code[address+i]; } |
| 35 | int const& operator[](std::size_t i) const { return code[address+i]; } |
| 36 | std::size_t size() const { return size_; } |
| 37 | std::size_t get_address() const { return address; } |
| 38 | |
| 39 | int nargs() const { return nargs_; } |
| 40 | int nvars() const { return variables.size(); } |
| 41 | int const* find_var(std::string const& name) const; |
| 42 | void add_var(std::string const& name); |
| 43 | void link_to(std::string const& name, std::size_t address); |
| 44 | |
| 45 | void print_assembler() const; |
| 46 | |
| 47 | private: |
| 48 | |
| 49 | std::map<std::string, int> variables; |
| 50 | std::map<std::size_t, std::string> function_calls; |
| 51 | std::vector<int>& code; |
| 52 | std::size_t address; |
| 53 | std::size_t size_; |
| 54 | std::size_t nargs_; |
| 55 | }; |
| 56 | |
| 57 | /////////////////////////////////////////////////////////////////////////// |
| 58 | // The Compiler |
| 59 | /////////////////////////////////////////////////////////////////////////// |
| 60 | struct compiler |
| 61 | { |
| 62 | typedef bool result_type; |
| 63 | |
| 64 | template <typename ErrorHandler> |
| 65 | compiler(ErrorHandler& error_handler_) |
| 66 | : current(0) |
| 67 | { |
| 68 | using namespace boost::phoenix::arg_names; |
| 69 | namespace phx = boost::phoenix; |
| 70 | using boost::phoenix::function; |
| 71 | |
| 72 | error_handler = function<ErrorHandler>(error_handler_)( |
| 73 | "Error! " , _2, phx::cref(error_handler_.iters)[_1]); |
| 74 | } |
| 75 | |
| 76 | bool operator()(ast::nil) { BOOST_ASSERT(0); return false; } |
| 77 | bool operator()(unsigned int x); |
| 78 | bool operator()(bool x); |
| 79 | bool operator()(ast::identifier const& x); |
| 80 | bool operator()(token_ids::type const& x); |
| 81 | bool operator()(ast::unary const& x); |
| 82 | bool operator()(ast::function_call const& x); |
| 83 | bool operator()(ast::expression const& x); |
| 84 | bool operator()(ast::assignment const& x); |
| 85 | bool operator()(ast::variable_declaration const& x); |
| 86 | bool operator()(ast::statement_list const& x); |
| 87 | bool operator()(ast::statement const& x); |
| 88 | bool operator()(ast::if_statement const& x); |
| 89 | bool operator()(ast::while_statement const& x); |
| 90 | bool operator()(ast::return_statement const& x); |
| 91 | bool operator()(ast::function const& x); |
| 92 | bool operator()(ast::function_list const& x); |
| 93 | |
| 94 | void print_assembler() const; |
| 95 | |
| 96 | boost::shared_ptr<code_gen::function> |
| 97 | find_function(std::string const& name) const; |
| 98 | |
| 99 | std::vector<int>& get_code() { return code; } |
| 100 | std::vector<int> const& get_code() const { return code; } |
| 101 | |
| 102 | private: |
| 103 | |
| 104 | bool compile_expression( |
| 105 | int min_precedence, |
| 106 | std::list<ast::operation>::const_iterator& rbegin, |
| 107 | std::list<ast::operation>::const_iterator rend); |
| 108 | |
| 109 | typedef std::map<std::string, boost::shared_ptr<code_gen::function> > function_table; |
| 110 | |
| 111 | std::vector<int> code; |
| 112 | code_gen::function* current; |
| 113 | std::string current_function_name; |
| 114 | function_table functions; |
| 115 | bool void_return; |
| 116 | |
| 117 | boost::function< |
| 118 | void(int tag, std::string const& what)> |
| 119 | error_handler; |
| 120 | }; |
| 121 | }} |
| 122 | |
| 123 | #endif |
| 124 | |