#include <cstdlib>
#include <iostream>
#include <fstream>
#include <list>
#include <map>
#include "main.h"
#include <bt/parser.h> using namespace std;
list<VAR *> var_list; list<LINE *> lines; int main()
{
srand(time(NULL));
get_input(); if ( !parse_input() ) {
cout << "\n\nFatal error, exiting...\n\n";
return EXIT_FAILURE;
}
execute();
cleanup();
return EXIT_SUCCESS;
}
void get_input()
{
LINE *line;
bool blank;
ifstream fin;
string fname;
cout << "\n\nSpecified file?\n> ";
cin >> fname;
fin.open(fname.c_str());
while ( fin ) {
blank = true; line = NULL;
line = new LINE;
getline(fin,line->data);
for ( int i = 0; i < line->data.length(); i++ )
if ( !isspace(line->data[i]) ) {
line->data = line->data + ' '; lines.push_back(line);
blank = false;
break;
}
if ( blank == true )
delete line;
}
fin.close();
}
void cleanup()
{
LINE *ln = NULL;
VAR * v = NULL;
while( lines.size() > 0 )
{
ln = lines.front();
lines.pop_front();
delete ln; }
while( var_list.size() > 0 )
{
v = var_list.front();
var_list.pop_front();
delete v; }
}
void execute( void )
{
list<LINE *>::const_iterator iter;
LINE *ln = NULL;
bool at_begin = false;
cout << "\n\n\nExecuting script...\n\n\n";
for ( iter = lines.begin(); iter != lines.end(); iter++ )
{
if ( at_begin ) {
iter = lines.begin();
at_begin = false;
}
ln = (*iter);
if ( ln )
{
if ( ln->command == "stop" || ln->command == "STOP" )
return;
else if ( ln->command == "goto" || ln->command == "GOTO" )
{
list<LINE *>::const_iterator a;
for ( a = lines.begin(); a != lines.end(); a++ )
if ( (*a)->line_num == ln->operand )
break;
iter = a;
if ( iter == lines.begin() )
at_begin = true;
else
iter--;
}
else if ( ln->command == "set" || ln->command == "SET" )
{
parse_expression(ln->operand); }
else if ( ln->command == "if" || ln->command == "IF" )
{
if ( parse_expression(ln->operand) != 0 ) { list<LINE *>::const_iterator a;
for ( a = lines.begin(); a != lines.end(); a++ )
if ( (*a)->line_num == ln->operand2 )
break;
iter = a;
if ( iter == lines.begin() )
at_begin = true;
else
iter--;
}
}
else if ( ln->command == "read" || ln->command == "READ" )
{
string var, s = ln->operand + ','; int x, j = ln->operand.length();
for ( x = 0; x <= j; x++ )
{
if ( s[x] == ',' ) {
VAR *v = find_variable(var);
int i = 0;
if ( v == NULL )
v = create_variable( var, 0 ); cin >> i;
v->value = i;
var = "";
cout << endl;
}
else
var += s[x];
}
cout << endl;
}
else if ( ln->command == "write" || ln->command == "WRITE" )
{
string s, var_name;
int x;
bool in_constant = false;
bool in_variable = false;
bool print_variable = false;
if ( ln->operand[0] != '"' && !isspace(ln->operand[0]) )
in_variable = true;
for ( x = 0; x < ln->operand.length(); x++ )
{
if ( print_variable ) {
bool found = false;
list<VAR *>::iterator a;
for ( a = var_list.begin(); a != var_list.end(); a++ )
{
if ( (*a)->name == var_name )
{
found = true;
break;
}
} if ( found == true )
s += num_to_string((*a)->value);
else
{
#ifdef PRINT_DEBUG
cout << "*** ERROR (Line #" << ln->ref << ") *** Could not find variable (" <<
var_name << ")!\n\n";
#endif
}
print_variable = false;
var_name = "";
}
if ( ln->operand[x] == '"' )
{
if ( in_constant == false )
in_constant = true;
else
in_constant = false;
}
else if ( ln->operand[x] == ',' )
{
if ( in_variable ) {
in_variable = false;
print_variable = true;
}
else if ( !in_constant && (ln->operand[x+1] != '"')
&& !isspace(ln->operand[x])) {
if ( print_variable == false )
in_variable = true;
}
}
else {
if ( in_constant )
s += ln->operand[x];
else if ( in_variable )
{
if ( isspace(ln->operand[x]) ) {
in_variable = false;
print_variable = true;
if ( x+1 >= ln->operand.length() ) x--; }
else
var_name += ln->operand[x];
}
#ifdef PRINT_DEBUG
else if ( !isspace(ln->operand[x]) ) cout << "\n\n\n*** ERROR *** Unsure what do do with character (" << ln->operand[x] <<
") on line #" << ln->ref << " \n\n\n";
#endif
}
}
cout << s << endl;
} #ifdef PRINT_DEBUG
else
{
cout << "\n\n\n*** ERROR *** Bad command (" << ln->command << ")! Exiting\n\n";
return;
}
#endif
}
#ifdef PRINT_DEBUG
else
{
cout << "\n\n*** ERROR *** NULL line! Exiting...\n\n";
return;
}
#endif
} }
bool parse_input( void )
{
list<LINE *>::iterator iter;
int x;
int num_lines = 0;
bool in_string_constant = false;
string data;
string line_num;
string command;
string operand;
string operand2 = "None";
for ( iter = lines.begin(); iter != lines.end(); iter++ )
{
data = line_num = command = operand = "";
x = 0;
if ( (*iter) && (*iter)->data.size() > 0 )
data = (*iter)->data;
else
return false;
num_lines++; if ( !isspace(data[0]) && isdigit(data[0])) for ( x = 0; x < data.length(); x++ )
{
if ( isspace(data[x]) ) {
line_num = data.substr(0,x); break;
}
}
else
line_num = "None";
while( isspace(data[x]) )
x++;
for ( int y = x; x < data.length(); x++ )
{
if ( isspace(data[x]) ) {
command = data.substr(y,x-y); break;
}
}
if ( command.length() <= 0 )
{
#ifdef PRINT_DEBUG
cout << "\n\n*** ERROR (Line #" << num_lines << ") *** No command found!\n\n";
cout << "\n\nCommand = " << command << ". Line_num = " << line_num << ".\n\n";
cout << "x = " << x << ". Data.length() = " << data.length() << ".\n\n";
#endif
return false;
}
while( isspace(data[x]) )
x++;
for ( int k = x; x < data.length(); x++ )
{
if ( data[x] == '"' )
{
if ( in_string_constant == true )
in_string_constant = false;
else
in_string_constant = true;
continue;
}
if ( isspace(data[x]) && !in_string_constant) {
operand = data.substr(k,x-k); break;
}
}
if ( command == "if" || command == "IF" ) {
while( isspace(data[x]) )
x++;
for ( int k = x; x < data.length(); x++ )
{
if ( isspace(data[x]) ) {
operand2 = data.substr(k,x-k); break;
}
}
}
if ( (command == "write" || command == "WRITE") ) operand += ' '; if ( (operand.length() <= 0) &&
( (command != "STOP") && (command != "stop") ) ) { #ifdef PRINT_DEBUG
cout << "\n\n*** ERROR (Line #" << num_lines << ") *** No operand found!\n\n";
cout << "\n\nCommand = " << command << ". Line_num = " << line_num << ".\n\n";
cout << "x = " << x << ". Data.length() = " << data.length() << ".\n\n";
#endif
return false;
}
if ( operand2 == "None" && (command == "if" || command == "IF" ) )
{
#ifdef PRINT_DEBUG
cout << "\n\n*** ERROR (Line #" << num_lines << ") *** No operand2 for an IF!\n\n";
cout << "\n\nCommand = " << command << ". Line_num = " << line_num << ".\n\n";
cout << "x = " << x << ". Data.length() = " << data.length() << ".\n\n";
#endif
return false;
}
(*iter)->operand = operand;
(*iter)->operand2 = operand2;
(*iter)->command = command;
(*iter)->line_num = line_num;
(*iter)->ref = num_lines;
}
return true; }
string num_to_string( int i )
{
string s = "";
char buf[16];
s = "";
buf[0] = '\0';
sprintf( buf, "%d", i );
s = buf;
return s;
}
VAR *find_variable( string name )
{
list<VAR *>::iterator iter;
VAR *v = NULL;
for ( iter = var_list.begin(); iter != var_list.end(); iter++ )
{
v = (*iter);
if ( v->name == name )
return v;
}
return NULL; }
VAR *create_variable( string name, int value )
{
VAR *v = NULL;
if ( (v = find_variable(name)) != NULL )
{
v->value = value;
return v;
}
else
v = new VAR;
v->name = (name[0] != '\0') ? name : "";
v->value = value;
var_list.push_back(v);
return v;
}
int parse_expression( string z )
{
list<VAR *>::iterator iter;
map<std::string, double>::iterator m_iter;
int y = 0;
string s;
VAR *v = NULL;
Parser p(z);
for ( iter = var_list.begin(); iter != var_list.end(); iter++ )
p[(*iter)->name] = (*iter)->value;
y = (int)p.Evaluate();
for ( m_iter = p.symbols_.begin(); m_iter != p.symbols_.end(); m_iter++ )
{
v = NULL;
s = "";
s = m_iter->first;
if ( s == "e" || s == "pi" )
continue;
if ( (v = find_variable(s)) == NULL )
v = create_variable(s, (int)m_iter->second ); else
v->value = (int)m_iter->second; }
#ifdef PRINT_COMP_DEBUG
for ( iter = var_list.begin(); iter != var_list.end(); iter++ )
cout << "\nVariable! Name = " << (*iter)->name << " , Value = " << (*iter)->value;
#endif
return y;
}