blob: afb98d4afe2b6034e4d2d64d7c955a9d551615e2 [file] [log] [blame]
/*=============================================================================
Copyright (c) 2001-2010 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
//
///////////////////////////////////////////////////////////////////////////////
#include "mini_c.hpp"
///////////////////////////////////////////////////////////////////////////////
// Our main compiler
///////////////////////////////////////////////////////////////////////////////
template <typename Grammar>
bool compile(Grammar const& prog, std::string const& expr)
{
typedef white_space<std::string::const_iterator> white_space;
white_space ws; // Our skipper
std::string::const_iterator iter = expr.begin();
std::string::const_iterator end = expr.end();
bool r = phrase_parse(iter, end, prog, ws);
if (r && iter == end)
{
std::cout << "-------------------------\n";
std::cout << "Parsing succeeded\n";
std::cout << "-------------------------\n";
return true;
}
else
{
std::cout << "-------------------------\n";
std::cout << "Parsing failed\n";
std::cout << "-------------------------\n";
return false;
}
}
///////////////////////////////////////////////////////////////////////////////
// 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;
typedef program<iterator_type> program;
vmachine mach; // Our virtual machine
std::vector<int> code; // Our VM code
program prog(code); // Our grammar definition
if (::compile(prog, source_code))
{
std::string fmain("main");
std::string::iterator fbegin = fmain.begin();
function_info* f = prog.functions.lookup->find(fbegin, fmain.end());
if (f == 0)
{
std::cerr << "Error: main function not defined" << std::endl;
return 1;
}
int nargs = argc-2;
if (f->arity != nargs)
{
std::cerr << "Error: main function requires " << f->arity << " arguments." << std::endl;
std::cerr << nargs << "supplied." << std::endl;
return 1;
}
for (int i = 0; i < nargs; ++i)
mach.stack[i] = boost::lexical_cast<int>(argv[i+2]);
int r = mach.execute(
code // code
, code.begin() + f->address // pc
, mach.stack.begin() // frame_ptr
);
std::cout << "-------------------------\n";
std::cout << "Result: " << r << std::endl;
std::cout << "-------------------------\n\n";
}
std::cout << "Bye... :-) \n\n";
return 0;
}