d
This commit is contained in:
1
v3/gen-C++
Executable file
1
v3/gen-C++
Executable file
@@ -0,0 +1 @@
|
||||
c++ -o test_memory_C++ -std=c++11 main.cpp
|
||||
10
v3/main.cpp
Normal file
10
v3/main.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
int main() {
|
||||
std::cout <<
|
||||
"check" //memory_test_generateConstPlayfield()
|
||||
<< std::endl
|
||||
;
|
||||
}
|
||||
120
v3/memory.cpp
Normal file
120
v3/memory.cpp
Normal 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
v3/memory_Context.cpp
Normal file
7
v3/memory_Context.cpp
Normal file
@@ -0,0 +1,7 @@
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "entities.h"
|
||||
|
||||
|
||||
|
||||
|
||||
209
v3/memory_test.cpp
Normal file
209
v3/memory_test.cpp
Normal 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
v3/tPythonC++/CPP.py
Normal file
153
v3/tPythonC++/CPP.py
Normal 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
v3/tPythonC++/Function.py
Normal file
76
v3/tPythonC++/Function.py
Normal 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
v3/tPythonC++/process.py
Executable file
37
v3/tPythonC++/process.py
Executable 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
v3/tPythonC++/translate
Executable file
17
v3/tPythonC++/translate
Executable 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
v3/translate-py-cxx
Executable file
7
v3/translate-py-cxx
Executable 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
|
||||
Reference in New Issue
Block a user