From 45581d3d376e8deed84952cb838ae330549e5241 Mon Sep 17 00:00:00 2001 From: manuel Date: Tue, 12 May 2009 23:18:17 +0200 Subject: my cpu design --- ue3/mycpu/Makefile | 8 +-- ue3/mycpu/ccpu.cpp | 78 +++++++++++++++++++++ ue3/mycpu/ccpu.h | 167 +++++++++++++++++++++++++++++++++++++++++++++ ue3/mycpu/cdat.h | 29 ++++++-- ue3/mycpu/cdisplay.h | 48 +++++++++++++ ue3/mycpu/cinstruction.cpp | 46 +++++++++++++ ue3/mycpu/cinstruction.h | 98 ++++++++++++++++++++++++++ ue3/mycpu/cmem.h | 109 +++++++++++++++++++++++++++++ ue3/mycpu/cprogram.cpp | 126 ++++++++++++++++++++++++++++++++++ ue3/mycpu/cprogram.h | 78 +++++++++++++++++++++ ue3/mycpu/instructions.cpp | 27 ++++++++ ue3/mycpu/instructions.h | 66 ++++++++++++++++++ ue3/mycpu/mycpu.cpp | 152 +++++++++++++++++++++++++++++++++++++++++ 13 files changed, 1022 insertions(+), 10 deletions(-) create mode 100644 ue3/mycpu/ccpu.cpp create mode 100644 ue3/mycpu/ccpu.h create mode 100644 ue3/mycpu/cdisplay.h create mode 100644 ue3/mycpu/cinstruction.cpp create mode 100644 ue3/mycpu/cinstruction.h create mode 100644 ue3/mycpu/cmem.h create mode 100644 ue3/mycpu/cprogram.cpp create mode 100644 ue3/mycpu/cprogram.h create mode 100644 ue3/mycpu/instructions.cpp create mode 100644 ue3/mycpu/instructions.h create mode 100644 ue3/mycpu/mycpu.cpp (limited to 'ue3') diff --git a/ue3/mycpu/Makefile b/ue3/mycpu/Makefile index 6f57741..16067d1 100644 --- a/ue3/mycpu/Makefile +++ b/ue3/mycpu/Makefile @@ -6,13 +6,13 @@ CXX= g++ LD= $(CXX) DEBUGFLAGS= -DNDEBUG INCLUDE_PATH= -I/usr/local/include -CXXFLAGS= -O -ansi -pedantic-errors -Wall $(INCLUDE_PATH) $(DEBUGFLAGS) +CXXFLAGS= -O -ansi -pedantic-errors -Wall -Wno-long-long $(INCLUDE_PATH) $(DEBUGFLAGS) LDFLAGS= -LIBS= -L/usr/local/lib +LIBS= -L/usr/local/lib -lboost_program_options BIN= mycpu -OBJS= mycpu.o cdat.o -HEADERS= cdat.h +OBJS= cinstruction.o instructions.o cprogram.o ccpu.o mycpu.o +HEADERS= cdat.h cmem.h cinstruction.h instructions.h cprogram.h cdisplay.h ccpu.h .SUFFIXES: .cpp .o diff --git a/ue3/mycpu/ccpu.cpp b/ue3/mycpu/ccpu.cpp new file mode 100644 index 0000000..6f364f8 --- /dev/null +++ b/ue3/mycpu/ccpu.cpp @@ -0,0 +1,78 @@ +/** + * @module ccpu + * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) + * @brief TODO + * @date 10.05.2009 + */ + +#ifdef DEBUG +# include +# include +#endif +#include "ccpu.h" + +using namespace std; + +CCPU::CCPU(const unsigned cnt) + : m_regcnt(cnt), m_memory(NULL), m_program(NULL), m_flagzero(0), m_flagsign(0) +{ + m_registers = new CDat[cnt]; + for(unsigned i = 0; i < cnt; ++i) + m_registers[i] = 0; +} + +/*----------------------------------------------------------------------------*/ + +CCPU::~CCPU() +{ + delete[] m_registers; + m_registers = NULL; +} + +/*----------------------------------------------------------------------------*/ + +void CCPU::run() +{ + if (m_memory == NULL) + throw runtime_error("CPU has no memory"); + if (m_program == NULL) + throw runtime_error("CPU has no program to execute"); + if (m_regcnt == 0) + throw runtime_error("CPU has no registers"); + + bool run = true; + while(run) + { + unsigned pc = static_cast(m_registers[0]); + + /* end of the program reached */ + if (pc == m_program->size()) + return; + + /* pc is out of bound */ + if (pc > m_program->size()) + throw runtime_error("Programcounter is out of bound"); + + /* execute instruction */ + m_program->at(pc)->execute(this); + ++m_registers[0]; + } + + cout << "LALA" << endl; +} + +/*----------------------------------------------------------------------------*/ + +#if DEBUG +void CCPU::dumpRegisters(std::ostream& out) +{ + out << "[REGISTER DUMP]" << endl; + for(unsigned i = 0; i < getRegisterCount(); ++i) + { + out << "[" << std::setw(4) << std::setfill('0') << i << "] " + << m_registers[i] << endl; + } +} +#endif + +/* vim: set et sw=2 ts=2: */ diff --git a/ue3/mycpu/ccpu.h b/ue3/mycpu/ccpu.h new file mode 100644 index 0000000..e28a7cc --- /dev/null +++ b/ue3/mycpu/ccpu.h @@ -0,0 +1,167 @@ +/** + * @module ccpu + * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) + * @brief TODO + * @date 10.05.2009 + */ + +#ifndef CCPU_H +#define CCPU_H 1 + +#include +#include +#include "cdat.h" +#include "cmem.h" +#include "cprogram.h" + +/** + * @class CCPU + * + * TODO + */ +class CCPU +{ + public: + /** + * @method CCPU + * @brief Default ctor + * @param cnt number of registers to allocate for this cpu + * @return - + * @globalvars none + * @exception none + * @conditions none + */ + CCPU(const unsigned cnt); + + /** + * @method ~CCPU + * @brief Default dtor + * @param - + * @return - + * @globalvars none + * @exception none + * @conditions none + */ + ~CCPU(); + + /** + * @method getRegisterCount + * @brief get number of registers + * @param - + * @return number of registers + * @globalvars none + * @exception none + * @conditions none + */ + const unsigned getRegisterCount() + { + return m_regcnt; + } + + /** + * @method getRegisters + * @brief get pointer to registers array + * @param - + * @return pointer to registers array + * @globalvars none + * @exception none + * @conditions none + */ + CDat *getRegisters() + { + return m_registers; + } + + /** + * @method setMemory + * @brief set memory of cpu + * @param memory pointer to memory + * @return - + * @globalvars none + * @exception none + * @conditions none + */ + void setMemory(const CMem *memory) + { + m_memory = memory; + } + + /** + * @method getMemory + * @brief get pointer to memory + * @param - + * @return pointer to memory + * @globalvars none + * @exception none + * @conditions none + */ + const CMem *getMemory() + { + return m_memory; + } + + /** + * @method setProgram + * @brief set program to execute + * @param memory pointer to program + * @return - + * @globalvars none + * @exception none + * @conditions none + */ + void setProgram(const CProgram *program) + { + m_program = program; + } + + /** + * @method getProgram + * @brief get pointer to program + * @param - + * @return pointer to program + * @globalvars none + * @exception none + * @conditions none + */ + const CProgram *getProgram() + { + return m_program; + } + + /** + * @method run + * @brief execute current program + * @param - + * @return - + * @globalvars none + * @exception runtime_error + * @conditions none + */ + void run(); + +#if DEBUG + /** + * @method dumpRegisters + * @brief dump content of registers to outputstream + * @param out outputstream to write to + * @return void + * @globalvars none + * @exception none + * @conditions none + */ + void dumpRegisters(std::ostream& out); +#endif + + private: + /* members */ + CDat *m_registers; + unsigned m_regcnt; + const CMem *m_memory; + const CProgram *m_program; + bool m_flagzero; + bool m_flagsign; +}; + +#endif + +/* vim: set et sw=2 ts=2: */ diff --git a/ue3/mycpu/cdat.h b/ue3/mycpu/cdat.h index dc8a07c..365bd88 100644 --- a/ue3/mycpu/cdat.h +++ b/ue3/mycpu/cdat.h @@ -1,12 +1,12 @@ /** * @module cdat * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) - * @brief Datatype template for mycpu + * @brief Datatype template and datatype definition for CCPU and CMem * @date 10.05.2009 */ -#ifndef CDATT_H -#define CDATT_H +#ifndef CDAT_H +#define CDAT_H 1 #include #include @@ -14,7 +14,7 @@ /** * @class CDatT * - * Datatype template for mycpu. + * Datatype template for CCPU and CMem. */ template class CDatT @@ -85,6 +85,20 @@ class CDatT return m_value; } + /** + * @method operator T + * @brief convert to T + * @param - + * @return T + * @globalvars none + * @exception none + * @conditions none + */ + operator T() + { + return m_value; + } + /** * @method operator< * @brief implementation of operator < @@ -300,8 +314,11 @@ class CDatT T m_value; }; - -/** define CDat */ +/** + * @class CDat + * + * Datatype for CCPU and CMem + */ typedef CDatT CDat; #endif diff --git a/ue3/mycpu/cdisplay.h b/ue3/mycpu/cdisplay.h new file mode 100644 index 0000000..629ec88 --- /dev/null +++ b/ue3/mycpu/cdisplay.h @@ -0,0 +1,48 @@ +/** + * @module cdisplay + * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) + * @brief TODO + * @date 10.05.2009 + */ + +#ifndef CDISPLAY_H +#define CDISPLAY_H #1 + +/** + * @class CDisplay + * + * TODO + */ +class CDisplay +{ + public: + /** + * @method CDisplay + * @brief Default ctor + * @param - + * @return - + * @globalvars none + * @exception none + * @conditions none + */ + CDisplay() + {}; + + /** + * @method ~CDisplay + * @brief Default dtor + * @param - + * @return - + * @globalvars none + * @exception none + * @conditions none + */ + ~CDisplay(); + + private: + /* members */ +}; + +#endif + +/* vim: set et sw=2 ts=2: */ diff --git a/ue3/mycpu/cinstruction.cpp b/ue3/mycpu/cinstruction.cpp new file mode 100644 index 0000000..32bdd2f --- /dev/null +++ b/ue3/mycpu/cinstruction.cpp @@ -0,0 +1,46 @@ +/** + * @module cinstruction + * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) + * @brief TODO + * @date 10.05.2009 + */ + +#include +#include +#include +#include "cinstruction.h" +#include "ccpu.h" + +using namespace std; + +const unsigned CInstruction::parseRegister(const std::string& str) +{ + unsigned reg; + if (str.length() < 2 || str[0] != 'R') + throw runtime_error("Invalid syntax of register"); + + try + { + reg = boost::lexical_cast(str.substr(1)); + } + catch(boost::bad_lexical_cast& ex) + { + throw runtime_error("Invalid syntax of register"); + } + + return reg; +} + +/*----------------------------------------------------------------------------*/ + +inline void CInstruction::checkRegister(CCPU *cpu, unsigned regidx) +{ + if (regidx >= cpu->getRegisterCount()) + { + stringstream sstr; + sstr << "Register R" << regidx << " doesn't exist (out of bound)"; + throw runtime_error(sstr.str()); + } +} + +/* vim: set et sw=2 ts=2: */ diff --git a/ue3/mycpu/cinstruction.h b/ue3/mycpu/cinstruction.h new file mode 100644 index 0000000..b16c067 --- /dev/null +++ b/ue3/mycpu/cinstruction.h @@ -0,0 +1,98 @@ +/** + * @module cinstruction + * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) + * @brief TODO + * @date 10.05.2009 + */ + +#ifndef CINSTRUCTION_H +#define CINSTRUCTION_H 1 + +#include +#include +//#include "ccpu.h" + +/* declare CCPU */ +class CCPU; + +/** + * @class CInstruction + * + * TODO + */ +class CInstruction +{ + public: + /** + * @method CInstruction + * @brief Default ctor + * @param - + * @return - + * @globalvars none + * @exception none + * @conditions none + */ + CInstruction(std::string name) + : m_name(name) + {}; + + /** + * @method ~CInstruction + * @brief Default dtor + * @param - + * @return - + * @globalvars none + * @exception none + * @conditions none + */ + virtual ~CInstruction() + {}; + + /* TODO */ + virtual bool operator==(std::string& name) + { + return name == m_name; + } + + /* TODO */ + virtual const std::string& getName() + { + return m_name; + } + + /* TODO */ + virtual std::ostream& dump(std::ostream& stream) + { + stream << m_name; + return stream; + } + + /* TODO */ + friend std::ostream& operator<<(std::ostream& stream, CInstruction& instr) + { + return instr.dump(stream); + } + + /* TODO */ + virtual const unsigned parseRegister(const std::string& str); + + /* TODO */ + virtual void checkRegister(CCPU *cpu, unsigned regidx); + + /* TODO */ + virtual CInstruction *factory() = 0; + + /* TODO */ + virtual void compile(std::list& params) = 0; + + /* TODO */ + virtual void execute(CCPU *cpu) = 0; + + protected: + /* members */ + std::string m_name; +}; + +#endif + +/* vim: set et sw=2 ts=2: */ diff --git a/ue3/mycpu/cmem.h b/ue3/mycpu/cmem.h new file mode 100644 index 0000000..5045c34 --- /dev/null +++ b/ue3/mycpu/cmem.h @@ -0,0 +1,109 @@ +/** + * @module cmem + * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) + * @brief Memory template and memory definition for CCPU + * @date 10.05.2009 + */ + +#ifndef CMEM_H +#define CMEM_H 1 + +#include +#include +#include +#include +#include +#ifdef DEBUG +# include +# include +#endif +#include "cdat.h" + +/** + * @class CVectorMem + * + * Extends std::vector template for use as memory for CCPU. + */ +template > +class CVectorMem + : public std::vector +{ + public: + using std::vector::size; + using std::vector::at; + + /** + * @method initialize + * @brief initialize the vector with the content of istream. istream is + * read per line. empty lines will add unitialized elements. + * @param in inputstream to read from + * @return void + * @globalvars none + * @exception std::runtime_error + * @conditions none + */ + void initialize(std::istream& in) + { + if (!in.good()) + return; + + std::string line; + unsigned i = 0; + while (!in.eof() && in.good()) + { + ++i; + std::getline(in, line); + + /* skip last line if it's empty */ + if (line.empty() && in.eof()) + break; + + T value; + try + { + if (!line.empty()) + value = boost::lexical_cast(line); + } + catch(boost::bad_lexical_cast& ex) + { + std::stringstream sstr; + sstr << "Unable to convert input (line " << i << "): " << ex.what(); + throw std::runtime_error(sstr.str()); + } + + push_back(value); + } + } + +#if DEBUG + /** + * @method dump + * @brief dumps contents of vector to outputstream + * @param out outputstream to write to + * @return void + * @globalvars none + * @exception none + * @conditions none + */ + void dump(std::ostream& out) + { + out << "[MEMORY DUMP]" << std::endl; + for(unsigned i = 0; i < size(); ++i) + { + out << "[" << std::setw(4) << std::setfill('0') << i << "] " + << at(i) << std::endl; + } + } +#endif +}; + +/** + * @class CMem + * + * Memory definition for CCPU + */ +typedef CVectorMem CMem; + +#endif + +/* vim: set et sw=2 ts=2: */ diff --git a/ue3/mycpu/cprogram.cpp b/ue3/mycpu/cprogram.cpp new file mode 100644 index 0000000..03d4c30 --- /dev/null +++ b/ue3/mycpu/cprogram.cpp @@ -0,0 +1,126 @@ +/** + * @module cprogram + * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) + * @brief TODO + * @date 12.05.2009 + */ + +#include +#include +#ifdef DEBUG +# include +# include +#endif +#include "cprogram.h" +#include "instructions.h" + +using namespace std; + +CProgram::CProgram() +{ + m_instrset.insert(new CInstructionInc); +} + +/*----------------------------------------------------------------------------*/ + +CProgram::~CProgram() +{ + /* free instruction set */ + set::iterator it; + for (it = m_instrset.begin(); it != m_instrset.end(); ++it) + delete *it; + + /* free instruction */ + for (iterator it = begin(); it != end(); ++it) + delete *it; +} + +/*----------------------------------------------------------------------------*/ + +void CProgram::compile(std::istream& in) +{ + if (!in.good()) + return; + + string line; + unsigned i = 0; + while (!in.eof() && in.good()) + { + ++i; + + /* read stream per line */ + getline(in, line); + if (line.empty()) + continue; + + boost::trim(line); + + /* ignore comments */ + if (line.find_first_of('#') == 0) + continue; + + /* get instruction name */ + size_t pos = line.find_first_of(' '); + string instrname = line.substr(0, pos); + + /* search and create instruction */ + CInstruction *instrptr = NULL; + set::iterator it; + for (it = m_instrset.begin(); it != m_instrset.end(); ++it) + { + if (*(*it) == instrname) + { + instrptr = *it; + break; + } + } + if (instrptr == NULL) + { + stringstream sstr; + sstr << "Unknown instruction '" << instrname << "' on line " << i << "."; + throw runtime_error(sstr.str()); + } + + /* create instruction */ + CInstruction *instr = instrptr->factory(); + + /* parse instruction parameters */ + string params = (pos == string::npos) ? "" : line.substr(pos + 1); + boost::trim(params); + list instrparams; + boost::split(instrparams, params, boost::is_any_of(", "), boost::token_compress_on); + + /* let instruction parse the parameters. catch+throw exception */ + try + { + instr->compile(instrparams); + } + catch(runtime_error& ex) + { + stringstream sstr; + sstr << "Unable to compile instruction '" << instrname + << "' (line " << i << "): " << ex.what(); + throw runtime_error(sstr.str()); + } + + push_back(instr); + } +} + +/*----------------------------------------------------------------------------*/ + +#if DEBUG +void CProgram::dump(std::ostream& out) +{ + out << "[PROGRAM DUMP]" << endl; + unsigned i = 0; + for(iterator it = begin(); it < end(); ++it) + { + out << "[" << std::setw(4) << std::setfill('0') << i << "] " + << *(*it) << endl; + ++i; + } +} +#endif + +/* vim: set et sw=2 ts=2: */ diff --git a/ue3/mycpu/cprogram.h b/ue3/mycpu/cprogram.h new file mode 100644 index 0000000..bf161b8 --- /dev/null +++ b/ue3/mycpu/cprogram.h @@ -0,0 +1,78 @@ +/** + * @module cprogram + * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) + * @brief TODO + * @date 10.05.2009 + */ + +#ifndef CPROGRAM_H +#define CPROGRAM_H 1 + +#include +#include +#include "cinstruction.h" + +/** + * @class CProgram + * + * TODO + */ +class CProgram + : public std::vector +{ + public: + /** + * @method CProgram + * @brief Default ctor + * @param - + * @return - + * @globalvars none + * @exception none + * @conditions none + */ + CProgram(); + + /** + * @method ~CProgram + * @brief Default dtor + * @param - + * @return - + * @globalvars none + * @exception none + * @conditions none + */ + ~CProgram(); + + /** + * @method compile + * @brief create instructions from parsing stream + * @param in inputstream to read from + * @return void + * @globalvars none + * @exception std::runtime_error + * @conditions none + */ + void compile(std::istream& in); + +#if DEBUG + /** + * @method dump + * @brief dumps contents to outputstream + * @param out outputstream to write to + * @return void + * @globalvars none + * @exception none + * @conditions none + */ + void dump(std::ostream& out); +#endif + + private: + /* members */ + /** set of known instructions */ + std::set m_instrset; +}; + +#endif + +/* vim: set et sw=2 ts=2: */ diff --git a/ue3/mycpu/instructions.cpp b/ue3/mycpu/instructions.cpp new file mode 100644 index 0000000..c283e57 --- /dev/null +++ b/ue3/mycpu/instructions.cpp @@ -0,0 +1,27 @@ +/** + * @module instructions + * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) + * @brief TODO + * @date 10.05.2009 + */ + +#include "instructions.h" + +using namespace std; + +void CInstructionInc::compile(std::list& params) +{ + if (params.size() != 1) + throw runtime_error("Invalid paramater count - must be 1"); + m_regidx1 = parseRegister(params.front()); +} + +/*----------------------------------------------------------------------------*/ + +void CInstructionInc::execute(CCPU *cpu) +{ + checkRegister(cpu, m_regidx1); + cpu->getRegisters()[m_regidx1]++; +} + +/* vim: set et sw=2 ts=2: */ diff --git a/ue3/mycpu/instructions.h b/ue3/mycpu/instructions.h new file mode 100644 index 0000000..ebd1533 --- /dev/null +++ b/ue3/mycpu/instructions.h @@ -0,0 +1,66 @@ +/** + * @module instructions + * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) + * @brief TODO + * @date 10.05.2009 + */ + +#ifndef INSTRUCTIONS_H +#define INSTRUCTIONS_H 1 + +#include "cinstruction.h" +#include "ccpu.h" + +/** + * @class CInstructionInc + * + * TODO + */ +class CInstructionInc + : public CInstruction +{ + public: + /** + * @method CInstruction + * @brief Default ctor + * @param - + * @return - + * @globalvars none + * @exception none + * @conditions none + */ + CInstructionInc() + : CInstruction("inc") + {}; + + /** + * @method ~CInstruction + * @brief Default dtor + * @param - + * @return - + * @globalvars none + * @exception none + * @conditions none + */ + ~CInstructionInc() + {}; + + /* TODO */ + CInstructionInc *factory() + { + return new CInstructionInc; + } + + /* TODO */ + void compile(std::list& params); + + /* TODO */ + void execute(CCPU *cpu); + + protected: + unsigned m_regidx1; +}; + +#endif + +/* vim: set et sw=2 ts=2: */ diff --git a/ue3/mycpu/mycpu.cpp b/ue3/mycpu/mycpu.cpp new file mode 100644 index 0000000..af91fe7 --- /dev/null +++ b/ue3/mycpu/mycpu.cpp @@ -0,0 +1,152 @@ +/** + * @module mycpu + * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) + * @brief TODO + * @date 11.05.2009 + * @par Exercise + * 3 + */ + +#include +#include +#include +#include +#include +#include "ccpu.h" +#include "cmem.h" +#include "cprogram.h" + +using namespace std; +namespace po = boost::program_options; + +/** TODO */ +void myterminate() +{ + cerr << "Unexpected termination" << endl; + abort(); +} + +/** + * @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 + * + * TODO + */ +int main(int argc, char* argv[]) +{ + //TODO set_terminate(myterminate); + 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(), "input programfile") + ("memory,m", po::value(), "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 [-m ]" << 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()); + 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(cout); +#endif + } + + /* create program instance */ + CProgram program; + string programfile(vm["compile"].as()); + 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(cout); +#endif + + + /* create cpu and execute the program */ + try + { + CCPU cpu(256); + cpu.setMemory(&memory); + cpu.setProgram(&program); + cpu.run(); +#if DEBUG + cpu.dumpRegisters(cout); +#endif + } + catch(runtime_error& ex) + { + cerr << me << ": Error while executing program:" << endl + << " " << ex.what() << endl; + return 1; + } + + return 0; +} + +/* vim: set et sw=2 ts=2: */ -- cgit v1.2.3