Research portable Memory game | Исследовать портируемую игру Память
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

154 行
3.7KB

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