constructors_object_visitor.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. from constructors_visitor import ConstructorsVisitor
  2. import urllib
  3. import urllib2
  4. timeout = 100
  5. class ConstructorsObjectVisitor(ConstructorsVisitor):
  6. def __init__(self, args):
  7. ConstructorsVisitor.__init__(self, args)
  8. self.username = args[0]
  9. self.obj_file = args[1]
  10. self.real_file = args[2]
  11. self.address = args[3]
  12. self.object_symbols = {}
  13. with open(self.real_file, 'r') as f:
  14. import hashlib
  15. md5 = hashlib.md5()
  16. md5.update(f.read())
  17. self.hash_file = md5.hexdigest()
  18. # Check if file is already compiled (with same hash) in Modelverse
  19. urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "set_input", "element_type": "V", "value": '"%s"' % self.username, "username": "user_manager"}))).read()
  20. urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "set_input", "element_type": "V", "value": '3', "username": self.username}))).read()
  21. urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "set_input", "element_type": "V", "value": '"is_defined"', "username": self.username}))).read()
  22. urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "set_input", "element_type": "V", "value": '"%s"' % self.obj_file, "username": self.username}))).read()
  23. v = urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "get_output", "username": self.username}))).read()
  24. v = v.split("=", 2)[2]
  25. if v == "None":
  26. # Not defined, so recompile
  27. print("[COMPILE] %s" % self.real_file.rsplit("/", 1)[1])
  28. else:
  29. # Is defined already, so let's compare hashes
  30. if v != self.hash_file:
  31. print("[COMPILE] %s" % self.real_file.rsplit("/", 1)[1])
  32. # Remove in Modelverse and recompile
  33. urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "set_input", "element_type": "V", "value": '3', "username": self.username}))).read()
  34. urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "set_input", "element_type": "V", "value": '"remove_obj"', "username": self.username}))).read()
  35. urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "set_input", "element_type": "V", "value": '"%s"' % self.obj_file, "username": self.username}))).read()
  36. else:
  37. self.visit = lambda i: i
  38. self.dump = lambda: True
  39. print("[CACHED] %s" % self.real_file.rsplit("/", 1)[1])
  40. def dump(self):
  41. v = ConstructorsVisitor.dump(self)
  42. import json
  43. # Set up interface
  44. urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "set_input", "element_type": "V", "value": '3', "username": self.username}))).read()
  45. # Start uploading the code
  46. urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "set_input", "element_type": "V", "value": '"upload"', "username": self.username}))).read()
  47. urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "set_input", "element_type": "V", "value": '"%s"' % self.obj_file, "username": self.username}))).read()
  48. urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "set_input", "element_type": "V", "value": '"%s"' % self.hash_file, "username": self.username}))).read()
  49. urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "set_input", "element_type": "V", "value": 'true', "username": self.username}))).read() # Use new interface
  50. def flush_data(data):
  51. if data:
  52. urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "set_input", "data": json.dumps(data), "username": self.username})), timeout=timeout).read()
  53. return []
  54. var_list = {}
  55. data = []
  56. for p in v:
  57. if isinstance(p, int):
  58. if p not in var_list:
  59. data = flush_data(data)
  60. val = urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "get_output", "username": self.username})), timeout=timeout).read()
  61. val = val.split("=", 2)[1].split("&", 1)[0]
  62. var_list[p] = val
  63. continue
  64. else:
  65. val = var_list[p]
  66. t = "R"
  67. else:
  68. val = p
  69. t = "V"
  70. data.append([t, val])
  71. data = flush_data(data)
  72. # Upload symbol table
  73. data = []
  74. for e, v in self.object_symbols.iteritems():
  75. data.append(["V", "true"])
  76. data.append(["V", '"%s"' % e])
  77. data.append(["V", "true" if v else "false"])
  78. urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "set_input", "data": json.dumps(data), "username": self.username}))).read()
  79. # Finish the symbol table
  80. urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "set_input", "element_type": "V", "value": 'false', "username": self.username}))).read()
  81. # Wait for kernel to signal that it finished
  82. urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "set_input", "element_type": "V", "value": '2', "username": self.username}))).read()
  83. v = urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "get_output", "username": self.username}))).read()
  84. v = v.split("=", 2)[2]
  85. if v == "DONE":
  86. return True
  87. else:
  88. return False
  89. def visit_definition(self, tree):
  90. for a in tree.get_children("ID"):
  91. name = a.get_tail()[0]
  92. self.object_symbols[name] = True
  93. return ConstructorsVisitor.visit_definition(self, tree)
  94. def visit_vardecl(self, tree):
  95. if len(tree.get_tail()) > 2:
  96. for a in tree.get_children("ID"):
  97. name = a.get_tail()[0]
  98. self.object_symbols.setdefault(name, False)
  99. return ConstructorsVisitor.visit_vardecl(self, tree)
  100. else:
  101. return ConstructorsVisitor.visit_vardecl(self, tree)
  102. def visit_funcdecl(self, tree):
  103. for a in tree.get_children("func_name"):
  104. for b in a.get_children("ID"):
  105. name = b.get_tail()[0]
  106. if tree.get_children("func_body") or tree.get_children("ASSIGN"):
  107. self.object_symbols[name] = True
  108. else:
  109. self.object_symbols.setdefault(name, False)
  110. return ConstructorsVisitor.visit_funcdecl(self, tree)