@@ -201,16 +201,31 @@ void IRGeneratorForStatements::endVisit(BinaryOperation const& _binaryOperation)
201
201
Type functionType = helper.functionType (helper.tupleType ({leftType, rightType}), resultType);
202
202
auto [typeClass, memberName] = m_context.analysis .annotation <TypeInference>().operators .at (_binaryOperation.getOperator ());
203
203
auto const & functionDefinition = resolveTypeClassFunction (typeClass, memberName, functionType);
204
- // TODO: deduplicate with FunctionCall
205
- // TODO: get around resolveRecursive by passing the environment further down?
206
- functionType = m_context.env ->resolveRecursive (functionType);
207
- m_context.enqueueFunctionDefinition (&functionDefinition, functionType);
208
204
std::string functionDeclaration = var (_binaryOperation).commaSeparatedList ();
209
205
if (!functionDeclaration.empty ())
210
206
m_code << " let " << functionDeclaration << " := " ;
211
- m_code << IRNames::function (*m_context.env , functionDefinition, functionType) << " (" <<
212
- var (_binaryOperation.leftExpression ()).commaSeparatedList () <<
213
- var (_binaryOperation.rightExpression ()).commaSeparatedListPrefixed () << " )\n " ;
207
+ m_code << buildFunctionCall (functionDefinition, functionType, _binaryOperation.arguments ());
208
+ }
209
+
210
+ std::string IRGeneratorForStatements::buildFunctionCall (FunctionDefinition const & _functionDefinition, Type _functionType, std::vector<ASTPointer<Expression const >> const & _arguments)
211
+ {
212
+ // Ensure type is resolved
213
+ // TODO: get around resolveRecursive by passing the environment further down?
214
+ Type resolvedFunctionType = m_context.env ->resolveRecursive (_functionType);
215
+ m_context.enqueueFunctionDefinition (&_functionDefinition, resolvedFunctionType);
216
+
217
+ std::ostringstream output;
218
+ output << IRNames::function (*m_context.env , _functionDefinition, resolvedFunctionType) << " (" ;
219
+ if (_arguments.size () == 1 )
220
+ output << var (*_arguments.back ()).commaSeparatedList ();
221
+ else if (_arguments.size () > 1 )
222
+ {
223
+ for (auto arg: _arguments | ranges::views::drop_last (1 ))
224
+ output << var (*arg).commaSeparatedList ();
225
+ output << var (*_arguments.back ()).commaSeparatedListPrefixed ();
226
+ }
227
+ output << " )\n " ;
228
+ return output.str ();
214
229
}
215
230
216
231
void IRGeneratorForStatements::declareAssign (IRVariable const & _lhs, IRVariable const & _rhs, bool _declare)
@@ -341,25 +356,12 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
341
356
}
342
357
FunctionDefinition const * functionDefinition = dynamic_cast <FunctionDefinition const *>(std::get<Declaration const *>(declaration));
343
358
solAssert (functionDefinition);
344
- // TODO: get around resolveRecursive by passing the environment further down?
345
- functionType = m_context.env ->resolveRecursive (functionType);
346
- m_context.enqueueFunctionDefinition (functionDefinition, functionType);
347
359
// TODO: account for return stack size
348
360
solAssert (!functionDefinition->returnParameterList ());
349
361
std::string functionDeclaration = var (_functionCall).commaSeparatedList ();
350
362
if (!functionDeclaration.empty ())
351
363
m_code << " let " << var (_functionCall).commaSeparatedList () << " := " ;
352
- m_code << IRNames::function (*m_context.env , *functionDefinition, functionType) << " (" ;
353
- auto const & arguments = _functionCall.arguments ();
354
- if (arguments.size () == 1 )
355
- m_code << var (*arguments.back ()).commaSeparatedList ();
356
- else if (arguments.size () > 1 )
357
- {
358
- for (auto arg: arguments | ranges::views::drop_last (1 ))
359
- m_code << var (*arg).commaSeparatedList ();
360
- m_code << var (*arguments.back ()).commaSeparatedListPrefixed ();
361
- }
362
- m_code << " )\n " ;
364
+ m_code << buildFunctionCall (*functionDefinition, functionType, _functionCall.arguments ());
363
365
}
364
366
365
367
bool IRGeneratorForStatements::visit (FunctionCall const &)
0 commit comments