constructors_object_visitor.py 4.3 KB

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