// Statement.cpp Dave Reed 3/1/05 /////////////////////////////////////////////////////////////////////////////////// #include #include #include #include "Token.h" #include "Tokenizer.h" #include "VarTable.h" #include "Statement.h" using namespace std; void Expression::Read(Tokenizer & program) // Assumes: program is the input stream for the program // Results: reads and stores the expression in the expr vector { expr = program.GetToken(); if (expr.GetType() != INTEGER && expr.GetType() != IDENTIFIER) { cout << "SYNTAX ERROR: malformed expression" << endl; exit(0); } } int Expression::Evaluate(VarTable & variables) const // Assumes: variables is a table of variable names and values // Returns: the value of the expression { if (expr.GetType() == INTEGER) { return atoi(expr.GetValue().c_str()); } else { return variables.Lookup(expr.GetValue()); } } void Expression::Display() const // Results: displays the expression, with a space between token values { cout << expr.GetValue(); } ////////////////////////////////////////////////////// Statement * Statement::GetNext(Tokenizer & program) { Token next = program.PeekAhead(); if (next.GetType() == UNKNOWN) { return NULL; } Statement * stmt; if (next.GetValue() == "output") { stmt = new OutputStatement(); } else if (next.GetValue() == "if") { stmt = new IfStatement(); } else if (next.GetType() == IDENTIFIER) { stmt = new AssignStatement(); } else { cout << "ERROR: unrecognized statement" << endl; exit(1); } stmt->Read(program); return stmt; } ////////////////////////////////////////////////////// void OutputStatement::Read(Tokenizer & program) // Assumes: program is the input stream for the program // Results: reads and stores the parts of the output statement { Token output = program.GetToken(); outValue.Read(program); } void OutputStatement::Execute(VarTable & variables) const // Assumes: variables is a table of variable names and values // Results: executes the output statement (displays the value of the rhs) { cout << outValue.Evaluate(variables) << endl; } STATEMENT_TYPE OutputStatement::GetType() const // Assumes: variables is a table of variable names and values // Results: executes the output statement (displays the value of the rhs) { return OUTPUT; } void OutputStatement::Display() const // Results: displays the output statement, with a space between token values { cout << "output "; outValue.Display(); cout << endl; } //////////////////////////////////////////////////////// void AssignStatement::Read(Tokenizer & program) // Assumes: program is the input stream for the program // Results: reads and stores the parts of the assignment statement { Token vbl = program.GetToken(); Token op = program.GetToken(); if (vbl.GetType() == IDENTIFIER && op.GetValue() == "=" && (program.PeekAhead().GetType() == INTEGER || program.PeekAhead().GetType() == IDENTIFIER)) { lhs = vbl.GetValue(); rhs.Read(program); } else { cout << "SYNTAX ERROR: malformed assignment" << endl; exit(0); } } void AssignStatement::Execute(VarTable & variables) const // Assumes: variables is a table of variable names and values // Results: executes the assignment statement (assigns lhs = rhs) { variables.Update(lhs, rhs.Evaluate(variables)); } STATEMENT_TYPE AssignStatement::GetType() const // Assumes: variables is a table of variable names and values // Results: executes the output statement (displays the value of the rhs) { return ASSIGN; } void AssignStatement::Display() const // Results: displays the assignment statement, with a space between token values { cout << lhs << " = "; rhs.Display(); cout << endl; } //////////////////////////////////////////////////////// void IfStatement::Read(Tokenizer & program) // Assumes: program is the input stream for the program // Results: reads and stores the parts of the assignment statement { Token start = program.GetToken(); test.Read(program); while (program.PeekAhead().GetValue() != "end") { stmts.push_back(GetNext(program)); } program.GetToken(); } void IfStatement::Execute(VarTable & variables) const // Assumes: variables is a table of variable names and values // Results: executes the assignment statement (assigns lhs = rhs) { if (test.Evaluate(variables) != 0) { for (int i = 0; i < stmts.size(); i++) { stmts[i]->Execute(variables); } } } STATEMENT_TYPE IfStatement::GetType() const // Assumes: variables is a table of variable names and values // Results: executes the output statement (displays the value of the rhs) { return IF; } void IfStatement::Display() const // Results: displays the assignment statement, with a space between token values { cout << "if "; test.Display(); cout << endl; for (int i = 0; i < stmts.size(); i++) { cout << " "; stmts[i]->Display(); } cout << "end" << endl; }