blob: f6fc3cbc8c41f165fe6d15158184617c0592b356 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
/**
* @module cprogram
* @author Guenther Neuwirth (0626638), Manuel Mausz (0728348)
* @brief TODO
* @date 12.05.2009
*/
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/split.hpp>
#ifdef DEBUG
# include <iostream>
# include <iomanip>
#endif
#include "cprogram.h"
#include "instructions.h"
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);
}
/*----------------------------------------------------------------------------*/
CProgram::~CProgram()
{
/* free instruction set */
set<CInstruction *>::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);
boost::to_lower(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<CInstruction *>::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<string> 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: */
|