/Src/Dependencies/Boost/libs/spirit/example/qi/compiler_tutorial/conjure2/main.cpp
http://hadesmem.googlecode.com/ · C++ · 134 lines · 87 code · 22 blank · 25 comment · 10 complexity · 075cc9a3215f8a47a3df89802b5e9068 MD5 · raw file
- /*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2001-2011 Hartmut Kaiser
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- =============================================================================*/
- ///////////////////////////////////////////////////////////////////////////////
- //
- // Not a calculator anymore, right? :-)
- //
- // [ JDG April 10, 2007 ] spirit2
- // [ JDG February 18, 2011 ] Pure attributes. No semantic actions.
- // [ HK June 3, 2011 ] Adding lexer
- //
- ///////////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////
- // Define this to enable debugging
- //#define BOOST_SPIRIT_QI_DEBUG
- #include "config.hpp"
- #include "function.hpp"
- #include "vm.hpp"
- #include "compiler.hpp"
- #include "lexer.hpp"
- #include <boost/lexical_cast.hpp>
- #include <fstream>
- ///////////////////////////////////////////////////////////////////////////////
- // Main program
- ///////////////////////////////////////////////////////////////////////////////
- int main(int argc, char **argv)
- {
- char const* filename;
- if (argc > 1)
- {
- filename = argv[1];
- }
- else
- {
- std::cerr << "Error: No input file provided." << std::endl;
- return 1;
- }
- std::ifstream in(filename, std::ios_base::in);
- if (!in)
- {
- std::cerr << "Error: Could not open input file: "
- << filename << std::endl;
- return 1;
- }
- std::string source_code; // We will read the contents here.
- in.unsetf(std::ios::skipws); // No white space skipping!
- std::copy(
- std::istream_iterator<char>(in),
- std::istream_iterator<char>(),
- std::back_inserter(source_code));
- typedef std::string::const_iterator base_iterator_type;
- typedef client::lexer::conjure_tokens<base_iterator_type> lexer_type;
- typedef lexer_type::iterator_type iterator_type;
- lexer_type lexer; // Our lexer
- base_iterator_type first = source_code.begin();
- base_iterator_type last = source_code.end();
- iterator_type iter = lexer.begin(first, last);
- iterator_type end = lexer.end();
- client::vmachine vm; // Our virtual machine
- client::ast::function_list ast; // Our AST
- client::error_handler<base_iterator_type, iterator_type>
- error_handler(first, last); // Our error handler
- client::parser::function<iterator_type, lexer_type>
- function(error_handler, lexer); // Our parser
- client::code_gen::compiler
- compiler(error_handler); // Our compiler
- // note: we don't need a skipper
- bool success = parse(iter, end, +function, ast);
- std::cout << "-------------------------\n";
- if (success && iter == end)
- {
- if (compiler(ast))
- {
- boost::shared_ptr<client::code_gen::function>
- p = compiler.find_function("main");
- if (!p)
- return 1;
- int nargs = argc-2;
- if (p->nargs() != nargs)
- {
- std::cerr << "Error: main function requires " << p->nargs() << " arguments." << std::endl;
- std::cerr << nargs << " supplied." << std::endl;
- return 1;
- }
- std::cout << "Success\n";
- std::cout << "-------------------------\n";
- std::cout << "Assembler----------------\n\n";
- compiler.print_assembler();
- // Push the arguments into our stack
- for (int i = 0; i < nargs; ++i)
- vm.get_stack()[i] = boost::lexical_cast<int>(argv[i+2]);
- // Call the interpreter
- int r = vm.execute(compiler.get_code());
- std::cout << "-------------------------\n";
- std::cout << "Result: " << r << std::endl;
- std::cout << "-------------------------\n\n";
- }
- else
- {
- std::cout << "Compile failure\n";
- }
- }
- else
- {
- std::cout << "Parse failure\n";
- }
- return 0;
- }