bootstrap_visitor.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import string
  2. from primitives_visitor import PrimitivesVisitor, Action
  3. class BootstrapVisitor(PrimitivesVisitor):
  4. def __init__(self, args):
  5. PrimitivesVisitor.__init__(self, args)
  6. self.main = "--main" in args
  7. for f in args:
  8. if "--prepend:" in f:
  9. self.prepend_name = f.split(":", 1)[1]
  10. break
  11. else:
  12. self.prepend_name = "auto"
  13. self.object_symbols = {}
  14. def rename(self, name):
  15. if name == "initial_IP":
  16. return "%s_%s" % (self.prepend_name, name)
  17. else:
  18. return "%s_%s" % (self.prepend_name, name) if isinstance(name, int) else name
  19. def dump(self):
  20. link_id = 0
  21. if self.main:
  22. call = self.value(Action("call"))
  23. access = self.value(Action("access"))
  24. resolve = self.value(Action("resolve"))
  25. main = self.value("__main")
  26. self.dict(resolve, "var", main)
  27. self.dict(access, "var", resolve)
  28. self.dict(call, "func", access)
  29. self.dict(self.last_instruction, "next", call)
  30. ret = self.value(Action("return"))
  31. self.dict(call, "next", ret)
  32. output = []
  33. for t, data in self.output:
  34. if t == "N":
  35. output.append("Node %s_%s()\n" % (self.prepend_name, data))
  36. elif t == "V":
  37. name, value = data
  38. name = name if self.first != name else "initial_IP"
  39. output.append("Node %s_%s(%s)\n" % (self.prepend_name, name, value))
  40. elif t == "D":
  41. source, value, target = data
  42. source = source if self.first != source else "initial_IP"
  43. target = target if self.first != target else "initial_IP"
  44. source = self.rename(source)
  45. target = self.rename(target)
  46. linkname = "%s_%s_%s" % (source, link_id, target)
  47. link_id += 1
  48. output.append("Edge _%s_0(%s, %s)\n" % (linkname, source, target))
  49. output.append("Node _%s_2(%s)\n" % (linkname, value))
  50. output.append("Edge _%s_1(_%s_0, _%s_2)\n" % (linkname, linkname, linkname))
  51. elif t == "E":
  52. name, source, target = data
  53. source = source if self.first != source else "initial_IP"
  54. target = target if self.first != target else "initial_IP"
  55. name = self.rename(name)
  56. source = self.rename(source)
  57. target = self.rename(target)
  58. output.append("Edge _%s(_%s, _%s)\n" % (name, source, target))
  59. return ''.join(output)
  60. def visit_definition(self, tree):
  61. for a in tree.get_children("ID"):
  62. name = a.get_tail()[0]
  63. self.object_symbols[name] = True
  64. return PrimitivesVisitor.visit_definition(self, tree)
  65. def visit_vardecl(self, tree):
  66. if len(tree.get_tail()) > 2:
  67. for a in tree.get_children("ID"):
  68. name = a.get_tail()[0]
  69. self.object_symbols.setdefault(name, False)
  70. return PrimitivesVisitor.visit_vardecl(self, tree)
  71. else:
  72. return PrimitivesVisitor.visit_vardecl(self, tree)
  73. def visit_funcdecl(self, tree):
  74. for a in tree.get_children("func_name"):
  75. for b in a.get_children("ID"):
  76. name = b.get_tail()[0]
  77. if tree.get_children("func_body") or tree.get_children("ASSIGN"):
  78. self.object_symbols[name] = True
  79. else:
  80. self.object_symbols.setdefault(name, False)
  81. return PrimitivesVisitor.visit_funcdecl(self, tree)