Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 41 additions & 2 deletions inkcpp/functional.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "value.h"
#include "stack.h"
#include "string_table.h"
#include "operations.h"

#ifdef INK_ENABLE_UNREAL
# include "InkVar.h"
Expand All @@ -28,8 +29,28 @@ template<>
int32_t function_base::pop<int32_t>(basic_eval_stack* stack, list_table& lists)
{
value val = stack->pop();
inkAssert(val.type() == value_type::int32, "Type mismatch!");
return val.get<value_type::int32>();
return casting::numeric_cast<value_type::int32>(val);
}

template<>
uint32_t function_base::pop<uint32_t>(basic_eval_stack* stack, list_table& lists)
{
value val = stack->pop();
return casting::numeric_cast<value_type::uint32>(val);
}

template<>
bool function_base::pop<bool>(basic_eval_stack* stack, list_table& lists)
{
value val = stack->pop();
return casting::numeric_cast<value_type::int32>(val) != 0;
}

template<>
float function_base::pop<float>(basic_eval_stack* stack, list_table& lists)
{
value val = stack->pop();
return casting::numeric_cast<value_type::float32>(val);
}

template<>
Expand All @@ -46,6 +67,24 @@ void function_base::push<int32_t>(basic_eval_stack* stack, const int32_t& v)
stack->push(value{}.set<value_type::int32>(v));
}

template<>
void function_base::push<uint32_t>(basic_eval_stack* stack, const uint32_t& v)
{
stack->push(value{}.set<value_type::uint32>(v));
}

template<>
void function_base::push<float>(basic_eval_stack* stack, const float& v)
{
stack->push(value{}.set<value_type::float32>(v));
}

template<>
void function_base::push<bool>(basic_eval_stack* stack, const bool& v)
{
stack->push(value{}.set<value_type::boolean>(v));
}

void function_base::push_void(basic_eval_stack* stack) { stack->push(values::null); }

void function_base::push_string(basic_eval_stack* stack, const char* dynamic_string)
Expand Down
1 change: 1 addition & 0 deletions inkcpp/numeric_operations.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ namespace casting
numeric_cast<value_type::uint32>(const value& v)
{
switch (v.type()) {
case value_type::int32: return v.get<value_type::int32>();
case value_type::uint32: return v.get<value_type::uint32>();
/// bool value can cast to uint32
case value_type::boolean: return static_cast<uint32_t>(v.get<value_type::boolean>());
Expand Down
1 change: 1 addition & 0 deletions inkcpp/output.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ char* basic_stream::get_alloc(string_table& strings, list_table& lists)
case value_type::int32:
case value_type::float32:
case value_type::uint32:
case value_type::boolean:
// Convert to string and advance
toStr(ptr, end - ptr, _data[i]);
while (*ptr != 0)
Expand Down
12 changes: 7 additions & 5 deletions inkcpp/string_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,18 +85,18 @@ inline int toStr(char* buffer, size_t size, float value)
return ec;
}

inline int toStr(char* buffer, size_t size, const char* c)
inline int toStr(char* buffer, size_t size, const char* str)
{
char* ptr = buffer;
size_t i = 0;
while (*c && i < size) {
*ptr++ = *c;
while (i < size && str[i]) {
ptr[i] = str[i];
++i;
}
if (i >= size) {
return EINVAL;
}
*ptr = 0;
ptr[i] = 0;
return 0;
}

Expand All @@ -113,7 +113,7 @@ inline int toStr(char* buffer, size_t size, const value& v)
case value_type::float32: return toStr(buffer, size, v.get<value_type::float32>());
case value_type::boolean: return toStr(buffer, size, v.get<value_type::boolean>());
case value_type::newline: return toStr(buffer, size, "\n");
default: inkFail("only support toStr for numeric types"); return -1;
default: inkFail("No toStr implementation for this type"); return -1;
}
}

Expand Down Expand Up @@ -148,6 +148,8 @@ inline constexpr size_t value_length(const value& v)
case value_type::uint32: return decimal_digits(v.get<value_type::uint32>());
case value_type::float32: return decimal_digits(v.get<value_type::float32>());
case value_type::string: return c_str_len(v.get<value_type::string>());
case value_type::boolean:
return v.get<value_type::boolean>() ? c_str_len("true") : c_str_len("false");
case value_type::newline: return 1;
default: inkFail("Can't determine length of this value type"); return -1;
}
Expand Down
1 change: 1 addition & 0 deletions inkcpp_test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ add_executable(inkcpp_test catch.hpp Main.cpp
ThirdTierChoiceAfterBrackets.cpp
NoEarlyTags.cpp
ExternalFunctionsExecuteProperly.cpp
ExternalFunctionTypes.cpp
LookaheadSafe.cpp
EmptyStringForDivert.cpp
MoveTo.cpp
Expand Down
48 changes: 48 additions & 0 deletions inkcpp_test/ExternalFunctionTypes.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#include "catch.hpp"

#include <../runner_impl.h>
#include <story.h>
#include <globals.h>
#include <runner.h>
#include <compiler.h>

using namespace ink::runtime;

SCENARIO("a story with external functions support types", "[story]")
{
GIVEN("a story with external functions")
{
auto ink = story::from_file(INK_TEST_RESOURCE_DIR "ExternalFunctionTypes.bin");
auto thread = ink->new_runner().cast<internal::runner_impl>();

std::stringstream debug;
thread->set_debug_enabled(&debug);

bool b = false;
int i = 0;
unsigned int u = 0;
float f = 0;
std::string s;

thread->bind("SET_BOOL", [&b](bool o) { b = o; });
thread->bind("SET_INT", [&i](int o) { i = o; });
thread->bind("SET_UINT", [&u](unsigned int o) { u = o; });
thread->bind("SET_FLOAT", [&f](float o) { f = o; });
thread->bind("SET_STRING", [&s](std::string o) { s = o; });

thread->bind("GET_BOOL", [&b]() { return b; });
thread->bind("GET_INT", [&i]() { return i; });
thread->bind("GET_UINT", [&u]() { return u; });
thread->bind("GET_FLOAT", [&f]() { return f; });
thread->bind("GET_STRING", [&s]() { return s; });

WHEN("run thread")
{
THEN("output shows values from ink")
{
auto line = thread->getline();
REQUIRE(line == "true 1.5 -5 17 foo\n");
}
}
}
}
20 changes: 20 additions & 0 deletions inkcpp_test/ink/ExternalFunctionTypes.ink
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
EXTERNAL GET_BOOL()
EXTERNAL GET_FLOAT()
EXTERNAL GET_INT()
EXTERNAL GET_UINT()
EXTERNAL GET_STRING()
EXTERNAL SET_BOOL(b)
EXTERNAL SET_FLOAT(f)
EXTERNAL SET_INT(i)
EXTERNAL SET_UINT(i)
EXTERNAL SET_STRING(s)

~ SET_BOOL(true)
~ SET_FLOAT(1.5)
~ SET_INT(-5)
~ SET_UINT(17)
~ SET_STRING("foo")

{GET_BOOL()} {GET_FLOAT()} {GET_INT()} {GET_UINT()} {GET_STRING()}

-> DONE
Loading