Download | Plain Text | Line Numbers
/**
* @module mycpu
* @author Guenther Neuwirth (0626638), Manuel Mausz (0728348)
* @brief mycpu executes a programfile (in simple assembler) by parsing the
* programfile first. This creates a vector of instructions, which will
* be executed in linear order (except jumps) afterwards. In order to
* initialize the memory of the cpu before execution an optional
* memoryfile can be passed as commandline option.
* @date 13.05.2009
* @par Exercise
* 4
*/
#include <boost/program_options.hpp>
#include <iostream>
#include <fstream>
#include <stdexcept>
#include <stdlib.h>
#include "ccpu.h"
#include "cmem.h"
#include "cprogram.h"
using namespace std;
namespace po = boost::program_options;
/**
* @func main
* @brief program entry point
* @param argc standard parameter of main
* @param argv standard parameter of main
* @return 0 on success, not 0 otherwise
* @globalvars none
* @exception none
* @conditions none
*
* parse commandline options, create and initialize memory,
* create cprogram instance, which parses the programfile and
* execute CCPU::run()
* On error print error message to stderr.
* Unknown commandline options will print a usage message.
*/
int main(int argc, char* argv[])
{
string me(argv[0]);
/* define commandline options */
po::options_description desc("Allowed options");
desc.add_options()
("help,h", "this help message")
("compile,c", po::value<string>(), "input programfile")
("memory,m", po::value<string>(), "input memoryfile");
/* parse commandline options */
po::variables_map vm;
try
{
po::store(po::parse_command_line(argc, argv, desc), vm);
po::notify(vm);
}
catch(po::error& ex)
{
cerr << me << ": Error: " << ex.what() << endl;
}
/* print usage upon request or missing params */
if (vm.count("help") || !vm.count("compile"))
{
cout << "Usage: " << me << " -c <programfile> [-m <memoryfile>]" << endl;
cout << desc << endl;
return 0;
}
/* create memory and optionally initialize memory from file */
CMem memory;
if (vm.count("memory"))
{
string memoryfile(vm["memory"].as<string>());
ifstream file(memoryfile.c_str(), ios::in);
if (!file.is_open())
{
cerr << me << ": Unable to open memoryfile '" << memoryfile << "' for reading." << endl;
return 1;
}
try
{
memory.initialize(file);
file.close();
}
catch(runtime_error& ex)
{
file.close();
cerr << me << ": Error while reading from memoryfile:" << endl
<< " " << ex.what() << endl;
return 1;
}
#if DEBUG
memory.dump(cerr);
#endif
}
/* create program instance */
CProgram program;
string programfile(vm["compile"].as<string>());
ifstream file(programfile.c_str(), ios::in);
if (!file.is_open())
{
cerr << me << ": Unable to open programfile '" << programfile << "' for reading." << endl;
return 1;
}
try
{
program.compile(file);
file.close();
}
catch(runtime_error& ex)
{
file.close();
cerr << me << ": Error while compiling programfile:" << endl
<< " " << ex.what() << endl;
return 1;
}
#if DEBUG
program.dump(cerr);
#endif
/* create cpu and execute the program */
try
{
CCPU cpu(256);
cpu.setMemory(&memory);
cpu.setProgram(&program);
cpu.run();
#if DEBUG
//cpu.dumpRegisters(cerr);
#endif
}
catch(runtime_error& ex)
{
cerr << me << ": Error while executing program:" << endl
<< " " << ex.what() << endl;
#if DEBUG
memory.dump(cerr);
#endif
return 1;
}
return 0;
}
/* vim: set et sw=2 ts=2: */