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.

CPP.py 4.6KB

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