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.

140 line
3.4KB

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