Fixed func pointer parse issue. Added Value decl ref and converter.

This commit is contained in:
kevstone 2024-01-23 10:09:39 +00:00
parent ab92b6114c
commit 58f88b4b0e
8 changed files with 114 additions and 51 deletions

View File

@ -2,25 +2,26 @@
import utils.debug as debug
import clang.cindex
import ast_object.ast_utils as ast_utils
import code_object.code_objects as code_objects
import code_object.variable_declaration as variable_declaration
import code_object.init_list as init_list
import code_object.declaration_specifier as declaration_specifier
import code_object.paren_expression as paren_expression
import code_object.unary_expression as unary_expression
import code_object.unary_operation as unary_operation
import code_object.array_access as array_access
import code_object.binary_operation as binary_operation
import code_object.struct_member_access as struct_member_access
import code_object.code_objects as code_objects
import code_object.compound_statement as compound_statement
import code_object.conditional_operation as conditional_operation
import code_object.declaration_specifier as declaration_specifier
import code_object.for_statement as for_statement
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
import code_object.conditional_operation as conditional_operation
import code_object.compound_statement as compound_statement
import code_object.init_list as init_list
import code_object.macro_definition as macro_definition
import code_object.macro_instantation as macro_instantation
import code_object.return_statement as return_statement
import code_object.literal as literal
import code_object.paren_expression as paren_expression
import code_object.return_statement as return_statement
import code_object.struct_member_access as struct_member_access
import code_object.unary_expression as unary_expression
import code_object.unary_operation as unary_operation
import code_object.value_declaration_reference as value_declaration_reference
import code_object.variable_declaration as variable_declaration
# Parse AstCode and create code interface objects: classes that implement the CodeInterface
#
@ -449,7 +450,7 @@ class AstParser:
return self.parse_BINARY_OPERATOR(node)
def parse_DECL_REF_EXPR(self, node):
return literal.Literal(node.spelling)
return value_declaration_reference.ValueDeclarationReference(node.spelling)
# This is simplified for now, need to come back to...
def parse_MEMBER_REF_EXPR(self, node):

View File

@ -1,4 +1,5 @@
import code_object.funcsig as funcsig
import code_object.arg as arg
# Represent a function pointer using a function signature - it is basically the same, except the as_string()
# function produces the correct string...
@ -17,4 +18,4 @@ class FuncSigPointer(funcsig.FuncSig):
super().__init__(return_type, name, args)
def as_lines(self):
return [f"typedef {self._func_arg.decl_spec.as_string()} (*{self._func_arg.name})({', '.join([a.as_string() for a in self.args if a])});"]
return [f"typedef {self._func_arg.decl_spec.as_string()} (*{self._func_arg.name})({', '.join([a.as_string() for a in self.args if a != arg.Arg.NONE])});"]

View File

@ -0,0 +1,17 @@
import utils.debug as debug
import code_object.code_interface as code_interface
# Represents an expression that refers to some value declaration, such as a function,
# variable, or enumerator.
#
# Models the LibClang DECL_REF_EXPR
class ValueDeclarationReference(code_interface.CodeInterface):
def __init__(self, value) -> None:
self._value = value
@property
def value(self):
return self._value
def as_lines(self):
return [f"{self._value}"]

View File

@ -27,7 +27,7 @@ class ArgConverter(code_interface_converter.CodeInterfaceConverter):
if match_type != DeclSpecMatchType.FULL:
conversion_data.add_type_mapping(carg.decl_spec, cpp_decl_spec)
debug.line("create_cpp_code_object", f"Arg conversion type mapping: carg.decl_spec=[{debug.as_debug_string(carg.decl_spec)}] cpp_decl_spec=[{debug.as_debug_string(cpp_decl_spec)}]")
cpp_name = standard_transforms.transform_variable_name(carg.name)
cpp_is_func_arg = carg.is_func_arg

View File

