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