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