1 //----------------------------------------------------------------------------
\r
3 // Interpreter for ntermediate code
\r
4 // $Date: 2003/02/20 00:24:16 $
\r
6 //----------------------------------------------------------------------------
\r
15 #include "QCompilerCntl.h"
\r
16 #include "QCalcUnit.h"
\r
18 typedef unsigned int Appoptions;
\r
19 typedef std::vector<QCalcUnit *> QCalcUnits;
\r
21 const char * const app_name = "qcrun";
\r
22 const char * const app_version = "1.0";
\r
24 const Appoptions opt_version = 1;
\r
25 const Appoptions opt_help = 1 << 1;
\r
26 const Appoptions opt_verbose = 1 << 2;
\r
27 const Appoptions opt_output = 1 << 3;
\r
28 const Appoptions opt_input = 1 << 4;
\r
30 //----------------------------------------------------------------------------
\r
31 // Function prototypes
\r
32 //----------------------------------------------------------------------------
\r
33 inline bool isSet(const Appoptions &o1, const Appoptions &o2) {
\r
34 return (o2 == (o1 & o2));
\r
37 Appoptions checkOption(const char * inOptions);
\r
38 void compile(QCompilerCntl * const , QCalcUnits * const);
\r
39 void forceQuit(void);
\r
40 void printUsage(void);
\r
41 void printVersion(void);
\r
42 void errorAndQuit(const char * const inMessage);
\r
43 std::string getBaseFilename(const std::string &inString);
\r
45 //----------------------------------------------------------------------------
\r
49 int main(int argc, char **argv) {
\r
50 Appoptions parameters_ready = 0;
\r
51 QBits *qBits = NULL;
\r
52 QCompilerCntl *qCCntl = NULL;
\r
53 QCalcUnits *qCalcUnits = NULL;
\r
55 std::string tfilename = "";
\r
56 std::string ofilename = "";
\r
57 std::string ifilename = "";
\r
58 std::vector<std::string> args;
\r
66 for (int i = 0; i < argc; i++) {
\r
67 std::string tmpstr = argv[i];
\r
68 args.push_back(tmpstr);
\r
71 int vec_size = args.size();
\r
74 while (arg_at < vec_size) {
\r
75 if ('-' == args[arg_at][0] && args[arg_at].length() > 1) {
\r
76 Appoptions tmpoptions = checkOption(args[arg_at].c_str());
\r
79 if (isSet(tmpoptions, opt_help)) {
\r
80 if (isSet(parameters_ready, opt_help)) {
\r
81 errorAndQuit("-h option can be used only once.");
\r
83 parameters_ready |= opt_help;
\r
87 //_____ VERBOSE _____
\r
88 if (isSet(tmpoptions, opt_verbose)) {
\r
89 if (isSet(parameters_ready, opt_verbose)) {
\r
90 errorAndQuit("-v option can be used only once.");
\r
92 parameters_ready |= opt_verbose;
\r
96 //_____ VERSION _____
\r
97 if (isSet(tmpoptions, opt_version)) {
\r
98 if (isSet(parameters_ready, opt_version)) {
\r
99 errorAndQuit("-V option can be used only once.");
\r
101 parameters_ready |= opt_version;
\r
105 //_____ OUTPUT _____
\r
106 if (isSet(tmpoptions, opt_output)) {
\r
107 if (isSet(parameters_ready, opt_output)) {
\r
108 errorAndQuit("-o option can be used only once.");
\r
111 if (arg_at < vec_size - 1) {
\r
112 ofilename = args[++arg_at];
\r
113 parameters_ready |= opt_output;
\r
115 errorAndQuit("too few parameters.");
\r
122 if (isSet(parameters_ready, opt_input)) {
\r
123 errorAndQuit("too many input file.");
\r
125 ifilename = args[arg_at];
\r
126 parameters_ready |= opt_input;
\r
131 //_____ VERSION _____
\r
132 if (isSet(parameters_ready, opt_version)) printVersion();
\r
134 //_____ HELP ________
\r
135 if (isSet(parameters_ready, opt_help)) printUsage();
\r
137 //_____ OUTPUT ______
\r
138 if (isSet(parameters_ready, opt_input)) {
\r
139 if (false == isSet(parameters_ready, opt_output)) {
\r
140 ofilename = getBaseFilename(ifilename)+".qdt";
\r
141 tfilename = getBaseFilename(ifilename)+".txt";
\r
144 std::cerr << "Reading " << ifilename << std::endl;
\r
145 std::ifstream ifs(ifilename.c_str(), std::ios::in);
\r
147 std::cerr << "Cannot open the input file.\n";
\r
151 if (isSet(parameters_ready, opt_verbose)) {
\r
152 std::cerr << "Input file: " << ifilename << "\n"
\r
153 << "Output file: " << ofilename << "\n";
\r
157 qCCntl = new QCompilerCntl(ifs);
\r
158 qCalcUnits = new QCalcUnits(0);
\r
159 } catch (const std::bad_alloc ex) {
\r
160 std::cerr << "Failed in memory allocation.\n";
\r
164 compile(qCCntl, qCalcUnits);
\r
167 qBits = new QBits(qCCntl->GetNumberOfQBits());
\r
168 } catch (const std::bad_alloc &ex) {
\r
169 std::cerr << "Failed in memory allocation.\n"
\r
170 << "This .mcd code needs at least "
\r
171 << (1 << (qCCntl->GetNumberOfQBits() + 1 + 3))
\r
172 << " bytes to allocate the qubits.\n";
\r
176 for (unsigned int i = 0; i < qCalcUnits->size(); i++) {
\r
177 if (isSet(parameters_ready, opt_verbose)) {
\r
178 std::cerr << std::setw(15) << std::left
\r
179 << (*qCalcUnits)[i]->GetName()
\r
182 (*qCalcUnits)[i]->Calc(qBits);
\r
183 if (isSet(parameters_ready, opt_verbose)) {
\r
184 std::cerr << "OK\n";
\r
188 //TODO: *.qdt file cannot be imported by QCAD.
\r
189 std::cerr << "Saving " << ofilename << std::endl;
\r
190 qBits->SaveToFile(ofilename.c_str());
\r
191 std::cerr << "Saving " << tfilename << std::endl;
\r
192 qBits->SaveAsText(tfilename.c_str());
\r
196 for (unsigned int i = 0; i < qCalcUnits->size(); i++) {
\r
197 delete (*qCalcUnits)[i];
\r
202 std::cerr << "done." << std::endl;
\r
208 //----------------------------------------------------------------------------
\r
212 Appoptions checkOption(const char * inOptions) {
\r
213 Appoptions retVal = 0;
\r
215 while ('\0' != *inOptions) {
\r
216 switch (*inOptions) {
\r
218 retVal |= opt_help;
\r
221 retVal |= opt_output;
\r
224 retVal |= opt_verbose;
\r
227 retVal |= opt_version;
\r
230 errorAndQuit("there are some invalid options.");
\r
238 //----------------------------------------------------------------------------
\r
242 void compile(QCompilerCntl * const ioCompiler, QCalcUnits * const ioUnits) {
\r
243 QCalcUnit *cu = NULL;
\r
246 if (true == ioCompiler->Compile()) {
\r
247 unsigned int cntl_size = ioCompiler->GetNumberOfControl();
\r
248 for (unsigned int i = 0; i < cntl_size; i++) {
\r
249 cu = ioCompiler->AllocateControl(i);
\r
250 if (NULL != cu) ioUnits->push_back(cu);
\r
253 errorAndQuit("Parse error occurred.\n");
\r
257 //----------------------------------------------------------------------------
\r
261 void forceQuit(void) {
\r
262 std::cerr << "Quit forced.\n";
\r
266 //----------------------------------------------------------------------------
\r
270 void printUsage(void) {
\r
271 std::cout << "Usage: " << app_name
\r
272 << " [-hvV] [-o output_file] input_file.mcd\n\n"
\r
273 << " -h show this help\n"
\r
274 << " -v verbose mode\n"
\r
275 << " -V show version\n\n"
\r
279 //----------------------------------------------------------------------------
\r
283 void printVersion(void) {
\r
284 std::cout << "\nCopyright (C) 2002-2003 QCAD project\n"
\r
285 << app_name << " version " << app_version << "\n\n"
\r
289 //----------------------------------------------------------------------------
\r
291 * Show message and quit
\r
293 void errorAndQuit(const char * const inMessage) {
\r
294 std::cerr << "Error: " << inMessage << "\n\n";
\r
299 //----------------------------------------------------------------------------
\r
301 * get basename of filename
\r
303 std::string getBaseFilename(const std::string &inString) {
\r
304 std::string retString = "";
\r
306 unsigned int posdot = inString.rfind(".", inString.length() - 1);
\r
308 if (posdot == std::string::npos) {
\r
309 retString = inString;
\r
311 retString.assign(inString, 0, posdot);
\r
315 //----------------------------------------------------------------------------
\r