From dfd287999e2179e83683893f07369ad86ca34b47 Mon Sep 17 00:00:00 2001 From: kevstone Date: Fri, 12 Jan 2024 08:13:26 +0000 Subject: [PATCH] Added if() and array subscript support --- src/clang_convert/code_object/array_access.py | 31 +++++++++++ src/clang_convert/code_object/if_statement.py | 2 - src/clang_convert/default/cnode_converter.py | 54 +++++++++++++++---- src/grib_accessor_class_proj_string.cc | 1 + 4 files changed, 75 insertions(+), 13 deletions(-) create mode 100755 src/clang_convert/code_object/array_access.py diff --git a/src/clang_convert/code_object/array_access.py b/src/clang_convert/code_object/array_access.py new file mode 100755 index 000000000..16c455963 --- /dev/null +++ b/src/clang_convert/code_object/array_access.py @@ -0,0 +1,31 @@ + +import code_object.code_interface as code_interface +import code_object.code_lines as code_lines + +# Represents accessing an element in an array in the form: name[index] +# +# name and index can be a string or a code_interface subclass +class ArrayAccess(code_interface.CodeInterface): + def __init__(self, name, index) -> None: + if isinstance(name, str): + self._name = code_lines.CodeLines(name) + else: + self._name = name + assert isinstance(self._name, code_interface.CodeInterface), f"Name must be a CodeInterface class (or a string)" + + if isinstance(index, str): + self._index = code_lines.CodeLines(index) + else: + self._index = index + assert isinstance(self._index, code_interface.CodeInterface), f"Index must be a CodeInterface class (or a string)" + + @property + def name(self): + return self._name + + @property + def index(self): + return self._index + + def as_lines(self): + return [f"{self._name.as_string()}[{self._index.as_string()}]"] diff --git a/src/clang_convert/code_object/if_statement.py b/src/clang_convert/code_object/if_statement.py index aab89d922..515f85a91 100755 --- a/src/clang_convert/code_object/if_statement.py +++ b/src/clang_convert/code_object/if_statement.py @@ -47,8 +47,6 @@ class IfStatement(code_interface.CodeInterface): 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() diff --git a/src/clang_convert/default/cnode_converter.py b/src/clang_convert/default/cnode_converter.py index 8eb2bd13f..b00e02d9a 100755 --- a/src/clang_convert/default/cnode_converter.py +++ b/src/clang_convert/default/cnode_converter.py @@ -16,6 +16,7 @@ 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 import code_object.for_statement as for_statement +import code_object.array_access as array_access # Convert a C node (AST) into lines of C++ code # @@ -497,18 +498,34 @@ class CNodeConverter: return None def convert_CALL_EXPR(self, node): - cfunc_call = function_call.FunctionCall(node.spelling) + tokens = [token.spelling for token in node.get_tokens()] + debug.line("convert_CALL_EXPR", f"spelling=[{node.spelling}] type=[{node.type.spelling}] kind=[{node.kind}]") + debug.line("convert_CALL_EXPR", f"CALL_EXPR tokens=[{tokens}]") - for arg_node in node.get_arguments(): - arg_entry = self.convert_node(arg_node) - debug.line("convert_CALL_EXPR", f"arg_node spelling=[{arg_node.spelling}] type=[{arg_node.type.spelling}] kind=[{arg_node.kind}]") - if arg_entry: - debug.line("convert_CALL_EXPR", f"arg_node arg_entry=[{arg_entry.as_string()}]") - cfunc_call.add_arg(arg_entry.as_string()) - else: - debug.line("convert_CALL_EXPR", f"arg_node arg_entry=[{arg_entry}] - IS THIS AN ERROR?") + if "(" in tokens: + debug.line("convert_CALL_EXPR", f"Found regular function call") + cfunc_call = function_call.FunctionCall(node.spelling) + + for arg_node in node.get_arguments(): + arg_entry = self.convert_node(arg_node) + debug.line("convert_CALL_EXPR", f"arg_node spelling=[{arg_node.spelling}] type=[{arg_node.type.spelling}] kind=[{arg_node.kind}]") + if arg_entry: + debug.line("convert_CALL_EXPR", f"arg_node arg_entry=[{arg_entry.as_string()}]") + cfunc_call.add_arg(arg_entry.as_string()) + else: + debug.line("convert_CALL_EXPR", f"arg_node arg_entry=[{arg_entry}] - IS THIS AN ERROR?") + + return cfunc_call + + # No "(" in the tokens, so this is not really a function call! + # It is probably a copy constructor, so we'll parse and return the (first) child node as whatever type it is... + debug.line("convert_CALL_EXPR", f"NOT a regular function call - parsing first child instead...") + children = node.get_children() + child = next(children, None) + assert child, f"Expected a child node while parsing a non-regular function call!" + + return self.convert_node(child) - return cfunc_call def convert_CSTYLE_CAST_EXPR(self, node): for child in node.get_children(): @@ -520,12 +537,27 @@ class CNodeConverter: return None + def convert_ARRAY_SUBSCRIPT_EXPR(self, node): + debug.line("convert_ARRAY_SUBSCRIPT_EXPR", f"IF spelling=[{node.spelling}] type=[{node.type.spelling}] kind=[{node.kind}]") + + # We expect two children: the variable name and the index + children = list(node.get_children()) + child_count = len(children) + assert child_count == 2, f"Expected exactly two children for array subscription" + + name = self.convert_node(children[0]) + index = self.convert_node(children[1]) + + arr_access = array_access.ArrayAccess(name, index) + + return arr_access + convert_EXPR_funcs = { clang.cindex.CursorKind.UNEXPOSED_EXPR: convert_UNEXPOSED_EXPR, clang.cindex.CursorKind.DECL_REF_EXPR: convert_DECL_REF_EXPR, clang.cindex.CursorKind.MEMBER_REF_EXPR: convert_MEMBER_REF_EXPR, clang.cindex.CursorKind.CALL_EXPR: convert_CALL_EXPR, - clang.cindex.CursorKind.ARRAY_SUBSCRIPT_EXPR: convert_node_not_implemented, + clang.cindex.CursorKind.ARRAY_SUBSCRIPT_EXPR: convert_ARRAY_SUBSCRIPT_EXPR, clang.cindex.CursorKind.CSTYLE_CAST_EXPR: convert_CSTYLE_CAST_EXPR, clang.cindex.CursorKind.COMPOUND_LITERAL_EXPR: convert_node_not_implemented, clang.cindex.CursorKind.INIT_LIST_EXPR: convert_INIT_LIST_EXPR, diff --git a/src/grib_accessor_class_proj_string.cc b/src/grib_accessor_class_proj_string.cc index 00b25c6a3..8a999f3e6 100644 --- a/src/grib_accessor_class_proj_string.cc +++ b/src/grib_accessor_class_proj_string.cc @@ -294,6 +294,7 @@ static proj_mapping proj_mappings[] = { #define ENDPOINT_SOURCE 0 #define ENDPOINT_TARGET 1 +int makeInt(){return 42;} static int unpack_string(grib_accessor* a, char* v, size_t* len) { grib_accessor_proj_string* self = (grib_accessor_proj_string*)a;