Sophie

Sophie

distrib > Mageia > 7 > i586 > media > core-release > by-pkgid > dc9b5eb62a4d8b54b80379fd86561955 > files > 5051

boost-examples-1.68.0-4.mga7.i586.rpm

/*=============================================================================
    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
//
///////////////////////////////////////////////////////////////////////////////

#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(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<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
    {
        error_handler.dump_error_line(first);
        std::cout << "Parse failure\n";
    }
    return 0;
}