linker.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import sys
  2. import urllib
  3. import urllib2
  4. def link(username, objects, fast):
  5. # Read out all symbol tables that are to be linked
  6. definers = {}
  7. users = {}
  8. if not fast:
  9. definers["main"] = None
  10. for obj in objects:
  11. print("[SYMB] %s" % (obj))
  12. urllib2.urlopen(urllib2.Request("http://localhost:8001/", urllib.urlencode({"op": "set_input", "element_type": "V", "value": '3', "username": username}))).read()
  13. urllib2.urlopen(urllib2.Request("http://localhost:8001/", urllib.urlencode({"op": "set_input", "element_type": "V", "value": '"read_symbols"', "username": username}))).read()
  14. urllib2.urlopen(urllib2.Request("http://localhost:8001/", urllib.urlencode({"op": "set_input", "element_type": "V", "value": '"%s"' % obj, "username": username}))).read()
  15. v = urllib2.urlopen(urllib2.Request("http://localhost:8001/", urllib.urlencode({"op": "get_output", "username": username}))).read()
  16. lst = v.rsplit("=", 1)[1]
  17. lst = lst.split("\n")
  18. for e in lst:
  19. if len(e) > 1:
  20. name, defined = e.rsplit(":", 1)
  21. if defined == "1":
  22. if definers.get(name, None):
  23. raise Exception("Double definition for symbol %s\nDefined in %s\nDefined in %s" % (name, definers[name], obj))
  24. definers[name] = obj
  25. else:
  26. users.setdefault(name, []).append(obj)
  27. if name not in definers:
  28. definers[name] = None
  29. # Check for undefined symbols with this linking set
  30. for symbol in definers:
  31. if definers[symbol] is None:
  32. if symbol not in ["input", "output"]:
  33. # Some symbols are built-ins which only look like functions
  34. raise Exception("Undefined symbol %s.\nUsed by modules:\n\t%s" % (symbol, "\n\t".join(users[symbol])))
  35. # Ok, we know that all symbols can be defined with this set of files, now link their initializers together
  36. initializers = []
  37. for obj in objects:
  38. print("[LINK] %s" % (obj))
  39. urllib2.urlopen(urllib2.Request("http://localhost:8001/", urllib.urlencode({"op": "set_input", "element_type": "V", "value": '3', "username": username}))).read()
  40. urllib2.urlopen(urllib2.Request("http://localhost:8001/", urllib.urlencode({"op": "set_input", "element_type": "V", "value": '"read_initializers"', "username": username}))).read()
  41. urllib2.urlopen(urllib2.Request("http://localhost:8001/", urllib.urlencode({"op": "set_input", "element_type": "V", "value": '"%s"' % obj, "username": username}))).read()
  42. v = urllib2.urlopen(urllib2.Request("http://localhost:8001/", urllib.urlencode({"op": "get_output", "username": username}))).read()
  43. start = str(v.split("&", 1)[0].split("=")[1])
  44. initializers.append(start)
  45. # Bind all initializers together
  46. if definers:
  47. print("[LOAD] %s:main()" % definers["main"])
  48. else:
  49. print("[LOAD] main()")
  50. # Set interface to constructors
  51. commands = [("V", '1')]
  52. # Link all initializers together
  53. for init in initializers:
  54. commands.extend([
  55. ("V", '"call"'),
  56. ("V", '"access"'),
  57. ("V", '"resolve"'),
  58. ("V", '"exec"'),
  59. ("V", '1'),
  60. ("V", '"const"'),
  61. ("R", str(init)),
  62. ("V", 'true'),
  63. ])
  64. # Load main function
  65. commands.extend([
  66. ("V", '"return"'),
  67. ("V", 'true'),
  68. ("V", '"call"'),
  69. ("V", '"access"'),
  70. ("V", '"resolve"'),
  71. ("V", '"main"'),
  72. ("V", '0'),
  73. ("V", 'false'),
  74. ])
  75. import json
  76. urllib2.urlopen(urllib2.Request("http://localhost:8001/", urllib.urlencode({"op": "set_input", "data": json.dumps(commands), "username": username}))).read()
  77. if len(sys.argv) == 1:
  78. print("No username defined")
  79. else:
  80. username = sys.argv[1]
  81. objects = set(sys.argv[2:])
  82. if "--fast" in objects:
  83. objects.remove("--fast")
  84. fast = True
  85. else:
  86. fast = False
  87. if objects:
  88. link(username, objects, fast)
  89. else:
  90. print("No files to link defined")