mirror of https://github.com/ecmwf/eccodes.git
Added if() support
This commit is contained in:
parent
ef0a88b1dc
commit
6ae5c4db01
|
@ -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
|
|
@ -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
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue