]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/example/qi/compiler_tutorial/mini_c/main.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / spirit / example / qi / compiler_tutorial / mini_c / main.cpp
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 ///////////////////////////////////////////////////////////////////////////////
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