• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 ///////////////////////////////////////////////////////////////////////////////
8 //
9 //  Not a calculator anymore, right? :-)
10 //
11 //  [ JDG April 10, 2007 ]      spirit2
12 //  [ JDG February 18, 2011 ]   Pure attributes. No semantic actions.
13 //
14 ///////////////////////////////////////////////////////////////////////////////
15 
16 #include "function.hpp"
17 #include "skipper.hpp"
18 #include "vm.hpp"
19 #include "compiler.hpp"
20 #include <boost/lexical_cast.hpp>
21 #include <fstream>
22 
23 ///////////////////////////////////////////////////////////////////////////////
24 //  Main program
25 ///////////////////////////////////////////////////////////////////////////////
main(int argc,char ** argv)26 int main(int argc, char **argv)
27 {
28     char const* filename;
29     if (argc > 1)
30     {
31         filename = argv[1];
32     }
33     else
34     {
35         std::cerr << "Error: No input file provided." << std::endl;
36         return 1;
37     }
38 
39     std::ifstream in(filename, std::ios_base::in);
40 
41     if (!in)
42     {
43         std::cerr << "Error: Could not open input file: "
44             << filename << std::endl;
45         return 1;
46     }
47 
48     std::string source_code; // We will read the contents here.
49     in.unsetf(std::ios::skipws); // No white space skipping!
50     std::copy(
51         std::istream_iterator<char>(in),
52         std::istream_iterator<char>(),
53         std::back_inserter(source_code));
54 
55     typedef std::string::const_iterator iterator_type;
56     iterator_type iter = source_code.begin();
57     iterator_type end = source_code.end();
58 
59     client::vmachine vm;                        // Our virtual machine
60     client::ast::function_list ast;             // Our AST
61 
62     client::error_handler<iterator_type>
63         error_handler(iter, end);               // Our error handler
64     client::parser::function<iterator_type>
65         function(error_handler);                // Our parser
66     client::parser::skipper<iterator_type>
67         skipper;                                // Our skipper
68     client::code_gen::compiler
69         compiler(error_handler);                // Our compiler
70 
71 
72     bool success = phrase_parse(iter, end, +function, skipper, ast);
73 
74     std::cout << "-------------------------\n";
75 
76     if (success && iter == end)
77     {
78         if (compiler(ast))
79         {
80             boost::shared_ptr<client::code_gen::function>
81                 p  = compiler.find_function("main");
82             if (!p)
83                 return 1;
84 
85             int nargs = argc-2;
86             if (p->nargs() != nargs)
87             {
88                 std::cerr << "Error: main function requires " << p->nargs() << " arguments." << std::endl;
89                 std::cerr << nargs << " supplied." << std::endl;
90                 return 1;
91             }
92 
93             std::cout << "Success\n";
94             std::cout << "-------------------------\n";
95             std::cout << "Assembler----------------\n\n";
96             compiler.print_assembler();
97 
98             // Push the arguments into our stack
99             for (int i = 0; i < nargs; ++i)
100                 vm.get_stack()[i] = boost::lexical_cast<int>(argv[i+2]);
101 
102             // Call the interpreter
103             int r = vm.execute(compiler.get_code());
104 
105             std::cout << "-------------------------\n";
106             std::cout << "Result: " << r << std::endl;
107             std::cout << "-------------------------\n\n";
108         }
109         else
110         {
111             std::cout << "Compile failure\n";
112         }
113     }
114     else
115     {
116         std::cout << "Parse failure\n";
117     }
118     return 0;
119 }
120 
121 
122