Михаил Капелько 6 months ago
parent
commit
3a24d68174
10 changed files with 637 additions and 0 deletions
  1. +1
    -0
      v3/gen-C++
  2. +10
    -0
      v3/main.cpp
  3. +120
    -0
      v3/memory.cpp
  4. +7
    -0
      v3/memory_Context.cpp
  5. +209
    -0
      v3/memory_test.cpp
  6. +153
    -0
      v3/tPythonC++/CPP.py
  7. +76
    -0
      v3/tPythonC++/Function.py
  8. +37
    -0
      v3/tPythonC++/process.py
  9. +17
    -0
      v3/tPythonC++/translate
  10. +7
    -0
      v3/translate-py-cxx

+ 1
- 0
v3/gen-C++ View File

@@ -0,0 +1 @@
c++ -o test_memory_C++ -std=c++11 main.cpp

+ 10
- 0
v3/main.cpp View File

@@ -0,0 +1,10 @@
#include <iostream>
#include <string>
#include <vector>

int main() {
std::cout <<
"check" //memory_test_generateConstPlayfield()
<< std::endl
;
}

+ 120
- 0
v3/memory.cpp View File

@@ -0,0 +1,120 @@
#include <map>
#include <string>
#include "entities.h"

////////////////
// Client initiated input
////////////////

// Generate constant playfield
memory_Context memory_generateConstPlayfield(
memory_Context& c
) {
std::map<int, int> idGroups = { };
auto id = 0;
for (auto gid = 0; gid < c.playfieldSize; ++gid) {
idGroups[id] = gid;
id += 1;
idGroups[id] = gid;
id += 1;
}
c.playfieldItems = idGroups;
c.recentField = "playfieldItems";
return c;
}

// Select item

