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.

196 lines
4.8KB

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