An emulator, assembler, and disassembler for the Sega Game Gear
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 

90 lignes
2.5 KiB

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
  4. # Released under the terms of the MIT License. See LICENSE for details.
  5. """
  6. This script generates 'src/assembler/instructions.inc.c' from
  7. 'src/assembler/instructions.yml'. It should be run automatically by make
  8. when the latter is modified, but can also be run manually.
  9. """
  10. from __future__ import print_function
  11. import re
  12. import time
  13. SOURCE = "src/assembler/instructions.yml"
  14. DEST = "src/assembler/instructions.inc.c"
  15. ENCODING = "utf8"
  16. TAB = " " * 4
  17. try:
  18. import yaml
  19. except ImportError:
  20. print("Error: PyYAML is required (https://pypi.python.org/pypi/PyYAML)\n"
  21. "If you don't want to rebuild {0}, do:\n`make -t {0}`".format(DEST))
  22. exit(1)
  23. re_date = re.compile(r"^(\s*@AUTOGEN_DATE\s*)(.*?)$", re.M)
  24. re_inst = re.compile(
  25. r"(/\* @AUTOGEN_INST_BLOCK_START \*/\n*)(.*?)"
  26. r"(\n*/\* @AUTOGEN_INST_BLOCK_END \*/)", re.S)
  27. re_lookup = re.compile(
  28. r"(/\* @AUTOGEN_LOOKUP_BLOCK_START \*/\n*)(.*?)"
  29. r"(\n*/\* @AUTOGEN_LOOKUP_BLOCK_END \*/)", re.S)
  30. def build_inst(name, data):
  31. """
  32. Convert data for an individual instruction into a C parse function.
  33. """
  34. # TODO
  35. return "INST_FUNC({0})\n{{\n}}".format(name)
  36. def build_inst_block(data):
  37. """
  38. Return the instruction parser block, given instruction data.
  39. """
  40. return "\n\n".join(build_inst(k, v) for k, v in sorted(data.items()))
  41. def build_lookup_block(data):
  42. """
  43. Return the instruction lookup block, given instruction data.
  44. """
  45. macro = TAB + "HANDLE({0})"
  46. return "\n".join(macro.format(inst) for inst in sorted(data.keys()))
  47. def process(template, data):
  48. """
  49. Return C code generated from a source template and instruction data.
  50. """
  51. inst_block = build_inst_block(data)
  52. lookup_block = build_lookup_block(data)
  53. date = time.asctime(time.gmtime())
  54. result = re_date.sub(r"\1{0} UTC".format(date), template)
  55. result = re_inst.sub(r"\1{0}\3".format(inst_block), result)
  56. result = re_lookup.sub(r"\1{0}\3".format(lookup_block), result)
  57. return result
  58. def main():
  59. """
  60. Main script entry point.
  61. """
  62. with open(SOURCE, "r") as fp:
  63. text = fp.read().decode(ENCODING)
  64. with open(DEST, "r") as fp:
  65. template = fp.read().decode(ENCODING)
  66. data = yaml.load(text)
  67. result = process(template, data)
  68. # with open(DEST, "w") as fp:
  69. # fp.write(result.encode(ENCODING))
  70. print(result) # TODO: remove me!
  71. if __name__ == "__main__":
  72. main()