@@ -9,7 +9,7 @@ from llm_test_Python import * | |||||
from memory_test import * | from memory_test import * | ||||
import sys | import sys | ||||
print(ctx_test_Controller_executeFunctions_set()) | |||||
print(ctx_test_Controller_executeFunctions_registerFunction_set()) | |||||
print(ctx_test_Controller_processQueue()) | print(ctx_test_Controller_processQueue()) | ||||
print(ctx_test_Controller_registerFieldCallback_match()) | print(ctx_test_Controller_registerFieldCallback_match()) | ||||
print(ctx_test_Controller_registerFieldCallback_mismatch()) | 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 |