JSValue *evaluate(Scope *scope) { JSValue *lhsValue = lhs->evaluate(scope); if (lhsValue->jsType() == JSExternalFunctionType) { vector<JSValue *> args; for (JSExpression *x: rhs) { args.push_back(x->evaluate(scope)); } JSExternalFunctionImplementation implementation = ((JSExternalFunction *) lhsValue)->getImplementation(); return implementation(args); } else if (lhsValue->jsType() == JSFunctionType) { JSFunction *functionValue = (JSFunction *) lhsValue; Scope *newScope = new Scope(scope); for (int i = 0; i < functionValue->getArgNames().size(); i++) { newScope->declareValue(functionValue->getArgNames()[i], rhs[i]->evaluate(scope)); } JSValue *result = interpretBlock(functionValue->getStatements(), newScope); return (result == nullptr) ? jsUndefined : result; } else { cout << "trying to call " << lhsValue->toString() << ", which can't be called :(" << endl; exit(123); } }