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/cprogram.cpp | 126 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 ue3/mycpu/cprogram.cpp (limited to 'ue3/mycpu/cprogram.cpp') 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: */ -- cgit v1.2.3 From 89e202f49b9857dcd3627fbc4e0262125d729bbc Mon Sep 17 00:00:00 2001 From: manuel Date: Wed, 13 May 2009 04:09:39 +0200 Subject: adding all instructions and displays --- ue3/mycpu/cprogram.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'ue3/mycpu/cprogram.cpp') diff --git a/ue3/mycpu/cprogram.cpp b/ue3/mycpu/cprogram.cpp index 03d4c30..f6fc3cb 100644 --- a/ue3/mycpu/cprogram.cpp +++ b/ue3/mycpu/cprogram.cpp @@ -19,6 +19,19 @@ using namespace std; CProgram::CProgram() { m_instrset.insert(new CInstructionInc); + m_instrset.insert(new CInstructionDec); + m_instrset.insert(new CInstructionAdd); + m_instrset.insert(new CInstructionSub); + m_instrset.insert(new CInstructionMul); + m_instrset.insert(new CInstructionDiv); + m_instrset.insert(new CInstructionLoad); + m_instrset.insert(new CInstructionStore); + m_instrset.insert(new CInstructionTest); + m_instrset.insert(new CInstructionLabel); + m_instrset.insert(new CInstructionJumpA); + m_instrset.insert(new CInstructionJumpZ); + m_instrset.insert(new CInstructionJumpS); + m_instrset.insert(new CInstructionWrite); } /*----------------------------------------------------------------------------*/ @@ -54,6 +67,7 @@ void CProgram::compile(std::istream& in) continue; boost::trim(line); + boost::to_lower(line); /* ignore comments */ if (line.find_first_of('#') == 0) -- cgit v1.2.3 From 431bbac5a99abbccf33500e22aa353ec792eff94 Mon Sep 17 00:00:00 2001 From: manuel Date: Wed, 13 May 2009 15:29:51 +0200 Subject: * adding -Wno-long-long to all Makefiles * adding execute operator to cinstruction * added labels map for better performance --- ue3/mycpu/cprogram.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'ue3/mycpu/cprogram.cpp') diff --git a/ue3/mycpu/cprogram.cpp b/ue3/mycpu/cprogram.cpp index f6fc3cb..f904bce 100644 --- a/ue3/mycpu/cprogram.cpp +++ b/ue3/mycpu/cprogram.cpp @@ -107,6 +107,16 @@ void CProgram::compile(std::istream& in) /* let instruction parse the parameters. catch+throw exception */ try { + /* handle label instruction ourself, but still add a dummy instruction */ + if (instrname == "label") + { + if (instrparams.size() != 1) + throw runtime_error("Invalid paramater count - must be 1"); + string label = instrparams.front(); + if (label.length() < 2 || label[ label.length() - 1] != ':') + throw runtime_error("Label has invalid syntax"); + m_labels[ label.substr(0, label.length() - 1) ] = size(); + } instr->compile(instrparams); } catch(runtime_error& ex) @@ -123,6 +133,17 @@ void CProgram::compile(std::istream& in) /*----------------------------------------------------------------------------*/ +unsigned CProgram::findLabel(const std::string& label) const +{ + map::const_iterator it; + it = m_labels.find(label); + if (it == m_labels.end()) + throw runtime_error("Unknown label '" + label + "'"); + return it->second; +} + +/*----------------------------------------------------------------------------*/ + #if DEBUG void CProgram::dump(std::ostream& out) { -- cgit v1.2.3 From 3c6f886d5a8bfd36c796b963d6e3178ad9577742 Mon Sep 17 00:00:00 2001 From: manuel Date: Wed, 13 May 2009 16:55:17 +0200 Subject: * added documentation (no more TODOs) * added testsuite + testcase * used copyctor instead of assign operator more often --- ue3/mycpu/cprogram.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'ue3/mycpu/cprogram.cpp') diff --git a/ue3/mycpu/cprogram.cpp b/ue3/mycpu/cprogram.cpp index f904bce..1a450f5 100644 --- a/ue3/mycpu/cprogram.cpp +++ b/ue3/mycpu/cprogram.cpp @@ -1,7 +1,7 @@ /** * @module cprogram * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) - * @brief TODO + * @brief CProgram extends std::vector and adds a method for parsing programfile * @date 12.05.2009 */ @@ -75,7 +75,7 @@ void CProgram::compile(std::istream& in) /* get instruction name */ size_t pos = line.find_first_of(' '); - string instrname = line.substr(0, pos); + string instrname(line.substr(0, pos)); /* search and create instruction */ CInstruction *instrptr = NULL; @@ -112,7 +112,7 @@ void CProgram::compile(std::istream& in) { if (instrparams.size() != 1) throw runtime_error("Invalid paramater count - must be 1"); - string label = instrparams.front(); + string label(instrparams.front()); if (label.length() < 2 || label[ label.length() - 1] != ':') throw runtime_error("Label has invalid syntax"); m_labels[ label.substr(0, label.length() - 1) ] = size(); -- cgit v1.2.3 From 9e7c204525a50f36ba7aa7563f1a9702d0bb6f44 Mon Sep 17 00:00:00 2001 From: manuel Date: Wed, 13 May 2009 17:11:40 +0200 Subject: adding tab as whitespace --- ue3/mycpu/cprogram.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ue3/mycpu/cprogram.cpp') diff --git a/ue3/mycpu/cprogram.cpp b/ue3/mycpu/cprogram.cpp index 1a450f5..3fcf734 100644 --- a/ue3/mycpu/cprogram.cpp +++ b/ue3/mycpu/cprogram.cpp @@ -102,7 +102,7 @@ void CProgram::compile(std::istream& in) 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); + boost::split(instrparams, params, boost::is_any_of(", \t"), boost::token_compress_on); /* let instruction parse the parameters. catch+throw exception */ try -- cgit v1.2.3