dab14454d1
[SVN r73979]
122 lines
3.7 KiB
C++
122 lines
3.7 KiB
C++
/*=============================================================================
|
|
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;
|
|
}
|
|
|
|
|