constructors_object_visitor.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import sys
  2. sys.path.append("scripts")
  3. from process import send_to_mv
  4. from constructors_visitor import ConstructorsVisitor
  5. import urllib
  6. import urllib2
  7. timeout = 100
  8. class ConstructorsObjectVisitor(ConstructorsVisitor):
  9. def __init__(self, args):
  10. ConstructorsVisitor.__init__(self, args)
  11. self.username = args[0]
  12. self.obj_file = args[1]
  13. self.real_file = args[2]
  14. self.address = args[3]
  15. self.object_symbols = {}
  16. with open(self.real_file, 'r') as f:
  17. import hashlib
  18. md5 = hashlib.md5()
  19. md5.update(f.read())
  20. self.hash_file = md5.hexdigest()
  21. data = ['"%s"' % self.username,
  22. '3',
  23. '"is_defined"',
  24. '"%s"' % self.obj_file,
  25. 1,
  26. ]
  27. v = send_to_mv(self.address, self.username, data)[1]
  28. simple_filename = self.real_file.rsplit("/")[-1]
  29. if v == "None":
  30. # Not defined, so recompile
  31. print("[COMPILE] %s" % simple_filename)
  32. else:
  33. # Is defined already, so let's compare hashes
  34. if v != self.hash_file:
  35. print("[COMPILE] %s" % simple_filename)
  36. # Remove in Modelverse and recompile
  37. data = ['3',
  38. '"remove_obj"',
  39. '"%s"' % self.obj_file
  40. ]
  41. send_to_mv(self.address, self.username, data)
  42. else:
  43. self.visit = lambda i: i
  44. self.dump = lambda: True
  45. print("[CACHED] %s" % simple_filename)
  46. def dump(self):
  47. v = ConstructorsVisitor.dump(self)
  48. import json
  49. # Set up interface
  50. data = ['3',
  51. '"upload"',
  52. '"%s"' % self.obj_file,
  53. '"%s"' % self.hash_file,
  54. 'true',
  55. ] + v
  56. # Upload symbol table
  57. for e, v in self.object_symbols.iteritems():
  58. data.append('true')
  59. data.append('"%s"' % e)
  60. data.append('true' if v else 'false')
  61. # Finish the symbol table
  62. data.append('false')
  63. # Wait for kernel to signal that it finished
  64. data.append('2')
  65. #TODO move this actual sending elsewhere (maybe?)
  66. send_to_mv(self.address, self.username, data)
  67. v = urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "get_output", "username": self.username}))).read()
  68. v = v.split("=", 2)[2]
  69. if v == "DONE":
  70. return True
  71. else:
  72. return False
  73. def visit_definition(self, tree):
  74. for a in tree.get_children("ID"):
  75. name = a.get_tail()[0]
  76. self.object_symbols[name] = True
  77. return ConstructorsVisitor.visit_definition(self, tree)
  78. def visit_vardecl(self, tree):
  79. if len(tree.get_tail()) > 2:
  80. for a in tree.get_children("ID"):
  81. name = a.get_tail()[0]
  82. self.object_symbols.setdefault(name, False)
  83. return ConstructorsVisitor.visit_vardecl(self, tree)
  84. else:
  85. return ConstructorsVisitor.visit_vardecl(self, tree)
  86. def visit_funcdecl(self, tree):
  87. for a in tree.get_children("func_name"):
  88. for b in a.get_children("ID"):
  89. name = b.get_tail()[0]
  90. if tree.get_children("func_body") or tree.get_children("ASSIGN"):
  91. self.object_symbols[name] = True
  92. else:
  93. self.object_symbols.setdefault(name, False)
  94. return ConstructorsVisitor.visit_funcdecl(self, tree)