linker.py 4.2 KB

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