You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

52 lines
1.5 KiB

  1. from pathlib import Path
  2. from pycparser import parse_file, c_ast
  3. def extract_asm(body: c_ast.Compound):
  4. for item in body.block_items:
  5. if isinstance(item, c_ast.FuncCall):
  6. if item.name.name == 'asm':
  7. for expr in item.args.exprs:
  8. if isinstance(expr, c_ast.Constant) and expr.type == 'string':
  9. return expr.value
  10. def get_decl_info(decl: c_ast.Decl):
  11. decl_info = decl.type
  12. maybe_string = False
  13. if isinstance(decl_info, c_ast.PtrDecl):
  14. maybe_string = True
  15. decl_info = decl_info.type
  16. name = decl_info.declname
  17. datatype = decl_info.type
  18. if isinstance(datatype, c_ast.Struct):
  19. return name, datatype.name
  20. elif maybe_string:
  21. if datatype.names[0] == 'char':
  22. return name, 'string'
  23. else:
  24. return name, datatype.names[0]
  25. class InstructionReader(c_ast.NodeVisitor):
  26. def __init__(self):
  27. self.funcs = dict()
  28. super().__init__()
  29. def visit_FuncDef(self, node):
  30. func_name = node.decl.name
  31. record = self.funcs.setdefault(func_name, dict())
  32. record['asm'] = extract_asm(node.body)[1:-1]
  33. self.parse_func_decl(node.decl.type)
  34. def parse_func_decl(self, node: c_ast.FuncDecl):
  35. return_info = node.type
  36. func_name = return_info.declname
  37. record = self.funcs.setdefault(func_name, dict())
  38. try:
  39. record['args'] = tuple(get_decl_info(decl) for decl in node.args.params)
  40. except AttributeError:
  41. record['args'] = tuple()
  42. instructions = parse_file(str(Path(__file__).parent / 'instruction_definition.c'), use_cpp=True)
  43. reader = InstructionReader()
  44. reader.visit(instructions)
  45. FUNCS = reader.funcs