Fixed issue with incorrect prefix/postfix conversion

This commit is contained in:
kevstone 2024-02-01 18:05:35 +00:00
parent fa2bd6ec64
commit 1d2e1c7518
6 changed files with 43 additions and 11 deletions

View File

@ -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):

View File

@ -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})"]

View File

@ -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())

View File

@ -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

View File

@ -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

View File

@ -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)