int IdentifierExp::eval(EvalState & state) { if (!state.isDefined(name)) { cout << "VARIABLE NOT DEFINED" << endl; error(""); } return state.getValue(name); }
bool ExprTree:: Evaluate( Value& val, ExprTree*& sig ) const { EvalState state; state.SetScopes( parentScope ); return( Evaluate( state, val, sig ) ); }
bool ExprTree:: Flatten( Value& val, ExprTree *&tree ) const { EvalState state; state.SetScopes( parentScope ); return( Flatten( state, val, tree ) ); }
void runProgram(Program & program, EvalState & state) { int lineNumber = program.getFirstLineNumber(); while (lineNumber != -1) { Statement * stmt = program.getParsedStatement(lineNumber); state.setCurrentLine(program.getNextLineNumber(lineNumber)); stmt->execute(state); lineNumber = state.getCurrentLine(); } }
int classad_get_string_list_attribute (classad_context cad, const char *attribute_name, char ***result) { if (cad == NULL) return C_CLASSAD_INVALID_CONTEXT; int n_results = 0; (*result) = (char **)malloc(sizeof(char **)); if ((*result) == NULL) return C_CLASSAD_OUT_OF_MEMORY; (*result)[0] = NULL; ClassAd *ad = (ClassAd *)cad; Value vl; ad->EvaluateAttr(attribute_name, vl); const ExprList *et_result; if (vl.IsListValue(et_result)) { std::vector<ExprTree*> ads; et_result->GetComponents(ads); // Get string values. for(std::vector<ExprTree*>::const_iterator it = ads.begin(); it != ads.end(); ++it) { if ((*it)->GetKind() == ExprTree::LITERAL_NODE) { Value v; EvalState state; state.SetScopes( ad ); (*it)->Evaluate(state,v); std::string res_str; if (v.IsStringValue( res_str )) { // add string value to result, which is a NULL-terminated // string array. n_results++; (*result) = (char **)realloc(*result, (n_results+1)*sizeof(char *)); if ((*result) == NULL) return C_CLASSAD_OUT_OF_MEMORY; (*result)[n_results-1] = strdup(res_str.c_str()); (*result)[n_results] = NULL; } } } return C_CLASSAD_NO_ERROR; } // The result list needs to be freed on success only. classad_free_string_list(*result); (*result) = NULL; return C_CLASSAD_VALUE_NOT_FOUND; }
bool ExprTree:: Evaluate( Value& val ) const { EvalState state; if (parentScope == NULL) { val.SetErrorValue(); return false; } else { state.SetScopes( parentScope ); return( Evaluate( state, val ) ); } }
void IfStmt::execute(EvalState & state) { if(op == "=") { if (lhsExp->eval(state) == rhsExp->eval(state)) { state.setCurrentLine(lineNumber); } } else if (op == ">") { if(lhsExp->eval(state) > rhsExp->eval(state)) state.setCurrentLine(lineNumber); } else { if(lhsExp->eval(state) < rhsExp->eval(state)) state.setCurrentLine(lineNumber); } }
void processLine(string line, Program & program, EvalState & state) { TokenScanner scanner; scanner.ignoreWhitespace(); scanner.scanNumbers(); scanner.setInput(line); string str=scanner.nextToken(); if (scanner.getTokenType(str)==NUMBER) { int lineNumber=stringToInteger(str); string token=scanner.nextToken(); scanner.saveToken(token); if (token!="") { program.addSourceLine(lineNumber, line); program.setParsedStatement(lineNumber, parseStatement(scanner)); } else { program.removeSourceLine(lineNumber); } } else if (str=="LIST") { for (int i=program.getFirstLineNumber(); i!=-1; i=program.getNextLineNumber(i)) { cout << program.getSourceLine(i)<<endl; } } else if (str=="CLEAR") { program.clear(); } else if(str=="QUIT") exit(0); else if (str=="HELP") cout<<"This is a minimal BASIC interpreter."<<endl; else if (str=="RUN") { int currentLine=program.getFirstLineNumber(); state.setCurrentLine(currentLine); while (currentLine!=-1) { program.getParsedStatement(currentLine)->execute(state); if(currentLine!=state.getCurrentLine()) { currentLine=state.getCurrentLine(); } else { currentLine=program.getNextLineNumber(currentLine); state.setCurrentLine(currentLine); } } } }
void IfStmt::execute(EvalState &state) { if (op == "=") { if (lhs->eval(state) == rhs->eval(state)) state.setCurrentLine(nextLine); } else if (op == ">") { if (lhs->eval(state) > rhs->eval(state)) state.setCurrentLine(nextLine); } else if (op == "<") { if (lhs->eval(state) < rhs->eval(state)) state.setCurrentLine(nextLine); } }
int CompoundExp::eval(EvalState & state) { if (op == "=") { if (lhs->getType() != IDENTIFIER) { error("Illegal variable in assignment"); } int val = rhs->eval(state); state.setValue(((IdentifierExp *) lhs)->getName(), val); return val; } int left = lhs->eval(state); int right = rhs->eval(state); if (op == "+") return left + right; if (op == "-") return left - right; if (op == "*") return left * right; if (op == "/") { if (right == 0) { cout << "DIVIDE BY ZERO" << endl; error(""); } else { return left / right; } } return 0; }
/* * Function: processLine * Usage: processLine(line, program, state); * ----------------------------------------- * Processes a single line entered by the user. In this version, * the implementation does exactly what the interpreter program * does in Chapter 19: read a line, parse it as an expression, * and then print the result. In your implementation, you will * need to replace this method with one that can respond correctly * when the user enters a program line (which begins with a number) * or one of the BASIC commands, such as LIST or RUN. */ void processLine(string line, Program & program, EvalState & state) { TokenScanner scanner; scanner.ignoreWhitespace(); scanner.scanNumbers(); scanner.setInput(line); string token=scanner.nextToken(); TokenType type=scanner.getTokenType(token); int lineNumb; int priorLineNumb; if(type==NUMBER){ if(scanner.hasMoreTokens()){ program.addSourceLine(stringToInteger(token),line); Statement *stmt=parseStatement(scanner); program.setParsedStatement(stringToInteger(token),stmt); //link statement to line number } else program.removeSourceLine(stringToInteger(token)); } if(type==WORD){ if(token=="LIST"){ lineNumb=program.getFirstLineNumber(); while(lineNumb!=-1){ cout<<program.getSourceLine(lineNumb)<<endl; lineNumb=program.getNextLineNumber(lineNumb); } } else if(token=="RUN"){ state.setCurrentLine(program.getFirstLineNumber()); lineNumb=state.getCurrentLine(); while(lineNumb!=-1){ if(program.hasLineNumber(lineNumb)==false) error("Invalid line reference at program line "+integerToString(priorLineNumb)); Statement *stmt=program.getParsedStatement(lineNumb); state.setCurrentLine(program.getNextLineNumber(lineNumb)); stmt->execute(state); priorLineNumb=lineNumb; lineNumb=state.getCurrentLine(); } } else if(token=="CLEAR"){ program.clear(); } else if(token=="HELP"){ cout<<"Minimal Basic Statements"<<endl; cout<<"REM This statement used for comments"<<endl; cout<<"LET This statement is BASIC's assigment statement"<<endl; cout<<"PRINT In minimal BASIC, the PRINT statement has the form: "<<endl; cout<<" PRINT exp"<<endl; cout<<" where exp is an expression."<<endl; cout<<"INPUT In the minimal version of the BASIC interpreter, the INPUT statement has the form:"<<endl; cout<<" INPUT var"<<endl; cout<<" where var is a variable read in from the user"<<endl; cout<<"GOTO This statement has the syntax"<<endl; cout<<" GOTO n"<<endl; cout<<" which forces the program to continue from line n instead of continuing with the next statement"<<endl; cout<<"IF This statement provides conditional control. The syntax for this statement is: "<<endl; cout<<" IF exp1 op exp2 THEN n"<<endl; cout<<" where exp1 and exp2 are expressions and op is one of the conditional operators =, <, or >."<<endl; cout<<"END This statment marks the end of the program."<<endl; cout<<"Commands to control the BASIC interpreter"<<endl; cout<<"RUN This command starts program execution beginning at the lowest-numbered line. "<<endl; cout<<"LIST This command lists the steps in the program in numerical sequence."<<endl; cout<<"CLEAR This command deletes the program so the user can start entering a new one."<<endl; cout<<"HELP This command provides a simple help message describing the interpreter."<<endl; cout<<"QUIT Typing QUIT exits from the BASIC interpreter by calling exit(0)."<<endl; } else if(token=="QUIT"){ exit(0); } else cout<<"Invalid command"<<endl; } }
void GotoStmt::execute(EvalState & state) { state.setCurrentLine(line); }
void InputStmt::execute(EvalState & state) { int value = getInteger("? "); state.setValue(identifier, value); }
int AttributeReference:: FindExpr(EvalState &state, ExprTree *&tree, ExprTree *&sig, bool wantSig) const { const ClassAd *current=NULL; const ExprList *adList = NULL; Value val; bool rval; sig = NULL; // establish starting point for search if( expr == NULL ) { // "attr" and ".attr" current = absolute ? state.rootAd : state.curAd; if( absolute && ( current == NULL ) ) { // NAC - circularity so no root return EVAL_FAIL; // NAC } // NAC } else { // "expr.attr" rval=wantSig?expr->Evaluate(state,val,sig):expr->Evaluate(state,val); if( !rval ) { return( EVAL_FAIL ); } if( val.IsUndefinedValue( ) ) { return( EVAL_UNDEF ); } else if( val.IsErrorValue( ) ) { return( EVAL_ERROR ); } if( !val.IsClassAdValue( current ) && !val.IsListValue( adList ) ) { return( EVAL_ERROR ); } } if( val.IsListValue( ) ) { vector< ExprTree *> eVector; const ExprTree *currExpr; // iterate through exprList and apply attribute reference // to each exprTree for(ExprListIterator itr(adList);!itr.IsAfterLast( );itr.NextExpr( )){ currExpr = itr.CurrentExpr( ); if( currExpr == NULL ) { return( EVAL_FAIL ); } else { AttributeReference *attrRef = NULL; attrRef = MakeAttributeReference( currExpr->Copy( ), attributeStr, false ); val.Clear( ); // Create new EvalState, within this scope, because // attrRef is only temporary, so we do not want to // cache the evaluated result in the outer state object. EvalState tstate; tstate.SetScopes(state.curAd); rval = wantSig ? attrRef->Evaluate( tstate, val, sig ) : attrRef->Evaluate( tstate, val ); delete attrRef; if( !rval ) { return( EVAL_FAIL ); } ClassAd *evaledAd = NULL; const ExprList *evaledList = NULL; if( val.IsClassAdValue( evaledAd ) ) { eVector.push_back( evaledAd ); continue; } else if( val.IsListValue( evaledList ) ) { eVector.push_back( evaledList->Copy( ) ); continue; } else { eVector.push_back( Literal::MakeLiteral( val ) ); } } } tree = ExprList::MakeExprList( eVector ); ClassAd *newRoot = new ClassAd( ); ((ExprList*)tree)->SetParentScope( newRoot ); return EVAL_OK; } // lookup with scope; this may side-affect state /* ClassAd::alternateScope is intended for transitioning Condor from * old to new ClassAds. It allows unscoped attribute references * in expressions that can't be found in the local scope to be * looked for in an alternate scope. In Condor, the alternate * scope is the Target ad in matchmaking. * Expect alternateScope to be removed from a future release. */ if (!current) { return EVAL_UNDEF; } int rc = current->LookupInScope( attributeStr, tree, state ); if ( !expr && !absolute && rc == EVAL_UNDEF && current->alternateScope ) { rc = current->alternateScope->LookupInScope( attributeStr, tree, state ); } return rc; }
int IdentifierExp::eval(EvalState & state) { if (!state.isDefined(name)) error("VARIABLE NOT DEFINED"); return state.getValue(name); }
void LetStmt::execute(EvalState &state) { int value = exp->eval(state); state.setValue(identifier, value); }
void EndStmt::execute(EvalState & state) { state.setCurrentLine(-1); }
int unwind_attributes(classad_context cad, char *attribute_name, char ***results) { if (cad == NULL) return C_CLASSAD_INVALID_CONTEXT; if ((results == NULL) || (attribute_name == NULL)) return C_CLASSAD_INVALID_ARG; ClassAd *ad = (ClassAd *)cad; ExprTree *et; bool need_to_delete_et = false; et = ad->Lookup(attribute_name); if (et == NULL) { return C_CLASSAD_VALUE_NOT_FOUND; } if (et->GetKind() == ExprTree::LITERAL_NODE) { // The attribute was probably stringified. Try to parse it. Value v; EvalState state; state.SetScopes( ad ); et->Evaluate(state,v); std::string strres; if (v.IsStringValue( strres )) { ClassAdParser parser; et=NULL; parser.ParseExpression(strres,et); need_to_delete_et = true; } } BinaryOpUnwind res_unp; std::string result; res_unp.Unparse(result, et); int n_results; if (*results == NULL) { n_results = 0; (*results) = (char **)malloc(sizeof(char **)); if ((*results) == NULL) return C_CLASSAD_OUT_OF_MEMORY; (*results)[0] = NULL; } else { for (n_results = 0; (*results)[n_results] != NULL; n_results++) /*NOP*/ ; } std::vector<std::string>::const_iterator it; for (it = res_unp.m_unwind_output.begin(); it != res_unp.m_unwind_output.end(); ++it) { n_results++; char **new_results; new_results = (char **)realloc(*results, (n_results+1)*sizeof(char *)); if (new_results == NULL) { if (need_to_delete_et) delete et; return C_CLASSAD_OUT_OF_MEMORY; } (*results) = new_results; (*results)[n_results] = NULL; (*results)[n_results-1] = strdup(it->c_str()); if (((*results)[n_results-1]) == NULL) { if (need_to_delete_et) delete et; return C_CLASSAD_OUT_OF_MEMORY; } } if (need_to_delete_et) delete et; return C_CLASSAD_NO_ERROR; }
void LetStmt::execute(EvalState & state) { state.setValue(identifier, exp->eval(state)); }
int IdentifierExp::eval(EvalState & state) { if (!state.isDefined(name)) error(name + " is undefined"); return state.getValue(name); }