def _parse_container_structure_fields( cursor: Cursor) -> List[ast.VariableDeclaration]: fields: List[ast.VariableDeclaration] = [] for f in cursor.type.get_fields(): typ: ast.Node = type_to_ehlit(f.type) assert isinstance(typ, ast.Symbol) fields.append( ast.VariableDeclaration(typ, ast.Identifier(0, f.spelling), None)) return fields
def type_FUNCTIONPROTO(typ: Type) -> ast.Node: args: List[ast.VariableDeclaration] = [] for a in typ.argument_types(): res: ast.Node = type_to_ehlit(a) assert isinstance(res, ast.Symbol) args.append(ast.VariableDeclaration(res, None)) ret_type: ast.Node = type_to_ehlit(typ.get_result()) assert isinstance(ret_type, ast.Symbol) return ast.TemplatedIdentifier(0, '@func', [ast.FunctionType(ret_type, args)])
def __init__(self, sym: ast.Identifier, arg_cnt: int) -> None: super().__init__( 0, ast.Qualifier.NONE, ast.TemplatedIdentifier(0, '@func', [ ast.FunctionType( CAnyType.make_symbol(), [ast.VariableDeclaration(CAnyType.make_symbol(), None)] * arg_cnt) ]), sym) self.declaration_type = ast.DeclarationType.C
def parse_FUNCTION_DECL(cursor: Cursor) -> ast.Node: args: List[ast.VariableDeclaration] = [] for c in cursor.get_children(): if c.kind == CursorKind.PARM_DECL: typ = type_to_ehlit(c.type) assert isinstance(typ, ast.Symbol) args.append( ast.VariableDeclaration(typ, ast.Identifier(0, c.spelling))) ret_type = type_to_ehlit(cursor.type.get_result()) assert isinstance(ret_type, ast.Symbol) return ast.Function( 0, ast.Qualifier.NONE, ast.TemplatedIdentifier(0, '@func', [ ast.FunctionType(ret_type, args, cursor.type.is_function_variadic()) ]), ast.Identifier(0, cursor.spelling))
def parse_VAR_DECL(cursor: Cursor) -> ast.Node: assign: Optional[Cursor] = cursor.get_definition() value: Optional[ast.Expression] = None if assign is not None: got_eq: bool = False for t in assign.get_tokens(): if value is not None: logging.debug( 'c_compat: error: unhandled token while getting value: {}'. format(t.spelling)) elif got_eq: value = value_to_ehlit(t.spelling, cursor.type) elif t.spelling == '=': got_eq = True if got_eq is False: logging.debug('c_compat: error: unhandled assignment') typ: ast.Node = type_to_ehlit(cursor.type) assert isinstance(typ, ast.Symbol) return ast.VariableDeclaration( typ, ast.Identifier(0, cursor.spelling), ast.Assignment(value) if value is not None else None)
def parse_MACRO_DEFINITION(cursor: Cursor) -> Optional[ast.Node]: tokens: List[Token] = list(cursor.get_tokens()) if tokens[0].spelling in builtin_defines: return None sym: ast.Identifier = ast.Identifier(0, tokens[0].spelling) # Simple define if len(tokens) == 1: return CDefine(sym) # Function macro if tokens[1].spelling == '(': i = 2 arg_cnt = 0 while i < len(tokens): if tokens[i].kind != TokenKind.IDENTIFIER or i + 1 >= len(tokens): break arg_cnt += 1 if tokens[i + 1].spelling == ')': if i + 2 >= len(tokens) and ',' not in [ t.spelling for t in tokens ]: break return CMacroFunction(sym, arg_cnt) elif tokens[i + 1].spelling != ',': break i += 2 # Constant macro next_relevant_token = 2 if tokens[1].spelling == '(' else 1 if tokens[next_relevant_token].kind == TokenKind.LITERAL: return ast.VariableDeclaration(_macro_var_type(tokens), sym) # Alias macro alias: Optional[ast.Symbol] = _macro_alias_value(tokens) if alias is not None: return ast.Alias(alias, ast.Identifier(0, tokens[0].spelling)) return None
def visit_function_type(self, node: ParseTreeNode, children: Tuple[StrMatch, ast.Symbol, Tuple[ast.Symbol, ...]] ) -> ast.TemplatedIdentifier: args: List[ast.VariableDeclaration] = [] variadic: bool = False variadic_type: Optional[ast.Symbol] = ast.CompoundIdentifier([ast.Identifier(0, '@any')]) if len(children) > 2: i = 0 while i < len(children[2]): arg = children[2][i] if arg == '...': variadic = True elif len(children[2]) > i + 1 and children[2][i + 1] == '...': assert isinstance(arg, ast.Symbol) variadic_type = arg variadic = True else: args.append(ast.VariableDeclaration(arg, None)) i += 2 return ast.TemplatedIdentifier( node.position, '@func', [ast.FunctionType(children[1], args, variadic, variadic_type)] )
def visit_variable_declaration(self, node: ParseTreeNode, children: Tuple[ast.Symbol, ast.Identifier] ) -> ast.VariableDeclaration: return ast.VariableDeclaration(children[0], children[1], None)