/*============================================================================= 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 #include /////////////////////////////////////////////////////////////////////////////// // 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(in), std::istream_iterator(), std::back_inserter(source_code)); typedef std::string::const_iterator base_iterator_type; typedef client::lexer::conjure_tokens 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 error_handler(first, last); // Our error handler client::parser::function 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 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(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; }