#include <iostream>
#include <string>
#include <fstream>
#include <math.h>
#include <time.h>
#include <stdio.h>
void get_file();
void break_apart(); //Withe GetWord, breaks a command into words
bool GetWord(char* theString, char* word, int& wordOffset);
void do_on(); //Interprets the on command
void do_show(); //Interprets the show command
void do_sleep(); //Interprets the sleep command
void do_comment(); //Interprets the note command
void do_off(); //Interprets the off command
void do_loop(); //Interprets the do command
void do_blink(); //Interprets the blink command
void decide(); //Makes a decision based on first word of command
void interpret(string); //Prepares a line of code for interpretation
string make_upper_case(string); //Makes an uppercase of a string
int to_int(string); //Converts the string to an integer
void do_rotate(); //Interprets the rotate command
void do_random(); //Interprets the random command
void do_all_off(); //Interprets the all off command
void do_all_on(); //Interprets the all on command
char random_letter(); //Draws a random letter
using namespace std; //We are using std::
ifstream filein; //Declare a file stream
char place[50]; //A character variable used to hold the file path
string coms[20]; //String array which stores up to 20 words in a command
string do_commands[20]; //An array for storing the commands from a do loop
int num_words,num_times;//The number of words and the number of times to execute a loop
int light_total=0; //The total of all activated lights
const int bufferSize=255; //Used to break the word apart
char buffer[bufferSize+1]; //Used to break the word apart
char word[bufferSize+1]; //Used to break the word apart
int main()
{
srand(time(NULL)); //Sets a random number seed based on the time of program execution
string command; //The inputted command
get_file(); //Open the file that the user specifies in execution folder
while (getline(filein,command)) //Without an error or end of file, input the line
{
cout << command.substr(0,6) << endl; //Interpret the command
}
filein.close(); //Close the file
return 0; //Terminate the program
}
void get_file()
{
cout << "What is the file name (no quotes)? "; //Prompt the user
cin >> place; //Input the file name
filein.open(place); //Open the file
if (filein.fail()) //If there is an error
{
cout << "You have entered an invalid file name.\n"; //Prompt the user
filein.clear(); //Prepare the file stream for re-use
get_file(); //Have the function invoke itself again
}
}
void break_apart()
{
int wordOffset=0; //Used for counting
string command; //The command
num_words=0; //Holds the number of words in the command
while (GetWord(buffer,word,wordOffset)) //For each word in the command
{
num_words++; //Increase the counter
coms[num_words]=word; //Move the word into an array
}
decide(); //Act upon the first word and branch off
}
bool GetWord (char* theString, char* word, int& wordOffset)
{
if (!theString[wordOffset]) //End of string?
return false;
char *p1, *p2;
p1=p2=theString+wordOffset; //Point to the next word
for (int i=0;i<(int)strlen(p1)&&!isalnum(p1[0]);i++) //Eat leading spaces
p1++;
if (!isalnum(p1[0])) //See if it is a word
return false;
p2=p1; //Point P1 to start of next word
while (isalnum(p2[0])) //Move P2 to end of word
p2++;
int len=int(p2-p1); //Length of word is difference between P1 and P2
strncpy(word,p1,len); //Copy the word into the buffer
word[len]='\0'; //Null terminate the buffer
for (int j= int(p2-theString);j<(int)strlen(theString) && !isalnum(p2[0]);j++)
p2++; //Find beginning of the next word
wordOffset=int(p2-theString);
return true;
}
void do_show()
{
int i; //Used for counting
cout << "PRINT ""; //Initial BASIC line
for (i=2;i<=num_words-1;i++) //Print each word from second until end
{
cout << coms[i] << " "; //Print the word and a space
}
cout << coms[num_words] << """ << endl; //Print a quote
}
void do_on()
{
int i,j; //Used for counting
light_total=0;
for (i=2;i<=num_words;i++) //Read each light number
{
j=coms[i][0]-48; //Convert the string to an integer
j--;
light_total+=pow(2,j); //Add the square of the light number to the light total
}
cout << "OUT(888), " << light_total; //Output the BASIC line of code
cout << endl; //Print an endline
}
void do_off()
{
int i,j; //Used for counting
for (i=2;i<=num_words;i++) //Read each light number
{
j=coms[i][0]-48; //Convert the string to an integer
light_total-=pow(2,j-1); //Subtract the square of the light number from the light total
}
cout << "OUT(888), " << light_total; //Output the BASIC line of code
cout << endl; //Print an endline
}
void do_comment()
{
int i; //Used for counting
cout << "'"; //Initial BASIC formatting
for (i=2;i<=num_words;i++) //For each word of the comment
{
cout << coms[i] << " "; //Print the word and a space
}
cout << endl; //Print an endline
}
void do_sleep()
{
int j; //Used for counting
j=coms[2][0]-48; //Convert the string to an integer
cout << "SLEEP (" << j << ")\n"; //Format the BASIC line
}
void decide() //Based on first word of line, move to appropriate function
{
if (coms[1]=="SHOW")
{
do_show();
}
if (coms[1]=="ON")
{
do_on();
}
if (coms[1]=="SLEEP")
{
do_sleep();
}
if (coms[1]=="NOTE")
{
do_comment();
}
if (coms[1]=="OFF")
{
do_off();
}
if (coms[1]=="DO")
{
do_loop();
}
if (coms[1]=="BLINK")
{
do_blink();
}
if (coms[1]=="ROTATE")
{
do_rotate();
}
if (coms[1]=="RANDOM")
{
do_random();
}
if (coms[1]=="ALL")
{
if (coms[2]=="OFF")
{
do_all_off();
}
if (coms[2]=="ON")
{
do_all_on();
}
}
coms[1]="foo";
}
string make_upper_case (string word)
{
int len,asc,i; //Used for counting
len=word.length(); //Find the length of the command
for (i=0;i<=len;i++) //For each letter of the command
{
asc=(int)word[i]; //Take the ASCII value
if (asc>=97&&asc<=122) //If upper-case (between 97 and 122)
asc-=32; //Subtract 32 from the ASCII
word[i]=(char)asc; //Typecast the ASCII as a character
}
return word; //Return the upper-cased word
}
void do_loop()
{
string foo; //A line within the do loop
char loop_var;
loop_var=random_letter();
int num_commands=0,k; //Used for counting
num_times=to_int(coms[2]); //How many times do I execute?
cout << "\nFOR " << loop_var << "=1 TO " << num_times << " STEP 1\n"; //Initial BASIC line
getline(filein,foo); //Input the "{," since we know it will be there
while(1) //Until we hit the "}"
{
getline(filein,foo); //Input the line of code
if (foo=="}")
{
break; //End of the do loop
}
else if (foo!="}")
{
foo=make_upper_case(foo); //Upper-case the command
num_commands++; //If not, increase the number of commands
do_commands[num_commands]=foo; //Add the command to the array
}
}
for (k=1;k<=num_commands;k++) //For each command
{
interpret(do_commands[k]); //Interpret each command in the array
}
cout << "NEXT " << loop_var << "\n\n"; //Conclude the do loop
}
void do_blink()
{
int i; //Used for counting
light_total=0;
for (i=2;i<=20;i++) //For each word in the command
{
if (coms[i]=="FOR") //If we have reached the end of the series of lights
break;
else
light_total+=pow(2,to_int(coms[i])-1); //Increase the light total
}
cout << "\n\nFOR Y=1 TO " << coms[i+1] << " STEP 1\n";;
cout << "OUT(888), " << light_total; //Output the BASIC line of code
cout << "\nFOR WAIT=1 TO 10000 STEP 1";
cout << " 'THE PAUSE BETWEEN BLINKS\nNEXT WAIT\n"; //The pause between blinks
cout << "OUT(888), 0\n";
cout << "NEXT Y\n\n";
}
void interpret(string command)
{
int i,len; //Used for counting
command=make_upper_case(command); //Upper-case the command
len=command.length(); //Find the length of the command
for (i=0;i<=len;i++) //For every letter of the command
{
buffer[i]=command[i]; //Move the letter to the buffer
}
break_apart(); //Break the command up into words
}
int to_int(string com)
{
int num=0,ipos=com.length(),ilength=com.length()-1; //Used for the conversion process
while (ipos!=0) //As long as we are not past the ones placeholder
{
ipos--; //Subtract the placeholder
num+=((com[ipos]-48)*pow(10,ilength-ipos)); //Multiply the number by a power of 10
}
return num; //Return the number
}
void do_rotate()
{
int pos=2,lights[20],i=0;
while (coms[pos]!="") //Loads the light numbers into the array
{
i++;
lights[i]=to_int(coms[pos]); //Convert the string to an integer
pos++;
}
cout << "'THE FOLLOWING IS A ROTATION ROUTINE\n";
for (int x=1;x<=i;x++) //For each light, output the 888 and a one-second pause
{
cout << "OUT (888), " << pow(2,lights[x]-1) << endl;
cout << "SLEEP (1)\n";
}
cout << "'END OF ROTATION ROUTINE\n";
}
void do_random()
{
int x;
x=1+rand()%8; //Pick a random number from 1 to 8
cout << "OUT (888), " << pow(2,(x-1)) << endl; //Ouput the BASIC code
cout << "SLEEP (1)\n";
}
void do_all_on()
{
int total=0;
for (int light=1;light<=8;light++) //For each light
{
total+=pow(2,light-1); //Add the binary of the light to the total
}
cout << "OUT (888), " << total << endl; //Output the 888 of the total
}
void do_all_off()
{
cout << "OUT (888), 0\n"; //A pretty stupid function to turn off all the lights
}
char random_letter()
{
int x; //A placeholding integer
char letter; //The character to be returned
x=65+rand()%26; //Pick a random number from 65 to 90
letter=(char)x; //Convert the number to an ASCII character, store in letter
return letter; //Return the letter
}