ExpressionPtr Expression::unneededHelper() { ExpressionListPtr elist = ExpressionListPtr (new ExpressionList(getScope(), getRange(), ExpressionList::ListKindWrapped)); bool change = false; for (int i=0, n = getKidCount(); i < n; i++) { ExpressionPtr kid = getNthExpr(i); if (kid && kid->getContainedEffects()) { ExpressionPtr rep = kid->unneeded(); if (rep != kid) change = true; if (rep->is(Expression::KindOfExpressionList)) { for (int j=0, m = rep->getKidCount(); j < m; j++) { elist->addElement(rep->getNthExpr(j)); } } else { elist->addElement(rep); } } } if (change) { getScope()->addUpdates(BlockScope::UseKindCaller); } int n = elist->getCount(); assert(n); if (n == 1) { return elist->getNthExpr(0); } else { return elist; } }
void FunctionScope::outputCPPParamsDecl(CodeGenerator &cg, AnalysisResultPtr ar, ExpressionListPtr params, bool showDefault) { if (isVariableArgument()) { cg.printf("int num_args, "); if (params) { ar->setInExpression(true); params->outputCPP(cg, ar); ar->setInExpression(false); cg.printf(", "); } if (showDefault) { cg.printf("Array args = Array()"); } else { cg.printf("Array args /* = Array() */"); } } else if (m_pseudoMain) { if (showDefault) { cg.printf("bool incOnce = false, LVariableTable* variables = NULL"); } else { cg.printf("bool incOnce /* = false */, " "LVariableTable* variables /* = NULL */"); } } else if (params) { ar->setInExpression(true); params->outputCPP(cg, ar); ar->setInExpression(false); } }
void InterfaceStatement::checkArgumentsToPromote( FileScopeRawPtr scope, ExpressionListPtr promotedParams, int type) { if (!m_stmt) { return; } for (int i = 0; i < m_stmt->getCount(); i++) { MethodStatementPtr meth = dynamic_pointer_cast<MethodStatement>((*m_stmt)[i]); if (meth && meth->isNamed("__construct")) { ExpressionListPtr params = meth->getParams(); if (params) { for (int i = 0; i < params->getCount(); i++) { ParameterExpressionPtr param = dynamic_pointer_cast<ParameterExpression>((*params)[i]); if (param->getModifier() != 0) { if (type == T_TRAIT || type == T_INTERFACE) { param->parseTimeFatal(scope, Compiler::InvalidAttribute, "Constructor parameter promotion " "not allowed on traits or interfaces"); } if (promotedParams) { promotedParams->addElement(param); } } } } return; // nothing else to look at } } }
ExpressionPtr UnaryOpExpression::postOptimize(AnalysisResultPtr ar) { bool insideScalarArray = ar->getInsideScalarArray(); if (m_op == T_ARRAY && (getContext() & (RefValue|LValue)) == 0) { if (m_exp) { ExpressionListPtr pairs = dynamic_pointer_cast<ExpressionList>(m_exp); if (pairs && pairs->isScalarArrayPairs()) { m_arrayId = ar->registerScalarArray(m_exp); ar->setInsideScalarArray(true); } } else { m_arrayId = ar->registerScalarArray(m_exp); // empty array } } ar->postOptimize(m_exp); if (m_op == T_PRINT && m_exp->is(KindOfEncapsListExpression) && !m_exp->hasEffect()) { EncapsListExpressionPtr e = static_pointer_cast<EncapsListExpression> (m_exp); e->stripConcat(); } ar->setInsideScalarArray(insideScalarArray); if (m_op == T_UNSET_CAST && !hasEffect()) { return CONSTANT("null"); } else if (m_op == T_UNSET && m_exp->is(KindOfExpressionList) && !static_pointer_cast<ExpressionList>(m_exp)->getCount()) { return CONSTANT("null"); } return ExpressionPtr(); }
void ClosureExpression::initializeFromUseList(ExpressionListPtr vars) { m_vars = ExpressionListPtr( new ExpressionList(vars->getScope(), vars->getRange())); // Because PHP is insane you can have a use variable with the same // name as a param name. // In that case, params win (which is different than zend but much easier) auto seenBefore = collectParamNames(); for (int i = vars->getCount() - 1; i >= 0; i--) { auto param = dynamic_pointer_cast<ParameterExpression>((*vars)[i]); assert(param); if (param->getName() == "this") { // "this" is automatically included. // Once we get rid of all the callsites, make this an error continue; } if (seenBefore.find(param->getName().c_str()) == seenBefore.end()) { seenBefore.insert(param->getName().c_str()); m_vars->insertElement(param); } } initializeValuesFromVars(); }
void CodeGenerator::printExpressionVector(ExpressionListPtr el) { printf("V:9:\"HH\\Vector\":%d:{", el->getCount()); if (el->getCount() > 0) { el->outputCodeModel(*this); } printf("}"); }
void Symbol::beginLocal(BlockScopeRawPtr scope) { m_prevCoerced = m_coerced; if (isClosureVar()) { ExpressionListPtr useVars = scope->getContainingFunction()->getClosureVars(); assert(useVars); // linear scan for now, since most use var lists are // fairly short bool found = false; for (int i = 0; i < useVars->getCount(); i++) { ParameterExpressionPtr param = dynamic_pointer_cast<ParameterExpression>((*useVars)[i]); if (m_name == param->getName()) { // bootstrap use var with parameter type m_coerced = param->getType(); found = true; break; } } if (!found) assert(false); assert(!isRefClosureVar() || (m_coerced && m_coerced->is(Type::KindOfVariant))); } else { m_coerced.reset(); } }
int BinaryOpExpression::getConcatList(ExpressionPtrVec &ev, ExpressionPtr exp, bool &hasVoid) { if (!exp->hasCPPTemp()) { if (exp->is(Expression::KindOfUnaryOpExpression)) { UnaryOpExpressionPtr u = static_pointer_cast<UnaryOpExpression>(exp); if (u->getOp() == '(') { return getConcatList(ev, u->getExpression(), hasVoid); } } else if (exp->is(Expression::KindOfBinaryOpExpression)) { BinaryOpExpressionPtr b = static_pointer_cast<BinaryOpExpression>(exp); if (b->getOp() == '.') { return getConcatList(ev, b->getExp1(), hasVoid) + getConcatList(ev, b->getExp2(), hasVoid); } } else if (exp->is(Expression::KindOfEncapsListExpression)) { EncapsListExpressionPtr e = static_pointer_cast<EncapsListExpression>(exp); if (e->getType() != '`') { ExpressionListPtr el = e->getExpressions(); int num = 0; for (int i = 0, s = el->getCount(); i < s; i++) { ExpressionPtr exp = (*el)[i]; num += getConcatList(ev, exp, hasVoid); } return num; } } } ev.push_back(exp); bool isVoid = !exp->getActualType(); hasVoid |= isVoid; return isVoid ? 0 : 1; }
static ExpressionPtr makeIsNull(AnalysisResultConstPtr ar, LocationPtr loc, ExpressionPtr exp, bool invert) { /* Replace "$x === null" with an is_null call; this requires slightly * less work at runtime. */ ExpressionListPtr expList = ExpressionListPtr(new ExpressionList(exp->getScope(), loc)); expList->insertElement(exp); SimpleFunctionCallPtr call (new SimpleFunctionCall(exp->getScope(), loc, "is_null", false, expList, ExpressionPtr())); call->setValid(); call->setActualType(Type::Boolean); call->setupScopes(ar); ExpressionPtr result(call); if (invert) { result = ExpressionPtr(new UnaryOpExpression( exp->getScope(), loc, result, '!', true)); } return result; }
static ExpressionPtr makeIsNull(LocationPtr loc, ExpressionPtr exp, bool invert) { /* Replace "$x === null" with an is_null call; this requires slightly * less work at runtime. */ ExpressionListPtr expList = ExpressionListPtr(new ExpressionList(loc, Expression::KindOfExpressionList)); expList->insertElement(exp); SimpleFunctionCallPtr call (new SimpleFunctionCall(loc, Expression::KindOfSimpleFunctionCall, "is_null", expList, ExpressionPtr())); call->setValid(); call->setActualType(Type::Boolean); ExpressionPtr result(call); if (invert) { result = ExpressionPtr(new UnaryOpExpression( loc, Expression::KindOfUnaryOpExpression, result, '!', true)); } return result; }
bool ExpressionList::flattenLiteralStrings(vector<ExpressionPtr> &literals) const { for (unsigned i = 0; i < m_exps.size(); i++) { ExpressionPtr e = m_exps[i]; if (e->is(Expression::KindOfArrayPairExpression)) { ArrayPairExpressionPtr ap = dynamic_pointer_cast<ArrayPairExpression>(e); if (ap->getName()) return false; e = ap->getValue(); } if (e->is(Expression::KindOfUnaryOpExpression)) { UnaryOpExpressionPtr unary = dynamic_pointer_cast<UnaryOpExpression>(e); if (unary->getOp() == T_ARRAY) { ExpressionListPtr el = dynamic_pointer_cast<ExpressionList>(unary->getExpression()); if (!el->flattenLiteralStrings(literals)) { return false; } } } else if (e->isLiteralString()) { literals.push_back(e); } else { return false; } } return true; }
void CodeGenerator::printExpressionVector(ExpressionListPtr el) { auto count = el == nullptr ? 0 : el->getCount(); printf("V:9:\"HH\\Vector\":%d:{", count); if (count > 0) { el->outputCodeModel(*this); } printf("}"); }
static void setListKind(ExpressionPtr e) { if (e && e->is(Expression::KindOfExpressionList)) { ExpressionListPtr list = static_pointer_cast<ExpressionList>(e); list->setListKind(ExpressionList::ListKindComma); } }
void BinaryOpExpression::outputPHP(CodeGenerator &cg, AnalysisResultPtr ar) { m_exp1->outputPHP(cg, ar); switch (m_op) { case T_PLUS_EQUAL: cg_printf(" += "); break; case T_MINUS_EQUAL: cg_printf(" -= "); break; case T_MUL_EQUAL: cg_printf(" *= "); break; case T_DIV_EQUAL: cg_printf(" /= "); break; case T_CONCAT_EQUAL: cg_printf(" .= "); break; case T_MOD_EQUAL: cg_printf(" %%= "); break; case T_AND_EQUAL: cg_printf(" &= "); break; case T_OR_EQUAL: cg_printf(" |= "); break; case T_XOR_EQUAL: cg_printf(" ^= "); break; case T_SL_EQUAL: cg_printf(" <<= "); break; case T_SR_EQUAL: cg_printf(" >>= "); break; case T_BOOLEAN_OR: cg_printf(" || "); break; case T_BOOLEAN_AND: cg_printf(" && "); break; case T_LOGICAL_OR: cg_printf(" or "); break; case T_LOGICAL_AND: cg_printf(" and "); break; case T_LOGICAL_XOR: cg_printf(" xor "); break; case '|': cg_printf(" | "); break; case '&': cg_printf(" & "); break; case '^': cg_printf(" ^ "); break; case '.': cg_printf(" . "); break; case '+': cg_printf(" + "); break; case '-': cg_printf(" - "); break; case '*': cg_printf(" * "); break; case '/': cg_printf(" / "); break; case '%': cg_printf(" %% "); break; case T_SL: cg_printf(" << "); break; case T_SR: cg_printf(" >> "); break; case T_IS_IDENTICAL: cg_printf(" === "); break; case T_IS_NOT_IDENTICAL: cg_printf(" !== "); break; case T_IS_EQUAL: cg_printf(" == "); break; case T_IS_NOT_EQUAL: cg_printf(" != "); break; case '<': cg_printf(" < "); break; case T_IS_SMALLER_OR_EQUAL: cg_printf(" <= "); break; case '>': cg_printf(" > "); break; case T_IS_GREATER_OR_EQUAL: cg_printf(" >= "); break; case T_INSTANCEOF: cg_printf(" instanceof "); break; case T_COLLECTION: { ExpressionListPtr el = static_pointer_cast<ExpressionList>(m_exp2); if (el->getCount() == 0) { cg_printf(" {}"); } else { cg_printf(" { "); el->outputPHP(cg, ar); cg_printf(" }"); } return; } default: assert(false); } m_exp2->outputPHP(cg, ar); }
/** * Rewrites any expression query clauses in this list of clauses, taking care * to track variables local to the query. */ ExpressionListPtr CaptureExtractor::rewriteExpressionList(ExpressionListPtr l) { int np = 0; int nc = l->getCount(); auto newList = std::make_shared<ExpressionList>(l->getScope(), l->getRange()); bool noRewrites = true; for (int i = 0; i < nc; i++) { auto e = (*l)[i]; assert(e != nullptr); auto kind = e->getKindOf(); switch (kind) { case Expression::KindOfIntoClause: { // The into expression is in the scope of the into clause SimpleQueryClausePtr qcp(static_pointer_cast<SimpleQueryClause>(e)); m_boundVars.push_back(qcp->getIdentifier()); np++; break; } case Expression::KindOfJoinClause: { JoinClausePtr jcp(static_pointer_cast<JoinClause>(e)); m_boundVars.push_back(jcp->getVar()); np++; break; } default: break; } auto ne = rewrite(e); if (ne != e) noRewrites = false; newList->addElement(ne); // deal with clauses that introduce names for subsequent clauses switch (kind) { case Expression::KindOfFromClause: case Expression::KindOfLetClause: { SimpleQueryClausePtr qcp(static_pointer_cast<SimpleQueryClause>(e)); m_boundVars.push_back(qcp->getIdentifier()); np++; break; } case Expression::KindOfJoinClause: { JoinClausePtr jcp(static_pointer_cast<JoinClause>(e)); auto groupId = jcp->getGroup(); if (!groupId.empty()) { m_boundVars.push_back(groupId); np++; } break; } default: break; } } while (np-- > 0) m_boundVars.pop_back(); if (noRewrites) return l; return newList; }
ClosureExpression::ClosureExpression (EXPRESSION_CONSTRUCTOR_PARAMETERS, FunctionStatementPtr func, ExpressionListPtr vars) : Expression(EXPRESSION_CONSTRUCTOR_PARAMETER_VALUES(ClosureExpression)), m_func(func) { if (vars) { m_vars = ExpressionListPtr (new ExpressionList(vars->getScope(), vars->getLocation())); // push the vars in reverse order, not retaining duplicates std::set<string> seenBefore; // Because PHP is insane you can have a use variable with the same // name as a param name. // In that case, params win (which is different than zend but much easier) ExpressionListPtr bodyParams = m_func->getParams(); if (bodyParams) { int nParams = bodyParams->getCount(); for (int i = 0; i < nParams; i++) { ParameterExpressionPtr par( static_pointer_cast<ParameterExpression>((*bodyParams)[i])); seenBefore.insert(par->getName()); } } for (int i = vars->getCount() - 1; i >= 0; i--) { ParameterExpressionPtr param( dynamic_pointer_cast<ParameterExpression>((*vars)[i])); assert(param); if (seenBefore.find(param->getName().c_str()) == seenBefore.end()) { seenBefore.insert(param->getName().c_str()); m_vars->insertElement(param); } } if (m_vars) { m_values = ExpressionListPtr (new ExpressionList(m_vars->getScope(), m_vars->getLocation())); for (int i = 0; i < m_vars->getCount(); i++) { ParameterExpressionPtr param = dynamic_pointer_cast<ParameterExpression>((*m_vars)[i]); const string &name = param->getName(); SimpleVariablePtr var(new SimpleVariable(param->getScope(), param->getLocation(), name)); if (param->isRef()) { var->setContext(RefValue); } m_values->addElement(var); } assert(m_vars->getCount() == m_values->getCount()); } } }
BinaryOpExpression::BinaryOpExpression (EXPRESSION_CONSTRUCTOR_PARAMETERS, ExpressionPtr exp1, ExpressionPtr exp2, int op) : Expression(EXPRESSION_CONSTRUCTOR_PARAMETER_VALUES(BinaryOpExpression)), m_exp1(exp1), m_exp2(exp2), m_op(op), m_assign(false), m_canThrow(false) { switch (m_op) { case T_PLUS_EQUAL: case T_MINUS_EQUAL: case T_MUL_EQUAL: case T_DIV_EQUAL: case T_CONCAT_EQUAL: case T_MOD_EQUAL: case T_AND_EQUAL: case T_OR_EQUAL: case T_XOR_EQUAL: case T_SL_EQUAL: case T_SR_EQUAL: m_assign = true; m_exp1->setContext(Expression::LValue); m_exp1->setContext(Expression::OprLValue); m_exp1->setContext(Expression::DeepOprLValue); if (m_exp1->is(Expression::KindOfObjectPropertyExpression)) { m_exp1->setContext(Expression::NoLValueWrapper); } break; case T_COLLECTION: { std::string s = m_exp1->getLiteralString(); Collection::Type cType = Collection::InvalidType; if (strcasecmp(s.c_str(), "vector") == 0) { cType = Collection::VectorType; } else if (strcasecmp(s.c_str(), "map") == 0) { cType = Collection::MapType; } else if (strcasecmp(s.c_str(), "stablemap") == 0) { cType = Collection::StableMapType; } else if (strcasecmp(s.c_str(), "set") == 0) { cType = Collection::SetType; } else if (strcasecmp(s.c_str(), "pair") == 0) { cType = Collection::PairType; } else if (strcasecmp(s.c_str(), "frozenvector") == 0) { cType = Collection::FrozenVectorType; } else if (strcasecmp(s.c_str(), "frozenmap") == 0) { cType = Collection::FrozenMapType; } else if (strcasecmp(s.c_str(), "frozenset") == 0) { cType = Collection::FrozenSetType; } ExpressionListPtr el = static_pointer_cast<ExpressionList>(m_exp2); el->setCollectionType(cType); break; } default: break; } }
void UnaryOpExpression::setExistContext() { if (m_exp) { if (m_exp->is(Expression::KindOfExpressionList)) { ExpressionListPtr exps = dynamic_pointer_cast<ExpressionList>(m_exp); for (int i = 0; i < exps->getCount(); i++) { (*exps)[i]->setContext(Expression::ExistContext); } } else { m_exp->setContext(Expression::ExistContext); } } }
void UnaryOpExpression::setExistContext() { if (m_exp) { if (m_exp->is(Expression::KindOfExpressionList)) { ExpressionListPtr exps = dynamic_pointer_cast<ExpressionList>(m_exp); if (exps->getListKind() == ExpressionList::ListKindParam) { for (int i = 0; i < exps->getCount(); i++) { (*exps)[i]->setContext(Expression::ExistContext); } return; } } m_exp->setContext(Expression::ExistContext); } }
int BinaryOpExpression::getConcatList(ExpressionPtrVec &ev, ExpressionPtr exp, bool &hasVoid) { if (!exp->hasCPPTemp()) { if (exp->is(Expression::KindOfUnaryOpExpression)) { UnaryOpExpressionPtr u = static_pointer_cast<UnaryOpExpression>(exp); if (u->getOp() == '(') { return getConcatList(ev, u->getExpression(), hasVoid); } } else if (exp->is(Expression::KindOfBinaryOpExpression)) { BinaryOpExpressionPtr b = static_pointer_cast<BinaryOpExpression>(exp); if (b->getOp() == '.') { if (b->getExp1()->is(Expression::KindOfSimpleVariable) && b->getExp1()->isLocalExprAltered() && !b->getExp1()->hasCPPTemp() && b->getExp2()->hasEffect() && !b->getExp2()->hasCPPTemp()) { /* In this case, the simple variable must be evaluated after b->getExp2(). But when we output a concat list we explicitly order the expressions from left to right. */ } else { return getConcatList(ev, b->getExp1(), hasVoid) + getConcatList(ev, b->getExp2(), hasVoid); } } } else if (exp->is(Expression::KindOfEncapsListExpression)) { EncapsListExpressionPtr e = static_pointer_cast<EncapsListExpression>(exp); if (e->getType() != '`') { ExpressionListPtr el = e->getExpressions(); int num = 0; for (int i = 0, s = el->getCount(); i < s; i++) { ExpressionPtr exp = (*el)[i]; num += getConcatList(ev, exp, hasVoid); } return num; } } } else if (!exp->getActualType()) { return 0; } ev.push_back(exp); bool isVoid = !exp->getActualType(); hasVoid |= isVoid; return isVoid ? 0 : 1; }
ClosureExpression::ClosureExpression (EXPRESSION_CONSTRUCTOR_PARAMETERS, FunctionStatementPtr func, ExpressionListPtr vars) : Expression(EXPRESSION_CONSTRUCTOR_PARAMETER_VALUES(ClosureExpression)), m_func(func) { if (vars) { m_vars = ExpressionListPtr (new ExpressionList(vars->getScope(), vars->getLocation())); // push the vars in reverse order, not retaining duplicates std::set<string> seenBefore; for (int i = vars->getCount() - 1; i >= 0; i--) { ParameterExpressionPtr param( dynamic_pointer_cast<ParameterExpression>((*vars)[i])); assert(param); if (param->getName() == "this") { // "this" is automatically included. // Once we get rid of all the callsites, make this an error continue; } if (seenBefore.find(param->getName().c_str()) == seenBefore.end()) { seenBefore.insert(param->getName().c_str()); m_vars->insertElement(param); } } if (m_vars) { m_values = ExpressionListPtr (new ExpressionList(m_vars->getScope(), m_vars->getLocation())); for (int i = 0; i < m_vars->getCount(); i++) { ParameterExpressionPtr param = dynamic_pointer_cast<ParameterExpression>((*m_vars)[i]); const string &name = param->getName(); SimpleVariablePtr var(new SimpleVariable(param->getScope(), param->getLocation(), name)); if (param->isRef()) { var->setContext(RefValue); } m_values->addElement(var); } assert(m_vars->getCount() == m_values->getCount()); } } }
bool UnaryOpExpression::preOutputCPP(CodeGenerator &cg, AnalysisResultPtr ar, int state) { if (m_op == T_ISSET && m_exp && m_exp->is(Expression::KindOfExpressionList)) { ExpressionListPtr exps = dynamic_pointer_cast<ExpressionList>(m_exp); int count = exps->getCount(); if (count > 1) { bool fix_e1 = (*exps)[0]->preOutputCPP(cg, ar, 0); bool inExpression = ar->inExpression(); ar->setInExpression(false); bool fix_en = false; for (int i = 1; i < count; i++) { if ((*exps)[i]->preOutputCPP(cg, ar, 0)) { fix_en = true; break; } } ar->setInExpression(inExpression); if (inExpression && fix_en) { ar->wrapExpressionBegin(cg); std::string tmp = genCPPTemp(cg, ar); cg.printf("bool %s = (", tmp.c_str()); (*exps)[0]->outputCPPExistTest(cg, ar, m_op); cg.printf(");\n"); for (int i = 1; i < count; i++) { cg.indentBegin("if (%s) {\n", tmp.c_str()); ExpressionPtr e = (*exps)[i]; e->preOutputCPP(cg, ar, 0); cg.printf("%s = (", tmp.c_str()); e->outputCPPExistTest(cg, ar, m_op); cg.printf(");\n"); } for (int i = 1; i < count; i++) { cg.indentEnd("}\n"); } m_cppTemp = tmp; } else if (state & FixOrder) { preOutputStash(cg, ar, state); fix_e1 = true; } return fix_e1 || fix_en; } } return Expression::preOutputCPP(cg, ar, state); }
bool Option::Load(map<string, int> &option, ExpressionPtr value) { ExpressionListPtr elements; if (!GetArrayElements(value, elements)) return false; for (int i = 0; i < elements->getCount(); i++) { ExpressionPtr e = (*elements)[i]; ArrayPairExpressionPtr pair = dynamic_pointer_cast<ArrayPairExpression>(e); bool negative = false; ScalarExpressionPtr n, v; if (pair) n = dynamic_pointer_cast<ScalarExpression>(pair->getName()); if (pair) { if (pair->getValue()->is(Expression::KindOfUnaryOpExpression)) { UnaryOpExpressionPtr una = dynamic_pointer_cast<UnaryOpExpression>(pair->getValue()); if (una->getOp() != '+' && una->getOp() != '-') { Logger::Error("Line %d: invalid integer: %s", una->getLocation()->line1, una->getText().c_str()); return false; } v = dynamic_pointer_cast<ScalarExpression>(una->getExpression()); if (una->getOp() == '-') { negative = true; } } else { v = dynamic_pointer_cast<ScalarExpression>(pair->getValue()); } } if (!pair || !n || !v || !n->isLiteralString() || !v->isLiteralInteger()) { Logger::Error("Line %d: invalid element: %s", e->getLocation()->line1, e->getText().c_str()); return false; } if (negative) { option[n->getLiteralString()] = - v->getLiteralInteger(); } else { option[n->getLiteralString()] = v->getLiteralInteger(); } } return true; }
void FunctionScope::outputCPPArguments(ExpressionListPtr params, CodeGenerator &cg, AnalysisResultPtr ar, int extraArg, bool variableArgument, int extraArgArrayId /* = -1 */) { int paramCount = params ? params->getOutputCount() : 0; ASSERT(extraArg <= paramCount); int iMax = paramCount - extraArg; bool extra = false; if (variableArgument) { if (paramCount == 0) { cg.printf("0"); } else { cg.printf("%d, ", paramCount); } } int firstExtra = 0; for (int i = 0; i < paramCount; i++) { ExpressionPtr param = (*params)[i]; cg.setItemIndex(i); if (i > 0) cg.printf(extra ? "." : ", "); if (!extra && (i == iMax || extraArg < 0)) { if (extraArgArrayId != -1) { if (cg.getOutput() == CodeGenerator::SystemCPP) { cg.printf("SystemScalarArrays::%s[%d]", Option::SystemScalarArrayName, extraArgArrayId); } else { cg.printf("ScalarArrays::%s[%d]", Option::ScalarArrayName, extraArgArrayId); } break; } extra = true; // Parameter arrays are always vectors. cg.printf("Array(ArrayInit(%d, true).", paramCount - i); firstExtra = i; } if (extra) { bool needRef = param->hasContext(Expression::RefValue) && !param->hasContext(Expression::NoRefWrapper) && param->isRefable(); cg.printf("set%s(%d, ", needRef ? "Ref" : "", i - firstExtra); if (needRef) { // The parameter itself shouldn't be wrapped with ref() any more. param->setContext(Expression::NoRefWrapper); } param->outputCPP(cg, ar); cg.printf(")"); } else { param->outputCPP(cg, ar); } } if (extra) { cg.printf(".create())"); } }
void Parser::onEcho(Token *out, Token *expr, bool html) { if (html) { LocationPtr loc = getLocation(); if (loc->line1 == 2 && loc->char1 == 0 && expr->text()[0] == '#') { // skipping linux interpreter declaration out->stmt = NEW_STMT0(StatementList); } else { ExpressionPtr exp = NEW_EXP(ScalarExpression, T_STRING, expr->text(), true); ExpressionListPtr expList = NEW_EXP(ExpressionList); expList->addElement(exp); out->stmt = NEW_STMT(EchoStatement, expList); } } else { out->stmt = NEW_STMT(EchoStatement, dynamic_pointer_cast<ExpressionList>(expr->exp)); } }
ExpressionPtr AssignmentExpression::makeIdCall(AnalysisResultPtr ar) { ExpressionListPtr arg = ExpressionListPtr(new ExpressionList(getLocation(), Expression::KindOfExpressionList)); arg->insertElement(m_value); SimpleFunctionCallPtr result = SimpleFunctionCallPtr( new SimpleFunctionCall(getLocation(), Expression::KindOfSimpleFunctionCall, "id", arg, NULL)); result->setFunctionAndClassScope(ar->findHelperFunction("id"), ClassScopePtr()); result->setValid(); result->setNoPrefix(); result->setActualType(m_value->getActualType()); result->setExpectedType(m_expectedType); return result; }
void CodeGenerator::printTypeExpressionVector(ExpressionListPtr el) { auto count = el == nullptr ? 0 : el->getCount(); printf("V:9:\"HH\\Vector\":%d:{", count); for (int i = 0; i < count; i++) { auto te = (*el)[i]; printTypeExpression(te); } printf("}"); }
void Parser::addEncap(Token *out, Token *list, Token *expr, int type) { ExpressionListPtr expList; if (list->exp) { expList = dynamic_pointer_cast<ExpressionList>(list->exp); } else { expList = NEW_EXP0(ExpressionList); } ExpressionPtr exp; if (type == -1) { exp = expr->exp; } else { ScalarExpressionPtr scalar = NEW_EXP(ScalarExpression, T_ENCAPSED_AND_WHITESPACE, expr->text(), true); scalar->onParse(m_ar); exp = scalar; } expList->addElement(exp); out->exp = expList; }
ClosureExpression::ClosureExpression (EXPRESSION_CONSTRUCTOR_PARAMETERS, FunctionStatementPtr func, ExpressionListPtr vars) : Expression(EXPRESSION_CONSTRUCTOR_PARAMETER_VALUES), m_func(func) { if (vars) { m_vars = ExpressionListPtr (new ExpressionList(vars->getScope(), vars->getLocation(), KindOfExpressionList)); // push the vars in reverse order, not retaining duplicates set<string> seenBefore; for (int i = vars->getCount() - 1; i >= 0; i--) { ParameterExpressionPtr param( dynamic_pointer_cast<ParameterExpression>((*vars)[i])); ASSERT(param); if (seenBefore.find(param->getName().c_str()) == seenBefore.end()) { seenBefore.insert(param->getName().c_str()); m_vars->insertElement(param); } } if (m_vars) { m_values = ExpressionListPtr (new ExpressionList(m_vars->getScope(), m_vars->getLocation(), KindOfExpressionList)); for (int i = 0; i < m_vars->getCount(); i++) { ParameterExpressionPtr param = dynamic_pointer_cast<ParameterExpression>((*m_vars)[i]); string name = param->getName(); SimpleVariablePtr var(new SimpleVariable(param->getScope(), param->getLocation(), KindOfSimpleVariable, name)); if (param->isRef()) { var->setContext(RefValue); } m_values->addElement(var); } } } }
void runTests8 (int argc, char* argv[]) { ilog("2 -------------"); ExpressionListPtr pL0 = Util::quickPerm(2); pL0->print(); ilog("3 -------------"); ExpressionListPtr pL = Util::quickPerm(3); pL->print(); ilog("4 -------------"); ExpressionListPtr pL1 = Util::quickPerm(4); pL1->print(); ilog("5 -------------"); ExpressionListPtr pL2 = Util::quickPerm(5); pL2->print(); }