main.cpp 4.9 KB

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