AST function factory for a callable, for one to three arguments. One-function arguments are typical, they may take many forms such as cast operations (:code:`float32(x)`) or transcendentals (:code:`sin(x)`) for example. Two-function arguments are rarer, an example being :
(self: NumExpr, node: ast.AST)
| 1270 | return outputRegister |
| 1271 | |
| 1272 | def _call(self: NumExpr, node: ast.AST) -> NumReg: |
| 1273 | ''' |
| 1274 | AST function factory for a callable, for one to three arguments. |
| 1275 | |
| 1276 | One-function arguments are typical, they may take many forms such as cast |
| 1277 | operations (:code:`float32(x)`) or transcendentals (:code:`sin(x)`) for |
| 1278 | example. |
| 1279 | |
| 1280 | Two-function arguments are rarer, an example being :code:`atan2(x, y)`. |
| 1281 | NE3 supports a number of two-function arguments found in :code:`scipy.misc`. |
| 1282 | |
| 1283 | The only supported three-function argument is :code:`where(test, a, b)` |
| 1284 | |
| 1285 | ast.Call fields are: (in Python >= 3.4) |
| 1286 | :code:`('func', 'args', 'keywords', 'starargs', 'kwargs')` |
| 1287 | |
| 1288 | Only `args` is examined. |
| 1289 | ''' |
| 1290 | # info( '$ast.Call: %s'%node.func.id ) |
| 1291 | |
| 1292 | argRegisters = [_ASTAssembler[type(arg)](self, arg) for arg in node.args] |
| 1293 | |
| 1294 | if len(argRegisters) == 1: |
| 1295 | argReg0 = argRegisters[0] |
| 1296 | # _cast1: We may have to do a cast here, for example 'cos(<int>A)' |
| 1297 | opSig = (node.func.id, self.lib, argReg0.dchar) |
| 1298 | |
| 1299 | argReg0, opSig = self._func_cast(argReg0, opSig) |
| 1300 | opCode, self.assignDChar = OPTABLE[opSig] |
| 1301 | outputRegister = self._transmit1(argReg0) |
| 1302 | |
| 1303 | self._codeStream.write(b''.join((opCode, outputRegister.token, |
| 1304 | argReg0.token, _NULL_REG, _NULL_REG))) |
| 1305 | |
| 1306 | elif len(argRegisters) == 2: |
| 1307 | argRegisters = self._cast2(*argRegisters) |
| 1308 | argReg0, argReg1 = argRegisters |
| 1309 | opCode, self.assignDChar = OPTABLE[(node.func.id, self.lib, |
| 1310 | argReg0.dchar, argReg1.dchar)] |
| 1311 | outputRegister = self._transmit2(argReg0, argReg1) |
| 1312 | |
| 1313 | self._codeStream.write( b''.join((opCode, outputRegister.token, |
| 1314 | argReg0.token, argReg1.token, _NULL_REG))) |
| 1315 | |
| 1316 | elif len(argRegisters) == 3: |
| 1317 | # The where() ternary operator function is currently the _only_ |
| 1318 | # 3 argument function |
| 1319 | argReg0, argReg1, argReg2 = argRegisters |
| 1320 | argReg1, argReg2 = self._cast2(argReg1, argReg2) |
| 1321 | |
| 1322 | opCode, self.assignDChar = OPTABLE[ (node.func.id, self.lib, |
| 1323 | argReg0.dchar, argReg1.dchar, argReg2.dchar)] |
| 1324 | # Because we know the first register is the bool, it's the least useful temporary to re-use |
| 1325 | # as it almost certainly must be promoted. |
| 1326 | outputRegister = self._transmit3(argReg1, argReg2, argReg0) |
| 1327 | |
| 1328 | self._codeStream.write( b''.join((opCode, outputRegister.token, |
| 1329 | argReg0.token, argReg1.token, argReg2.token))) |
nothing calls this directly
no test coverage detected
searching dependent graphs…