mirror of https://github.com/ecmwf/eccodes.git
Fixed issue with incorrect prefix/postfix conversion
This commit is contained in:
parent
fa2bd6ec64
commit
1d2e1c7518
|
@ -496,19 +496,29 @@ class AstParser:
|
|||
def parse_UNARY_OPERATOR(self, node):
|
||||
children = list(node.get_children())
|
||||
assert len(children) == 1, f"Expected exactly one child for unary operator"
|
||||
right_operand = children[0]
|
||||
operand = children[0]
|
||||
|
||||
# Tokenize and find the operator
|
||||
tokens = [token.spelling for token in node.get_tokens()]
|
||||
right_tokens = [token.spelling for token in right_operand.get_tokens()]
|
||||
tokens_count = len(tokens)
|
||||
operand_tokens = [token.spelling for token in operand.get_tokens()]
|
||||
operand_tokens_count = len(operand_tokens)
|
||||
assert tokens_count == operand_tokens_count+1, f"Expected tokens_count [{tokens_count}] to be 1 more than operand_tokens_count [{operand_tokens_count}]"
|
||||
|
||||
# Find the operator by excluding operand tokens
|
||||
operator_tokens = [t for t in tokens if t not in right_tokens]
|
||||
# Find the operator by eliminating the operand tokens
|
||||
# Need to determine if it is prefix or postfix operator
|
||||
if tokens[:operand_tokens_count] == operand_tokens[:operand_tokens_count]:
|
||||
op_value = tokens[-1]
|
||||
op_position = "postfix"
|
||||
else:
|
||||
op_value = tokens[0]
|
||||
op_position = "prefix"
|
||||
|
||||
operator_str = "".join(t for t in operator_tokens)
|
||||
right_operand_cvalue = self.parse_ast_node(right_operand)
|
||||
debug.line("parse_UNARY_OPERATOR", f"op_position=[{op_position}] op_value=[{op_value}]")
|
||||
|
||||
operand_cvalue = self.parse_ast_node(operand)
|
||||
c_unary_op = unary_operation.UnaryOperation(op_value, operand_cvalue, op_position)
|
||||
|
||||
c_unary_op = unary_operation.UnaryOperation(operator_str, right_operand_cvalue)
|
||||
return c_unary_op
|
||||
|
||||
def parse_BINARY_OPERATOR(self, node):
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import utils.debug as debug
|
||||
import code_object.code_interface as code_interface
|
||||
import code_object.literal as literal
|
||||
from utils.string_funcs import strip_semicolon
|
||||
|
||||
# Represents a for loop in the form:
|
||||
#
|
||||
|
@ -65,6 +66,7 @@ class ForStatement(code_interface.CodeInterface):
|
|||
cond_string += ";"
|
||||
if self._iteration_expression:
|
||||
iter_string = self._iteration_expression.as_string()
|
||||
iter_string = strip_semicolon(iter_string)
|
||||
|
||||
lines = [f"for({init_string}{cond_string}{iter_string})"]
|
||||
|
||||
|
|
|
@ -39,9 +39,11 @@ class IfStatement(code_interface.CodeInterface):
|
|||
if_lines = []
|
||||
if_lines.extend(self._expression.as_lines())
|
||||
if_lines[0] = "if (" + if_lines[0]
|
||||
if_lines[-1] = strip_semicolon(if_lines[-1])
|
||||
if_lines[-1] += ")"
|
||||
|
||||
for i in range(len(if_lines)):
|
||||
if_lines[i] = if_lines[i].replace(";","")
|
||||
|
||||
action_lines = []
|
||||
action_lines.extend(self._action.as_lines())
|
||||
|
||||
|
|
|
@ -40,6 +40,8 @@ class InitList(code_interface.CodeInterface):
|
|||
else:
|
||||
line = f"{{{', '.join(e.as_string() for e in self._entries)}}}"
|
||||
|
||||
line = line.replace(";", "")
|
||||
|
||||
lines.append(line)
|
||||
|
||||
return lines
|
||||
|
|
|
@ -10,7 +10,7 @@ import code_object.operation as operation
|
|||
#
|
||||
# unary_op can be a string or an operation.Operation class
|
||||
class UnaryOperation(code_interface.CodeInterface):
|
||||
def __init__(self, unary_op, operand) -> None:
|
||||
def __init__(self, unary_op, operand, op_position="prefix") -> None:
|
||||
if isinstance(unary_op, str):
|
||||
self._unary_op = operation.Operation(unary_op)
|
||||
elif isinstance(unary_op, operation.Operation):
|
||||
|
@ -21,6 +21,11 @@ class UnaryOperation(code_interface.CodeInterface):
|
|||
self._operand = operand
|
||||
assert isinstance(self._operand, code_interface.CodeInterface), f"Operand must be a CodeInterface class"
|
||||
|
||||
op_position_values = ["prefix", "postfix"]
|
||||
self._op_position = op_position
|
||||
assert isinstance(self._op_position, str), f"op_position must be a str, not [{type(self._op_position).__name__}]"
|
||||
assert self._op_position in ["prefix", "postfix"], f"op_position must be on of {op_position_values}, not=[{self._op_position}]"
|
||||
|
||||
@property
|
||||
def unary_op(self):
|
||||
return self._unary_op
|
||||
|
@ -28,10 +33,20 @@ class UnaryOperation(code_interface.CodeInterface):
|
|||
@property
|
||||
def operand(self):
|
||||
return self._operand
|
||||
|
||||
@property
|
||||
def op_position(self):
|
||||
return self._op_position
|
||||
|
||||
def as_lines(self):
|
||||
lines = []
|
||||
lines.extend(self._operand.as_lines())
|
||||
lines[0] = self._unary_op.as_string() + lines[0]
|
||||
if self._op_position == "prefix":
|
||||
lines[0] = self._unary_op.as_string() + lines[0]
|
||||
else:
|
||||
lines[-1] = lines[-1] + self._unary_op.as_string()
|
||||
|
||||
if not lines[-1].endswith(";"):
|
||||
lines[-1] += ";"
|
||||
|
||||
return lines
|
|
@ -13,6 +13,7 @@ class UnaryOperationConverter(code_interface_converter.CodeInterfaceConverter):
|
|||
def create_cpp_code_object(self, conversion_pack):
|
||||
cpp_unary_op = conversion_funcs.convert_ccode_object(self._ccode_object.unary_op, conversion_pack)
|
||||
cpp_operand = conversion_funcs.convert_ccode_object(self._ccode_object.operand, conversion_pack)
|
||||
cpp_op_position = self._ccode_object.op_position
|
||||
|
||||
cpp_unary_operation = unary_operation.UnaryOperation(cpp_unary_op, cpp_operand)
|
||||
cpp_unary_operation = unary_operation.UnaryOperation(cpp_unary_op, cpp_operand, cpp_op_position)
|
||||
return conversion_pack.conversion_validation.validate_unary_operation(self._ccode_object, cpp_unary_operation)
|
||||
|
|
Loading…
Reference in New Issue