/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

  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Joel de Guzman
  3. Copyright (c) 2001-2011 Hartmut Kaiser
  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. // [ HK June 3, 2011 ] Adding lexer
  14. //
  15. ///////////////////////////////////////////////////////////////////////////////
  16. ///////////////////////////////////////////////////////////////////////////////
  17. // Define this to enable debugging
  18. //#define BOOST_SPIRIT_QI_DEBUG
  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. // Main program
  28. ///////////////////////////////////////////////////////////////////////////////
  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. std::ifstream in(filename, std::ios_base::in);
  42. if (!in)
  43. {
  44. std::cerr << "Error: Could not open input file: "
  45. << filename << std::endl;
  46. return 1;
  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. typedef std::string::const_iterator base_iterator_type;
  55. typedef client::lexer::conjure_tokens<base_iterator_type> lexer_type;
  56. typedef lexer_type::iterator_type iterator_type;
  57. lexer_type lexer; // Our lexer
  58. base_iterator_type first = source_code.begin();
  59. base_iterator_type last = source_code.end();
  60. iterator_type iter = lexer.begin(first, last);
  61. iterator_type end = lexer.end();
  62. client::vmachine vm; // Our virtual machine
  63. client::ast::function_list ast; // Our AST
  64. client::error_handler<base_iterator_type, iterator_type>
  65. error_handler(first, last); // Our error handler
  66. client::parser::function<iterator_type, lexer_type>
  67. function(error_handler, lexer); // Our parser
  68. client::code_gen::compiler
  69. compiler(error_handler); // Our compiler
  70. // note: we don't need a skipper
  71. bool success = parse(iter, end, +function, ast);
  72. std::cout << "-------------------------\n";
  73. if (success && iter == end)
  74. {
  75. if (compiler(ast))
  76. {
  77. boost::shared_ptr<client::code_gen::function>
  78. p = compiler.find_function("main");
  79. if (!p)
  80. return 1;
  81. int nargs = argc-2;
  82. if (p->nargs() != nargs)
  83. {
  84. std::cerr << "Error: main function requires " << p->nargs() << " arguments." << std::endl;
  85. std::cerr << nargs << " supplied." << std::endl;
  86. return 1;
  87. }
  88. std::cout << "Success\n";
  89. std::cout << "-------------------------\n";
  90. std::cout << "Assembler----------------\n\n";
  91. compiler.print_assembler();
  92. // Push the arguments into our stack
  93. for (int i = 0; i < nargs; ++i)
  94. vm.get_stack()[i] = boost::lexical_cast<int>(argv[i+2]);
  95. // Call the interpreter
  96. int r = vm.execute(compiler.get_code());
  97. std::cout << "-------------------------\n";
  98. std::cout << "Result: " << r << std::endl;
  99. std::cout << "-------------------------\n\n";
  100. }
  101. else
  102. {
  103. std::cout << "Compile failure\n";
  104. }
  105. }
  106. else
  107. {
  108. std::cout << "Parse failure\n";
  109. }
  110. return 0;
  111. }