double Evaluator::eval(FunctionCall &e) { string name = String::toUpper(e.getName()); double arg1 = e.getArg1()->eval(*this); if (e.getArg2().isNull()) { if (name == "ABS") return fabs(arg1); if (name == "ACOS") return acos(arg1) * 180.0 / M_PI; if (name == "ASIN") return asin(arg1) * 180.0 / M_PI; if (name == "COS") return cos(arg1 * M_PI / 180.0); if (name == "EXP") return exp(arg1); if (name == "FIX") return floor(arg1); if (name == "FUP") return ceil(arg1); if (name == "ROUND") return Math::round(arg1); if (name == "LN") return log(arg1); if (name == "SIN") return sin(arg1 * M_PI / 180.0); if (name == "SQRT") return sqrt(arg1); if (name == "TAN") return tan(arg1 * M_PI / 180.0); } else { double arg2 = e.getArg2()->eval(*this); if (name == "ATAN") return atan2(arg1, arg2) * 180.0 / M_PI; } THROWS(e.getLocation() << " Unsupported function '" << name << "'"); }
unsigned int __stdcall slThreadProc(void* lpParameter) { // Copy FunctionCall call = *((FunctionCall*)lpParameter); // Signal that we copied the function call SetEvent(call.confirmation); // Call function call.func(call.args); return S_OK; }
double Evaluator::eval(FunctionCall &e) { string name = String::toUpper(e.getName()); if (name == "EXISTS") { if (!e.getArg1().isInstance<NamedReference>()) return false; return hasReference(e.getArg1().cast<NamedReference>()->getName()); } double arg1 = e.getArg1()->eval(*this); if (e.getArg2().isNull()) { if (name == "ABS") return fabs(arg1); if (name == "ACOS") return acos(arg1) * 180.0 / M_PI; if (name == "ASIN") return asin(arg1) * 180.0 / M_PI; if (name == "COS") return cos(arg1 * M_PI / 180.0); if (name == "EXP") return exp(arg1); if (name == "FIX") return floor(arg1); if (name == "FUP") return ceil(arg1); if (name == "ROUND") return Math::round(arg1); if (name == "LN") return log(arg1); if (name == "SIN") return sin(arg1 * M_PI / 180.0); if (name == "SQRT") return sqrt(arg1); if (name == "TAN") return tan(arg1 * M_PI / 180.0); } else { // NOTE, ATAN is treated as a special case in Parser::functionCall() double arg2 = e.getArg2()->eval(*this); if (name == "ATAN") return atan2(arg1, arg2) * 180.0 / M_PI; } THROW(e.getLocation() << " Unsupported function '" << name << "'"); }
void Expression::handleFunctionCalls(OperationCode *opcode, Parser *parser) { for (list<ExpressionTerm*>::iterator it=postfix.begin(); it!=postfix.end(); it++) { FunctionCall *fcall = (*it)->func; if (fcall) { fcall->provideIntermediates(opcode, parser); if (postfix.size() > 1) { uint id = setVariable(parser, ""); allocateVariable(opcode, id); opcode->addInterop(new ByteOperation(OP_POPMOV)); opcode->addInterop(new DwordOperation(&id)); expressionVars[*it] = id; } } } }
bool RVMockIntervalReplacer::try_replace(Expression** it){ if ((*it) -> etype == ET_FunctionCall ){ FunctionCall* fc = (FunctionCall*) *it; string name = ((Variable*) fc->function)->name->name; if (name.compare(currFuncName) != 0 && name.compare(framacIntervalFunction) != 0) return true; Symbol* symbolFuncName = new Symbol(); symbolFuncName -> name = framacIntervalFunction; Expression* framaName = new Variable(symbolFuncName, (*it)->location); IntConstant* top = new IntConstant(functionToInterval[currFuncName].top, false, (*it)->location); IntConstant* bottom = new IntConstant(functionToInterval[currFuncName].bottom, false, (*it)->location); FunctionCall* framaCall = new FunctionCall(framaName, (*it)->location); framaCall->addArg(bottom); framaCall->addArg(top); *it = framaCall; } return true; }
bool Why3Translator::visit(FunctionCall const& _node) { if (_node.annotation().isTypeConversion || _node.annotation().isStructConstructorCall) { error(_node, "Only ordinary function calls supported."); return true; } FunctionType const& function = dynamic_cast<FunctionType const&>(*_node.expression().annotation().type); switch (function.location()) { case FunctionType::Location::AddMod: case FunctionType::Location::MulMod: { //@todo require that third parameter is not zero add("(of_int (mod (Int.("); add(function.location() == FunctionType::Location::AddMod ? "+" : "*"); add(") (to_int "); _node.arguments().at(0)->accept(*this); add(") (to_int "); _node.arguments().at(1)->accept(*this); add(")) (to_int "); _node.arguments().at(2)->accept(*this); add(")))"); return false; } case FunctionType::Location::Internal: { if (!_node.names().empty()) { error(_node, "Function calls with named arguments not supported."); return true; } //@TODO check type conversions add("("); _node.expression().accept(*this); add(" state"); for (auto const& arg: _node.arguments()) { add(" "); arg->accept(*this); } add(")"); return false; } case FunctionType::Location::Bare: { if (!_node.arguments().empty()) { error(_node, "Function calls with named arguments not supported."); return true; } add("("); indent(); add("let amount = 0 in "); _node.expression().accept(*this); addLine("if amount <= this.balance then"); indent(); addLine("let balance_precall = this.balance in"); addLine("begin"); indent(); addLine("this.balance <- this.balance - amount;"); addLine("if not (external_call this) then begin this.balance = balance_precall; false end else true"); unindent(); addLine("end"); unindent(); addLine("else false"); unindent(); add(")"); return false; } case FunctionType::Location::SetValue: { add("let amount = "); solAssert(_node.arguments().size() == 2, ""); _node.arguments()[0]->accept(*this); add(" in "); return false; } default: error(_node, "Only internal function calls supported."); return true; } }
nsresult txExprParser::createExpr(txExprLexer& lexer, txIParseContext* aContext, Expr** aResult) { *aResult = nullptr; nsresult rv = NS_OK; bool done = false; nsAutoPtr<Expr> expr; txStack exprs; txStack ops; while (!done) { uint16_t negations = 0; while (lexer.peek()->mType == Token::SUBTRACTION_OP) { negations++; lexer.nextToken(); } rv = createUnionExpr(lexer, aContext, getter_Transfers(expr)); if (NS_FAILED(rv)) { break; } if (negations > 0) { if (negations % 2 == 0) { FunctionCall* fcExpr = new txCoreFunctionCall(txCoreFunctionCall::NUMBER); rv = fcExpr->addParam(expr); if (NS_FAILED(rv)) return rv; expr.forget(); expr = fcExpr; } else { expr = new UnaryExpr(expr.forget()); } } short tokPrecedence = precedence(lexer.peek()); if (tokPrecedence != 0) { Token* tok = lexer.nextToken(); while (!exprs.isEmpty() && tokPrecedence <= precedence(static_cast<Token*>(ops.peek()))) { // can't use expr as argument due to order of evaluation nsAutoPtr<Expr> left(static_cast<Expr*>(exprs.pop())); nsAutoPtr<Expr> right(expr); rv = createBinaryExpr(left, right, static_cast<Token*>(ops.pop()), getter_Transfers(expr)); if (NS_FAILED(rv)) { done = true; break; } } exprs.push(expr.forget()); ops.push(tok); } else { done = true; } } while (NS_SUCCEEDED(rv) && !exprs.isEmpty()) { nsAutoPtr<Expr> left(static_cast<Expr*>(exprs.pop())); nsAutoPtr<Expr> right(expr); rv = createBinaryExpr(left, right, static_cast<Token*>(ops.pop()), getter_Transfers(expr)); } // clean up on error while (!exprs.isEmpty()) { delete static_cast<Expr*>(exprs.pop()); } NS_ENSURE_SUCCESS(rv, rv); *aResult = expr.forget(); return NS_OK; }
/** * Creates an Attribute Value Template using the given value * This should move to XSLProcessor class */ nsresult txExprParser::createAVT(const nsSubstring& aAttrValue, txIParseContext* aContext, Expr** aResult) { *aResult = nullptr; nsresult rv = NS_OK; nsAutoPtr<Expr> expr; FunctionCall* concat = nullptr; nsAutoString literalString; bool inExpr = false; nsSubstring::const_char_iterator iter, start, end, avtStart; aAttrValue.BeginReading(iter); aAttrValue.EndReading(end); avtStart = iter; while (iter != end) { // Every iteration through this loop parses either a literal section // or an expression start = iter; nsAutoPtr<Expr> newExpr; if (!inExpr) { // Parse literal section literalString.Truncate(); while (iter != end) { PRUnichar q = *iter; if (q == '{' || q == '}') { // Store what we've found so far and set a new |start| to // skip the (first) brace literalString.Append(Substring(start, iter)); start = ++iter; // Unless another brace follows we've found the start of // an expression (in case of '{') or an unbalanced brace // (in case of '}') if (iter == end || *iter != q) { if (q == '}') { aContext->SetErrorOffset(iter - avtStart); return NS_ERROR_XPATH_UNBALANCED_CURLY_BRACE; } inExpr = true; break; } // We found a second brace, let that be part of the next // literal section being parsed and continue looping } ++iter; } if (start == iter && literalString.IsEmpty()) { // Restart the loop since we didn't create an expression continue; } newExpr = new txLiteralExpr(literalString + Substring(start, iter)); } else { // Parse expressions, iter is already past the initial '{' when // we get here. while (iter != end) { if (*iter == '}') { rv = createExprInternal(Substring(start, iter), start - avtStart, aContext, getter_Transfers(newExpr)); NS_ENSURE_SUCCESS(rv, rv); inExpr = false; ++iter; // skip closing '}' break; } else if (*iter == '\'' || *iter == '"') { PRUnichar q = *iter; while (++iter != end && *iter != q) {} /* do nothing */ if (iter == end) { break; } } ++iter; } if (inExpr) { aContext->SetErrorOffset(start - avtStart); return NS_ERROR_XPATH_UNBALANCED_CURLY_BRACE; } } // Add expression, create a concat() call if necessary if (!expr) { expr = newExpr; } else { if (!concat) { concat = new txCoreFunctionCall(txCoreFunctionCall::CONCAT); NS_ENSURE_TRUE(concat, NS_ERROR_OUT_OF_MEMORY); rv = concat->addParam(expr.forget()); expr = concat; NS_ENSURE_SUCCESS(rv, rv); } rv = concat->addParam(newExpr.forget()); NS_ENSURE_SUCCESS(rv, rv); } } if (inExpr) { aContext->SetErrorOffset(iter - avtStart); return NS_ERROR_XPATH_UNBALANCED_CURLY_BRACE; } if (!expr) { expr = new txLiteralExpr(EmptyString()); } *aResult = expr.forget(); return NS_OK; }
void Expression::buildPostfix(Tokens *tokens, Parser *parser) { Stack<Token*> stack; int paranthCnt = 0; const Token *next = tokens->checkNext(); while (tokens->isMore() && next->aType != Token::SEMICOLON && next->aType != Token::COMMA) { if (next->aType == Token::VARIABLE_INT || next->aType == Token::VARIABLE_FLOAT) { postfix.push_back(new ExpressionTerm(tokens->popNext())); } else if (next->aType == Token::VARIABLE_FUNCTION) { Token *token = tokens->popNext(); // Function call if (tokens->checkNext()->aType == Token::PARANTH_BEG) { FunctionCall *func = new FunctionCall(token); func->parseFragment(tokens, parser); postfix.push_back(new ExpressionTerm(func)); } else { postfix.push_back(new ExpressionTerm(token)); } } else if (next->aType & Token::OPERATOR) { Token *token = tokens->popNext(); while (stack.Size() && stack.peek()->aType != Token::PARANTH_BEG) { if (operatorPrecedence(stack.peek()) > operatorPrecedence(token)) { postfix.push_back(new ExpressionTerm(stack.pop())); } else { break; } } stack.push(token); } else if (next->aType == Token::PARANTH_BEG) { paranthCnt++; stack.push(tokens->popNext()); } else if (next->aType == Token::PARANTH_END) { paranthCnt--; if (paranthCnt < 0) break; while (stack.Size() && stack.peek()->aType != Token::PARANTH_BEG) { postfix.push_back(new ExpressionTerm(stack.pop())); } // Pop the "(" stack.pop(); // Pop the ")" tokens->popNext(); } else { throw InvalidTokenException("Unexpected token: " + next->token); } next = tokens->checkNext(); } while (stack.Size()) { postfix.push_back(new ExpressionTerm(stack.pop())); } if (!isParam) { delete tokens->popExpected(Token::SEMICOLON); } }
void Line::process_function(Tokenizer& tokens, string& errs) /*****************************************************************************/ { //create a function call object string temp = tokens.token().value(); FunctionCall* funcCall = Registrar::generateCall(temp); CHECKERR((funcCall == NULL), func_err(temp)) tokens.nextToken(); //move past funcname tokens.nextToken(); //move past open paren //put tokens into the argument lists.. We loop until we have seen the paren //that terminates this function call or until we have run out of tokens on //this line list< vector<Token> > args; vector<Token> currArg; int depth = 0; while(!((tokens.token().value() == ")" && depth == 0) || tokens.eol())) { //if we see a comma at paren depth zero, we have just reached the end of an //argument if (tokens.token().type() == COMMA && depth == 0) { assert(!currArg.empty()); args.push_back(currArg); currArg.clear(); } else { currArg.push_back(tokens.token()); if (tokens.token() == Token(OPERATOR, "(", 0)) ++depth; if (tokens.token() == Token(OPERATOR, ")", 0)) --depth; } tokens.nextToken(); } if (!currArg.empty()) args.push_back(currArg); CHECKERR( tokens.eol() || tokens.token().value() != ")", arg_err(temp) ) if (funcCall->hasVariableArgs()) { CHECKERR ( args.size() < funcCall->getNumArgs(), arg_err(temp) ) } else { CHECKERR( args.size() != funcCall->getNumArgs(), arg_err(temp) ) } //Construct a Line for each argument list< vector<Token> >::iterator arg_itr = args.begin(); for ( ; arg_itr != args.end(); ++arg_itr) { CHECKERR (((*arg_itr).size() == 0), arg_err(temp)) Tokenizer tempToken(*arg_itr); Line* arg = new Line(tempToken, _parent, errs, true); funcCall->fillArg(arg); } addNewObject(funcCall); }