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_MINIC_COMPILER_HPP) 8 #define BOOST_SPIRIT_MINIC_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/spirit/include/phoenix_core.hpp> 17 #include <boost/spirit/include/phoenix_function.hpp> 18 #include <boost/spirit/include/phoenix_operator.hpp> 19 20 namespace client { namespace code_gen 21 { 22 /////////////////////////////////////////////////////////////////////////// 23 // The Function 24 /////////////////////////////////////////////////////////////////////////// 25 struct function 26 { functionclient::code_gen::function27 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 operator []client::code_gen::function34 int& operator[](std::size_t i) { return code[address+i]; } operator []client::code_gen::function35 int const& operator[](std::size_t i) const { return code[address+i]; } sizeclient::code_gen::function36 std::size_t size() const { return size_; } get_addressclient::code_gen::function37 std::size_t get_address() const { return address; } 38 nargsclient::code_gen::function39 int nargs() const { return nargs_; } nvarsclient::code_gen::function40 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> compilerclient::code_gen::compiler65 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 operator ()client::code_gen::compiler76 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()(ast::operation 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 get_codeclient::code_gen::compiler99 std::vector<int>& get_code() { return code; } get_codeclient::code_gen::compiler100 std::vector<int> const& get_code() const { return code; } 101 102 private: 103 104 typedef std::map<std::string, boost::shared_ptr<code_gen::function> > function_table; 105 106 std::vector<int> code; 107 code_gen::function* current; 108 std::string current_function_name; 109 function_table functions; 110 bool void_return; 111 112 boost::function< 113 void(int tag, std::string const& what)> 114 error_handler; 115 }; 116 }} 117 118 #endif 119