@ -27,6 +27,7 @@ import code_object.struct_arg as struct_arg
import code_object.struct_member_access as struct_member_access
import code_object.unary_expression as unary_expression
import code_object.unary_operation as unary_operation
import code_object.value_declaration_reference as value_declaration_reference
import code_object.variable_declaration as variable_declaration
import code_object.virtual_member_function as virtual_member_function
@ -58,6 +59,7 @@ import code_object_converter.struct_arg_converter as struct_arg_converter
import code_object_converter.struct_member_access_converter as struct_member_access_converter
import code_object_converter.unary_expression_converter as unary_expression_converter
import code_object_converter.unary_operation_converter as unary_operation_converter
import code_object_converter.value_declaration_reference_converter as value_declaration_reference_converter
import code_object_converter.variable_declaration_converter as variable_declaration_converter
import code_object_converter.virtual_member_function_converter as virtual_member_function_converter
@ -67,36 +69,37 @@ from utils.standard_transforms import transform_variable_name
# Mapping from C code objects to their converters
CodeInterfaceConverterClasses = {
arr_access.ArrayAccess : array_access_converter.ArrayAccessConverter,
arg.Arg : arg_converter.ArgConverter,
binary_operation.BinaryOperation : binary_operation_converter.BinaryOperationConverter,
code_objects.CodeObjects : code_objects_converter.CodeObjectsConverter,
compound_statement.CompoundStatement : compound_statement_converter.CompoundStatementConverter,
conditional_operation.ConditionalOperation : conditional_operation_converter.ConditionalOperationConverter,
constructor_function.ConstructorFunction : constructor_function_converter.ConstructorFunctionConverter,
declaration_specifier.DeclSpec : declaration_specifier_converter.DeclSpecConverter,
destructor_function.DestructorFunction : destructor_function_converter.DestructorFunctionConverter,
for_statement.ForStatement : for_statement_converter.ForStatementConverter,
funcsig.FuncSig : funcsig_converter.FuncSigConverter,
funcsig_pointer.FuncSigPointer : funcsig_pointer_converter.FuncSigPointerConverter,
function_call.FunctionCall : function_call_converter.FunctionCallConverter,
function.Function : function_converter.FunctionConverter,
global_function.GlobalFunction : global_function_converter.GlobalFunctionConverter,
if_statement.IfStatement : if_statement_converter.IfStatementConverter,
init_list.InitList : init_list_converter.InitListConverter,
literal.Literal : literal_converter.LiteralConverter,
member_function.MemberFunction : member_function_converter.MemberFunctionConverter,
macro_definition.MacroDefinition : macro_definition_converter.MacroDefinitionConverter,
macro_instantation.MacroInstantation : macro_instantiation_converter.MacroInstantiationConverter,
operation.Operation : operation_converter.OperationConverter,
paren_expression.ParenExpression : paren_expression_converter.ParenExpressionConverter,
return_statement.ReturnStatement : return_statement_converter.ReturnStatementConverter,
struct_arg.StructArg : struct_arg_converter.StructArgConverter,
struct_member_access.StructMemberAccess : struct_member_access_converter.StructMemberAccessConverter,
unary_expression.UnaryExpression : unary_expression_converter.UnaryExpressionConverter,
unary_operation.UnaryOperation : unary_operation_converter.UnaryOperationConverter,
variable_declaration.VariableDeclaration : variable_declaration_converter.VariableDeclarationConverter,
virtual_member_function.VirtualMemberFunction : virtual_member_function_converter.VirtualMemberFunctionConverter,
arr_access.ArrayAccess : array_access_converter.ArrayAccessConverter,
arg.Arg : arg_converter.ArgConverter,
binary_operation.BinaryOperation : binary_operation_converter.BinaryOperationConverter,
code_objects.CodeObjects : code_objects_converter.CodeObjectsConverter,
compound_statement.CompoundStatement : compound_statement_converter.CompoundStatementConverter,
conditional_operation.ConditionalOperation : conditional_operation_converter.ConditionalOperationConverter,
constructor_function.ConstructorFunction : constructor_function_converter.ConstructorFunctionConverter,
declaration_specifier.DeclSpec : declaration_specifier_converter.DeclSpecConverter,
destructor_function.DestructorFunction : destructor_function_converter.DestructorFunctionConverter,
for_statement.ForStatement : for_statement_converter.ForStatementConverter,
funcsig.FuncSig : funcsig_converter.FuncSigConverter,
funcsig_pointer.FuncSigPointer : funcsig_pointer_converter.FuncSigPointerConverter,
function_call.FunctionCall : function_call_converter.FunctionCallConverter,
function.Function : function_converter.FunctionConverter,
global_function.GlobalFunction : global_function_converter.GlobalFunctionConverter,
if_statement.IfStatement : if_statement_converter.IfStatementConverter,
init_list.InitList : init_list_converter.InitListConverter,
literal.Literal : literal_converter.LiteralConverter,
member_function.MemberFunction : member_function_converter.MemberFunctionConverter,
macro_definition.MacroDefinition : macro_definition_converter.MacroDefinitionConverter,
macro_instantation.MacroInstantation : macro_instantiation_converter.MacroInstantiationConverter,
operation.Operation : operation_converter.OperationConverter,
paren_expression.ParenExpression : paren_expression_converter.ParenExpressionConverter,
return_statement.ReturnStatement : return_statement_converter.ReturnStatementConverter,
struct_arg.StructArg : struct_arg_converter.StructArgConverter,
struct_member_access.StructMemberAccess : struct_member_access_converter.StructMemberAccessConverter,
unary_expression.UnaryExpression : unary_expression_converter.UnaryExpressionConverter,
unary_operation.UnaryOperation : unary_operation_converter.UnaryOperationConverter,
value_declaration_reference.ValueDeclarationReference : value_declaration_reference_converter.ValueDeclarationReferenceConverter,
variable_declaration.VariableDeclaration : variable_declaration_converter.VariableDeclarationConverter,
virtual_member_function.VirtualMemberFunction : virtual_member_function_converter.VirtualMemberFunctionConverter,
}
def get_debug_string(code_obj):
@ -118,11 +121,6 @@ def convert_ccode_object(ccode_object, conversion_data):
converter = converter_class(ccode_object)
cpp_obj = converter.to_cpp_code_object(conversion_data)
if cpp_obj:
dbg_txt = f"{cpp_obj if type(cpp_obj) is str else cpp_obj.as_string()}"
else:
dbg_txt = "None"
debug.line("convert_ccode_object", f"[OUT][{type(cpp_obj).__name__}] {get_debug_string(cpp_obj)}")
return cpp_obj

