For anything that doesn't need special function handling.
(opsList: List[Operation])
| 928 | |
| 929 | |
| 930 | def OpsFactory(opsList: List[Operation]) -> None: |
| 931 | """ |
| 932 | For anything that doesn't need special function handling. |
| 933 | """ |
| 934 | global OP_COUNT |
| 935 | |
| 936 | # Constructor signature: |
| 937 | # Operation( python_name template, [libs], [return_dchars], |
| 938 | # [arg1_dchars], {[arg2_dchars], ... } ) |
| 939 | |
| 940 | ###### Copy ###### |
| 941 | opsList += [Operation('copy', '$DEST = $ARG1', (LIB_STD,), ALL_NUM, [ALL_NUM])] |
| 942 | # Casts are built in CastFactory(). |
| 943 | |
| 944 | ###### Standard arithmatic operations ###### |
| 945 | opsList += [Operation(ast.Add, '$DEST = $ARG1 + $ARG2', (LIB_STD,), |
| 946 | REAL_NUM, [REAL_NUM, REAL_NUM] )] |
| 947 | opsList += [Operation(ast.Sub, '$DEST = $ARG1 - $ARG2', (LIB_STD,), |
| 948 | ALL_INT+DECIMAL, [ALL_INT+DECIMAL, ALL_INT+DECIMAL])] |
| 949 | opsList += [Operation(ast.Mult ,'$DEST = $ARG1 * $ARG2', (LIB_STD,), |
| 950 | REAL_NUM, [REAL_NUM, REAL_NUM])] |
| 951 | |
| 952 | # Division in NumPy (Py3+) typically returns float64 for integers. |
| 953 | # * In NE2 division tried to out-smart the compiler with a ternary |
| 954 | # operation but it's easier to let the compiler determine when a |
| 955 | # INFINITY or NAN result is generated. |
| 956 | opsList +=[Operation(ast.Div, '$DEST = (npy_float64)$ARG1 / (npy_float64)$ARG2', |
| 957 | (LIB_STD,), ['d']*len(BOOL+ALL_INT), [BOOL+ALL_INT, BOOL+ALL_INT])] |
| 958 | opsList +=[Operation(ast.Div, '$DEST = $ARG1 / $ARG2', (LIB_STD,), |
| 959 | DECIMAL, [DECIMAL, DECIMAL])] |
| 960 | # Floor division |
| 961 | # Now C++ integer division is truncation and Python is floor, so |
| 962 | # probably this does need to be floordiv instead... |
| 963 | opsList += [Operation('floordiv', ''' |
| 964 | if($ARG2) { |
| 965 | $DEST = $ARG1 / $ARG2; |
| 966 | $DEST = $DEST > 0 ? $DEST : $DEST - 1; |
| 967 | } else { |
| 968 | $DEST = 0; |
| 969 | }''', (LIB_STD,), ALL_INT, [ALL_INT, ALL_INT], aliases=ast.FloorDiv)] |
| 970 | opsList += [Operation('floordiv', '$DEST = $ARG2 ? ($DTYPE0)floor($ARG1 / $ARG2) : 0', |
| 971 | (LIB_STD,), DECIMAL, [DECIMAL, DECIMAL], aliases=ast.FloorDiv)] |
| 972 | |
| 973 | |
| 974 | ###### Mathematical functions ###### |
| 975 | # NumPy has `power`, which overflows for integers, and `float_power`, which |
| 976 | # casts to np.float64 |
| 977 | opsList += [Operation('float_power', '$DEST = pow((npy_float64)$ARG1, (npy_float64)$ARG2)', (LIB_STD,), |
| 978 | [np.dtype('float64').char] * 8, [ALL_INT, ALL_INT])] |
| 979 | # We can't autotest as NumPy generates ValueErrors for negative exponents on |
| 980 | # integer powers |
| 981 | opsList += [Operation('power', 'nr_int_pow(task_size, ($DTYPE1 *)x1, sb1, ($DTYPE2 *)x2, sb2, ($DTYPE0 *)dest)', (LIB_STD,), |
| 982 | ALL_INT, [ALL_INT, ALL_INT], aliases=[ast.Pow, 'pow'], autotest=False)] |
| 983 | opsList += [Operation('power', '$DEST = pow($ARG1, $ARG2)', (LIB_STD,), |
| 984 | DECIMAL, [DECIMAL, DECIMAL], aliases=[ast.Pow, 'pow'])] |
| 985 | |
| 986 | # C will seg-fault if you call modulo with ARG2 == 0 on integers, so it |
| 987 | # needs a guard. |