1
0

nsigen.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. class Comment(object):
  2. def __init__(self, content):
  3. self.content = content
  4. def generate(self, state=None):
  5. yield "; " + self.content
  6. def _should_quote(arg):
  7. return (' ' in arg) or ('$' in arg)
  8. def assemble_line(parts):
  9. quoted_parts = [("%s" % p) if _should_quote(p) else p
  10. for p in parts if p is not None]
  11. return ' '.join(quoted_parts)
  12. class Instruction(object):
  13. def __init__(self, name, *parameters):
  14. self.name = name
  15. self.parameters = parameters
  16. def generate(self, state=None):
  17. yield assemble_line([self.name] + list(self.parameters))
  18. def make_instruction_class(name):
  19. def __init__(self, *parameters):
  20. Instruction.__init__(self, name, *parameters)
  21. return type(name, (Instruction,), {'__init__': __init__})
  22. File = make_instruction_class('File')
  23. class Scope(object):
  24. def __init__(self, contents=None):
  25. self.contents = contents or []
  26. def generate_children(self, state=None):
  27. for child in self.contents:
  28. for line in child.generate(state):
  29. yield ' ' + line
  30. class Section(Scope):
  31. def __init__(self, name=None, index_var=None, selected=True, contents=None):
  32. super(Section, self).__init__(contents)
  33. self.name = name
  34. self.index_var = index_var
  35. self.selected = selected
  36. def generate(self, state=None):
  37. parts = ['Section',
  38. None if self.selected else '/o',
  39. self.name, self.index_var]
  40. yield assemble_line(parts)
  41. for line in self.generate_children(state):
  42. yield line
  43. yield 'SectionEnd'
  44. yield '' # Blank line after a section
  45. class SectionGroup(Scope):
  46. def __init__(self, name, index_var=None, expanded=False, contents=None):
  47. super(SectionGroup, self).__init__(contents)
  48. self.name = name
  49. self.expanded = expanded
  50. self.index_var = index_var
  51. def generate(self, state=None):
  52. parts = ['SectionGroup',
  53. '/e' if self.expanded else None,
  54. self.name, self.index_var]
  55. yield assemble_line(parts)
  56. for line in self.generate_children(state):
  57. yield line
  58. yield 'SectionGroupEnd'
  59. class Function(Scope):
  60. def __init__(self, name, contents=None):
  61. super(Function, self).__init__(contents)
  62. self.name = name
  63. def generate(self, state=None):
  64. yield assemble_line(['Function', self.name])
  65. for line in self.generate_children(state):
  66. yield
  67. class Label(object):
  68. def __init__(self, name):
  69. self.name = name
  70. def generate(self, scope):
  71. yield self.name + ":"
  72. class Conditional(object):
  73. # e.g. IfSilent, IntCmp
  74. def __init__(self, name, *parameters, ifbody=None, elsebody=None):
  75. self.name = name
  76. self.parameters = parameters
  77. self.ifbody = ifbody or []
  78. self.elsebody = elsebody or []
  79. def generate(self, state):
  80. if_counter = state.get('if_counter', 1)
  81. state['if_counter'] = if_counter + 1
  82. yield assemble_line([self.name] + self.parameters + ["0",
  83. ("else%d" if self.elsebody else "endif%d") % if_counter])
  84. for child in self.ifbody:
  85. for line in child.generate(state):
  86. yield " " + line
  87. if self.elsebody:
  88. yield (" Goto endif%d" % if_counter)
  89. yield ("else%d:" % if_counter)
  90. for child in self.elsebody:
  91. for line in child.generate(state):
  92. yield " " + line
  93. yield ("endif%d:" % if_counter)
  94. class CompilerCommand(object):
  95. def __init__(self, name, *parameters):
  96. self.name = name
  97. self.parameters = parameters
  98. def generate(self, state=None):
  99. yield "!" + assemble_line([self.name] + list(self.parameters))
  100. class CompilerConditional(object):
  101. # ifdef etc
  102. def __init__(self, name, parameters, ifbody=None, elsebody=None):
  103. self.name = name
  104. self.parameters = parameters
  105. self.ifbody = ifbody or []
  106. self.elsebody = elsebody or []
  107. def generate(self, state=None):
  108. yield "!" + assemble_line([self.name] + self.parameters)
  109. for child in self.ifbody:
  110. for line in child.generate(state):
  111. yield ' ' + line
  112. if self.elsebody:
  113. yield "!else"
  114. for child in self.elsebody:
  115. for line in child.generate(state):
  116. yield ' ' + line
  117. yield "!endif"
  118. def make_compiler_command_class(name):
  119. def __init__(self, *parameters):
  120. CompilerCommand.__init__(self, name, *parameters)
  121. return type(name, (CompilerCommand,), {'__init__': __init__})
  122. define = make_compiler_command_class('define')
  123. insertmacro = make_compiler_command_class('insertmacro')
  124. class Macro(Scope):
  125. def __init__(self, name, parameters):
  126. super(Macro, self).__init__()
  127. self.name = name
  128. self.parameters = parameters
  129. def generate(self, state=None):
  130. yield "!" + assemble_line([self.name] + self.parameters)
  131. for line in self.generate_children(state):
  132. yield " " + line
  133. yield "!macroend"
  134. class Document(object):
  135. def __init__(self, children=None):
  136. self.children = children or []
  137. def generate(self, state):
  138. for child in self.children:
  139. for line in child.generate(state):
  140. yield line
  141. def write(self, fileobj_or_path):
  142. if isinstance(fileobj_or_path, str):
  143. with open(fileobj_or_path, 'w') as f:
  144. return self.write(f)
  145. for line in self.generate(state={}):
  146. fileobj_or_path.write(line + '\n')