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.

191 lines
4.7KB

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