CMake setup
Here is a minimal CMakeLists.txt to integrate ArkScript in a project:
cmake_minimum_required(VERSION 3.11)
project(IntegrateArk)
# setting flags to build only what we need in ArkScript
# - no executable
# - no modules (console, http, random...)
# - disallowing access to the sys:exec command
set(ARK_BUILD_EXE OFF)
set(ARK_BUILD_MODULES OFF)
set(ARK_ENABLE_SYSTEM OFF)
add_subdirectory(ArkScript)
# creating our executable
add_executable(${PROJECT_NAME} main.cpp)
# adding ArkScript includes to the executable,
# linking it to the dynamic library for the language
target_include_directories(${PROJECT_NAME} PUBLIC ArkScript/include)
target_link_libraries(${PROJECT_NAME} PUBLIC ArkReactor)
set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 17)
Using ArkScript
An example is often worth a thousands words:
{
state.
doString(
"(let foo (fun (x y) (+ x y 2)))");
vm.run();
auto value = vm.call("foo", 5, 6.0);
std::cout << value << "\n";
return 0;
}
Includes the needed files to start using ArkScript.
Ark state to handle the dirty job of loading and compiling ArkScript code.
bool doString(const std::string &code)
Compile a string (representing ArkScript code) and store resulting bytecode in m_bytecode.
The ArkScript virtual machine, executing ArkScript bytecode.
int main(int argc, char **argv)
Adding your own functions
{
if (args.size() != 4)
throw std::runtime_error("my_function needs 4 arguments!");
"my_function",
} } } },
args);
auto a = args[0],
b = args[1],
c = args[2],
d = args[3];
return Ark::Value(a.number() * b.number() - c.number() / d.number());
}
{
});
state.
doString(
"(let bar (my_function 1 2 3 1)) (let egg (foo 1 2 3))");
auto bar = vm["bar"];
std::cout << bar << "\n";
auto egg = vm["egg"];
std::cout << egg << "\n";
return 0;
}
void loadFunction(const std::string &name, Value::ProcType function) noexcept
Register a function in the virtual machine.
int run() noexcept
Run the bytecode held in the state.
bool check(const std::vector< Value > &args, Ts... types)
Helper to see if a builtin has been given a wanted set of types.
ARK_API void generateError(std::string_view funcname, const std::vector< Contract > &contracts, const std::vector< Value > &args)
Generate an error message based on a given set of types contracts provided argument list.
A contract is a list of typed arguments that a function can follow.
A type definition within a contract.
Adding your own types in ArkScript
enum class Breakfast { Eggs, Bacon, Pizza };
Breakfast& getBreakfast()
{
static Breakfast bf = Breakfast::Pizza;
return bf;
}
UserType::ControlFuncs* get_cfs()
{
static UserType::ControlFuncs cfs;
cfs.ostream_func = [](std::ostream& os, const UserType& a) -> std::ostream& {
os << "Breakfast::";
switch (a.as<Breakfast>())
{
case Breakfast::Eggs: os << "Eggs"; break;
case Breakfast::Bacon: os << "Bacon"; break;
case Breakfast::Pizza: os << "Pizza"; break;
default: os << "Unknown"; break;
}
return os;
};
return &cfs;
}
{
return v;
});
{
std::cout << "UserType detected as an enum class Breakfast" << std::endl;
std::cout << "Got " << n[0].usertype() << "\n";
if (bf == Breakfast::Pizza)
std::cout << "Good choice! Have a nice breakfast ;)" << std::endl;
}
});
state.
doString(
"(begin (let a (getBreakfast)) (print a) (useBreakfast a))");
return 0;
}
A class to be use C++ objects in ArkScript.
T & as() noexcept
Return the underlying object as a given type.
const UserType & usertype() const
Return the stored user type.
UserType & usertypeRef()
Return the stored user type as a reference.
const Value Nil
ArkScript Nil value.