View File

@ -22,6 +22,7 @@ class FuncSigPointerConverter(funcsig_converter.FuncSigConverter):
if not cppfuncsig_pointer:
cppfunc_arg = self.to_cpp_func_arg()
cpp_args = self.to_cpp_args()
cppfuncsig_pointer = funcsig_pointer.FuncSigPointer(cppfunc_arg.decl_spec,
cppfunc_arg.name,
cpp_args)

View File

@ -49,6 +49,10 @@ class ConversionData:
debug.line("add_type_mapping", f"Adding decl_spec: [{cdecl_spec.as_string()}] -> [{cppdecl_spec.as_string()}]")
def add_arg_mapping(self, carg, cpparg):
if not carg.name:
debug.line("add_arg_mapping", f"carg name is empty, not adding mapping!")
return
if carg in self.active_map.arg_mappings:
assert self.active_map.arg_mappings[carg] == cpparg, f"Updating an existing arg: [{carg.as_string()}] -> [{cpparg.as_string()}] Previous arg=[{self.active_map.arg_mappings[carg]}]"
else:
@ -133,7 +137,20 @@ class ConversionData:
return value
return None
def cpparg_for_carg_name(self, carg_name):
assert carg_name, f"carg_name can't be empty!"
for mapping in self.all_mappings():
for key, value in mapping.arg_mappings.items():
if key.name == carg_name:
return value
return None
def cppfunction_arg_for_carg(self, carg):
if not carg.name:
debug.line("cppfunction_arg_for_carg", f"carg has no name - can't look up a match")
return None
for mapping in self.all_mappings():
for key, value in mapping.function_arg_mappings.items():
if key.name == carg.name:

View File

@ -0,0 +1,28 @@
import utils.debug as debug
import code_object.value_declaration_reference as value_declaration_reference
import code_object_converter.code_interface_converter as code_interface_converter
import code_object_converter.conversion_funcs as conversion_funcs
class ValueDeclarationReferenceConverter(code_interface_converter.CodeInterfaceConverter):
def __init__(self, ccode_object) -> None:
super().__init__(ccode_object)
assert isinstance(ccode_object, value_declaration_reference.ValueDeclarationReference), f"Expected ValueDeclarationReference, got type=[{type(ccode_object)}]"
def create_cpp_code_object(self, conversion_data):
cdecl_ref_expr_value = self._ccode_object.as_string()
# 1. Check if it is a function name
cppfuncsig = conversion_data.cppfuncsig_for_cfuncname(cdecl_ref_expr_value)
if cppfuncsig:
return value_declaration_reference.ValueDeclarationReference(cppfuncsig.name)
# 2. Check if it is an arg
cpparg = conversion_data.cpparg_for_carg_name(cdecl_ref_expr_value)
if cpparg:
return value_declaration_reference.ValueDeclarationReference(cpparg.name)
# 3. Perform a default conversion
cdecl_ref_expr_value = conversion_funcs.convert_ccode_object(cdecl_ref_expr_value, conversion_data)
return value_declaration_reference.ValueDeclarationReference(cdecl_ref_expr_value)