123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- /*=============================================================================
- 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
- // [ JDG July 18, 2011 ] Switching to LLVM backend
- //
- ///////////////////////////////////////////////////////////////////////////////
- #include "config.hpp"
- #include "function.hpp"
- #include "vm.hpp"
- #include "compiler.hpp"
- #include "lexer.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 base_iterator_type;
- typedef client::lexer::conjure_tokens<base_iterator_type> 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<base_iterator_type, iterator_type>
- error_handler(first, last); // Our error handler
- client::parser::function<iterator_type, lexer_type>
- function(error_handler, lexer); // Our parser
- client::code_gen::compiler
- compiler(vm, 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))
- {
- // JIT the main function
- client::function main_function = vm.get_function("main");
- if (!main_function)
- {
- std::cerr << "function main not found" << std::endl;
- return 1;
- }
- int nargs = argc-2;
- if (main_function.arity() != nargs)
- {
- std::cerr << "Error: main function requires "
- << main_function.arity() << " arguments." << std::endl;
- std::cerr << nargs << " supplied." << std::endl;
- return 1;
- }
- std::cout << "Success\n";
- std::cout << "-------------------------\n";
- std::cout << "Assembler----------------\n\n";
- vm.print_assembler();
- // Call the main function
- int r;
- char** args = argv + 2;
- switch (nargs)
- {
- case 0: r = main_function(); break;
- case 1: r = main_function(
- boost::lexical_cast<int>(args[0]));
- break;
- case 2: r = main_function(
- boost::lexical_cast<int>(args[0]),
- boost::lexical_cast<int>(args[1]));
- break;
- case 3: r = main_function(
- boost::lexical_cast<int>(args[0]),
- boost::lexical_cast<int>(args[1]),
- boost::lexical_cast<int>(args[2]));
- break;
- default:
- std::cerr << "Function calls with more " <<
- "than 3 arguments not supported" << std::endl;
- return 1;
- }
- 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;
- }
|