Research portable Memory game | Исследовать портируемую игру Память
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

176 lines
4.3KB

  1. from Function import *
  2. def includes():
  3. return """#include <map>
  4. #include <string>
  5. #include <vector>
  6. #include "memory_Context.h"
  7. """
  8. def replaceAnd(s):
  9. return s.replace("and", "&&")
  10. def replaceAppend(s):
  11. return s.replace(".append(", ".push_back(")
  12. def replaceComment(s):
  13. return s.replace("#", "//")
  14. def replaceLen(s):
  15. posLen = s.find("len(")
  16. posEnd = s.find(")", posLen)
  17. if (
  18. posLen == -1 or
  19. posEnd == -1
  20. ):
  21. return s
  22. before = s[:posLen]
  23. name = s[posLen + len("len("):posEnd]
  24. after = s[posEnd + len(")"):]
  25. return f"{before}{name}.size(){after}"
  26. def replaceTrue(s):
  27. return s.replace("True", "true")
  28. def translateParameter(s):
  29. # name: type -> type name
  30. parts = s.split(": ")
  31. indent = len(s) - len(s.lstrip())
  32. name = parts[0].lstrip()
  33. t = translateType(parts[1])
  34. indentation = "".join(" " * indent)
  35. return f"{indentation}{t} {name}"
  36. def translateStatement(s, state):
  37. indent = len(s) - len(s.lstrip())
  38. indentation = "".join(" " * indent)
  39. ss = s.lstrip()
  40. posColon = ss.find(": ")
  41. posComma = ss.find(", ")
  42. posCtx = ss.find("c.")
  43. posEqual = ss.find(" = ")
  44. posFor = ss.find("for ")
  45. posIn = ss.find(" in ")
  46. posRange = ss.find("range(")
  47. posRangeEnd = ss.find("):")
  48. posClosingScope = ss.find("#}")
  49. posOpenSquareBracket = ss.find("[")
  50. # #} -> }
  51. if posClosingScope != -1:
  52. return f"{indentation}}}"
  53. # for name in range(x, y): -> for (auto name = x; name < y; ++name) {
  54. if (
  55. posFor >= 0 and
  56. posIn >= 0 and
  57. posRange >= 0
  58. ):
  59. name = ss[posFor + len("for "):posIn]
  60. x = ss[posRange + len("range("):posComma]
  61. y = ss[posComma + len(", "):posRangeEnd]
  62. return f"{indentation}for (auto {name} = {x}; {name} < {y}; ++{name}) {{"
  63. # name: type = value -> type name = value
  64. if (
  65. posColon >= 0 and
  66. posEqual >= 0
  67. ):
  68. name = ss[:posColon]
  69. type = ss[posColon + len(": "):posEqual]
  70. t = translateType(type)
  71. value = ss[posEqual + len(" = "):]
  72. return f"{indentation}{t} {name} = {value};"
  73. # name = value -> auto name = value
  74. if (
  75. posCtx == -1 and
  76. posColon == -1 and
  77. posOpenSquareBracket == -1 and
  78. posEqual >= 0
  79. ):
  80. name = ss[:posEqual]
  81. value = ss[posEqual + len(" = "):]
  82. return f"{indentation}auto {name} = {value};"
  83. # Keep "if ("
  84. if ss == "if (":
  85. state.isIf = True
  86. return s
  87. # Keep "if not ("
  88. if ss == "if not (":
  89. state.isIfNot = True
  90. return f"{indentation}if (!("
  91. # ): -> }
  92. if ss == "):":
  93. # if
  94. if state.isIf:
  95. state.isIf = False
  96. return f"{indentation}) {{"
  97. # if not
  98. state.isIfNot = False
  99. return f"{indentation})) {{"
  100. ending = ";"
  101. if state.isIf or state.isIfNot:
  102. ending = ""
  103. # Unknown.
  104. return f"{s}{ending}"
  105. def translateType(s):
  106. # dict[X, Y] -> std::map<X, Y>
  107. if s.startswith("dict["):
  108. kv = s[len("dict["):-len("]")]
  109. parts = kv.split(", ")
  110. return f"std::map<{parts[0]}, {parts[1]}>"
  111. # str -> std::string
  112. if s == "str":
  113. return "std::string"
  114. # Unknown. Return as is.
  115. return s
  116. class CPP:
  117. def __init__(self, fn):
  118. self.fn = fn
  119. self.isIf = False
  120. self.isIfNot = False
  121. def translate(self):
  122. returnType = translateType(self.fn.returnType)
  123. # Parameters.
  124. params = []
  125. for i in range(0, len(self.fn.parameters)):
  126. p = translateParameter(self.fn.parameters[i])
  127. # Make Context passed by reference.
  128. #if "Context" in p:
  129. # p = p.replace("Context", "Context&")
  130. params.append(p)
  131. strparams = "\n".join(params)
  132. if (len(strparams) > 0):
  133. strparams += "\n"
  134. # Statements.
  135. sts = []
  136. for i in range(0, len(self.fn.statements)):
  137. s = translateStatement(self.fn.statements[i], self)
  138. s = replaceAnd(s)
  139. s = replaceAppend(s)
  140. # Replace len twice to account for double invocation.
  141. s = replaceLen(s)
  142. s = replaceLen(s)
  143. s = replaceTrue(s)
  144. sts.append(s)
  145. strstatements = "\n".join(sts)
  146. return f"""{returnType} {self.fn.name}(
  147. {strparams}) {{
  148. {strstatements}
  149. }}
  150. """