Expression *TypeCompiler::visit(CallExpression *call) { MethodBase *methodBase = call->methodBase; call->function->visitExpression(this); // check whether we're calling a methodbase if (methodBase) { lmAssert(methodBase->isMethod(), "Non-method called"); MethodInfo *method = (MethodInfo *)methodBase; generateCall(&call->function->e, call->arguments, method); call->e = call->function->e; } else { lmAssert(call->function->type, "Untyped call"); // if we're calling a delegate we need to load up the call method if (call->function->type->isDelegate()) { MethodInfo *method = (MethodInfo *)call->function->type->findMember("call"); lmAssert(method, "delegate with no call method"); ExpDesc right; BC::initExpDesc(&right, VKNUM, 0); right.u.nval = method->getOrdinal(); BC::expToNextReg(cs->fs, &call->function->e); BC::expToNextReg(cs->fs, &right); BC::expToVal(cs->fs, &right); BC::indexed(cs->fs, &call->function->e, &right); generateCall(&call->function->e, call->arguments, NULL); call->e = call->function->e; } else { // we're directly calling a local, instance (bound), or static method of type Function generateCall(&call->function->e, call->arguments, NULL); call->e = call->function->e; } } return call; }
Expression *TypeCompiler::visit(AssignmentOperatorExpression *expression) { Tokens *tok = Tokens::getSingletonPtr(); BinOpr op = getassignmentopr(expression->type); lmAssert(op != OPR_NOBINOPR, "Unknown bin op on AssignentOperatorExpression"); Expression *eleft = expression->leftExpression; Expression *eright = expression->rightExpression; lmAssert(eleft->type, "Untyped error on left expression"); const char *opmethod = tok->getOperatorMethodName(expression->type); if (opmethod) { MemberInfo *mi = eleft->type->findMember(opmethod); if (mi) { lmAssert(mi->isMethod(), "Non-method operator"); MethodInfo *method = (MethodInfo *)mi; lmAssert(method->isOperator(), "Non-operator method"); utArray<Expression *> args; args.push_back(eright); ExpDesc opcall; ExpDesc emethod; eleft->visitExpression(this); opcall = eleft->e; BC::initExpDesc(&emethod, VKNUM, 0); emethod.u.nval = method->getOrdinal(); BC::expToNextReg(cs->fs, &opcall); BC::expToNextReg(cs->fs, &emethod); BC::expToVal(cs->fs, &emethod); BC::indexed(cs->fs, &opcall, &emethod); generateCall(&opcall, &args, method); expression->e = opcall; return expression; } } eleft->assignment = false; eleft->visitExpression(this); BC::infix(cs->fs, op, &eleft->e); eright->visitExpression(this); BC::expToNextReg(cs->fs, &eright->e); BC::posFix(cs->fs, op, &eleft->e, &eright->e); ExpDesc right = eleft->e; BC::expToNextReg(cs->fs, &right); memset(&eleft->e, 0, sizeof(ExpDesc)); eleft->assignment = true; eleft->visitExpression(this); ExpDesc left = eleft->e; if (eleft->memberInfo && eleft->memberInfo->isProperty()) { eright->e = right; generatePropertySet(&eleft->e, eright, false); } else { BC::storeVar(cs->fs, &left, &right); } return expression; }