123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- /*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- 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.
- //
- ///////////////////////////////////////////////////////////////////////////////
- #include "function.hpp"
- #include "skipper.hpp"
- #include "vm.hpp"
- #include "compiler.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 iterator_type;
- iterator_type iter = source_code.begin();
- iterator_type end = source_code.end();
- client::vmachine vm; // Our virtual machine
- client::ast::function_list ast; // Our AST
- client::error_handler<iterator_type>
- error_handler(iter, end); // Our error handler
- client::parser::function<iterator_type>
- function(error_handler); // Our parser
- client::parser::skipper<iterator_type>
- skipper; // Our skipper
- client::code_gen::compiler
- compiler(error_handler); // Our compiler
- bool success = phrase_parse(iter, end, +function, skipper, 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;
- }
|