Added if() support

This commit is contained in:
kevstone 2024-01-11 09:56:44 +00:00
parent ef0a88b1dc
commit 6ae5c4db01
3 changed files with 86 additions and 3 deletions

View File

@ -45,6 +45,8 @@ class BinaryOperation(code_interface.CodeInterface):
lines.extend(right_lines[1:])
lines[-1] += ";"
# Determine whether to add a ;
if self._binary_op.is_assignment():
lines[-1] += ";"
return lines

View File

@ -0,0 +1,59 @@
import debug
import code_object.code_interface as code_interface
import code_object.code_lines as code_lines
# Represents an if statement in the form:
#
# if (expression) action else [...]
#
# [...] represents a child node, which could be another if, another action or None
#
# expression & action can be a string or a code_interface subclass (or None)
class IfStatement(code_interface.CodeInterface):
def __init__(self, expression, action) -> None:
if isinstance(expression, str):
self._expression = code_lines.CodeLines(expression)
else:
self._expression = expression
assert isinstance(self._expression, code_interface.CodeInterface), f"Expression must be a CodeInterface class (or a string)"
if isinstance(action, str):
self._action = code_lines.CodeLines(action)
else:
self._action = action
assert isinstance(self._action, code_interface.CodeInterface), f"Action must be a CodeInterface class (or a string)"
self._else = None
@property
def expression(self):
return self._expression
@property
def action(self):
return self._action
def add_else(self, else_statement):
if isinstance(else_statement, str):
self._else = code_lines.CodeLines(else_statement)
else:
self._else = else_statement
assert isinstance(self._else, code_interface.CodeInterface), f"Else statement must be a CodeInterface class (or a string)"
def as_lines(self):
if_lines = self._expression.as_lines()
if_lines[0] = "if (" + if_lines[0]
if_lines[-1] += ")"
action_lines = self._action.as_lines()
#action_lines[0] = "{" + action_lines[0]
#action_lines[-1] += "}"
if self._else:
else_lines = self._else.as_lines()
else_lines[0] = "else " + else_lines[0]
else:
else_lines = []
return if_lines + action_lines + else_lines

View File

@ -14,6 +14,7 @@ import code_object.unary_operation as unary_operation
import code_object.binary_operation as binary_operation
import code_object.struct_member_access as struct_member_access
import code_object.function_call as function_call
import code_object.if_statement as if_statement
# Convert a C node (AST) into lines of C++ code
#
@ -82,7 +83,7 @@ class CNodeConverter:
debug.line("convert_node_not_implemented", f"*** kind=[{node.kind}] not implemented ***")
cnode_utils.dump_node(node,5)
debug.line("convert_node_not_implemented", f"No convert routine implemented for kind=[{node.kind}]")
assert False, f"No convert routine implemented for kind=[{node.kind}]"
#assert False, f"No convert routine implemented for kind=[{node.kind}]"
return None
# =================================== Macros Convert functions [BEGIN] ===================================
@ -124,9 +125,13 @@ class CNodeConverter:
stmt_lines = code_lines.CodeLines()
stmt_lines.add_line("{")
for child in node.get_children():
stmt_lines.add_lines(self.convert_node(child))
stmt_lines.add_line("}")
return stmt_lines
# DECL_STMT is an "Adaptor class for mixing declarations with statements and expressions."
@ -161,13 +166,30 @@ class CNodeConverter:
return code_lines.CodeLines(return_lines)
def convert_IF_STMT(self, node):
debug.line("convert_IF_STMT", f"IF spelling=[{node.spelling}] type=[{node.type.spelling}] kind=[{node.kind}]")
cnode_utils.dump_node(node, 2)
children = list(node.get_children())
child_count = len(children)
assert child_count >= 2, f"Expected at least two children for if statement"
if_expression = self.convert_node(children[0])
if_action = self.convert_node(children[1])
if_stmt = if_statement.IfStatement(if_expression, if_action)
if child_count == 3:
else_statement = self.convert_node(children[2])
if_stmt.add_else(else_statement)
return if_stmt
convert_STMT_funcs = {
clang.cindex.CursorKind.COMPOUND_STMT: convert_COMPOUND_STMT,
clang.cindex.CursorKind.DECL_STMT: convert_DECL_STMT,
clang.cindex.CursorKind.CASE_STMT: convert_node_not_implemented,
clang.cindex.CursorKind.DEFAULT_STMT: convert_node_not_implemented,
clang.cindex.CursorKind.IF_STMT: convert_node_not_implemented,
clang.cindex.CursorKind.IF_STMT: convert_IF_STMT,
clang.cindex.CursorKind.SWITCH_STMT: convert_node_not_implemented,
clang.cindex.CursorKind.WHILE_STMT: convert_node_not_implemented,
clang.cindex.CursorKind.DO_STMT: convert_node_not_implemented,