From 1d2e1c7518c325a825725bff3f2e5f66f41f8641 Mon Sep 17 00:00:00 2001 From: kevstone Date: Thu, 1 Feb 2024 18:05:35 +0000 Subject: [PATCH] Fixed issue with incorrect prefix/postfix conversion --- src/clang_convert/ast_object/ast_parser.py | 24 +++++++++++++------ .../code_object/for_statement.py | 2 ++ src/clang_convert/code_object/if_statement.py | 4 +++- src/clang_convert/code_object/init_list.py | 2 ++ .../code_object/unary_operation.py | 19 +++++++++++++-- .../unary_operation_converter.py | 3 ++- 6 files changed, 43 insertions(+), 11 deletions(-) diff --git a/src/clang_convert/ast_object/ast_parser.py b/src/clang_convert/ast_object/ast_parser.py index c8a2cdfea..7420456bc 100755 --- a/src/clang_convert/ast_object/ast_parser.py +++ b/src/clang_convert/ast_object/ast_parser.py @@ -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): diff --git a/src/clang_convert/code_object/for_statement.py b/src/clang_convert/code_object/for_statement.py index b22a4a227..8c655d80a 100755 --- a/src/clang_convert/code_object/for_statement.py +++ b/src/clang_convert/code_object/for_statement.py @@ -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})"] diff --git a/src/clang_convert/code_object/if_statement.py b/src/clang_convert/code_object/if_statement.py index ec7bde504..8577c4781 100755 --- a/src/clang_convert/code_object/if_statement.py +++ b/src/clang_convert/code_object/if_statement.py @@ -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()) diff --git a/src/clang_convert/code_object/init_list.py b/src/clang_convert/code_object/init_list.py index 50a1c0ec4..490c7d098 100755 --- a/src/clang_convert/code_object/init_list.py +++ b/src/clang_convert/code_object/init_list.py @@ -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 diff --git a/src/clang_convert/code_object/unary_operation.py b/src/clang_convert/code_object/unary_operation.py index ab99a0a44..80f095ec5 100755 --- a/src/clang_convert/code_object/unary_operation.py +++ b/src/clang_convert/code_object/unary_operation.py @@ -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 \ No newline at end of file diff --git a/src/clang_convert/code_object_converter/unary_operation_converter.py b/src/clang_convert/code_object_converter/unary_operation_converter.py index b9c5cae27..ce1dc19da 100755 --- a/src/clang_convert/code_object_converter/unary_operation_converter.py +++ b/src/clang_convert/code_object_converter/unary_operation_converter.py @@ -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)