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.

192 lines
4.7KB

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