• 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 //  [ JDG July 18, 2011 ]       Switching to LLVM backend
16 //
17 ///////////////////////////////////////////////////////////////////////////////
18 
19 #include "config.hpp"
20 #include "function.hpp"
21 #include "vm.hpp"
22 #include "compiler.hpp"
23 #include "lexer.hpp"
24 #include <boost/lexical_cast.hpp>
25 #include <fstream>
26 
27 ///////////////////////////////////////////////////////////////////////////////
28 //  Main program
29 ///////////////////////////////////////////////////////////////////////////////
main(int argc,char ** argv)30 int main(int argc, char **argv)
31 {
32     char const* filename;
33     if (argc > 1)
34     {
35         filename = argv[1];
36     }
37     else
38     {
39         std::cerr << "Error: No input file provided." << std::endl;
40         return 1;
41     }
42 
43     std::ifstream in(filename, std::ios_base::in);
44 
45     if (!in)
46     {
47         std::cerr << "Error: Could not open input file: "
48             << filename << std::endl;
49         return 1;
50     }
51 
52     std::string source_code; // We will read the contents here.
53     in.unsetf(std::ios::skipws); // No white space skipping!
54     std::copy(
55         std::istream_iterator<char>(in),
56         std::istream_iterator<char>(),
57         std::back_inserter(source_code));
58 
59     typedef std::string::const_iterator base_iterator_type;
60     typedef client::lexer::conjure_tokens<base_iterator_type> lexer_type;
61     typedef lexer_type::iterator_type iterator_type;
62 
63     lexer_type lexer;                           // Our lexer
64 
65     base_iterator_type first = source_code.begin();
66     base_iterator_type last = source_code.end();
67 
68     iterator_type iter = lexer.begin(first, last);
69     iterator_type end = lexer.end();
70 
71     client::vmachine vm;                        // Our virtual machine
72     client::ast::function_list ast;             // Our AST
73 
74     client::error_handler<base_iterator_type, iterator_type>
75         error_handler(first, last);             // Our error handler
76     client::parser::function<iterator_type, lexer_type>
77         function(error_handler, lexer);         // Our parser
78     client::code_gen::compiler
79         compiler(vm, error_handler);            // Our compiler
80 
81     // note: we don't need a skipper
82     bool success = parse(iter, end, +function, ast);
83 
84     std::cout << "-------------------------\n";
85 
86     if (success && iter == end)
87     {
88         if (compiler(ast))
89         {
90             // JIT the main function
91             client::function main_function = vm.get_function("main");
92             if (!main_function)
93             {
94                 std::cerr << "function main not found" << std::endl;
95                 return 1;
96             }
97 
98             int nargs = argc-2;
99             if (main_function.arity() != nargs)
100             {
101                 std::cerr << "Error: main function requires "
102                     << main_function.arity() << " arguments." << std::endl;
103                 std::cerr << nargs << " supplied." << std::endl;
104                 return 1;
105             }
106 
107             std::cout << "Success\n";
108             std::cout << "-------------------------\n";
109             std::cout << "Assembler----------------\n\n";
110             vm.print_assembler();
111 
112             // Call the main function
113             int r;
114             char** args = argv + 2;
115             switch (nargs)
116             {
117                 case 0: r = main_function(); break;
118 
119                 case 1: r = main_function(
120                     boost::lexical_cast<int>(args[0]));
121                     break;
122 
123                 case 2: r = main_function(
124                     boost::lexical_cast<int>(args[0]),
125                     boost::lexical_cast<int>(args[1]));
126                     break;
127 
128                 case 3: r = main_function(
129                     boost::lexical_cast<int>(args[0]),
130                     boost::lexical_cast<int>(args[1]),
131                     boost::lexical_cast<int>(args[2]));
132                     break;
133 
134                 default:
135                     std::cerr << "Function calls with more " <<
136                         "than 3 arguments not supported" << std::endl;
137                     return 1;
138             }
139 
140             std::cout << "-------------------------\n";
141             std::cout << "Result: " << r << std::endl;
142             std::cout << "-------------------------\n\n";
143         }
144         else
145         {
146             std::cout << "Compile failure\n";
147         }
148     }
149     else
150     {
151         std::cout << "Parse failure\n";
152     }
153     return 0;
154 }
155 
156 
157