memory_Context memory_selectItem(
memory_Context& c
) {
if (
c.selectedItems.size() == 2
) {
c.selectedItems = [];
c.selectedItems.append(c.selectedId);
c.recentField = "selectedItems";
return c;
}

////////////////
// System initiated reaction
////////////////

// Deselect mismatched items
//
// Conditions:
// 0. Two items has just been selected
// 1. The same item has been selected twice
// 1. Selected items are of different groups



memory_Context memory_shouldDeselectMismatchedItems(
memory_Context& c
) {
if not (;
c.recentField == "selectedItems" &&;
c.selectedItems.size() == 2;
) {
c.recentField = None;
return c;
if (
c.selectedItems[0] == c.selectedItems[1]
) {
c.mismatchedItems.clear();
c.mismatchedItems.append(c.selectedItems[0]);
c.recentField = "mismatchedItems";
return c;
if (
c.playfieldItems[c.selectedItems[0]] != c.playfieldItems[c.selectedItems[1]]
) {
c.mismatchedItems.clear();
c.mismatchedItems.append(c.selectedItems[0]);
c.mismatchedItems.append(c.selectedItems[1]);
c.recentField = "mismatchedItems";
return c;
c.recentField = None;
return c;
}

// Detect victory
//
// Conditions:
// 1. Matching items have just been hidden and all items are hidden now

memory_Context memory_shouldDetectVictory(
memory_Context& c
) {
if (
c.recentField == "hiddenItems" &&
c.hiddenItems.size() == len(c.playfieldItems)
) {
c.victory = True;
c.recentField = "victory";
return c;
c.recentField = None;
return c;
}

// Hide matching selected items
//
// Conditions:
// 1. Two items are selected and they are of the same group

memory_Context memory_shouldHideMatchingItems(
memory_Context& c
) {
if (
c.recentField == "selectedItems" &&
c.selectedItems.size() == 2 &&
c.playfieldItems[c.selectedItems[0]] == c.playfieldItems[c.selectedItems[1]]
) {
c.hiddenItems.append(c.selectedItems[0]);
c.hiddenItems.append(c.selectedItems[1]);
c.recentField = "hiddenItems";
return c;
c.recentField = None;
return c;
}


+ 7
- 0
v3/memory_Context.cpp View File

@@ -0,0 +1,7 @@
#include <map>
#include <string>
#include "entities.h"





+ 209
- 0
v3/memory_test.cpp View File

@@ -0,0 +1,209 @@
#include <map>
#include <string>
#include "entities.h"

std::string memory_test_generateConstPlayfield(
) {
auto c = memory_createContext();
c.playfieldSize = 2;
auto c = memory_generateConstPlayfield(c);
if (
c.recentField == "playfieldItems" &&
c.playfieldItems.size() == 4 &&
c.playfieldItems[0] == 0 &&
c.playfieldItems[1] == 0 &&
c.playfieldItems[2] == 1 &&
c.playfieldItems[3] == 1
) {
return "OK: memory_generateConstPlayfield";
}
return "ERR: memory_generateConstPlayfield";
}



std::string memory_test_selectItem_1x(
) {
auto c = memory_createContext();
c.playfieldSize = 2;
auto c = memory_generateConstPlayfield(c);
# Select the first item.;
c.selectedId = 0;
auto c = memory_selectItem(c);
# See if it's in selectedItems now.;
if (
c.recentField == "selectedItems" &&
c.selectedItems.size() == 1 &&
c.selectedItems[0] == 0
) {
return "OK: memory_selectItem_1x";
}
return "ERR: memory_selectItem_1x";
}



std::string memory_test_selectItem_2x(
) {
auto c = memory_createContext();
c.playfieldSize = 2;
auto c = memory_generateConstPlayfield(c);
# Select the first two items.;
c.selectedId = 0;
auto c = memory_selectItem(c);
c.selectedId = 1;
auto c = memory_selectItem(c);
# See if both items are selected now.;
if (
c.recentField == "selectedItems" &&
c.selectedItems.size() == 2 &&
c.selectedItems[0] == 0 &&
c.selectedItems[1] == 1
) {
return "OK: memory_selectItem_2x";
}
return "ERR: memory_selectItem_2x";
}



std::string memory_test_selectItem_3x(
) {
auto c = memory_createContext();
c.playfieldSize = 2;
auto c = memory_generateConstPlayfield(c);
# Select three items.;
c.selectedId = 0;
auto c = memory_selectItem(c);
c.selectedId = 1;
auto c = memory_selectItem(c);
c.selectedId = 2;
auto c = memory_selectItem(c);
# See if only one (last) item is selected now.;
if (
c.recentField == "selectedItems" &&
c.selectedItems.size() == 1 &&
c.selectedItems[0] == 2
) {
return "OK: memory_selectItem_3x";
}
return "ERR: memory_selectItem_3x";
}




std::string memory_test_shouldDeselectMismatchedItems(
) {
auto c = memory_createContext();
c.playfieldSize = 2;
auto c = memory_generateConstPlayfield(c);
# Select two items of different groups.;
c.selectedId = 0;
auto c = memory_selectItem(c);
c.selectedId = 2;
auto c = memory_selectItem(c);
# Detect mismatching.;
auto c = memory_shouldDeselectMismatchedItems(c);
# See if the two selected items do not match.;
if (
c.recentField == "mismatchedItems" &&
c.mismatchedItems.size() == 2 &&
c.mismatchedItems[0] == 0 &&
c.mismatchedItems[1] == 2
) {
return "OK: memory_shouldDeselectMismatchedItems";
}
return "ERR: memory_shouldDeselectMismatchedItems";
}




std::string memory_test_shouldDeselectMismatchedItems_itemTwice(
) {
auto c = memory_createContext();
c.playfieldSize = 2;
auto c = memory_generateConstPlayfield(c);
# Select the same item twice.;
c.selectedId = 0;
auto c = memory_selectItem(c);
c.selectedId = 0;
auto c = memory_selectItem(c);
# Detect mismatching.;
auto c = memory_shouldDeselectMismatchedItems(c);
# See if the two selected items do not match.;
if (
c.recentField == "mismatchedItems" &&
c.mismatchedItems.size() == 1 &&
c.mismatchedItems[0] == 0
) {
return "OK: memory_shouldDeselectMismatchedItems_itemTwice";
}
return "ERR: memory_shouldDeselectMismatchedItems_itemTwice";
}







std::string memory_test_shouldDetectVictory(
) {
auto c = memory_createContext();
c.playfieldSize = 2;
auto c = memory_generateConstPlayfield(c);
# Select the first two items of the same group.;
c.selectedId = 0;
auto c = memory_selectItem(c);
c.selectedId = 1;
auto c = memory_selectItem(c);
# Hide the first pair.;
auto c = memory_shouldHideMatchingItems(c);
# Select the last two items of the same group.;
c.selectedId = 2;
auto c = memory_selectItem(c);
c.selectedId = 3;
auto c = memory_selectItem(c);
# Hide the second pair.;
auto c = memory_shouldHideMatchingItems(c);
# Detect victory.;
auto c = memory_shouldDetectVictory(c);
# See if victory has been detected.;
if (
c.recentField == "victory" &&
c.victory == True
) {
return "OK: memory_shouldDetectVictory";
}
return "ERR: memory_shouldDetectVictory";
}




std::string memory_test_shouldHideMatchingItems(
) {
auto c = memory_createContext();
c.playfieldSize = 2;
auto c = memory_generateConstPlayfield(c);
# Select two items of the same group.;
c.selectedId = 0;
auto c = memory_selectItem(c);
c.selectedId = 1;
auto c = memory_selectItem(c);
# Hide matching items.;
auto c = memory_shouldHideMatchingItems(c);
# See if the two selected items match.;
if (
c.recentField == "hiddenItems" &&
c.hiddenItems.size() == 2 &&
c.hiddenItems[0] == 0 &&
c.hiddenItems[1] == 1
) {
return "OK: memory_shouldHideMatchingItems";
}
return "ERR: memory_shouldHideMatchingItems";
}


+ 153
- 0
v3/tPythonC++/CPP.py View File

@@ -0,0 +1,153 @@
from Function import *

def includes():
return """#include <map>
#include <string>
#include "entities.h"
"""

def replaceAnd(s):
return s.replace("and", "&&")

def replaceComment(s):
return s.replace("#", "//")

def replaceLen(s):
posLen = s.find("len(")
posEnd = s.find(")")
if (
posLen == -1 or
posEnd == -1
):
return s
before = s[:posLen]
name = s[posLen + len("len("):posEnd]
after = s[posEnd + len(")"):]
return f"{before}{name}.size(){after}"

def translateParameter(s):
# name: type -> type name
parts = s.split(": ")
indent = len(s) - len(s.lstrip())
name = parts[0].lstrip()
t = translateType(parts[1])
indentation = "".join(" " * indent)
return f"{indentation}{t} {name}"

def translateStatement(s, state):
indent = len(s) - len(s.lstrip())
indentation = "".join(" " * indent)
ss = s.lstrip()
posColon = ss.find(": ")
posComma = ss.find(", ")
posCtx = ss.find("c.")
posEqual = ss.find(" = ")
posFor = ss.find("for ")
posIn = ss.find(" in ")
posRange = ss.find("range(")
posRangeEnd = ss.find("):")
posClosingScope = ss.find("#}")
posOpenSquareBracket = ss.find("[")

# #} -> }
if posClosingScope != -1:
return f"{indentation}}}"

# for name in range(x, y): -> for (auto name = x; name < y; ++name) {
if (
posFor >= 0 and
posIn >= 0 and
posRange >= 0
):
name = ss[posFor + len("for "):posIn]
x = ss[posRange + len("range("):posComma]
y = ss[posComma + len(", "):posRangeEnd]
return f"{indentation}for (auto {name} = {x}; {name} < {y}; ++{name}) {{"

# name: type = value -> type name = value
if (
posColon >= 0 and
posEqual >= 0
):
name = ss[:posColon]
type = ss[posColon + len(": "):posEqual]
t = translateType(type)
value = ss[posEqual + len(" = "):]
return f"{indentation}{t} {name} = {value};"

# name = value -> auto name = value
if (
posCtx == -1 and
posColon == -1 and
posOpenSquareBracket == -1 and
posEqual >= 0
):
name = ss[:posEqual]
value = ss[posEqual + len(" = "):]
return f"{indentation}auto {name} = {value};"

# Keep "if ("
if ss == "if (":
state.isIf = True
return s

# ): -> }
if ss == "):":
state.isIf = False
return f"{indentation}) {{"

ending = ";"
if state.isIf:
ending = ""

# Unknown.
return f"{s}{ending}"

def translateType(s):
# dict[X, Y] -> std::map<X, Y>
if s.startswith("dict["):
kv = s[len("dict["):-len("]")]
parts = kv.split(", ")
return f"std::map<{parts[0]}, {parts[1]}>"
# str -> std::string
if s == "str":
return "std::string"

# Unknown. Return as is.
return s

class CPP:
def __init__(self, fn):
self.fn = fn
self.isIf = False

def translate(self):
returnType = translateType(self.fn.returnType)

# Parameters.
params = []
for i in range(0, len(self.fn.parameters)):
p = translateParameter(self.fn.parameters[i])
# Make Context passed by reference.
if "Context" in p:
p = p.replace("Context", "Context&")
params.append(p)
strparams = "\n".join(params)
if (len(strparams) > 0):
strparams += "\n"

# Statements.
sts = []
for i in range(0, len(self.fn.statements)):
s = translateStatement(self.fn.statements[i], self)
s = replaceAnd(s)
s = replaceLen(s)
sts.append(s)
strstatements = "\n".join(sts)

return f"""{returnType} {self.fn.name}(
{strparams}) {{
{strstatements}
}}
"""


+ 76
- 0
v3/tPythonC++/Function.py View File

@@ -0,0 +1,76 @@
class Function:
def __init__(self):
self.isBody = False
self.isComplete = False
self.isSignature = False
self.name = None
self.parameters = []
self.returnType = None
self.statements = []

def parseLine(self, ln):
parts = ln.split(" ")
count = len(parts)
lastPart = parts[count - 1]

# Complete.
if (
self.isBody and
ln.startswith("#}")
):
self.isComplete = True

# Statements.
if (
self.isBody and
not ln.startswith("#}")
):
self.statements.append(ln)

# Parameters.
if (
self.isSignature and
not ln.endswith(":")
):
p = ln
# Remove comma if present.
if p.endswith(","):
p = p[:-1]
self.parameters.append(p)

# Beginning of signature.
if (
self.returnType is None and
self.name is None
and lastPart.endswith("(")
):
self.isSignature = True

# Return type.
if (
self.isSignature and
ln.startswith(") -> ") and
ln.endswith(":")
):
self.returnType = ln[len(") -> "):-len(":")]

# End of parameters/signature.
if (
self.isSignature and
ln.startswith(") -> ") and
ln.endswith(":")
):
self.isSignature = False
self.isBody = True

# Name.
if (
self.isSignature and
lastPart.endswith("(")
):
self.name = lastPart[:-1]

def __repr__(self):
return self.__str__()
def __str__(self):
return f"Function(name/returnT/parameters/statements: '{self.name}'/'{self.returnType}'/'{self.parameters}'/'{self.statements}')"

+ 37
- 0
v3/tPythonC++/process.py View File

@@ -0,0 +1,37 @@
from CPP import *
from Function import *

def process(FILE_IN):
# Read file.
lines_in = []
with open(FILE_IN) as file:
for line in file:
lines_in.append(line.rstrip())

f = Function()
out = includes()

# Parse.
for ln in lines_in:
ln = ln.rstrip()

# Empty line.
if ln == "":
out += "\n"
# Comment.
elif (
ln.startswith("#") and
not f.isBody
):
out += replaceComment(ln) + "\n"
# Function.
else:
f.parseLine(ln)

if f.isComplete:
cpp = CPP(f)
out += cpp.translate()
# Create new function instance.
f = Function()

return out

+ 17
- 0
v3/tPythonC++/translate View File

@@ -0,0 +1,17 @@
#!/usr/bin/env python3
import os
import sys
from process import *

DIR = os.path.dirname(os.path.realpath(sys.argv[0]))

# Demand file as input
if len(sys.argv) < 2:
print("Usage: /path/to/translate PYTHON_FILE")
sys.exit(1)

FILE_IN = sys.argv[1]

# Translate file.
out = process(FILE_IN)
print(out)

+ 7
- 0
v3/translate-py-cxx View File

@@ -0,0 +1,7 @@
#!/bin/bash

DIR=$(cd "$(dirname "$0")" ; pwd -P)
TR=$DIR/tPythonC++/translate

$TR $DIR/memory.py > $DIR/memory.cpp
$TR $DIR/memory_test.py > $DIR/memory_test.cpp

Loading…
Cancel
Save