// Stephen Bassoli // CSE 124 Section 01 // Lab 4 #include #include #include #include #include #include "Variables.h" #include "stack.h" int LinesLeft = 0; int NumVars = 0; Variables Vars[20]; int temp = 1; int main() { ofstream outfile("code.txt"); assert(outfile); char name[100]; bool cont = true; void WriteOutfile(ofstream& outfile); void DecVars(ifstream& infile, int i); void Directions(void); void GetAssembly(char* equation); bool CheckDec(char* variable); int GetDec(char* variable); Directions(); WriteOutfile(outfile); outfile.close(); ifstream infile("code.txt"); assert(infile); for (int i = 0 ; i < NumVars ; i++ ) { DecVars(infile,i); } while (cont) { infile.getline(name, 100); if (name[0] == '}') cont = false; else GetAssembly(name); } return 0; } // Input: Outfile with code from user // Precond: None // Process: Counts variables, lines of code, and removes semicolons // Output: Modified outfile with semicolons removed // Postcond: None void WriteOutfile(ofstream& outfile) { char input[100]; bool go = true; int Length; while (go) { cin.getline(input, 100); Length = strlen(input); if (!(Length == 1)) { if ((input[Length-1] != ';')&&(LinesLeft>0)) { cerr << "STATEMENT MUST END WITH SEMICOLIN\n"; exit(1); } else { input[Length-1] = '\0'; } } if ((LinesLeft == 0)&&(input[0] != '{')) { cerr << "PROGRAM MUST START WITH OPEN CURLY BRACES\n"; exit(1); } else if ((LinesLeft == 0)&&(input[0] == '{')) input[0] = '\0'; outfile << input << endl; LinesLeft++; if ((input[0] == 'i')&&(input[1] == 'n')&&(input[2] == 't')&&(input[3] == ' ')) NumVars++; if ((input[0] == '}')&&((input[1] == '\0')||(input[1] == ' '))) { LinesLeft--; cout << endl << "Lines of Code: " << LinesLeft-1 << endl; cout << "Number of Variables: " << NumVars << endl << endl; go = false; } } } // Input: The infile, and table number of the variable // Precond: None // Process: Declares the variables // Output: None // Postcond: None void DecVars(ifstream& infile, int i) { static bool getuseless = false; char input[100]; if (getuseless == false) { infile.getline(input,100); getuseless = true; } infile.getline(input,100); if ((input[0] == 'i')&&(input[1] == 'n')&&(input[2] == 't')&&(input[3] == ' ')) { Vars[i].Declare(input + 4); } } // Input: None // Precond: None // Process: None // Output: Displays the instructions of using the program // Postcond: None void Directions(void) { cout << "To use this simple compiler follow these procedures...\n"; cout << "1) Begin and end the code with open and close curly braces\n"; cout << "2) Initialize all variables at the beginning of the code\n"; cout << "3) Seperate all operators, operands, variables, or cout statements with a space\n"; cout << "4) The Increment and Decrement operators are not seperated by a space, ie ++i\n" << endl; cout << "Enter Code:\n"; } // Input: Variable name // Precond: None // Process: Checks to see if the variable has been declared // Output: Returns true if variable has been declared // Postcond: None bool CheckDec(char* variable) { char temp[100]; for (int i = 0 ; i < NumVars ; i++) { strcpy(temp, Vars[i].ReturnIdent()); if (strcmp(variable,temp) == 0) return true; } return false; } // Input: Variable name // Precond: None // Process: Searches for the table number of the variable // Output: Returns with table number of variable // Postcond: None int GetDec(char* variable) { char temp[100]; for (int i = 0 ; i < NumVars ; i++) { strcpy(temp, Vars[i].ReturnIdent()); if (strcmp(variable,temp) == 0) return i; } return 0; } // Input: Equation string to be converted to assembly language // Precond: Equation must be in postfix notation // Process: Converts the postfix equation to assembly language // Output: Displays the pseudo assembly language // Postcond: None void GetAssembly(char* equation) { char Token[100][100]; int index = 0; int val; void Compute(ofstream& outfile); Operator Op; ofstream out("BaseEquation.txt"); assert(out); ofstream out2("equation.txt"); assert(out2); ofstream out3("FinalEquation.txt"); assert(out3); out << equation; out.close(); ifstream in("BaseEquation.txt"); assert(in); if ((equation[0] == '+')&&(equation[1] == '+')) { if (CheckDec(equation+2)) { val = GetDec(equation+2); if (Vars[val].CheckInit()) { cout << "INC(" << Vars[val].ReturnIdent() << ",$TEMP" << temp << ")" << endl; temp++; return; } else { cerr << "UNINITIALIZED VARIABLE\n"; exit(1); } } } else if ((equation[0] == '-')&&(equation[1] == '-')) { if (CheckDec(equation+2)) { val = GetDec(equation+2); if (Vars[val].CheckInit()) { cout << "DEC(" << Vars[val].ReturnIdent() << ",$TEMP" << temp << ")" << endl; temp++; return; } else { cerr << "UNINITIALIZED VARIABLE\n"; exit(1); } } else { cout << "UNDECLARED IDENTIFIER\n"; exit(1); } } else if ((equation[0] == 'c')&&(equation[1] == 'o')&&(equation[2] == 'u')&&(equation[3] == 't')&&(equation[4] == ' ')&&(equation[5] == '<')&&(equation[6] == '<')&&(equation[7] == ' ')) { if (CheckDec(equation+8)) { val = GetDec(equation+8); if (Vars[val].CheckInit()) { cout << "PRN(cout," << Vars[val].ReturnIdent() << ")" << endl; return; } else { cerr << "UNINITIALIZED VARIABLE\n"; exit(1); } } else { cout << "UNDECLARED IDENTIFIER\n"; exit(1); } } else { while (in >> (Token[index])) { index++; } if (CheckDec(Token[0])) { val = GetDec(Token[0]); if (Token[1][0] == '=') Vars[val].Initialize(); else { cerr << "INCORRECT SYNTAX FOR ASSINGMENT OPERATOR\n"; exit(1); } for (int j = 2 ; j < index ; j++) { if (isalpha(Token[j][0])) { if (!CheckDec(Token[j])) { cerr << "UNDECLARED IDENTIFIER\n"; exit(1); } } out2 << Token[j]; out2 << ' '; } if ( index > 3 ) { out3 << Token[0] << ' ' << Token[1] << ' '; out3 << Op.Convert(out2); Compute(out3); return; } else { out3 << Token[0] << ' ' << Token[1] << ' ' << Token[2]; Compute(out3); return; } } else { cerr << "UNDECLARED IDENTIFIER\n"; exit(1); } } return; } // Input: Outfile with postfix equation // Precond: Is not an INC, DEC, or PRN statement // Process: Processes each operator // Output: Generates assembly code for each operator // Postcond: None void Compute(ofstream& outfile) { outfile.close(); ifstream infile("FinalEquation.txt"); assert(infile); Operator Ops; char* GetTemp(); int index = 0; bool run = false; char Op1[20],Op2[20],Op3[20]; char Token[100][100]; while (infile >> (Token[index])) { index++; } for ( int i = 2 ; i < index ; i++) { if (Token[i][0] == '+') { strcpy(Op2,Ops.Pop()); strcpy(Op1,Ops.Pop()); strcpy(Op3,GetTemp()); if (Op2[0] == '$' && Op1[0] == '$') { cout << "ADD(" << "$TEMP" << temp-2 << "," << Op2 << "," << Op3 << ")\n"; } else cout << "ADD(" << Op1 << "," << Op2 << "," << Op3 << ")\n"; Ops.Push(Op3); temp++; run = true; } else if (Token[i][0] == '-') { strcpy(Op2,Ops.Pop()); strcpy(Op1,Ops.Pop()); strcpy(Op3,GetTemp()); if (Op2[0] == '$' && Op1[0] == '$') { cout << "SUB(" << "$TEMP" << temp-2 << "," << Op2 << "," << Op3 << ")\n"; } else cout << "SUB(" << Op1 << "," << Op2 << "," << Op3 << ")\n"; Ops.Push(Op3); temp++; run = true; } else if (Token[i][0] == '*') { strcpy(Op2,Ops.Pop()); strcpy(Op1,Ops.Pop()); strcpy(Op3,GetTemp()); if (Op2[0] == '$' && Op1[0] == '$') { cout << "MUL(" << "$TEMP" << temp-2 << "," << Op2 << "," << Op3 << ")\n"; } else cout << "MUL(" << Op1 << "," << Op2 << "," << Op3 << ")\n"; Ops.Push(Op3); temp++; run = true; } else if (Token[i][0] == '/') { strcpy(Op2,Ops.Pop()); strcpy(Op1,Ops.Pop()); strcpy(Op3,GetTemp()); if (Op2[0] == '$' && Op1[0] == '$') { cout << "DIV(" << "$TEMP" << temp-2 << "," << Op2 << "," << Op3 << ")\n"; } else cout << "DIV(" << Op1 << "," << Op2 << "," << Op3 << ")\n"; Ops.Push(Op3); temp++; run = true; } else if (Token[i][0] == '%') { strcpy(Op2,Ops.Pop()); strcpy(Op1,Ops.Pop()); strcpy(Op3,GetTemp()); if (Op2[0] == '$' && Op1[0] == '$') { cout << "MOD(" << "$TEMP" << temp-2 << "," << Op2 << "," << Op3 << ")\n"; } else cout << "MOD(" << Op1 << "," << Op2 << "," << Op3 << ")\n"; Ops.Push(Op3); temp++; run = true; } else if (isalnum(Token[i][0])) { Ops.Push(Token[i]); } } if (run) cout << "ASG(" << Token[0] << "," << Op3 << ")" << endl; else cout << "ASG(" << Token[0] << "," << Token[2] << ")" << endl; } // Input: None // Precond: None // Process: Creates a temp variable character string // Output: Returns the temp variable string // Postcond: None char* GetTemp() { int raw = temp + 48; char Temp[10] = "$TEMP"; // I know there is a warning here, it is intentional char String[10]; if ( raw > 57 ) { itoa(temp,String,10); strcat(Temp,String); return Temp; } else { Temp[5] = char(raw); Temp[6] = '\0'; return Temp; } }