@@ -9,7 +9,7 @@ from llm_test_Python import * | |||
from memory_test import * | |||
import sys | |||
print(ctx_test_Controller_executeFunctions_set()) | |||
print(ctx_test_Controller_executeFunctions_registerFunction_set()) | |||
print(ctx_test_Controller_processQueue()) | |||
print(ctx_test_Controller_registerFieldCallback_match()) | |||
print(ctx_test_Controller_registerFieldCallback_mismatch()) | |||
@@ -0,0 +1,86 @@ | |||
#include <map> | |||
#include <string> | |||
#include <vector> | |||
#include "ctx.h" | |||
#include "llm.h" | |||
#include "memory_Context.h" | |||
#include "main.h" | |||
std::string ctx_test_Controller_executeFunctions_set( | |||
) { | |||
auto c = memory_createContext(); | |||
auto ctrl = ctx_Controller(c); | |||
// Disable automatic invocation of executeFunctions. | |||
ctrl.isProcessingQueue = true; | |||
ctrl.set("input", "123"); | |||
ctrl.registerFunction(__processInput); | |||
// Apply 'input'. | |||
ctrl.executeFunctions(); | |||
// Apply 'outputHelp'. | |||
ctrl.executeFunctions(); | |||
if ( | |||
c.input == "123" && | |||
c.outputHelp == "Checked" | |||
) { | |||
return "OK: ctx_Controller_executeFunctions_set"; | |||
} | |||
return "ERR: ctx_Controller_executeFunctions_set"; | |||
} | |||
std::string ctx_test_Controller_processQueue( | |||
) { | |||
auto c = memory_createContext(); | |||
auto ctrl = ctx_Controller(c); | |||
ctrl.registerFunction(__processInput); | |||
ctrl.set("input", "abc");; | |||
if ( | |||
c.input == "abc" && | |||
c.outputHelp == "Checked" | |||
) { | |||
return "OK: ctx_Controller_processQueue"; | |||
} | |||
return "ERR: ctx_Controller_processQueue"; | |||
} | |||
std::string ctx_test_memoryContext_field( | |||
) { | |||
auto c = memory_createContext(); | |||
c.input = "abc"; | |||
if ( | |||
c.field("input") == "abc" | |||
) { | |||
return "OK: ctx_memoryContext_field"; | |||
} | |||
return "ERR: ctx_memoryContext_field"; | |||
} | |||
std::string ctx_test_memoryContext_setField( | |||
) { | |||
auto c = memory_createContext(); | |||
c.input = "abc"; | |||
c.setField("input", "123"); | |||
if ( | |||
c.field("input") == "123" | |||
) { | |||
return "OK: ctx_memoryContext_setField"; | |||
} | |||
return "ERR: ctx_memoryContext_setField"; | |||
} | |||
// Auxiliary functions. | |||
memory_Context __processInput( | |||
memory_Context c | |||
) { | |||
if ( | |||
c.recentField == "input" | |||
) { | |||
c.outputHelp = "Checked"; | |||
c.recentField = "outputHelp"; | |||
return c; | |||
} | |||
c.recentField = "none"; | |||
return c; | |||
} | |||
@@ -0,0 +1,81 @@ | |||
from ctx import * | |||
from memory import * | |||
from memory_Context import * | |||
def ctx_test_Controller_executeFunctions_set( | |||
) -> str: | |||
c = memory_createContext() | |||
ctrl = ctx_Controller(c) | |||
# Disable automatic invocation of executeFunctions. | |||
ctrl.isProcessingQueue = True | |||
ctrl.set("input", "123") | |||
ctrl.registerFunction(__processInput) | |||
# Apply 'input'. | |||
ctrl.executeFunctions() | |||
# Apply 'outputHelp'. | |||
ctrl.executeFunctions() | |||
if ( | |||
c.input == "123" and | |||
c.outputHelp == "Checked" | |||
): | |||
return "OK: ctx_Controller_executeFunctions_set" | |||
#} | |||
return "ERR: ctx_Controller_executeFunctions_set" | |||
#} | |||
def ctx_test_Controller_processQueue( | |||
) -> str: | |||
c = memory_createContext() | |||
ctrl = ctx_Controller(c) | |||
ctrl.registerFunction(__processInput) | |||
ctrl.set("input", "abc"); | |||
if ( | |||
c.input == "abc" and | |||
c.outputHelp == "Checked" | |||
): | |||
return "OK: ctx_Controller_processQueue" | |||
#} | |||
return "ERR: ctx_Controller_processQueue" | |||
#} | |||
def ctx_test_memoryContext_field( | |||
) -> str: | |||
c = memory_createContext() | |||
c.input = "abc" | |||
if ( | |||
c.field("input") == "abc" | |||
): | |||
return "OK: ctx_memoryContext_field" | |||
#} | |||
return "ERR: ctx_memoryContext_field" | |||
#} | |||
def ctx_test_memoryContext_setField( | |||
) -> str: | |||
c = memory_createContext() | |||
c.input = "abc" | |||
c.setField("input", "123") | |||
if ( | |||
c.field("input") == "123" | |||
): | |||
return "OK: ctx_memoryContext_setField" | |||
#} | |||
return "ERR: ctx_memoryContext_setField" | |||
#} | |||
# Auxiliary functions. | |||
@llm_by_value | |||
def __processInput( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if ( | |||
c.recentField == "input" | |||
): | |||
c.outputHelp = "Checked" | |||
c.recentField = "outputHelp" | |||
return c | |||
#} | |||
c.recentField = "none" | |||
return c | |||
#} |
@@ -0,0 +1,53 @@ | |||
from ctx import * | |||
from memory import * | |||
from memory_Context import * | |||
def ctx_test_Python_Controller_registerFieldCallback_match( | |||
) -> str: | |||
c = memory_createContext() | |||
ctrl = ctx_Controller(c) | |||
c.input = "123" | |||
c.recentField = "input" | |||
globals()["__callbackInput"] = "" | |||
ctrl.registerFieldCallback("input", __setCallbackInput) | |||
ctrl.reportContext() | |||
val = globals()["__callbackInput"] | |||
if ( | |||
c.input == globals()["__callbackInput"] | |||
): | |||
return "OK: ctx_Python_Controller_registerFieldCallback_match" | |||
#} | |||
return f"ERR: ctx_Python_Controller_registerFieldCallback_match" | |||
#} | |||
def ctx_test_Python_Controller_registerFieldCallback_mismatch( | |||
) -> str: | |||
c = memory_createContext() | |||
ctrl = ctx_Controller(c) | |||
c.input = "123" | |||
c.outputHelp = "you" | |||
c.recentField = "outputHelp" | |||
globals()["__callbackInput"] = "" | |||
ctrl.registerFieldCallback("input", __setCallbackInput) | |||
ctrl.reportContext() | |||
val = globals()["__callbackInput"] | |||
if ( | |||
globals()["__callbackInput"] == "" | |||
): | |||
return "OK: ctx_Python_Controller_registerFieldCallback_mismatch" | |||
#} | |||
return f"ERR: ctx_Python_Controller_registerFieldCallback_mismatch" | |||
#} | |||
# Auxiliary. | |||
__callbackInput = "" | |||
@llm_by_value | |||
def __setCallbackInput(c): | |||
if ( | |||
c.recentField == "input" | |||
): | |||
globals()["__callbackInput"] = c.input | |||
#} | |||
#} |
@@ -0,0 +1,549 @@ | |||
/** | |||
* Implementation of N4562 std::experimental::any (merged into C++17 as std::any) | |||
* for C++11 compilers. | |||
* | |||
* See also: | |||
* + http://en.cppreference.com/w/cpp/any | |||
* + http://en.cppreference.com/w/cpp/experimental/any | |||
* + http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4562.html#any | |||
* + https://cplusplus.github.io/LWG/lwg-active.html#2509 | |||
* | |||
* Copyright (c) 2016 Denilson das Mercês Amorim | |||
* Copyright (c) 2018 Claudio Fantacci | |||
* | |||
* Distributed under the Boost Software License, Version 1.0. | |||
* (See accompanying file LICENSE.md or copy at http://www.boost.org/LICENSE_1_0.txt) | |||
*/ | |||
#ifndef ANY_H | |||
#define ANY_H | |||
#include <stdexcept> | |||
#include <typeinfo> | |||
#include <type_traits> | |||
namespace libany | |||
{ | |||
class bad_any_cast : public std::bad_cast | |||
{ | |||
public: | |||
const char* what() const noexcept override | |||
{ | |||
return "bad any_cast"; | |||
} | |||
}; | |||
class any final | |||
{ | |||
public: | |||
/** | |||
* Constructs an object of type any with an empty state. | |||
*/ | |||
any() : | |||
vtable(nullptr) | |||
{ } | |||
/** | |||
* Constructs an object of type any with an equivalent state as other. | |||
*/ | |||
any(const any& rhs) : | |||
vtable(rhs.vtable) | |||
{ | |||
if(rhs.has_value()) | |||
{ | |||
rhs.vtable->copy(rhs.storage, this->storage); | |||
} | |||
} | |||
/** | |||
* Constructs an object of type any with a state equivalent to the original state of other. | |||
* rhs is left in a valid but otherwise unspecified state. | |||
*/ | |||
any(any&& rhs) noexcept : | |||
vtable(rhs.vtable) | |||
{ | |||
if(rhs.has_value()) | |||
{ | |||
rhs.vtable->move(rhs.storage, this->storage); | |||
rhs.vtable = nullptr; | |||
} | |||
} | |||
/** | |||
* Same effect as this->clear(). | |||
*/ | |||
~any() | |||
{ | |||
this->reset(); | |||
} | |||
/** | |||
* Constructs an object of type any that contains an object of type T direct-initialized with std::forward<ValueType>(value). | |||
* T shall satisfy the CopyConstructible requirements, otherwise the program is ill-formed. | |||
* This is because an `any` may be copy constructed into another `any` at any time, so a copy should always be allowed. | |||
*/ | |||
template<typename ValueType, typename = typename std::enable_if<!std::is_same<typename std::decay<ValueType>::type, any>::value>::type> | |||
any(ValueType&& value) | |||
{ | |||
static_assert(std::is_copy_constructible<typename std::decay<ValueType>::type>::value, | |||
"T shall satisfy the CopyConstructible requirements."); | |||
this->construct(std::forward<ValueType>(value)); | |||
} | |||
/** | |||
* Has the same effect as any(rhs).swap(*this). No effects if an exception is thrown. | |||
*/ | |||
any& operator=(const any& rhs) | |||
{ | |||
any(rhs).swap(*this); | |||
return *this; | |||
} | |||
/** | |||
* Has the same effect as any(std::move(rhs)).swap(*this). | |||
* The state of *this is equivalent to the original state of rhs and rhs is left in a valid | |||
* but otherwise unspecified state. | |||
*/ | |||
any& operator=(any&& rhs) noexcept | |||
{ | |||
any(std::move(rhs)).swap(*this); | |||
return *this; | |||
} | |||
/** | |||
* Has the same effect as any(std::forward<ValueType>(value)).swap(*this). No effect if a exception is thrown. | |||
* T shall satisfy the CopyConstructible requirements, otherwise the program is ill-formed. | |||
* This is because an `any` may be copy constructed into another `any` at any time, so a copy should always be allowed. | |||
*/ | |||
template<typename ValueType, typename = typename std::enable_if<!std::is_same<typename std::decay<ValueType>::type, any>::value>::type> | |||
any& operator=(ValueType&& value) | |||
{ | |||
static_assert(std::is_copy_constructible<typename std::decay<ValueType>::type>::value, "T shall satisfy the CopyConstructible requirements."); | |||
any(std::forward<ValueType>(value)).swap(*this); | |||
return *this; | |||
} | |||
/** | |||
* If not empty, destroys the contained object. | |||
*/ | |||
void reset() noexcept | |||
{ | |||
if(has_value()) | |||
{ | |||
this->vtable->destroy(storage); | |||
this->vtable = nullptr; | |||
} | |||
} | |||
/** | |||
* Returns true if *this has no contained object, otherwise false. | |||
*/ | |||
bool has_value() const noexcept | |||
{ | |||
return this->vtable != nullptr; | |||
} | |||
/** | |||
* If *this has a contained object of type T, typeid(T); otherwise typeid(void). | |||
*/ | |||
const std::type_info& type() const noexcept | |||
{ | |||
return has_value()? this->vtable->type() : typeid(void); | |||
} | |||
/** | |||
* Exchange the states of *this and rhs. | |||
*/ | |||
void swap(any& other) noexcept | |||
{ | |||
if(this->vtable != other.vtable) | |||
{ | |||
any tmp(std::move(other)); | |||
other.vtable = this->vtable; | |||
if(this->vtable != nullptr) | |||
this->vtable->move(this->storage, other.storage); | |||
this->vtable = tmp.vtable; | |||
if(tmp.vtable != nullptr) | |||
{ | |||
tmp.vtable->move(tmp.storage, this->storage); | |||
tmp.vtable = nullptr; | |||
} | |||
} | |||
else | |||
{ | |||
if(this->vtable != nullptr) | |||
this->vtable->swap(this->storage, other.storage); | |||
} | |||
} | |||
private: | |||
union storage_union | |||
{ | |||
using stack_storage_t = typename std::aligned_storage<2 * sizeof(void*), std::alignment_of<void*>::value>::type; | |||
void* dynamic; | |||
stack_storage_t stack; | |||
}; | |||
/** | |||
* Base VTable specification. | |||
* | |||
* Note: The caller is responsible for doing .vtable = nullptr after destructful operations | |||
* such as destroy() and/or move(). | |||
*/ | |||
struct vtable_type | |||
{ | |||
/** | |||
* The type of the object this vtable is for. | |||
*/ | |||
const std::type_info& (*type)() noexcept; | |||
/** | |||
* Destroys the object in the union. | |||
* The state of the union after this call is unspecified, caller must ensure not to use src anymore. | |||
*/ | |||
void(*destroy)(storage_union&) noexcept; | |||
/** | |||
* Copies the **inner** content of the src union into the yet unitialized dest union. | |||
* As such, both inner objects will have the same state, but on separate memory locations. | |||
*/ | |||
void(*copy)(const storage_union& src, storage_union& dest); | |||
/** | |||
* Moves the storage from src to the yet unitialized dest union. | |||
* The state of src after this call is unspecified, caller must ensure not to use src anymore. | |||
*/ | |||
void(*move)(storage_union& src, storage_union& dest) noexcept; | |||
/** | |||
* Exchanges the storage between lhs and rhs. | |||
*/ | |||
void(*swap)(storage_union& lhs, storage_union& rhs) noexcept; | |||
}; | |||
/** | |||
* VTable for dynamically allocated storage. | |||
*/ | |||
template<typename T> | |||
struct vtable_dynamic | |||
{ | |||
static const std::type_info& type() noexcept | |||
{ | |||
return typeid(T); | |||
} | |||
static void destroy(storage_union& storage) noexcept | |||
{ | |||
delete reinterpret_cast<T*>(storage.dynamic); | |||
} | |||
static void copy(const storage_union& src, storage_union& dest) | |||
{ | |||
dest.dynamic = new T(*reinterpret_cast<const T*>(src.dynamic)); | |||
} | |||
static void move(storage_union& src, storage_union& dest) noexcept | |||
{ | |||
dest.dynamic = src.dynamic; | |||
src.dynamic = nullptr; | |||
} | |||
static void swap(storage_union& lhs, storage_union& rhs) noexcept | |||
{ | |||
std::swap(lhs.dynamic, rhs.dynamic); | |||
} | |||
}; | |||
/** | |||
* VTable for stack allocated storage. | |||
*/ | |||
template<typename T> | |||
struct vtable_stack | |||
{ | |||
static const std::type_info& type() noexcept | |||
{ | |||
return typeid(T); | |||
} | |||
static void destroy(storage_union& storage) noexcept | |||
{ | |||
reinterpret_cast<T*>(&storage.stack)->~T(); | |||
} | |||
static void copy(const storage_union& src, storage_union& dest) | |||
{ | |||
new (&dest.stack) T(reinterpret_cast<const T&>(src.stack)); | |||
} | |||
static void move(storage_union& src, storage_union& dest) noexcept | |||
{ | |||
/** | |||
* One of the conditions for using vtable_stack is a nothrow move constructor, | |||
* so this move constructor will never throw a exception. | |||
*/ | |||
new (&dest.stack) T(std::move(reinterpret_cast<T&>(src.stack))); | |||
destroy(src); | |||
} | |||
static void swap(storage_union& lhs, storage_union& rhs) noexcept | |||
{ | |||
storage_union tmp_storage; | |||
move(rhs, tmp_storage); | |||
move(lhs, rhs); | |||
move(tmp_storage, lhs); | |||
} | |||
}; | |||
/** | |||
* Whether the type T must be dynamically allocated or can be stored on the stack. | |||
*/ | |||
template<typename T> | |||
struct requires_allocation : | |||
std::integral_constant<bool, !(std::is_nothrow_move_constructible<T>::value // N4562 6.3/3 [any.class] | |||
&& sizeof(T) <= sizeof(storage_union::stack) | |||
&& std::alignment_of<T>::value <= std::alignment_of<storage_union::stack_storage_t>::value)> | |||
{ }; | |||
/** | |||
* Returns the pointer to the vtable of the type T. | |||
*/ | |||
template<typename T> | |||
static vtable_type* vtable_for_type() | |||
{ | |||
using VTableType = typename std::conditional<requires_allocation<T>::value, vtable_dynamic<T>, vtable_stack<T>>::type; | |||
static vtable_type table = { VTableType::type, VTableType::destroy, VTableType::copy, VTableType::move, VTableType::swap }; | |||
return &table; | |||
} | |||
protected: | |||
template<typename T> | |||
friend const T* any_cast(const any* operand) noexcept; | |||
template<typename T> | |||
friend T* any_cast(any* operand) noexcept; | |||
/** | |||
* Same effect as is_same(this->type(), t); | |||
*/ | |||
bool is_typed(const std::type_info& t) const | |||
{ | |||
return is_same(this->type(), t); | |||
} | |||
/** | |||
* Checks if two type infos are the same. | |||
* If ANY_IMPL_FAST_TYPE_INFO_COMPARE is defined, checks only the address of the | |||
* type infos, otherwise does an actual comparision. Checking addresses is | |||
* only a valid approach when there's no interaction with outside sources | |||
* (other shared libraries and such). | |||
*/ | |||
static bool is_same(const std::type_info& a, const std::type_info& b) | |||
{ | |||
#ifdef ANY_IMPL_FAST_TYPE_INFO_COMPARE | |||
return &a == &b; | |||
#else | |||
return a == b; | |||
#endif | |||
} | |||
/** | |||
* Casts (with no type_info checks) the storage pointer as const T*. | |||
*/ | |||
template<typename T> | |||
const T* cast() const noexcept | |||
{ | |||
return requires_allocation<typename std::decay<T>::type>::value ? reinterpret_cast<const T*>(storage.dynamic) : reinterpret_cast<const T*>(&storage.stack); | |||
} | |||
/** | |||
* Casts (with no type_info checks) the storage pointer as T*. | |||
*/ | |||
template<typename T> | |||
T* cast() noexcept | |||
{ | |||
return requires_allocation<typename std::decay<T>::type>::value ? reinterpret_cast<T*>(storage.dynamic) : reinterpret_cast<T*>(&storage.stack); | |||
} | |||
private: | |||
storage_union storage; // On offset(0) so no padding for align | |||
vtable_type* vtable; | |||
template<typename ValueType, typename T> | |||
typename std::enable_if<requires_allocation<T>::value>::type do_construct(ValueType&& value) | |||
{ | |||
storage.dynamic = new T(std::forward<ValueType>(value)); | |||
} | |||
template<typename ValueType, typename T> | |||
typename std::enable_if<!requires_allocation<T>::value>::type do_construct(ValueType&& value) | |||
{ | |||
new (&storage.stack) T(std::forward<ValueType>(value)); | |||
} | |||
/** | |||
* Chooses between stack and dynamic allocation for the type decay_t<ValueType>, | |||
* assigns the correct vtable, and constructs the object on our storage. | |||
*/ | |||
template<typename ValueType> | |||
void construct(ValueType&& value) | |||
{ | |||
using T = typename std::decay<ValueType>::type; | |||
this->vtable = vtable_for_type<T>(); | |||
do_construct<ValueType,T>(std::forward<ValueType>(value)); | |||
} | |||
}; | |||
namespace detail | |||
{ | |||
template<typename ValueType> | |||
inline ValueType any_cast_move_if_true(typename std::remove_reference<ValueType>::type* p, std::true_type) | |||
{ | |||
return std::move(*p); | |||
} | |||
template<typename ValueType> | |||
inline ValueType any_cast_move_if_true(typename std::remove_reference<ValueType>::type* p, std::false_type) | |||
{ | |||
return *p; | |||
} | |||
} | |||
/** | |||
* Performs *any_cast<add_const_t<remove_reference_t<ValueType>>>(&operand), or throws bad_any_cast on failure. | |||
*/ | |||
template<typename ValueType> | |||
inline ValueType any_cast(const any& operand) | |||
{ | |||
auto p = any_cast<typename std::add_const<typename std::remove_reference<ValueType>::type>::type>(&operand); | |||
if(p == nullptr) throw bad_any_cast(); | |||
return *p; | |||
} | |||
/** | |||
* Performs *any_cast<remove_reference_t<ValueType>>(&operand), or throws bad_any_cast on failure. | |||
*/ | |||
template<typename ValueType> | |||
inline ValueType any_cast(any& operand) | |||
{ | |||
auto p = any_cast<typename std::remove_reference<ValueType>::type>(&operand); | |||
if(p == nullptr) throw bad_any_cast(); | |||
return *p; | |||
} | |||
/** | |||
* If ANY_IMPL_ANYCAST_MOVEABLE is not defined, does as N4562 specifies: | |||
* Performs *any_cast<remove_reference_t<ValueType>>(&operand), or throws bad_any_cast on failure. | |||
* | |||
* If ANY_IMPL_ANYCAST_MOVEABLE is defined, does as LWG Defect 2509 specifies [1]: | |||
* If ValueType is MoveConstructible and isn't a lvalue reference, performs | |||
* std::move(*any_cast<remove_reference_t<ValueType>>(&operand)), otherwise | |||
* *any_cast<remove_reference_t<ValueType>>(&operand). | |||
* Throws bad_any_cast on failure. | |||
* | |||
* [1] https://cplusplus.github.io/LWG/lwg-active.html#2509 | |||
*/ | |||
template<typename ValueType> | |||
inline ValueType any_cast(any&& operand) | |||
{ | |||
#ifdef ANY_IMPL_ANY_CAST_MOVEABLE | |||
using can_move = std::integral_constant<bool, std::is_move_constructible<ValueType>::value && !std::is_lvalue_reference<ValueType>::value>; | |||
#else | |||
using can_move = std::false_type; | |||
#endif | |||
auto p = any_cast<typename std::remove_reference<ValueType>::type>(&operand); | |||
if(p == nullptr) throw bad_any_cast(); | |||
return detail::any_cast_move_if_true<ValueType>(p, can_move()); | |||
} | |||
/** | |||
* If operand != nullptr && operand->type() == typeid(ValueType), a pointer to the object | |||
* contained by operand, otherwise nullptr. | |||
*/ | |||
template<typename T> | |||
inline const T* any_cast(const any* operand) noexcept | |||
{ | |||
if(operand == nullptr || !operand->is_typed(typeid(T))) | |||
return nullptr; | |||
else | |||
return operand->cast<T>(); | |||
} | |||
/** | |||
* If operand != nullptr && operand->type() == typeid(ValueType), a pointer to the object | |||
* contained by operand, otherwise nullptr. | |||
*/ | |||
template<typename T> | |||
inline T* any_cast(any* operand) noexcept | |||
{ | |||
if(operand == nullptr || !operand->is_typed(typeid(T))) | |||
return nullptr; | |||
else | |||
return operand->cast<T>(); | |||
} | |||
inline void swap(any& lhs, any& rhs) noexcept | |||
{ | |||
lhs.swap(rhs); | |||
} | |||
} | |||
#endif /* ANY_H */ |
@@ -0,0 +1,220 @@ | |||
#include <map> | |||
#include <string> | |||
#include <vector> | |||
#include "ctx.h" | |||
#include "llm.h" | |||
#include "memory_Context.h" | |||
#include "main.h" | |||
// Exit | |||
// | |||
// Conditions: | |||
// 1. `e`, `exit`, `q`, or `quit` was entered | |||
// 2. Victory has just been reported | |||
memory_Context cli_exit( | |||
memory_Context c | |||
) { | |||
if ( | |||
c.recentField == "input" && | |||
( | |||
c.input == "e" || | |||
c.input == "exit" || | |||
c.input == "q" || | |||
c.input == "quit" | |||
) | |||
) { | |||
c.exit = true; | |||
c.recentField = "exit"; | |||
return c; | |||
} | |||
if ( | |||
c.recentField == "outputVictory" | |||
) { | |||
c.exit = true; | |||
c.recentField = "exit"; | |||
return c; | |||
} | |||
c.recentField = "none"; | |||
return c; | |||
} | |||
// Ask user to go on | |||
// | |||
// Conditions: | |||
// 1. Items have just matched and there are still items left to select | |||
memory_Context cli_goOn( | |||
memory_Context c | |||
) { | |||
if ( | |||
c.recentField == "outputMatchedItems" && | |||
c.hiddenItems.size() != c.playfieldItems.size() | |||
) { | |||
c.outputGoOn = "Go on:"; | |||
c.recentField = "outputGoOn"; | |||
return c; | |||
} | |||
c.recentField = "none"; | |||
return c; | |||
} | |||
// Greet the user | |||
// | |||
// Conditions: | |||
// 1. Just launched | |||
memory_Context cli_greetUser( | |||
memory_Context c | |||
) { | |||
if ( | |||
c.recentField == "didLaunch" && | |||
c.didLaunch == true | |||
) { | |||
c.outputGreeting = "OGS Memory Command Line Interface"; | |||
c.recentField = "outputGreeting"; | |||
return c; | |||
} | |||
c.recentField = "none"; | |||
return c; | |||
} | |||
// Ask user to select second item to have a pair of selected items | |||
// | |||
// Conditions: | |||
// 1. Single item has just been selected | |||
memory_Context cli_promptSecondItemSelection( | |||
memory_Context c | |||
) { | |||
if ( | |||
c.recentField == "selectedItems" && | |||
c.selectedItems.size() == 1 | |||
) { | |||
c.outputPromptSelection = "Select the second item now:"; | |||
c.recentField = "outputPromptSelection"; | |||
return c; | |||
} | |||
c.recentField = "none"; | |||
return c; | |||
} | |||
// Report matched items | |||
// | |||
// Conditions: | |||
// 1. Items were hidden (i.e., they matched) | |||
memory_Context cli_reportMatchedItems( | |||
memory_Context c | |||
) { | |||
if ( | |||
c.recentField == "hiddenItems" | |||
) { | |||
c.outputMatchedItems = "Items matched!"; | |||
c.recentField = "outputMatchedItems"; | |||
return c; | |||
} | |||
c.recentField = "none"; | |||
return c; | |||
} | |||
// Report victory | |||
memory_Context cli_reportVictory( | |||
memory_Context c | |||
) { | |||
if ( | |||
c.recentField == "victory" | |||
) { | |||
c.outputVictory = "VICTORY! The game is over now"; | |||
c.recentField = "outputVictory"; | |||
return c; | |||
} | |||
c.recentField = "none"; | |||
return c; | |||
} | |||
// Select item | |||
// | |||
// Conditions: | |||
// 1. Id is digit | |||
memory_Context cli_selectItem( | |||
memory_Context c | |||
) { | |||
if ( | |||
c.recentField == "input" && | |||
llm_isDigit(c.input) | |||
) { | |||
// CLI ids start with 1 while memory module has ids starting with 0 | |||
// Convert CLI id to memory id | |||
c.selectedId = llm_strToInt(c.input) - 1; | |||
c.recentField = "selectedId"; | |||
return c; | |||
} | |||
c.recentField = "none"; | |||
return c; | |||
} | |||
// Show help (aka commands) | |||
// | |||
// Conditions: | |||
// 1. Just launched | |||
// 1. `h` or `help` was entered | |||
memory_Context cli_showHelp( | |||
memory_Context c | |||
) { | |||
if ( | |||
( | |||
c.recentField == "didLaunch" && | |||
c.didLaunch == true | |||
) || | |||
( | |||
c.recentField == "input" && | |||
c.input == "h" | |||
) || | |||
( | |||
c.recentField == "input" && | |||
c.input == "help" | |||
) | |||
) { | |||
c.outputHelp = "Commands:\n\te, exit, q, quit\n\t\tExit\n\th, help\n\t\tList commands\n\t1, 2, 3, ...\n\t\tSelect item\nEnter your choice:"; | |||
c.recentField = "outputHelp"; | |||
return c; | |||
} | |||
c.recentField = "none"; | |||
return c; | |||
} | |||
// Report mismatched items | |||
memory_Context cli_reportMismatchedItems( | |||
memory_Context c | |||
) { | |||
if ( | |||
c.recentField == "mismatchedItems" | |||
) { | |||
c.outputMismatchedItems = "Wrong! Try again:"; | |||
c.recentField = "outputMismatchedItems"; | |||
return c; | |||
} | |||
c.recentField = "none"; | |||
return c; | |||
} | |||
//// Report selection of invalid item ids | |||
//// | |||
//// Conditions: | |||
//// 1. Index out of bounds: less than minimum | |||
//// 2. Index out of bounds: greater than maximum | |||
//// 3. Item is already hidden | |||
////@llm_by_value | |||
////def cli_shouldReportInvalidItemSelection( | |||
//// c: cli_Context | |||
////) -> cli_Context: | |||
//// if ( | |||
//// c.recentField == "cMemory" and | |||
//// c.cMemory.recentField == "selectedItems" and | |||
//// len(c.cMemory.selectedItems) == 1 | |||
//// ): | |||
//// c.outputPromptSelection = "Select the second item now:" | |||
//// c.recentField = "outputPromptSelection" | |||
//// return c | |||
//// //} | |||
//// c.recentField = "none" | |||
//// return c | |||
//////} | |||
@@ -0,0 +1,222 @@ | |||
from memory_Context import * | |||
from llm import * | |||
# Exit | |||
# | |||
# Conditions: | |||
# 1. `e`, `exit`, `q`, or `quit` was entered | |||
# 2. Victory has just been reported | |||
@llm_by_value | |||
def cli_exit( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if ( | |||
c.recentField == "input" and | |||
( | |||
c.input == "e" or | |||
c.input == "exit" or | |||
c.input == "q" or | |||
c.input == "quit" | |||
) | |||
): | |||
c.exit = True | |||
c.recentField = "exit" | |||
return c | |||
#} | |||
if ( | |||
c.recentField == "outputVictory" | |||
): | |||
c.exit = True | |||
c.recentField = "exit" | |||
return c | |||
#} | |||
c.recentField = "none" | |||
return c | |||
#} | |||
# Ask user to go on | |||
# | |||
# Conditions: | |||
# 1. Items have just matched and there are still items left to select | |||
@llm_by_value | |||
def cli_goOn( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if ( | |||
c.recentField == "outputMatchedItems" and | |||
len(c.hiddenItems) != len(c.playfieldItems) | |||
): | |||
c.outputGoOn = "Go on:" | |||
c.recentField = "outputGoOn" | |||
return c | |||
#} | |||
c.recentField = "none" | |||
return c | |||
#} | |||
# Greet the user | |||
# | |||
# Conditions: | |||
# 1. Just launched | |||
@llm_by_value | |||
def cli_greetUser( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if ( | |||
c.recentField == "didLaunch" and | |||
c.didLaunch == True | |||
): | |||
c.outputGreeting = "OGS Memory Command Line Interface" | |||
c.recentField = "outputGreeting" | |||
return c | |||
#} | |||
c.recentField = "none" | |||
return c | |||
#} | |||
# Ask user to select second item to have a pair of selected items | |||
# | |||
# Conditions: | |||
# 1. Single item has just been selected | |||
@llm_by_value | |||
def cli_promptSecondItemSelection( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if ( | |||
c.recentField == "selectedItems" and | |||
len(c.selectedItems) == 1 | |||
): | |||
c.outputPromptSelection = "Select the second item now:" | |||
c.recentField = "outputPromptSelection" | |||
return c | |||
#} | |||
c.recentField = "none" | |||
return c | |||
#} | |||
# Report matched items | |||
# | |||
# Conditions: | |||
# 1. Items were hidden (i.e., they matched) | |||
@llm_by_value | |||
def cli_reportMatchedItems( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if ( | |||
c.recentField == "hiddenItems" | |||
): | |||
c.outputMatchedItems = "Items matched!" | |||
c.recentField = "outputMatchedItems" | |||
return c | |||
#} | |||
c.recentField = "none" | |||
return c | |||
#} | |||
# Report victory | |||
@llm_by_value | |||
def cli_reportVictory( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if ( | |||
c.recentField == "victory" | |||
): | |||
c.outputVictory = "VICTORY! The game is over now" | |||
c.recentField = "outputVictory" | |||
return c | |||
#} | |||
c.recentField = "none" | |||
return c | |||
#} | |||
# Select item | |||
# | |||
# Conditions: | |||
# 1. Id is digit | |||
@llm_by_value | |||
def cli_selectItem( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if ( | |||
c.recentField == "input" and | |||
llm_isDigit(c.input) | |||
): | |||
# CLI ids start with 1 while memory module has ids starting with 0 | |||
# Convert CLI id to memory id | |||
c.selectedId = llm_strToInt(c.input) - 1 | |||
c.recentField = "selectedId" | |||
return c | |||
#} | |||
c.recentField = "none" | |||
return c | |||
#} | |||
# Show help (aka commands) | |||
# | |||
# Conditions: | |||
# 1. Just launched | |||
# 1. `h` or `help` was entered | |||
@llm_by_value | |||
def cli_showHelp( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if ( | |||
( | |||
c.recentField == "didLaunch" and | |||
c.didLaunch == True | |||
) or | |||
( | |||
c.recentField == "input" and | |||
c.input == "h" | |||
) or | |||
( | |||
c.recentField == "input" and | |||
c.input == "help" | |||
) | |||
): | |||
c.outputHelp = "Commands:\n\te, exit, q, quit\n\t\tExit\n\th, help\n\t\tList commands\n\t1, 2, 3, ...\n\t\tSelect item\nEnter your choice:" | |||
c.recentField = "outputHelp" | |||
return c | |||
#} | |||
c.recentField = "none" | |||
return c | |||
#} | |||
# Report mismatched items | |||
@llm_by_value | |||
def cli_reportMismatchedItems( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if ( | |||
c.recentField == "mismatchedItems" | |||
): | |||
c.outputMismatchedItems = "Wrong! Try again:" | |||
c.recentField = "outputMismatchedItems" | |||
return c | |||
#} | |||
c.recentField = "none" | |||
return c | |||
#} | |||
## Report selection of invalid item ids | |||
## | |||
## Conditions: | |||
## 1. Index out of bounds: less than minimum | |||
## 2. Index out of bounds: greater than maximum | |||
## 3. Item is already hidden | |||
##@llm_by_value | |||
##def cli_shouldReportInvalidItemSelection( | |||
## c: cli_Context | |||
##) -> cli_Context: | |||
## if ( | |||
## c.recentField == "cMemory" and | |||
## c.cMemory.recentField == "selectedItems" and | |||
## len(c.cMemory.selectedItems) == 1 | |||
## ): | |||
## c.outputPromptSelection = "Select the second item now:" | |||
## c.recentField = "outputPromptSelection" | |||
## return c | |||
## #} | |||
## c.recentField = "none" | |||
## return c | |||
###} |
@@ -0,0 +1,309 @@ | |||
#include <map> | |||
#include <string> | |||
#include <vector> | |||
#include "ctx.h" | |||
#include "llm.h" | |||
#include "memory_Context.h" | |||
#include "main.h" | |||
std::string cli_test_exit_e( | |||
) { | |||
auto c = memory_createContext(); | |||
c.input = "e"; | |||
c.recentField = "input"; | |||
c = cli_exit(c); | |||
if ( | |||
c.recentField == "exit" | |||
) { | |||
return "OK: cli_exit_e"; | |||
} | |||
return "ERR: cli_exit_e"; | |||
} | |||
std::string cli_test_exit_exit( | |||
) { | |||
auto c = memory_createContext(); | |||
c.input = "exit"; | |||
c.recentField = "input"; | |||
c = cli_exit(c); | |||
if ( | |||
c.recentField == "exit" | |||
) { | |||
return "OK: cli_exit_exit"; | |||
} | |||
return "ERR: cli_exit_e"; | |||
} | |||
std::string cli_test_exit_victory( | |||
) { | |||
auto c = memory_createContext(); | |||
c.playfieldSize = 2; | |||
c.recentField = "playfieldSize"; | |||
c = memory_generateConstPlayfield(c); | |||
// Match the first pair of tiles. | |||
c.input = "1"; | |||
c.recentField = "input"; | |||
c = cli_selectItem(c); | |||
c = memory_selectItem(c); | |||
c.input = "2"; | |||
c.recentField = "input"; | |||
c = cli_selectItem(c); | |||
c = memory_selectItem(c); | |||
c = memory_hideMatchingItems(c); | |||
// Match the second pair of tiles. | |||
c.input = "3"; | |||
c.recentField = "input"; | |||
c = cli_selectItem(c); | |||
c = memory_selectItem(c); | |||
c.input = "4"; | |||
c.recentField = "input"; | |||
c = cli_selectItem(c); | |||
c = memory_selectItem(c); | |||
c = memory_hideMatchingItems(c); | |||
c = memory_detectVictory(c); | |||
c = cli_reportVictory(c); | |||
c = cli_exit(c); | |||
if ( | |||
c.recentField == "exit" | |||
) { | |||
return "OK: cli_exit_victory"; | |||
} | |||
return "ERR: cli_exit_victory"; | |||
} | |||
std::string cli_test_exit_q( | |||
) { | |||
auto c = memory_createContext(); | |||
c.input = "q"; | |||
c.recentField = "input"; | |||
c = cli_exit(c); | |||
if ( | |||
c.recentField == "exit" | |||
) { | |||
return "OK: cli_exit_q"; | |||
} | |||
return "ERR: cli_exit_q"; | |||
} | |||
std::string cli_test_exit_quit( | |||
) { | |||
auto c = memory_createContext(); | |||
c.input = "quit"; | |||
c.recentField = "input"; | |||
c = cli_exit(c); | |||
if ( | |||
c.recentField == "exit" | |||
) { | |||
return "OK: cli_exit_quit"; | |||
} | |||
return "ERR: cli_exit_quit"; | |||
} | |||
std::string cli_test_goOn( | |||
) { | |||
auto c = memory_createContext(); | |||
c.playfieldSize = 2; | |||
c.recentField = "playfieldSize"; | |||
c = memory_generateConstPlayfield(c); | |||
// Match the first pair of items. | |||
c.input = "1"; | |||
c.recentField = "input"; | |||
c = cli_selectItem(c); | |||
c = memory_selectItem(c); | |||
c.input = "2"; | |||
c.recentField = "input"; | |||
c = cli_selectItem(c); | |||
c = memory_selectItem(c); | |||
c = memory_hideMatchingItems(c); | |||
c = cli_reportMatchedItems(c); | |||
c = cli_goOn(c); | |||
if ( | |||
c.recentField == "outputGoOn" | |||
) { | |||
return "OK: cli_goOn"; | |||
} | |||
return "ERR: cli_goOn"; | |||
} | |||
std::string cli_test_greetUser( | |||
) { | |||
auto c = memory_createContext(); | |||
c.didLaunch = true; | |||
c.recentField = "didLaunch"; | |||
c = cli_greetUser(c); | |||
if ( | |||
c.recentField == "outputGreeting" | |||
) { | |||
return "OK: cli_greetUser"; | |||
} | |||
return "ERR: cli_greetUser"; | |||
} | |||
std::string cli_test_promptSecondItemSelection( | |||
) { | |||
auto c = memory_createContext(); | |||
c.input = "1"; | |||
c.recentField = "input"; | |||
c = cli_selectItem(c); | |||
c = memory_selectItem(c); | |||
c = cli_promptSecondItemSelection(c); | |||
if ( | |||
c.recentField == "outputPromptSelection" | |||
) { | |||
return "OK: cli_promptSecondItemSelection"; | |||
} | |||
return "ERR: cli_promptSecondItemSelection"; | |||
} | |||
std::string cli_test_reportMatchedItems( | |||
) { | |||
auto c = memory_createContext(); | |||
c.playfieldSize = 2; | |||
c.recentField = "playfieldSize"; | |||
c = memory_generateConstPlayfield(c); | |||
c.input = "1"; | |||
c.recentField = "input"; | |||
c = cli_selectItem(c); | |||
c = memory_selectItem(c); | |||
c.input = "2"; | |||
c.recentField = "input"; | |||
c = cli_selectItem(c); | |||
c = memory_selectItem(c); | |||
c = memory_hideMatchingItems(c); | |||
c = cli_reportMatchedItems(c); | |||
if ( | |||
c.recentField == "outputMatchedItems" | |||
) { | |||
return "OK: cli_reportMatchedItems"; | |||
} | |||
return "ERR: cli_reportMatchedItems"; | |||
} | |||
std::string cli_test_reportMismatchedItems( | |||
) { | |||
auto c = memory_createContext(); | |||
c.playfieldSize = 2; | |||
c.recentField = "playfieldSize"; | |||
c = memory_generateConstPlayfield(c); | |||
c.input = "1"; | |||
c.recentField = "input"; | |||
c = cli_selectItem(c); | |||
c = memory_selectItem(c); | |||
c.input = "3"; | |||
c.recentField = "input"; | |||
c = cli_selectItem(c); | |||
c = memory_selectItem(c); | |||
c = memory_detectMismatchedItems(c); | |||
c = cli_reportMismatchedItems(c); | |||
if ( | |||
c.recentField == "outputMismatchedItems" | |||
) { | |||
return "OK: cli_reportMismatchedItems"; | |||
} | |||
return "ERR: cli_reportMismatchedItems"; | |||
} | |||
std::string cli_test_selectItem( | |||
) { | |||
auto c = memory_createContext(); | |||
c.input = "1"; | |||
c.recentField = "input"; | |||
c = cli_selectItem(c); | |||
if ( | |||
c.recentField == "selectedId" && | |||
c.selectedId == 0 | |||
) { | |||
return "OK: cli_selectItem"; | |||
} | |||
return "ERR: cli_selectItem"; | |||
} | |||
std::string cli_test_showHelp_h( | |||
) { | |||
auto c = memory_createContext(); | |||
c.input = "h"; | |||
c.recentField = "input"; | |||
c = cli_showHelp(c); | |||
if ( | |||
c.recentField == "outputHelp" | |||
) { | |||
return "OK: cli_showHelp_h"; | |||
} | |||
return "ERR: cli_showHelp_h"; | |||
} | |||
std::string cli_test_showHelp_help( | |||
) { | |||
auto c = memory_createContext(); | |||
c.input = "help"; | |||
c.recentField = "input"; | |||
c = cli_showHelp(c); | |||
if ( | |||
c.recentField == "outputHelp" | |||
) { | |||
return "OK: cli_showHelp_help"; | |||
} | |||
return "ERR: cli_showHelp_help"; | |||
} | |||
std::string cli_test_reportVictory( | |||
) { | |||
auto c = memory_createContext(); | |||
c.playfieldSize = 2; | |||
c.recentField = "playfieldSize"; | |||
c = memory_generateConstPlayfield(c); | |||
// Match the first pair of tiles. | |||
c.input = "1"; | |||
c.recentField = "input"; | |||
c = cli_selectItem(c); | |||
c = memory_selectItem(c); | |||
c.input = "2"; | |||
c.recentField = "input"; | |||
c = cli_selectItem(c); | |||
c = memory_selectItem(c); | |||
c = memory_hideMatchingItems(c); | |||
// Match the second pair of tiles. | |||
c.input = "3"; | |||
c.recentField = "input"; | |||
c = cli_selectItem(c); | |||
c = memory_selectItem(c); | |||
c.input = "4"; | |||
c.recentField = "input"; | |||
c = cli_selectItem(c); | |||
c = memory_selectItem(c); | |||
c = memory_hideMatchingItems(c); | |||
c = memory_detectVictory(c); | |||
c = cli_reportVictory(c); | |||
if ( | |||
c.recentField == "outputVictory" | |||
) { | |||
return "OK: cli_reportVictory"; | |||
} | |||
return "ERR: cli_reportVictory"; | |||
} | |||
//def cli_test_shouldReportIvalidItemSelection_outOfBoundsMin( | |||
//) -> str: | |||
// c = cli_createContext() | |||
// c.cMemory = memory_createContext() | |||
// c.input = "0" | |||
// c = cli_selectItem(c) | |||
// c = cli_shouldReportInvalidItemSelection(c) | |||
// if ( | |||
// c.recentField == "outputInvalidItemSelection" | |||
// ): | |||
// return "OK: cli_shouldReportInvalidItemSelection" | |||
// //} | |||
// return "ERR: cli_shouldReportInvalidItemSelection" | |||
////} | |||
// | |||
@@ -0,0 +1,303 @@ | |||
from cli import * | |||
from memory import * | |||
from memory_Context import * | |||
def cli_test_exit_e( | |||
) -> str: | |||
c = memory_createContext() | |||
c.input = "e" | |||
c.recentField = "input" | |||
c = cli_exit(c) | |||
if ( | |||
c.recentField == "exit" | |||
): | |||
return "OK: cli_exit_e" | |||
#} | |||
return "ERR: cli_exit_e" | |||
#} | |||
def cli_test_exit_exit( | |||
) -> str: | |||
c = memory_createContext() | |||
c.input = "exit" | |||
c.recentField = "input" | |||
c = cli_exit(c) | |||
if ( | |||
c.recentField == "exit" | |||
): | |||
return "OK: cli_exit_exit" | |||
#} | |||
return "ERR: cli_exit_e" | |||
#} | |||
def cli_test_exit_victory( | |||
) -> str: | |||
c = memory_createContext() | |||
c.playfieldSize = 2 | |||
c.recentField = "playfieldSize" | |||
c = memory_generateConstPlayfield(c) | |||
# Match the first pair of tiles. | |||
c.input = "1" | |||
c.recentField = "input" | |||
c = cli_selectItem(c) | |||
c = memory_selectItem(c) | |||
c.input = "2" | |||
c.recentField = "input" | |||
c = cli_selectItem(c) | |||
c = memory_selectItem(c) | |||
c = memory_hideMatchingItems(c) | |||
# Match the second pair of tiles. | |||
c.input = "3" | |||
c.recentField = "input" | |||
c = cli_selectItem(c) | |||
c = memory_selectItem(c) | |||
c.input = "4" | |||
c.recentField = "input" | |||
c = cli_selectItem(c) | |||
c = memory_selectItem(c) | |||
c = memory_hideMatchingItems(c) | |||
c = memory_detectVictory(c) | |||
c = cli_reportVictory(c) | |||
c = cli_exit(c) | |||
if ( | |||
c.recentField == "exit" | |||
): | |||
return "OK: cli_exit_victory" | |||
#} | |||
return "ERR: cli_exit_victory" | |||
#} | |||
def cli_test_exit_q( | |||
) -> str: | |||
c = memory_createContext() | |||
c.input = "q" | |||
c.recentField = "input" | |||
c = cli_exit(c) | |||
if ( | |||
c.recentField == "exit" | |||
): | |||
return "OK: cli_exit_q" | |||
#} | |||
return "ERR: cli_exit_q" | |||
#} | |||
def cli_test_exit_quit( | |||
) -> str: | |||
c = memory_createContext() | |||
c.input = "quit" | |||
c.recentField = "input" | |||
c = cli_exit(c) | |||
if ( | |||
c.recentField == "exit" | |||
): | |||
return "OK: cli_exit_quit" | |||
#} | |||
return "ERR: cli_exit_quit" | |||
#} | |||
def cli_test_goOn( | |||
) -> str: | |||
c = memory_createContext() | |||
c.playfieldSize = 2 | |||
c.recentField = "playfieldSize" | |||
c = memory_generateConstPlayfield(c) | |||
# Match the first pair of items. | |||
c.input = "1" | |||
c.recentField = "input" | |||
c = cli_selectItem(c) | |||
c = memory_selectItem(c) | |||
c.input = "2" | |||
c.recentField = "input" | |||
c = cli_selectItem(c) | |||
c = memory_selectItem(c) | |||
c = memory_hideMatchingItems(c) | |||
c = cli_reportMatchedItems(c) | |||
c = cli_goOn(c) | |||
if ( | |||
c.recentField == "outputGoOn" | |||
): | |||
return "OK: cli_goOn" | |||
#} | |||
return "ERR: cli_goOn" | |||
#} | |||
def cli_test_greetUser( | |||
) -> str: | |||
c = memory_createContext() | |||
c.didLaunch = True | |||
c.recentField = "didLaunch" | |||
c = cli_greetUser(c) | |||
if ( | |||
c.recentField == "outputGreeting" | |||
): | |||
return "OK: cli_greetUser" | |||
#} | |||
return "ERR: cli_greetUser" | |||
#} | |||
def cli_test_promptSecondItemSelection( | |||
) -> str: | |||
c = memory_createContext() | |||
c.input = "1" | |||
c.recentField = "input" | |||
c = cli_selectItem(c) | |||
c = memory_selectItem(c) | |||
c = cli_promptSecondItemSelection(c) | |||
if ( | |||
c.recentField == "outputPromptSelection" | |||
): | |||
return "OK: cli_promptSecondItemSelection" | |||
#} | |||
return "ERR: cli_promptSecondItemSelection" | |||
#} | |||
def cli_test_reportMatchedItems( | |||
) -> str: | |||
c = memory_createContext() | |||
c.playfieldSize = 2 | |||
c.recentField = "playfieldSize" | |||
c = memory_generateConstPlayfield(c) | |||
c.input = "1" | |||
c.recentField = "input" | |||
c = cli_selectItem(c) | |||
c = memory_selectItem(c) | |||
c.input = "2" | |||
c.recentField = "input" | |||
c = cli_selectItem(c) | |||
c = memory_selectItem(c) | |||
c = memory_hideMatchingItems(c) | |||
c = cli_reportMatchedItems(c) | |||
if ( | |||
c.recentField == "outputMatchedItems" | |||
): | |||
return "OK: cli_reportMatchedItems" | |||
#} | |||
return "ERR: cli_reportMatchedItems" | |||
#} | |||
def cli_test_reportMismatchedItems( | |||
) -> str: | |||
c = memory_createContext() | |||
c.playfieldSize = 2 | |||
c.recentField = "playfieldSize" | |||
c = memory_generateConstPlayfield(c) | |||
c.input = "1" | |||
c.recentField = "input" | |||
c = cli_selectItem(c) | |||
c = memory_selectItem(c) | |||
c.input = "3" | |||
c.recentField = "input" | |||
c = cli_selectItem(c) | |||
c = memory_selectItem(c) | |||
c = memory_detectMismatchedItems(c) | |||
c = cli_reportMismatchedItems(c) | |||
if ( | |||
c.recentField == "outputMismatchedItems" | |||
): | |||
return "OK: cli_reportMismatchedItems" | |||
#} | |||
return "ERR: cli_reportMismatchedItems" | |||
#} | |||
def cli_test_selectItem( | |||
) -> str: | |||
c = memory_createContext() | |||
c.input = "1" | |||
c.recentField = "input" | |||
c = cli_selectItem(c) | |||
if ( | |||
c.recentField == "selectedId" and | |||
c.selectedId == 0 | |||
): | |||
return "OK: cli_selectItem" | |||
#} | |||
return "ERR: cli_selectItem" | |||
#} | |||
def cli_test_showHelp_h( | |||
) -> str: | |||
c = memory_createContext() | |||
c.input = "h" | |||
c.recentField = "input" | |||
c = cli_showHelp(c) | |||
if ( | |||
c.recentField == "outputHelp" | |||
): | |||
return "OK: cli_showHelp_h" | |||
#} | |||
return "ERR: cli_showHelp_h" | |||
#} | |||
def cli_test_showHelp_help( | |||
) -> str: | |||
c = memory_createContext() | |||
c.input = "help" | |||
c.recentField = "input" | |||
c = cli_showHelp(c) | |||
if ( | |||
c.recentField == "outputHelp" | |||
): | |||
return "OK: cli_showHelp_help" | |||
#} | |||
return "ERR: cli_showHelp_help" | |||
#} | |||
def cli_test_reportVictory( | |||
) -> str: | |||
c = memory_createContext() | |||
c.playfieldSize = 2 | |||
c.recentField = "playfieldSize" | |||
c = memory_generateConstPlayfield(c) | |||
# Match the first pair of tiles. | |||
c.input = "1" | |||
c.recentField = "input" | |||
c = cli_selectItem(c) | |||
c = memory_selectItem(c) | |||
c.input = "2" | |||
c.recentField = "input" | |||
c = cli_selectItem(c) | |||
c = memory_selectItem(c) | |||
c = memory_hideMatchingItems(c) | |||
# Match the second pair of tiles. | |||
c.input = "3" | |||
c.recentField = "input" | |||
c = cli_selectItem(c) | |||
c = memory_selectItem(c) | |||
c.input = "4" | |||
c.recentField = "input" | |||
c = cli_selectItem(c) | |||
c = memory_selectItem(c) | |||
c = memory_hideMatchingItems(c) | |||
c = memory_detectVictory(c) | |||
c = cli_reportVictory(c) | |||
if ( | |||
c.recentField == "outputVictory" | |||
): | |||
return "OK: cli_reportVictory" | |||
#} | |||
return "ERR: cli_reportVictory" | |||
#} | |||
#def cli_test_shouldReportIvalidItemSelection_outOfBoundsMin( | |||
#) -> str: | |||
# c = cli_createContext() | |||
# c.cMemory = memory_createContext() | |||
# c.input = "0" | |||
# c = cli_selectItem(c) | |||
# c = cli_shouldReportInvalidItemSelection(c) | |||
# if ( | |||
# c.recentField == "outputInvalidItemSelection" | |||
# ): | |||
# return "OK: cli_shouldReportInvalidItemSelection" | |||
# #} | |||
# return "ERR: cli_shouldReportInvalidItemSelection" | |||
##} | |||
# |
@@ -0,0 +1,6 @@ | |||
#include <map> | |||
#include <string> | |||
#include <vector> | |||
#// file unused | |||
#include "memory.h" | |||
#include "memory_Context.h" |
@@ -0,0 +1,92 @@ | |||
#include <list> | |||
#include <queue> | |||
#include <string> | |||
#ifndef ctx_HEADER | |||
#define ctx_HEADER | |||
template <class T> class ctx_Controller { | |||
std::list<std::function<void(T)> > callbacks; | |||
std::list<std::function<T(T)> > functions; | |||
std::queue<T> queue; | |||
public: | |||
T context; | |||
bool isProcessingQueue = false; | |||
ctx_Controller(const T &c) { | |||
context = c; | |||
} | |||
void executeFunctions() { | |||
auto c = queue.front(); | |||
queue.pop(); | |||
for (const auto &f : functions) { | |||
auto ctx = f(c); | |||
if (ctx.recentField != "none") { | |||
queue.push(ctx); | |||
} | |||
} | |||
context.recentField = c.recentField; | |||
context.setField(c.recentField, c.field(c.recentField)); | |||
reportContext(); | |||
} | |||
void processQueue() { | |||
// Decline recursion. | |||
if (isProcessingQueue) { | |||
return; | |||
} | |||
isProcessingQueue = true; | |||
while (!queue.empty()) { | |||
executeFunctions(); | |||
} | |||
isProcessingQueue = false; | |||
} | |||
void registerCallback(std::function<void(T)> cb) { | |||
callbacks.push_back(cb); | |||
} | |||
void registerFieldCallback( | |||
const std::string &fieldName, | |||
std::function<void(T)> cb | |||
) { | |||
auto execCB = [fieldName, cb](T c) { | |||
if (c.recentField == fieldName) { | |||
cb(c); | |||
} | |||
}; | |||
callbacks.push_back(execCB); | |||
} | |||
void registerFunction(std::function<T(T)> f) { | |||
functions.push_back(f); | |||
} | |||
void registerFunctions(std::list<std::function<T(T)> > funcs) { | |||
for (const auto &f : funcs) { | |||
functions.push_back(f); | |||
} | |||
} | |||
void reportContext() { | |||
for (const auto &cb : callbacks) { | |||
cb(context); | |||
} | |||
} | |||
template <typename U> void set( | |||
const std::string &fieldName, | |||
const U &value | |||
) { | |||
auto c = context; | |||
c.setField(fieldName, value); | |||
c.recentField = fieldName; | |||
queue.push(c); | |||
processQueue(); | |||
} | |||
}; | |||
#endif // ctx_HEADER |
@@ -0,0 +1,53 @@ | |||
import copy | |||
class ctx_Controller: | |||
def __init__(self, c): | |||
self.callbacks = [] | |||
self.context = c | |||
self.functions = [] | |||
self.isProcessingQueue = False | |||
self.queue = [] | |||
def executeFunctions(self): | |||
c = self.queue.pop(0) | |||
for f in self.functions: | |||
ctx = f(c) | |||
if ctx.recentField != "none": | |||
self.queue.append(ctx) | |||
self.context.recentField = c.recentField | |||
self.context.setField(c.recentField, c.field(c.recentField)) | |||
self.reportContext() | |||
def processQueue(self): | |||
# Decline recursion. | |||
if self.isProcessingQueue: | |||
return | |||
self.isProcessingQueue = True | |||
while len(self.queue) > 0: | |||
self.executeFunctions() | |||
self.isProcessingQueue = False | |||
def registerCallback(self, cb): | |||
self.callbacks.append(cb) | |||
def registerFieldCallback(self, fieldName, cb): | |||
self.callbacks.append(lambda c: cb(c) if c.recentField == fieldName else None) | |||
def registerFunction(self, f): | |||
self.functions.append(f) | |||
def registerFunctions(self, funcs): | |||
for f in funcs: | |||
self.functions.append(f) | |||
def reportContext(self): | |||
for cb in self.callbacks: | |||
cb(self.context) | |||
def set(self, fieldName, value): | |||
c = copy.deepcopy(self.context) | |||
c.setField(fieldName, value) | |||
c.recentField = fieldName | |||
self.queue.append(c) | |||
self.processQueue() |
@@ -0,0 +1,141 @@ | |||
#include <string> | |||
#include "any.h" | |||
#include "ctx.h" | |||
#include "memory_Context.h" | |||
std::string s(const char *str) { | |||
return std::string(str); | |||
} | |||
std::string test_ctx_Controller_executeFunctions_registerFunction_set() { | |||
auto c = memory_createContext(); | |||
ctx_Controller<memory_Context> ctrl(c); | |||
// Disable automatic invocation of executeFunctions. | |||
ctrl.isProcessingQueue = true; | |||
ctrl.set("input", s("123")); | |||
auto processInput = [](memory_Context c) -> memory_Context { | |||
if (c.recentField == "input") { | |||
c.outputHelp = "Checked"; | |||
c.recentField = "outputHelp"; | |||
return c; | |||
} | |||
c.recentField = "none"; | |||
return c; | |||
}; | |||
ctrl.registerFunction(processInput); | |||
// Apply 'input'. | |||
ctrl.executeFunctions(); | |||
// Apply 'outputHelp'. | |||
ctrl.executeFunctions(); | |||
if ( | |||
ctrl.context.input == "123" && | |||
ctrl.context.outputHelp == "Checked" | |||
) { | |||
return "OK: ctx_Controller_executeFunctions_set"; | |||
} | |||
return "ERR: ctx_Controller_executeFunctions_set"; | |||
} | |||
std::string test_ctx_Controller_processQueue() { | |||
auto c = memory_createContext(); | |||
ctx_Controller<memory_Context> ctrl(c); | |||
auto processInput = [](memory_Context c) -> memory_Context { | |||
if (c.recentField == "input") { | |||
c.outputHelp = "Checked"; | |||
c.recentField = "outputHelp"; | |||
return c; | |||
} | |||
c.recentField = "none"; | |||
return c; | |||
}; | |||
ctrl.registerFunction(processInput); | |||
ctrl.set("input", s("abc")); | |||
if ( | |||
ctrl.context.input == "abc" && | |||
ctrl.context.outputHelp == "Checked" | |||
) { | |||
return "OK: ctx_Controller_processQueue"; | |||
} | |||
return "ERR: ctx_Controller_processQueue"; | |||
} | |||
std::string test_ctx_Controller_registerFieldCallback_match() { | |||
auto c = memory_createContext(); | |||
ctx_Controller<memory_Context> ctrl(c); | |||
c.input = "123"; | |||
c.recentField = "input"; | |||
std::string callbackInput = ""; | |||
auto setCallbackInput = [&callbackInput](memory_Context c) { | |||
if ( | |||
c.recentField == "input" | |||
) { | |||
callbackInput = c.input; | |||
} | |||
}; | |||
ctrl.registerFieldCallback("input", setCallbackInput); | |||
ctrl.reportContext(); | |||
if ( | |||
ctrl.context.input == callbackInput | |||
) { | |||
return "OK: ctx_Controller_registerFieldCallback_match"; | |||
} | |||
return "ERR: ctx_Controller_registerFieldCallback_match"; | |||
} | |||
std::string test_ctx_Controller_registerFieldCallback_mismatch() { | |||
auto c = memory_createContext(); | |||
ctx_Controller<memory_Context> ctrl(c); | |||
c.input = "123"; | |||
c.outputHelp = "you"; | |||
// A field other than 'input' is marked recent. | |||
c.recentField = "outputHelp"; | |||
std::string callbackInput = ""; | |||
auto setCallbackInput = [&callbackInput](memory_Context c) { | |||
if ( | |||
c.recentField == "input" | |||
) { | |||
callbackInput = c.input; | |||
} | |||
}; | |||
ctrl.registerFieldCallback("input", setCallbackInput); | |||
ctrl.reportContext(); | |||
if ( | |||
callbackInput == "" | |||
) { | |||
return "OK: ctx_Controller_registerFieldCallback_mismatch"; | |||
} | |||
return "ERR: ctx_Controller_registerFieldCallback_mismatch"; | |||
} | |||
std::string test_memory_Context_field() { | |||
auto c = memory_createContext(); | |||
c.input = "abc"; | |||
if ( | |||
libany::any_cast<std::string>(c.field("input")) == "abc" | |||
) { | |||
return "OK: memory_Context_field"; | |||
} | |||
return "ERR: memory_Context_field"; | |||
} | |||
std::string test_memory_Context_setField() { | |||
auto c = memory_createContext(); | |||
c.input = "abc"; | |||
c.setField("input", s("123")); | |||
if ( | |||
c.input == "123" | |||
) { | |||
return "OK: memory_Context_setField"; | |||
} | |||
return "ERR: memory_Context_setField"; | |||
} |
@@ -0,0 +1,13 @@ | |||
#include <string> | |||
#ifndef ctx_test_HEADER | |||
#define ctx_test_HEADER | |||
std::string test_ctx_Controller_executeFunctions_registerFunction_set(); | |||
std::string test_ctx_Controller_processQueue(); | |||
std::string test_ctx_Controller_registerFieldCallback_match(); | |||
std::string test_ctx_Controller_registerFieldCallback_mismatch(); | |||
std::string test_memory_Context_field(); | |||
std::string test_memory_Context_setField(); | |||
#endif // ctx_test_HEADER |
@@ -0,0 +1,142 @@ | |||
from ctx import * | |||
from memory import * | |||
from memory_Context import * | |||
def ctx_test_Controller_executeFunctions_registerFunction_set( | |||
) -> str: | |||
c = memory_createContext() | |||
ctrl = ctx_Controller(c) | |||
# Disable automatic invocation of executeFunctions. | |||
ctrl.isProcessingQueue = True | |||
ctrl.set("input", "123") | |||
@llm_by_value | |||
def processInput(c): | |||
if ( | |||
c.recentField == "input" | |||
): | |||
c.outputHelp = "Checked" | |||
c.recentField = "outputHelp" | |||
return c | |||
#} | |||
c.recentField = "none" | |||
return c | |||
#} | |||
ctrl.registerFunction(processInput) | |||
# Apply 'input'. | |||
ctrl.executeFunctions() | |||
# Apply 'outputHelp'. | |||
ctrl.executeFunctions() | |||
if ( | |||
c.input == "123" and | |||
c.outputHelp == "Checked" | |||
): | |||
return "OK: ctx_Controller_executeFunctions_set" | |||
#} | |||
return "ERR: ctx_Controller_executeFunctions_set" | |||
#} | |||
def ctx_test_Controller_processQueue( | |||
) -> str: | |||
c = memory_createContext() | |||
ctrl = ctx_Controller(c) | |||
@llm_by_value | |||
def processInput(c): | |||
if ( | |||
c.recentField == "input" | |||
): | |||
c.outputHelp = "Checked" | |||
c.recentField = "outputHelp" | |||
return c | |||
#} | |||
c.recentField = "none" | |||
return c | |||
#} | |||
ctrl.registerFunction(processInput) | |||
ctrl.set("input", "abc"); | |||
if ( | |||
c.input == "abc" and | |||
c.outputHelp == "Checked" | |||
): | |||
return "OK: ctx_Controller_processQueue" | |||
#} | |||
return "ERR: ctx_Controller_processQueue" | |||
#} | |||
def ctx_test_Controller_registerFieldCallback_match( | |||
) -> str: | |||
c = memory_createContext() | |||
ctrl = ctx_Controller(c) | |||
c.input = "123" | |||
c.recentField = "input" | |||
globals()["callbackInput"] = "" | |||
def setCallbackInput(c): | |||
if ( | |||
c.recentField == "input" | |||
): | |||
globals()["callbackInput"] = c.input | |||
ctrl.registerFieldCallback("input", setCallbackInput) | |||
ctrl.reportContext() | |||
if ( | |||
c.input == globals()["callbackInput"] | |||
): | |||
return "OK: ctx_Controller_registerFieldCallback_match" | |||
#} | |||
return "ERR: ctx_Controller_registerFieldCallback_match" | |||
#} | |||
def ctx_test_Controller_registerFieldCallback_mismatch( | |||
) -> str: | |||
c = memory_createContext() | |||
ctrl = ctx_Controller(c) | |||
c.input = "123" | |||
c.outputHelp = "you" | |||
# A field other than 'input' is marked recent. | |||
c.recentField = "outputHelp" | |||
globals()["callbackInput"] = "" | |||
def setCallbackInput(c): | |||
if ( | |||
c.recentField == "input" | |||
): | |||
globals()["callbackInput"] = c.input | |||
ctrl.registerFieldCallback("input", setCallbackInput) | |||
ctrl.reportContext() | |||
if ( | |||
globals()["callbackInput"] == "" | |||
): | |||
return "OK: ctx_Controller_registerFieldCallback_mismatch" | |||
#} | |||
return "ERR: ctx_Controller_registerFieldCallback_mismatch" | |||
#} | |||
def ctx_test_memoryContext_field( | |||
) -> str: | |||
c = memory_createContext() | |||
c.input = "abc" | |||
if ( | |||
c.field("input") == "abc" | |||
): | |||
return "OK: ctx_memoryContext_field" | |||
#} | |||
return "ERR: ctx_memoryContext_field" | |||
#} | |||
def ctx_test_memoryContext_setField( | |||
) -> str: | |||
c = memory_createContext() | |||
c.input = "abc" | |||
c.setField("input", "123") | |||
if ( | |||
c.input == "123" | |||
): | |||
return "OK: ctx_memoryContext_setField" | |||
#} | |||
return "ERR: ctx_memoryContext_setField" | |||
#} |
@@ -0,0 +1,27 @@ | |||
#!/bin/bash | |||
DIR=$(cd "$(dirname "$0")" ; pwd -P) | |||
TMP=/tmp/cxx-headers.tmp | |||
grep '^memory_Context ' memory.cpp > $TMP | |||
grep '^std::string ' memory_test.cpp >> $TMP | |||
grep '^memory_Context ' cli.cpp >> $TMP | |||
grep '^std::string ' cli_test.cpp >> $TMP | |||
grep '^std::string ' ctx_test.cpp >> $TMP | |||
grep '^std::string ' llm_test.cpp >> $TMP | |||
IN=$TMP | |||
OUT=$DIR/main.h | |||
echo ' | |||
#include "memory_Context.h" | |||
#ifndef main_HEADER | |||
#define main_HEADER | |||
' > $OUT | |||
sed -Ef cxx-headers.sed <$IN >>$OUT | |||
echo ' | |||
#endif // main_HEADER | |||
' >> $OUT |
@@ -0,0 +1,15 @@ | |||
# #} -> } | |||
#s|#}|}| | |||
# # -> // | |||
#s|#|//| | |||
# dict[X, Y] -> std::map<X, Y> | |||
#s_dict\[(.*), (.*)\]_std::map<\1, \2>_ | |||
# def functionName(X) -> Y -> Y functionName(X) { | |||
#s|def (.*) -> (.*):|\2 \1 {| | |||
s|memory_Context (.*)\(|memory_Context \1(memory_Context);| | |||
s|std::string (.*)\(|std::string \1();| | |||
@@ -0,0 +1,10 @@ | |||
c++ -o test_memory_C++ -std=c++11 -I. \ | |||
memory.cpp \ | |||
memory_Context.cpp \ | |||
memory_test.cpp \ | |||
llm.cpp \ | |||
llm_test.cpp \ | |||
cli.cpp \ | |||
cli_test.cpp \ | |||
ctx_test2.cpp \ | |||
main.cpp |
@@ -0,0 +1,2 @@ | |||
echo "python3 main.py" > test_memory_Python | |||
chmod +x test_memory_Python |
@@ -0,0 +1,19 @@ | |||
#include "llm.h" | |||
bool llm_isDigit(const std::string &str) { | |||
return | |||
!str.empty() && | |||
str.find_first_not_of("0123456789") == std::string::npos; | |||
} | |||
bool llm_startsWith( | |||
const std::string &str, | |||
const std::string &prefix | |||
) { | |||
// https://stackoverflow.com/a/40441240 | |||
return str.rfind(prefix, 0) == 0; | |||
} | |||
int llm_strToInt(const std::string &str) { | |||
return std::stoi(str); | |||
} |
@@ -0,0 +1,10 @@ | |||
#ifndef llm_HEADER | |||
#define llm_HEADER | |||
#include <string> | |||
bool llm_isDigit(const std::string &str); | |||
bool llm_startsWith(const std::string &str, const std::string &prefix); | |||
int llm_strToInt(const std::string &str); | |||
#endif // llm_HEADER |
@@ -0,0 +1,22 @@ | |||
import copy | |||
# Make deep copies of arguments to treat the arguments as structs. | |||
# https://stackoverflow.com/a/15398021 | |||
def llm_by_value(f): | |||
def _f(*args, **kwargs): | |||
argsCopy = copy.deepcopy(args) | |||
kwargsCopy = copy.deepcopy(kwargs) | |||
return f(*argsCopy, **kwargsCopy) | |||
return _f | |||
# Tell if string is a digit | |||
def llm_isDigit(s): | |||
return s.isdigit() | |||
# Tell if string starts with certain prefix. | |||
def llm_startsWith(s, prefix): | |||
return s.startswith(prefix) | |||
# Convert string to integer | |||
def llm_strToInt(s): | |||
return int(s) |
@@ -0,0 +1,39 @@ | |||
#include <map> | |||
#include <string> | |||
#include <vector> | |||
#include "ctx.h" | |||
#include "llm.h" | |||
#include "memory_Context.h" | |||
#include "main.h" | |||
std::string llm_test_isDigit_digit( | |||
) { | |||
if ( | |||
llm_isDigit("123") | |||
) { | |||
return "OK: llm_isDigit_digit"; | |||
} | |||
return "ERR: llm_isDigit_digit"; | |||
} | |||
std::string llm_test_isDigit_notDigit( | |||
) { | |||
if ( | |||
llm_isDigit("abc") | |||
) { | |||
return "ERR: llm_isDigit_notDigit"; | |||
} | |||
return "OK: llm_isDigit_notDigit"; | |||
} | |||
std::string llm_test_strToInt( | |||
) { | |||
if ( | |||
llm_strToInt("123") == 123 | |||
) { | |||
return "OK: llm_strToInt"; | |||
} | |||
return "ERR: llm_strToInt"; | |||
} | |||
@@ -0,0 +1,31 @@ | |||
from llm import * | |||
def llm_test_isDigit_digit( | |||
) -> str: | |||
if ( | |||
llm_isDigit("123") | |||
): | |||
return "OK: llm_isDigit_digit" | |||
#} | |||
return "ERR: llm_isDigit_digit" | |||
#} | |||
def llm_test_isDigit_notDigit( | |||
) -> str: | |||
if ( | |||
llm_isDigit("abc") | |||
): | |||
return "ERR: llm_isDigit_notDigit" | |||
#} | |||
return "OK: llm_isDigit_notDigit" | |||
#} | |||
def llm_test_strToInt( | |||
) -> str: | |||
if ( | |||
llm_strToInt("123") == 123 | |||
): | |||
return "OK: llm_strToInt" | |||
#} | |||
return "ERR: llm_strToInt" | |||
#} |
@@ -0,0 +1,21 @@ | |||
from llm import * | |||
from memory_Context import * | |||
def llm_test_Python_copyByValue( | |||
) -> str: | |||
c = memory_createContext() | |||
c.input = "abc" | |||
@llm_by_value | |||
def alterValue(c): | |||
c.input = "alteredValue" | |||
alterValue(c) | |||
if ( | |||
c.input == "abc" | |||
): | |||
return "OK: llm_Python_copyByValue" | |||
#} | |||
return "ERR: llm_Python_copyByValue" | |||
#} |
@@ -0,0 +1,119 @@ | |||
#include <iostream> | |||
#include <string> | |||
#include <vector> | |||
#include "any.h" | |||
#include "ctx_test2.h" | |||
#include "llm.h" | |||
#include "main.h" | |||
#include "memory_Context.h" | |||
int main() { | |||
std::cout | |||
<< test_ctx_Controller_executeFunctions_registerFunction_set() | |||
<< std::endl | |||
<< test_ctx_Controller_processQueue() | |||
<< std::endl | |||
<< test_ctx_Controller_registerFieldCallback_match() | |||
<< std::endl | |||
<< test_ctx_Controller_registerFieldCallback_mismatch() | |||
<< std::endl | |||
<< test_memory_Context_field() | |||
<< std::endl | |||
<< test_memory_Context_setField() | |||
<< std::endl | |||
<< llm_test_isDigit_digit() | |||
<< std::endl | |||
<< llm_test_isDigit_notDigit() | |||
<< std::endl | |||
<< llm_test_strToInt() | |||
<< std::endl | |||
; | |||
std::cout | |||
<< memory_test_detectMismatchedItems() | |||
<< std::endl | |||
<< memory_test_detectMismatchedItems_itemTwice() | |||
<< std::endl | |||
<< memory_test_detectVictory() | |||
<< std::endl | |||
<< memory_test_generateConstPlayfield() | |||
<< std::endl | |||
<< memory_test_hideMatchingItems() | |||
<< std::endl | |||
<< memory_test_selectItem_1x() | |||
<< std::endl | |||
<< memory_test_selectItem_2x() | |||
<< std::endl | |||
<< memory_test_selectItem_3x() | |||
<< std::endl | |||
; | |||
std::cout | |||
<< cli_test_exit_e() | |||
<< std::endl | |||
<< cli_test_exit_exit() | |||
<< std::endl | |||
<< cli_test_exit_victory() | |||
<< std::endl | |||
<< cli_test_exit_q() | |||
<< std::endl | |||
<< cli_test_exit_quit() | |||
<< std::endl | |||
<< cli_test_goOn() | |||
<< std::endl | |||
<< cli_test_greetUser() | |||
<< std::endl | |||
<< cli_test_showHelp_h() | |||
<< std::endl | |||
<< cli_test_showHelp_help() | |||
<< std::endl | |||
<< cli_test_selectItem() | |||
<< std::endl | |||
<< cli_test_promptSecondItemSelection() | |||
<< std::endl | |||
<< cli_test_reportMatchedItems() | |||
<< std::endl | |||
<< cli_test_reportMismatchedItems() | |||
<< std::endl | |||
<< cli_test_reportVictory() | |||
<< std::endl | |||
; | |||
ctx_Controller<memory_Context> ctrl(memory_createContext()); | |||
ctrl.registerFunctions({ | |||
cli_exit, | |||
cli_goOn, | |||
cli_greetUser, | |||
cli_promptSecondItemSelection, | |||
cli_reportMatchedItems, | |||
cli_reportMismatchedItems, | |||
cli_reportVictory, | |||
cli_selectItem, | |||
cli_showHelp, | |||
memory_detectMismatchedItems, | |||
memory_detectVictory, | |||
memory_generateConstPlayfield, | |||
memory_hideMatchingItems, | |||
memory_selectItem, | |||
}); | |||
auto printOutput = [](memory_Context c) { | |||
if (llm_startsWith(c.recentField, "output")) { | |||
std::cout | |||
<< libany::any_cast<std::string>(c.field(c.recentField)) | |||
<< std::endl; | |||
} | |||
}; | |||
ctrl.registerCallback(printOutput); | |||
ctrl.registerFieldCallback("exit", [](memory_Context c) { exit(0); }); | |||
ctrl.set("didLaunch", true); | |||
ctrl.set("playfieldSize", 2); | |||
while (true) { | |||
std::string ln; | |||
getline(std::cin, ln); | |||
ctrl.set("input", ln); | |||
} | |||
} |
@@ -0,0 +1,52 @@ | |||
#include "memory_Context.h" | |||
#ifndef main_HEADER | |||
#define main_HEADER | |||
memory_Context memory_detectMismatchedItems(memory_Context); | |||
memory_Context memory_detectVictory(memory_Context); | |||
memory_Context memory_generateConstPlayfield(memory_Context); | |||
memory_Context memory_hideMatchingItems(memory_Context); | |||
memory_Context memory_selectItem(memory_Context); | |||
std::string memory_test_detectMismatchedItems(); | |||
std::string memory_test_detectMismatchedItems_itemTwice(); | |||
std::string memory_test_detectVictory(); | |||
std::string memory_test_generateConstPlayfield(); | |||
std::string memory_test_hideMatchingItems(); | |||
std::string memory_test_selectItem_1x(); | |||
std::string memory_test_selectItem_2x(); | |||
std::string memory_test_selectItem_3x(); | |||
memory_Context cli_exit(memory_Context); | |||
memory_Context cli_goOn(memory_Context); | |||
memory_Context cli_greetUser(memory_Context); | |||
memory_Context cli_promptSecondItemSelection(memory_Context); | |||
memory_Context cli_reportMatchedItems(memory_Context); | |||
memory_Context cli_reportVictory(memory_Context); | |||
memory_Context cli_selectItem(memory_Context); | |||
memory_Context cli_showHelp(memory_Context); | |||
memory_Context cli_reportMismatchedItems(memory_Context); | |||
std::string cli_test_exit_e(); | |||
std::string cli_test_exit_exit(); | |||
std::string cli_test_exit_victory(); | |||
std::string cli_test_exit_q(); | |||
std::string cli_test_exit_quit(); | |||
std::string cli_test_goOn(); | |||
std::string cli_test_greetUser(); | |||
std::string cli_test_promptSecondItemSelection(); | |||
std::string cli_test_reportMatchedItems(); | |||
std::string cli_test_reportMismatchedItems(); | |||
std::string cli_test_selectItem(); | |||
std::string cli_test_showHelp_h(); | |||
std::string cli_test_showHelp_help(); | |||
std::string cli_test_reportVictory(); | |||
std::string ctx_test_Controller_executeFunctions_set(); | |||
std::string ctx_test_Controller_processQueue(); | |||
std::string ctx_test_memoryContext_field(); | |||
std::string ctx_test_memoryContext_setField(); | |||
std::string llm_test_isDigit_digit(); | |||
std::string llm_test_isDigit_notDigit(); | |||
std::string llm_test_strToInt(); | |||
#endif // main_HEADER | |||
@@ -0,0 +1,77 @@ | |||
from cli import * | |||
from cli_test import * | |||
from ctx import * | |||
from ctx_test2 import * | |||
#from ctx_test import * | |||
#from ctx_test_Python import * | |||
from llm_test import * | |||
from llm_test_Python import * | |||
from memory_test import * | |||
import sys | |||
print(ctx_test_Controller_executeFunctions_registerFunction_set()) | |||
print(ctx_test_Controller_processQueue()) | |||
print(ctx_test_Controller_registerFieldCallback_match()) | |||
print(ctx_test_Controller_registerFieldCallback_mismatch()) | |||
print(ctx_test_memoryContext_field()) | |||
print(ctx_test_memoryContext_setField()) | |||
print(llm_test_Python_copyByValue()) | |||
print(llm_test_isDigit_digit()) | |||
print(llm_test_isDigit_notDigit()) | |||
print(llm_test_strToInt()) | |||
print(memory_test_detectMismatchedItems()) | |||
print(memory_test_detectMismatchedItems_itemTwice()) | |||
print(memory_test_detectVictory()) | |||
print(memory_test_generateConstPlayfield()) | |||
print(memory_test_hideMatchingItems()) | |||
print(memory_test_selectItem_1x()) | |||
print(memory_test_selectItem_2x()) | |||
print(memory_test_selectItem_3x()) | |||
print(cli_test_exit_e()) | |||
print(cli_test_exit_exit()) | |||
print(cli_test_exit_victory()) | |||
print(cli_test_exit_q()) | |||
print(cli_test_exit_quit()) | |||
print(cli_test_goOn()) | |||
print(cli_test_greetUser()) | |||
print(cli_test_showHelp_h()) | |||
print(cli_test_showHelp_help()) | |||
print(cli_test_selectItem()) | |||
print(cli_test_promptSecondItemSelection()) | |||
print(cli_test_reportMatchedItems()) | |||
print(cli_test_reportMismatchedItems()) | |||
print(cli_test_reportVictory()) | |||
ctrl = ctx_Controller(memory_createContext()) | |||
ctrl.registerFunctions([ | |||
cli_exit, | |||
cli_goOn, | |||
cli_greetUser, | |||
cli_promptSecondItemSelection, | |||
cli_reportMatchedItems, | |||
cli_reportMismatchedItems, | |||
cli_reportVictory, | |||
cli_selectItem, | |||
cli_showHelp, | |||
memory_detectMismatchedItems, | |||
memory_detectVictory, | |||
memory_generateConstPlayfield, | |||
memory_hideMatchingItems, | |||
memory_selectItem, | |||
]) | |||
def printOutput(c): | |||
if c.recentField.startswith("output"): | |||
print(c.field(c.recentField)) | |||
ctrl.registerCallback(printOutput) | |||
ctrl.registerFieldCallback("exit", lambda c: sys.exit(0)) | |||
ctrl.set("didLaunch", True) | |||
ctrl.set("playfieldSize", 2) | |||
for line in sys.stdin: | |||
ln = line.rstrip() | |||
ctrl.set("input", ln) |
@@ -0,0 +1,140 @@ | |||
#include <map> | |||
#include <string> | |||
#include <vector> | |||
#include "ctx.h" | |||
#include "llm.h" | |||
#include "memory_Context.h" | |||
#include "main.h" | |||
// Detect mismatched items | |||
// | |||
// Conditions: | |||
// 0. Two items has just been selected | |||
// 1. The same item has been selected twice | |||
// 2. Selected items are of different groups | |||
memory_Context memory_detectMismatchedItems( | |||
memory_Context c | |||
) { | |||
if (!( | |||
c.recentField == "selectedItems" && | |||
c.selectedItems.size() == 2 | |||
)) { | |||
c.recentField = "none"; | |||
return c; | |||
} | |||
if ( | |||
c.selectedItems[0] == c.selectedItems[1] | |||
) { | |||
c.mismatchedItems.clear(); | |||
c.mismatchedItems.push_back(c.selectedItems[0]); | |||
c.recentField = "mismatchedItems"; | |||
return c; | |||
} | |||
if ( | |||
c.playfieldItems[c.selectedItems[0]] != c.playfieldItems[c.selectedItems[1]] | |||
) { | |||
c.mismatchedItems.clear(); | |||
c.mismatchedItems.push_back(c.selectedItems[0]); | |||
c.mismatchedItems.push_back(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_detectVictory( | |||
memory_Context c | |||
) { | |||
if ( | |||
c.recentField == "hiddenItems" && | |||
c.hiddenItems.size() == c.playfieldItems.size() | |||
) { | |||
c.victory = true; | |||
c.recentField = "victory"; | |||
return c; | |||
} | |||
c.recentField = "none"; | |||
return c; | |||
} | |||
// Generate constant playfield | |||
// | |||
// Conditions: | |||
// 1. Size has just been specified | |||
// | |||
// Both ids and group ids start with 0 | |||
memory_Context memory_generateConstPlayfield( | |||
memory_Context c | |||
) { | |||
if (!( | |||
c.recentField == "playfieldSize" | |||
)) { | |||
c.recentField = "none"; | |||
return 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; | |||
} | |||
// Hide matching selected items | |||
// | |||
// Conditions: | |||
// 1. Two items are selected and they are of the same group | |||
memory_Context memory_hideMatchingItems( | |||
memory_Context c | |||
) { | |||
if ( | |||
c.recentField == "selectedItems" && | |||
c.selectedItems.size() == 2 && | |||
c.playfieldItems[c.selectedItems[0]] == c.playfieldItems[c.selectedItems[1]] | |||
) { | |||
c.hiddenItems.push_back(c.selectedItems[0]); | |||
c.hiddenItems.push_back(c.selectedItems[1]); | |||
c.recentField = "hiddenItems"; | |||
return c; | |||
} | |||
c.recentField = "none"; | |||
return c; | |||
} | |||
// Select item | |||
// | |||
// Conditions: | |||
// 1. Id has just been specified for selection | |||
memory_Context memory_selectItem( | |||
memory_Context c | |||
) { | |||
if (!( | |||
c.recentField == "selectedId" | |||
)) { | |||
c.recentField = "none"; | |||
return c; | |||
} | |||
if ( | |||
c.selectedItems.size() == 2 | |||
) { | |||
c.selectedItems.clear(); | |||
} | |||
c.selectedItems.push_back(c.selectedId); | |||
c.recentField = "selectedItems"; | |||
return c; | |||
} | |||
@@ -0,0 +1,138 @@ | |||
from memory_Context import * | |||
from llm import * | |||
# Detect mismatched items | |||
# | |||
# Conditions: | |||
# 0. Two items has just been selected | |||
# 1. The same item has been selected twice | |||
# 2. Selected items are of different groups | |||
@llm_by_value | |||
def memory_detectMismatchedItems( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if not ( | |||
c.recentField == "selectedItems" and | |||
len(c.selectedItems) == 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 | |||
@llm_by_value | |||
def memory_detectVictory( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if ( | |||
c.recentField == "hiddenItems" and | |||
len(c.hiddenItems) == len(c.playfieldItems) | |||
): | |||
c.victory = True | |||
c.recentField = "victory" | |||
return c | |||
#} | |||
c.recentField = "none" | |||
return c | |||
#} | |||
# Generate constant playfield | |||
# | |||
# Conditions: | |||
# 1. Size has just been specified | |||
# | |||
# Both ids and group ids start with 0 | |||
@llm_by_value | |||
def memory_generateConstPlayfield( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if not ( | |||
c.recentField == "playfieldSize" | |||
): | |||
c.recentField = "none" | |||
return c | |||
#} | |||
idGroups: dict[int, int] = { } | |||
id = 0 | |||
for gid in range(0, c.playfieldSize): | |||
idGroups[id] = gid | |||
id += 1 | |||
idGroups[id] = gid | |||
id += 1 | |||
#} | |||
c.playfieldItems = idGroups | |||
c.recentField = "playfieldItems" | |||
return c | |||
#} | |||
# Hide matching selected items | |||
# | |||
# Conditions: | |||
# 1. Two items are selected and they are of the same group | |||
@llm_by_value | |||
def memory_hideMatchingItems( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if ( | |||
c.recentField == "selectedItems" and | |||
len(c.selectedItems) == 2 and | |||
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 | |||
#} | |||
# Select item | |||
# | |||
# Conditions: | |||
# 1. Id has just been specified for selection | |||
@llm_by_value | |||
def memory_selectItem( | |||
c: memory_Context | |||
) -> memory_Context: | |||
if not ( | |||
c.recentField == "selectedId" | |||
): | |||
c.recentField = "none" | |||
return c | |||
#} | |||
if ( | |||
len(c.selectedItems) == 2 | |||
): | |||
c.selectedItems.clear() | |||
#} | |||
c.selectedItems.append(c.selectedId) | |||
c.recentField = "selectedItems" | |||
return c | |||
#} | |||
@@ -0,0 +1,83 @@ | |||
#include <utility> | |||
#include "any.h" | |||
#include "memory_Context.h" | |||
libany::any memory_Context::field(const std::string &fieldName) { | |||
if (fieldName == "didLaunch") { | |||
return didLaunch; | |||
} else if (fieldName == "exit") { | |||
return exit; | |||
} else if (fieldName == "hiddenItems") { | |||
return hiddenItems; | |||
} else if (fieldName == "input") { | |||
return input; | |||
} else if (fieldName == "mismatchedItems") { | |||
return mismatchedItems; | |||
} else if (fieldName == "outputGoOn") { | |||
return outputGoOn; | |||
} else if (fieldName == "outputGreeting") { | |||
return outputGreeting; | |||
} else if (fieldName == "outputHelp") { | |||
return outputHelp; | |||
} else if (fieldName == "outputMatchedItems") { | |||
return outputMatchedItems; | |||
} else if (fieldName == "outputMismatchedItems") { | |||
return outputMismatchedItems; | |||
} else if (fieldName == "outputPromptSelection") { | |||
return outputPromptSelection; | |||
} else if (fieldName == "outputVictory") { | |||
return outputVictory; | |||
} else if (fieldName == "playfieldItems") { | |||
return playfieldItems; | |||
} else if (fieldName == "playfieldSize") { | |||
return playfieldSize; | |||
} else if (fieldName == "selectedId") { | |||
return selectedId; | |||
} else if (fieldName == "selectedItems") { | |||
return selectedItems; | |||
} | |||
// victory | |||
return victory; | |||
} | |||
void memory_Context::setField(const std::string &fieldName, libany::any value) { | |||
if (fieldName == "didLaunch") { | |||
didLaunch = libany::any_cast<bool>(value); | |||
} else if (fieldName == "exit") { | |||
exit = libany::any_cast<bool>(value); | |||
} else if (fieldName == "hiddenItems") { | |||
hiddenItems = libany::any_cast<std::vector<int> >(value); | |||
} else if (fieldName == "input") { | |||
input = libany::any_cast<std::string>(value); | |||
} else if (fieldName == "mismatchedItems") { | |||
mismatchedItems = libany::any_cast<std::vector<int> >(value); | |||
} else if (fieldName == "outputGoOn") { | |||
outputGoOn = libany::any_cast<std::string>(value); | |||
} else if (fieldName == "outputGreeting") { | |||
outputGreeting = libany::any_cast<std::string>(value); | |||
} else if (fieldName == "outputHelp") { | |||
outputHelp = libany::any_cast<std::string>(value); | |||
} else if (fieldName == "outputMatchedItems") { | |||
outputMatchedItems = libany::any_cast<std::string>(value); | |||
} else if (fieldName == "outputMismatchedItems") { | |||
outputMismatchedItems = libany::any_cast<std::string>(value); | |||
} else if (fieldName == "outputPromptSelection") { | |||
outputPromptSelection = libany::any_cast<std::string>(value); | |||
} else if (fieldName == "outputVictory") { | |||
outputVictory = libany::any_cast<std::string>(value); | |||
} else if (fieldName == "playfieldItems") { | |||
playfieldItems = libany::any_cast<std::map<int, int> >(value); | |||
} else if (fieldName == "playfieldSize") { | |||
playfieldSize = libany::any_cast<int>(value); | |||
} else if (fieldName == "selectedId") { | |||
selectedId = libany::any_cast<int>(value); | |||
} else if (fieldName == "selectedItems") { | |||
selectedItems = libany::any_cast<std::vector<int> >(value); | |||
} else if (fieldName == "victory") { | |||
victory = libany::any_cast<bool>(value); | |||
} | |||
} | |||
memory_Context memory_createContext() { | |||
return memory_Context(); | |||
} |
@@ -0,0 +1,36 @@ | |||
#include <map> | |||
#include <string> | |||
#include <vector> | |||
#include "any.h" | |||
#include "ctx.h" | |||
#ifndef memory_Context_HEADER | |||
#define memory_Context_HEADER | |||
struct memory_Context { | |||
bool didLaunch = false; | |||
bool exit = false; | |||
std::vector<int> hiddenItems; | |||
std::string input = ""; | |||
std::vector<int> mismatchedItems; | |||
std::string outputGoOn = ""; | |||
std::string outputGreeting = ""; | |||
std::string outputHelp = ""; | |||
std::string outputMatchedItems = ""; | |||
std::string outputMismatchedItems = ""; | |||
std::string outputPromptSelection = ""; | |||
std::string outputVictory = ""; | |||
std::map<int, int> playfieldItems; | |||
int playfieldSize = 0; | |||
std::string recentField = "none"; | |||
int selectedId = -1; | |||
std::vector<int> selectedItems; | |||
bool victory = false; | |||
libany::any field(const std::string &fieldName); | |||
void setField(const std::string &fieldName, libany::any value); | |||
}; | |||
memory_Context memory_createContext(); | |||
#endif // memory_Context_HEADER |
@@ -0,0 +1,35 @@ | |||
class memory_Context: | |||
def __init__(self): | |||
self.didLaunch = False | |||
self.exit = False | |||
self.hiddenItems = [] | |||
self.input = "" | |||
self.mismatchedItems = [] | |||
self.outputGoOn = "" | |||
self.outputGreeting = "" | |||
self.outputHelp = "" | |||
self.outputMatchedItems = "" | |||
self.outputMismatchedItems = "" | |||
self.outputPromptSelection = "" | |||
self.outputVictory = "" | |||
self.playfieldItems = {} | |||
self.playfieldSize = 0 | |||
self.recentField = "none" | |||
self.selectedId = -1 | |||
self.selectedItems = [] | |||
self.victory = False | |||
def field(self, fieldName): | |||
return getattr(self, fieldName) | |||
def setField(self, fieldName, value): | |||
setattr(self, fieldName, value) | |||
def __repr__(self): | |||
return self.__str__() | |||
def __str__(self): | |||
return f"memory_Context(playfieldI/playfieldS/recentF/selectedId/selectedI: '{self.playfieldItems}'/'{self.playfieldSize}'/'{self.recentField}'/'{self.selectedId}'/'{self.selectedItems}')" | |||
def memory_createContext(): | |||
return memory_Context() |
@@ -0,0 +1,238 @@ | |||
#include <map> | |||
#include <string> | |||
#include <vector> | |||
#include "ctx.h" | |||
#include "llm.h" | |||
#include "memory_Context.h" | |||
#include "main.h" | |||
std::string memory_test_detectMismatchedItems( | |||
) { | |||
auto c = memory_createContext(); | |||
c.playfieldSize = 2; | |||
c.recentField = "playfieldSize"; | |||
c = memory_generateConstPlayfield(c); | |||
// Select two items of different groups. | |||
c.selectedId = 0; | |||
c.recentField = "selectedId"; | |||
c = memory_selectItem(c); | |||
c.selectedId = 2; | |||
c.recentField = "selectedId"; | |||
c = memory_selectItem(c); | |||
// Detect mismatching. | |||
c = memory_detectMismatchedItems(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_detectMismatchedItems"; | |||
} | |||
return "ERR: memory_detectMismatchedItems"; | |||
} | |||
std::string memory_test_detectMismatchedItems_itemTwice( | |||
) { | |||
auto c = memory_createContext(); | |||
c.playfieldSize = 2; | |||
c.recentField = "playfieldSize"; | |||
c = memory_generateConstPlayfield(c); | |||
// Select the same item twice. | |||
c.selectedId = 0; | |||
c.recentField = "selectedId"; | |||
c = memory_selectItem(c); | |||
c.selectedId = 0; | |||
c.recentField = "selectedId"; | |||
c = memory_selectItem(c); | |||
// Detect mismatching. | |||
c = memory_detectMismatchedItems(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_detectMismatchedItems_itemTwice"; | |||
} | |||
return "ERR: memory_detectMismatchedItems_itemTwice"; | |||
} | |||
std::string memory_test_detectVictory( | |||
) { | |||
auto c = memory_createContext(); | |||
c.playfieldSize = 2; | |||
c.recentField = "playfieldSize"; | |||
c = memory_generateConstPlayfield(c); | |||
// Select the first two items of the same group. | |||
c.selectedId = 0; | |||
c.recentField = "selectedId"; | |||
c = memory_selectItem(c); | |||
c.selectedId = 1; | |||
c.recentField = "selectedId"; | |||
c = memory_selectItem(c); | |||
// Hide the first pair. | |||
c = memory_hideMatchingItems(c); | |||
// Select the last two items of the same group. | |||
c.selectedId = 2; | |||
c.recentField = "selectedId"; | |||
c = memory_selectItem(c); | |||
c.selectedId = 3; | |||
c.recentField = "selectedId"; | |||
c = memory_selectItem(c); | |||
// Hide the second pair. | |||
c = memory_hideMatchingItems(c); | |||
// Detect victory. | |||
c = memory_detectVictory(c); | |||
// See if victory has been detected. | |||
if ( | |||
c.recentField == "victory" && | |||
c.victory == true | |||
) { | |||
return "OK: memory_detectVictory"; | |||
} | |||
return "ERR: memory_detectVictory"; | |||
} | |||
std::string memory_test_generateConstPlayfield( | |||
) { | |||
auto c = memory_createContext(); | |||
c.playfieldSize = 2; | |||
c.recentField = "playfieldSize"; | |||
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_hideMatchingItems( | |||
) { | |||
auto c = memory_createContext(); | |||
c.playfieldSize = 2; | |||
c.recentField = "playfieldSize"; | |||
c = memory_generateConstPlayfield(c); | |||
// Select two items of the same group. | |||
c.selectedId = 0; | |||
c.recentField = "selectedId"; | |||
c = memory_selectItem(c); | |||
c.selectedId = 1; | |||
c.recentField = "selectedId"; | |||
c = memory_selectItem(c); | |||
// Hide matching items. | |||
c = memory_hideMatchingItems(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_hideMatchingItems"; | |||
} | |||
return "ERR: memory_hideMatchingItems"; | |||
} | |||
std::string memory_test_selectItem_1x( | |||
) { | |||
auto c = memory_createContext(); | |||
c.playfieldSize = 2; | |||
c.recentField = "playfieldSize"; | |||
c = memory_generateConstPlayfield(c); | |||
// Select the first item. | |||
c.selectedId = 0; | |||
c.recentField = "selectedId"; | |||
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; | |||
c.recentField = "playfieldSize"; | |||
c = memory_generateConstPlayfield(c); | |||
// Select the first two items. | |||
c.selectedId = 0; | |||
c.recentField = "selectedId"; | |||
c = memory_selectItem(c); | |||
c.selectedId = 1; | |||
c.recentField = "selectedId"; | |||
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; | |||
c.recentField = "playfieldSize"; | |||
c = memory_generateConstPlayfield(c); | |||
// Select three items. | |||
c.selectedId = 0; | |||
c.recentField = "selectedId"; | |||
c = memory_selectItem(c); | |||
c.selectedId = 1; | |||
c.recentField = "selectedId"; | |||
c = memory_selectItem(c); | |||
c.selectedId = 2; | |||
c.recentField = "selectedId"; | |||
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"; | |||
} | |||
@@ -0,0 +1,231 @@ | |||
from memory import * | |||
from memory_Context import * | |||
def memory_test_detectMismatchedItems( | |||
) -> str: | |||
c = memory_createContext() | |||
c.playfieldSize = 2 | |||
c.recentField = "playfieldSize" | |||
c = memory_generateConstPlayfield(c) | |||
# Select two items of different groups. | |||
c.selectedId = 0 | |||
c.recentField = "selectedId" | |||
c = memory_selectItem(c) | |||
c.selectedId = 2 | |||
c.recentField = "selectedId" | |||
c = memory_selectItem(c) | |||
# Detect mismatching. | |||
c = memory_detectMismatchedItems(c) | |||
# See if the two selected items do not match. | |||
if ( | |||
c.recentField == "mismatchedItems" and | |||
len(c.mismatchedItems) == 2 and | |||
c.mismatchedItems[0] == 0 and | |||
c.mismatchedItems[1] == 2 | |||
): | |||
return "OK: memory_detectMismatchedItems" | |||
#} | |||
return "ERR: memory_detectMismatchedItems" | |||
#} | |||
def memory_test_detectMismatchedItems_itemTwice( | |||
) -> str: | |||
c = memory_createContext() | |||
c.playfieldSize = 2 | |||
c.recentField = "playfieldSize" | |||
c = memory_generateConstPlayfield(c) | |||
# Select the same item twice. | |||
c.selectedId = 0 | |||
c.recentField = "selectedId" | |||
c = memory_selectItem(c) | |||
c.selectedId = 0 | |||
c.recentField = "selectedId" | |||
c = memory_selectItem(c) | |||
# Detect mismatching. | |||
c = memory_detectMismatchedItems(c) | |||
# See if the two selected items do not match. | |||
if ( | |||
c.recentField == "mismatchedItems" and | |||
len(c.mismatchedItems) == 1 and | |||
c.mismatchedItems[0] == 0 | |||
): | |||
return "OK: memory_detectMismatchedItems_itemTwice" | |||
#} | |||
return "ERR: memory_detectMismatchedItems_itemTwice" | |||
#} | |||
def memory_test_detectVictory( | |||
) -> str: | |||
c = memory_createContext() | |||
c.playfieldSize = 2 | |||
c.recentField = "playfieldSize" | |||
c = memory_generateConstPlayfield(c) | |||
# Select the first two items of the same group. | |||
c.selectedId = 0 | |||
c.recentField = "selectedId" | |||
c = memory_selectItem(c) | |||
c.selectedId = 1 | |||
c.recentField = "selectedId" | |||
c = memory_selectItem(c) | |||
# Hide the first pair. | |||
c = memory_hideMatchingItems(c) | |||
# Select the last two items of the same group. | |||
c.selectedId = 2 | |||
c.recentField = "selectedId" | |||
c = memory_selectItem(c) | |||
c.selectedId = 3 | |||
c.recentField = "selectedId" | |||
c = memory_selectItem(c) | |||
# Hide the second pair. | |||
c = memory_hideMatchingItems(c) | |||
# Detect victory. | |||
c = memory_detectVictory(c) | |||
# See if victory has been detected. | |||
if ( | |||
c.recentField == "victory" and | |||
c.victory == True | |||
): | |||
return "OK: memory_detectVictory" | |||
#} | |||
return "ERR: memory_detectVictory" | |||
#} | |||
def memory_test_generateConstPlayfield( | |||
) -> str: | |||
c = memory_createContext() | |||
c.playfieldSize = 2 | |||
c.recentField = "playfieldSize" | |||
c = memory_generateConstPlayfield(c) | |||
if ( | |||
c.recentField == "playfieldItems" and | |||
len(c.playfieldItems) == 4 and | |||
c.playfieldItems[0] == 0 and | |||
c.playfieldItems[1] == 0 and | |||
c.playfieldItems[2] == 1 and | |||
c.playfieldItems[3] == 1 | |||
): | |||
return "OK: memory_generateConstPlayfield" | |||
#} | |||
return "ERR: memory_generateConstPlayfield" | |||
#} | |||
def memory_test_hideMatchingItems( | |||
) -> str: | |||
c = memory_createContext() | |||
c.playfieldSize = 2 | |||
c.recentField = "playfieldSize" | |||
c = memory_generateConstPlayfield(c) | |||
# Select two items of the same group. | |||
c.selectedId = 0 | |||
c.recentField = "selectedId" | |||
c = memory_selectItem(c) | |||
c.selectedId = 1 | |||
c.recentField = "selectedId" | |||
c = memory_selectItem(c) | |||
# Hide matching items. | |||
c = memory_hideMatchingItems(c) | |||
# See if the two selected items match. | |||
if ( | |||
c.recentField == "hiddenItems" and | |||
len(c.hiddenItems) == 2 and | |||
c.hiddenItems[0] == 0 and | |||
c.hiddenItems[1] == 1 | |||
): | |||
return "OK: memory_hideMatchingItems" | |||
#} | |||
return "ERR: memory_hideMatchingItems" | |||
#} | |||
def memory_test_selectItem_1x( | |||
) -> str: | |||
c = memory_createContext() | |||
c.playfieldSize = 2 | |||
c.recentField = "playfieldSize" | |||
c = memory_generateConstPlayfield(c) | |||
# Select the first item. | |||
c.selectedId = 0 | |||
c.recentField = "selectedId" | |||
c = memory_selectItem(c) | |||
# See if it's in selectedItems now. | |||
if ( | |||
c.recentField == "selectedItems" and | |||
len(c.selectedItems) == 1 and | |||
c.selectedItems[0] == 0 | |||
): | |||
return "OK: memory_selectItem_1x" | |||
#} | |||
return "ERR: memory_selectItem_1x" | |||
#} | |||
def memory_test_selectItem_2x( | |||
) -> str: | |||
c = memory_createContext() | |||
c.playfieldSize = 2 | |||
c.recentField = "playfieldSize" | |||
c = memory_generateConstPlayfield(c) | |||
# Select the first two items. | |||
c.selectedId = 0 | |||
c.recentField = "selectedId" | |||
c = memory_selectItem(c) | |||
c.selectedId = 1 | |||
c.recentField = "selectedId" | |||
c = memory_selectItem(c) | |||
# See if both items are selected now. | |||
if ( | |||
c.recentField == "selectedItems" and | |||
len(c.selectedItems) == 2 and | |||
c.selectedItems[0] == 0 and | |||
c.selectedItems[1] == 1 | |||
): | |||
return "OK: memory_selectItem_2x" | |||
#} | |||
return "ERR: memory_selectItem_2x" | |||
#} | |||
def memory_test_selectItem_3x( | |||
) -> str: | |||
c = memory_createContext() | |||
c.playfieldSize = 2 | |||
c.recentField = "playfieldSize" | |||
c = memory_generateConstPlayfield(c) | |||
# Select three items. | |||
c.selectedId = 0 | |||
c.recentField = "selectedId" | |||
c = memory_selectItem(c) | |||
c.selectedId = 1 | |||
c.recentField = "selectedId" | |||
c = memory_selectItem(c) | |||
c.selectedId = 2 | |||
c.recentField = "selectedId" | |||
c = memory_selectItem(c) | |||
# See if only one (last) item is selected now. | |||
if ( | |||
c.recentField == "selectedItems" and | |||
len(c.selectedItems) == 1 and | |||
c.selectedItems[0] == 2 | |||
): | |||
return "OK: memory_selectItem_3x" | |||
#} | |||
return "ERR: memory_selectItem_3x" | |||
#} |
@@ -0,0 +1,195 @@ | |||
from Function import * | |||
def includes(): | |||
return """ | |||
#include <map> | |||
#include <string> | |||
#include <vector> | |||
#include "ctx.h" | |||
#include "llm.h" | |||
#include "memory_Context.h" | |||
#include "main.h" | |||
""" | |||
def replaceAnd(s): | |||
return s.replace(" and", " &&") | |||
def replaceAppend(s): | |||
return s.replace(".append(", ".push_back(") | |||
def replaceComment(s): | |||
return s.replace("#", "//") | |||
def replaceLen(s): | |||
posLen = s.find("len(") | |||
posEnd = s.find(")", posLen) | |||
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 replaceOr(s): | |||
return s.replace(" or", " ||") | |||
def replaceTrue(s): | |||
return s.replace("True", "true") | |||
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(", ") | |||
posComment = ss.find("# ") | |||
posCtrl = ss.find("ctrl.") | |||
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 posComment != -1: | |||
return replaceComment(s) | |||
# #} -> } | |||
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 | |||
posCtrl == -1 and | |||
posColon == -1 and | |||
posOpenSquareBracket == -1 and | |||
posEqual >= 0 | |||
): | |||
name = ss[:posEqual] | |||
# Skip prepending 'auto' each time variable is assigned, | |||
# only do it the first time | |||
if name not in state.varNames: | |||
state.varNames[name] = True | |||
value = ss[posEqual + len(" = "):] | |||
return f"{indentation}auto {name} = {value};" | |||
# Keep "if (" | |||
if ss == "if (": | |||
state.isIf = True | |||
return s | |||
# Keep "if not (" | |||
if ss == "if not (": | |||
state.isIfNot = True | |||
return f"{indentation}if (!(" | |||
# ): -> } | |||
if ss == "):": | |||
# if | |||
if state.isIf: | |||
state.isIf = False | |||
return f"{indentation}) {{" | |||
# if not | |||
state.isIfNot = False | |||
return f"{indentation})) {{" | |||
ending = ";" | |||
if state.isIf or state.isIfNot: | |||
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 | |||
self.isIfNot = False | |||
self.varNames = {} | |||
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 = replaceOr(s) | |||
s = replaceAppend(s) | |||
# Replace len twice to account for double invocation. | |||
s = replaceLen(s) | |||
s = replaceLen(s) | |||
s = replaceTrue(s) | |||
sts.append(s) | |||
strstatements = "\n".join(sts) | |||
return f"""{returnType} {self.fn.name}( | |||
{strparams}) {{ | |||
{strstatements} | |||
}} | |||
""" | |||
@@ -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}')" |
@@ -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 |
@@ -0,0 +1,25 @@ | |||
#!/usr/bin/env python3 | |||
import os | |||
import sys | |||
from process import * | |||
DIR = os.path.dirname(os.path.realpath(sys.argv[0])) | |||
if len(sys.argv) < 2: | |||
print("Usage: /path/to/translate [OPTIONS] PYTHON_FILE") | |||
sys.exit(1) | |||
FILE_IN = sys.argv[-1] | |||
# Parse options | |||
# TODO Use options | |||
OPT_HEADER = "--header" in sys.argv | |||
OPT_INCLUDES = None | |||
OPT_PREFIX_INCLUDES = "--includes=" | |||
for arg in sys.argv: | |||
if arg.startswith(OPT_PREFIX_INCLUDES): | |||
OPT_INCLUDES = arg[len(OPT_PREFIX_INCLUDES):] | |||
# Translate file. | |||
out = process(FILE_IN)#, OPT_HEADER, OPT_INCLUDES) | |||
print(out) |
@@ -0,0 +1,12 @@ | |||
#!/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 | |||
$TR $DIR/cli.py > $DIR/cli.cpp | |||
$TR $DIR/cli_test.py > $DIR/cli_test.cpp | |||
$TR $DIR/ctx_test.py > $DIR/ctx_test.cpp | |||
$TR $DIR/llm_test.py > $DIR/llm_test.cpp | |||
$DIR/cxx-headers |