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