Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
:returns: the SIR Python code.
:rtype: str
:raises VisitorError: if there is no mapping from the PSyIR \
operator to SIR.
'''
binary_operators = {
BinaryOperation.Operator.ADD: '+',
BinaryOperation.Operator.SUB: '-',
BinaryOperation.Operator.MUL: '*',
BinaryOperation.Operator.DIV: '/',
BinaryOperation.Operator.POW: '**',
BinaryOperation.Operator.EQ: '==',
BinaryOperation.Operator.NE: '!=',
BinaryOperation.Operator.LE: '<=',
BinaryOperation.Operator.LT: '<',
BinaryOperation.Operator.GE: '>=',
BinaryOperation.Operator.GT: '>',
BinaryOperation.Operator.AND: '&&',
BinaryOperation.Operator.OR: '||'}
self._depth += 1
lhs = self._visit(node.children[0])
try:
oper = binary_operators[node.operator]
except KeyError:
raise VisitorError(
"Method binaryoperation_node in class SIRWriter, unsupported "
"operator '{0}' found.".format(str(node.operator)))
rhs = self._visit(node.children[1])
('log', UnaryOperation.Operator.LOG),
('log10', UnaryOperation.Operator.LOG10),
('sin', UnaryOperation.Operator.SIN),
('asin', UnaryOperation.Operator.ASIN),
('cos', UnaryOperation.Operator.COS),
('acos', UnaryOperation.Operator.ACOS),
('tan', UnaryOperation.Operator.TAN),
('atan', UnaryOperation.Operator.ATAN),
('sqrt', UnaryOperation.Operator.SQRT),
('real', UnaryOperation.Operator.REAL),
('int', UnaryOperation.Operator.INT)])
binary_operators = OrderedDict([
('+', BinaryOperation.Operator.ADD),
('-', BinaryOperation.Operator.SUB),
('*', BinaryOperation.Operator.MUL),
('/', BinaryOperation.Operator.DIV),
('**', BinaryOperation.Operator.POW),
('==', BinaryOperation.Operator.EQ),
('.eq.', BinaryOperation.Operator.EQ),
('/=', BinaryOperation.Operator.NE),
('.ne.', BinaryOperation.Operator.NE),
('<=', BinaryOperation.Operator.LE),
('.le.', BinaryOperation.Operator.LE),
('<', BinaryOperation.Operator.LT),
('.lt.', BinaryOperation.Operator.LT),
('>=', BinaryOperation.Operator.GE),
('.ge.', BinaryOperation.Operator.GE),
('>', BinaryOperation.Operator.GT),
('.gt.', BinaryOperation.Operator.GT),
('.and.', BinaryOperation.Operator.AND),
('.or.', BinaryOperation.Operator.OR),
:param int index: the array index to check.
:returns: True if the array index is a range with its start \
value being LBOUND(array,index) and False otherwise.
:rtype: bool
'''
self._validate_index(index)
array_dimension = self.children[index]
if not isinstance(array_dimension, Range):
return False
lower = array_dimension.children[0]
if not (isinstance(lower, BinaryOperation) and
lower.operator == BinaryOperation.Operator.LBOUND):
return False
if not (isinstance(lower.children[0], Reference) and
lower.children[0].name == self.name):
return False
if not (isinstance(lower.children[1], Literal) and
lower.children[1].datatype.intrinsic ==
ScalarType.Intrinsic.INTEGER
and lower.children[1].value == str(index+1)):
return False
return True
(BinaryOperation, BinaryOperation, Literal)
:raises TransformationError: if the shape of the array's symbol is \
not supported.
'''
my_dim = array.symbol.shape[index]
if isinstance(my_dim, int):
lower_bound = Literal("1", INTEGER_TYPE)
upper_bound = Literal(str(my_dim), INTEGER_TYPE)
elif isinstance(my_dim, DataSymbol):
lower_bound = Literal("1", INTEGER_TYPE)
upper_bound = Reference(my_dim)
elif my_dim in [ArrayType.Extent.DEFERRED, ArrayType.Extent.ATTRIBUTE]:
lower_bound = BinaryOperation.create(
BinaryOperation.Operator.LBOUND, Reference(array.symbol),
Literal(str(index), INTEGER_TYPE))
upper_bound = BinaryOperation.create(
BinaryOperation.Operator.UBOUND, Reference(array.symbol),
Literal(str(index), INTEGER_TYPE))
else:
# Added import here to avoid circular dependencies.
from psyclone.psyir.transformations import TransformationError
raise TransformationError(
"Unsupported index type '{0}' found for dimension {1} of array "
"'{2}'.".format(type(my_dim).__name__, index+1, array.name))
step = Literal("1", INTEGER_TYPE)
return (lower_bound, upper_bound, step)
('ceiling', UnaryOperation.Operator.CEIL),
('exp', UnaryOperation.Operator.EXP),
('log', UnaryOperation.Operator.LOG),
('log10', UnaryOperation.Operator.LOG10),
('sin', UnaryOperation.Operator.SIN),
('asin', UnaryOperation.Operator.ASIN),
('cos', UnaryOperation.Operator.COS),
('acos', UnaryOperation.Operator.ACOS),
('tan', UnaryOperation.Operator.TAN),
('atan', UnaryOperation.Operator.ATAN),
('sqrt', UnaryOperation.Operator.SQRT),
('real', UnaryOperation.Operator.REAL),
('int', UnaryOperation.Operator.INT)])
binary_operators = OrderedDict([
('+', BinaryOperation.Operator.ADD),
('-', BinaryOperation.Operator.SUB),
('*', BinaryOperation.Operator.MUL),
('/', BinaryOperation.Operator.DIV),
('**', BinaryOperation.Operator.POW),
('==', BinaryOperation.Operator.EQ),
('.eq.', BinaryOperation.Operator.EQ),
('/=', BinaryOperation.Operator.NE),
('.ne.', BinaryOperation.Operator.NE),
('<=', BinaryOperation.Operator.LE),
('.le.', BinaryOperation.Operator.LE),
('<', BinaryOperation.Operator.LT),
('.lt.', BinaryOperation.Operator.LT),
('>=', BinaryOperation.Operator.GE),
('.ge.', BinaryOperation.Operator.GE),
('>', BinaryOperation.Operator.GT),
('.gt.', BinaryOperation.Operator.GT),
def __init__(self):
super(NemoSignTrans, self).__init__()
self._operator_name = "SIGN"
self._classes = (BinaryOperation,)
self._operators = (BinaryOperation.Operator.SIGN,)
:param my_range: the Range node to check.
:type my_range: :py:class:`psyclone.psyir.node.Range`
'''
array = my_range.parent
# The array index of this range is determined by its position in
# the array list (+1 as the index starts from 0 but Fortran
# dimensions start from 1).
dim = array.children.index(my_range) + 1
# Check lower bound
is_lower = _is_bound_full_extent(
array, dim, BinaryOperation.Operator.LBOUND)
# Check upper bound
is_upper = _is_bound_full_extent(
array, dim, BinaryOperation.Operator.UBOUND)
# Check step (index 2 is the step index for the range function)
is_step = _is_array_range_literal(array, dim, 2, 1)
return is_lower and is_upper and is_step
:param int index: the array index to check.
:returns: True if the array index is a range with its stop \
value being UBOUND(array,index) and False otherwise.
:rtype: bool
'''
self._validate_index(index)
array_dimension = self.children[index]
if not isinstance(array_dimension, Range):
return False
upper = array_dimension.children[1]
if not (isinstance(upper, BinaryOperation) and
upper.operator == BinaryOperation.Operator.UBOUND):
return False
if not (isinstance(upper.children[0], Reference) and
upper.children[0].name == self.name):
return False
if not (isinstance(upper.children[1], Literal) and
upper.children[1].datatype.intrinsic ==
ScalarType.Intrinsic.INTEGER
and upper.children[1].value == str(index+1)):
return False
return True