void Resolver::resolveCall(CallExpr& expr, bool isLValue) { // Resolve the arguments. if (!expr.leftArg().isNull()) resolve(expr.leftArg()); if (!expr.rightArg().isNull()) resolve(expr.rightArg()); // Resolve the method. gc<String> signature = SignatureBuilder::build(expr, isLValue); int method = compiler_.findMethod(signature); if (method == -1) { compiler_.reporter().error(expr.pos(), "Could not find a method with signature '%s'.", signature->cString()); // Just pick a method so we can keep compiling to report later errors. method = 0; } expr.setResolved(method); }
gc<String> SignatureBuilder::build(const CallExpr& expr, bool isLValue) { SignatureBuilder builder; if (!expr.leftArg().isNull()) { builder.writeArg(expr.leftArg()); } builder.add(expr.name()->cString()); if (isLValue) builder.add("="); if (!expr.rightArg().isNull()) { builder.add(" "); builder.writeArg(expr.rightArg()); } // TODO(bob): Can you do destructuring here? if (isLValue) builder.add("=0:"); return String::create(builder.signature_, builder.length_); }
void ExprCompiler::compileCall(const CallExpr& call, int dest, int valueSlot) { ASSERT(call.resolved() != -1, "Method should be resolved before compiling."); // Compile the method arguments. int firstArg = getNextTemp(); int numTemps = 0; numTemps += compileArg(call.leftArg()); numTemps += compileArg(call.rightArg()); // Then add the value as the last argument. if (valueSlot != -1) { int valueArg = makeTemp(); write(call, OP_MOVE, valueSlot, valueArg); } write(call, OP_CALL, call.resolved(), firstArg, dest); if (valueSlot != -1) releaseTemp(); // valueArg. releaseTemps(numTemps); }