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