mirror of https://github.com/ecmwf/eccodes.git
Added compound statement and parser
This commit is contained in:
parent
6b8a687d48
commit
75dac9fab0
|
@ -37,10 +37,12 @@ class BinaryOperation(code_interface.CodeInterface):
|
|||
return self._right_operand
|
||||
|
||||
def as_lines(self):
|
||||
lines = self._left_operand.as_lines()
|
||||
lines = []
|
||||
lines.extend(self._left_operand.as_lines())
|
||||
lines[-1] += " " + self._binary_op.as_string()
|
||||
|
||||
right_lines = self._right_operand.as_lines()
|
||||
right_lines = []
|
||||
right_lines.extend(self._right_operand.as_lines())
|
||||
lines[-1] += " " + right_lines[0]
|
||||
|
||||
lines.extend(right_lines[1:])
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import code_object.code_interface as code_interface
|
||||
import code_object.code_objects as code_objects
|
||||
|
||||
# Represents a group of code objects (CodeInterface classes) that make up a coherent collection of code (e.g. a function body)
|
||||
# Provides convenient ways of accessing the underlyting code
|
||||
class CodeObjects:
|
||||
# Provides convenient ways of accessing the underlying code
|
||||
class CodeObjects(code_interface.CodeInterface):
|
||||
def __init__(self) -> None:
|
||||
self._code_objects = []
|
||||
|
||||
|
@ -14,6 +15,11 @@ class CodeObjects:
|
|||
assert isinstance(item, code_interface.CodeInterface), f"Item type=[{item.__class__}] is not a CodeInterface"
|
||||
self._code_objects.append(item)
|
||||
|
||||
def add_code_object_collection(self, collection):
|
||||
assert isinstance(collection, code_objects.CodeObjects), f"Collection type=[{collection.__class__}] is not a CodeObjects instance"
|
||||
for entry in collection.code_objects:
|
||||
self.add_code_object(entry)
|
||||
|
||||
# Get the textual representation as an array of strings
|
||||
def as_lines(self):
|
||||
lines = []
|
||||
|
@ -22,9 +28,4 @@ class CodeObjects:
|
|||
lines.extend(entry.as_lines())
|
||||
|
||||
return lines
|
||||
|
||||
# Get the textual representation as a single string (with line breaks)
|
||||
def as_string(self):
|
||||
lines = self.as_lines()
|
||||
return "\n".join(lines)
|
||||
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
import code_object.code_objects as code_objects
|
||||
|
||||
# Represents a block of code enclosed in parentheses
|
||||
#
|
||||
# Stored as code objects (CodeInterface classes)
|
||||
class CompoundStatement(code_objects.CodeObjects):
|
||||
|
||||
# Get the textual representation as an array of strings
|
||||
def as_lines(self):
|
||||
lines = ["{"]
|
||||
|
||||
for entry in self._code_objects:
|
||||
lines.extend(entry.as_lines())
|
||||
|
||||
lines.append("}")
|
||||
|
||||
return lines
|
|
@ -42,16 +42,17 @@ class IfStatement(code_interface.CodeInterface):
|
|||
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 = []
|
||||
if_lines.extend(self._expression.as_lines())
|
||||
if_lines[0] = "if (" + if_lines[0]
|
||||
if_lines[-1] += ")"
|
||||
|
||||
action_lines = self._action.as_lines()
|
||||
action_lines = []
|
||||
action_lines.extend(self._action.as_lines())
|
||||
|
||||
else_lines = []
|
||||
if self._else:
|
||||
else_lines = self._else.as_lines()
|
||||
else_lines.extend(self._else.as_lines())
|
||||
else_lines[0] = "else " + else_lines[0]
|
||||
else:
|
||||
else_lines = []
|
||||
|
||||
return if_lines + action_lines + else_lines
|
|
@ -30,7 +30,8 @@ class UnaryOperation(code_interface.CodeInterface):
|
|||
return self._operand
|
||||
|
||||
def as_lines(self):
|
||||
lines = self._operand.as_lines()
|
||||
lines = []
|
||||
lines.extend(self._operand.as_lines())
|
||||
lines[0] = self._unary_op.as_string() + lines[0]
|
||||
|
||||
return lines
|
|
@ -24,5 +24,5 @@ class CodeInterfaceConverter:
|
|||
# Actual implementation of to_cpp_code_object()
|
||||
# It must be overridden - this version just returns the passed in ccode_object!
|
||||
def create_cpp_code_object(self, conversion_data):
|
||||
debug.line("to_cpp_code_object_internal", f"Base version - just returning the C code object")
|
||||
debug.line("create_cpp_code_object", f"Base version - just returning the C code object")
|
||||
return self._ccode_object
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
import code_object_converter.code_interface_converter as code_interface_converter
|
||||
import code_object_converter.conversion_funcs as conversion_funcs
|
||||
import code_object.compound_statement as compound_statement
|
||||
import utils.debug as debug
|
||||
|
||||
# Base class for converting a C code object to C++
|
||||
#
|
||||
# Call convert_ccode_object() for generic convert behaviour
|
||||
class CompoundStatementConverter(code_interface_converter.CodeInterfaceConverter):
|
||||
|
||||
def create_cpp_code_object(self, conversion_data):
|
||||
debug.line("create_cpp_code_object", f"Creating C++ compound statement")
|
||||
cpp_compound_statement = compound_statement.CompoundStatement()
|
||||
converted_objects = conversion_funcs.convert_ccode_object_collection(self._ccode_object, conversion_data)
|
||||
cpp_compound_statement.add_code_object_collection(converted_objects)
|
||||
return cpp_compound_statement
|
|
@ -1,17 +1,20 @@
|
|||
import code_object.arg as arg
|
||||
import code_object.compound_statement as compound_statement
|
||||
import code_object.code_objects as code_objects
|
||||
import code_object.funcsig as funcsig
|
||||
|
||||
import code_object_converter.arg_converter as arg_converter
|
||||
import code_object_converter.code_interface_converter as code_interface_converter
|
||||
import code_object_converter.funcsig_converter as funcsig_converter
|
||||
import code_object_converter.compound_statement_converter as compound_statement_converter
|
||||
|
||||
import utils.debug as debug
|
||||
|
||||
# Mapping from C code objects to their converters
|
||||
CodeInterfaceConverterClasses = {
|
||||
arg.Arg: arg_converter.ArgConverter,
|
||||
funcsig.FuncSig: funcsig_converter.FuncSigConverter,
|
||||
arg.Arg : arg_converter.ArgConverter,
|
||||
compound_statement.CompoundStatement : compound_statement_converter.CompoundStatementConverter,
|
||||
funcsig.FuncSig : funcsig_converter.FuncSigConverter,
|
||||
}
|
||||
|
||||
# Convert a single C code_object into a C++ code_object
|
||||
|
@ -27,6 +30,7 @@ def convert_ccode_object(ccode_object, conversion_data):
|
|||
def convert_ccode_object_collection(ccode_objects, conversion_data):
|
||||
cpp_code_objects = code_objects.CodeObjects()
|
||||
for cobj in ccode_objects.code_objects:
|
||||
debug.line("convert_ccode_object_collection",f"cobj as string=[{cobj.as_string()}]")
|
||||
cpp_obj = convert_ccode_object(cobj, conversion_data)
|
||||
cpp_code_objects.add_code_object(cpp_obj)
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ import code_object.if_statement as if_statement
|
|||
import code_object.for_statement as for_statement
|
||||
import code_object.array_access as array_access
|
||||
import code_object.conditional_operation as conditional_operation
|
||||
import code_object.compound_statement as compound_statement
|
||||
|
||||
# Parse C AST nodes and create code interface objects (classes that implement the CodeInterface)
|
||||
#
|
||||
|
@ -158,14 +159,10 @@ class DefaultCASTParser:
|
|||
|
||||
debug.line("parse_COMPOUND_STMT", f">>> spelling=[{node.spelling}] kind=[{node.kind}]")
|
||||
|
||||
stmt_lines = code_lines.CodeLines()
|
||||
|
||||
stmt_lines.add_line("{")
|
||||
stmt_lines = compound_statement.CompoundStatement()
|
||||
|
||||
for child in node.get_children():
|
||||
stmt_lines.add_lines(self.parse_ast_node(child))
|
||||
|
||||
stmt_lines.add_line("}")
|
||||
stmt_lines.add_code_object(self.parse_ast_node(child))
|
||||
|
||||
return stmt_lines
|
||||
|
||||
|
|
Loading…
Reference in New Issue