Imported function definition
C++ Oversim Generator
In the following we will explain the data types employed by the runtime libraries for Oversim, and how to extend the behavior of ants using user-defined functions.
Types
All types extend the abstract base type OvSwValue. This type cannot be instanced. In order to ease memory management,
reference counted pointers are used. The type OvSwValue::Ptr
is in fact a shared_ptr
around a pointer to an OvSwValue. All functions and containers expect and manage pointers to OvSwValue wrapped inside an OvSwValue::Ptr. To
wrap generic values into their corresponding OvSwValue derived type and then into a smart pointer use the wrap
functions defined in OvSwWrappers.h
. This library also contains unwrapping methods for common types. Additional wrapping and unwrapping functions are found in OvSwBridgeUtils.h
. In the following we detail the different data types (for further information please refer to the source code of OvSwLib)
Numbers
Numbers are stored within OvSwNumber<T> objects. T can be either int, long, float, or double. All numbers implement the OvSwNumeric pure virtual class, which contains methods to extract integer and floating point values.
Nil
The nil symbol is represented by an object of type OvSwNil.
String
String values are stored in OvSwString objects. This class extends the standard std::string
class.
Lists
Lists are stored as OvSwList objects, which extend the std::vector<OvSwValue::Ptr>
class.
Map
Maps are stored as OvSwMap objects, which extend the tr1::unordered_map<OvSwValue::Ptr,OvSwValue::Ptr>
class.
Blob
The blob type can be used to wrap char arrays.
External functions
If a function that is not included in the default library is used, the compiler will try to map it to a user-defined method in the protocol's class. For that, a function following a generic template must be written. The Oversim generator expects the following function template:
OvSwValue::Ptr [method name](void* owner, OvSwStack* st, OvSwValue::Ptr p1, OvSwValue::Ptr p2) { // TODO }
The type OvSwValue::Ptr
contains a reference-counted pointer to types defined by OverSwarm; each of the OvSwValue::Ptr parameters corresponds to a parameter in the ant behavior's function. All functions must return an OvSwValue::Ptr. To wrap a simple C++ type (string, char*, int, long, double, float) into an OvSwValue::Ptr use the wrap
methods defined in OvSwWrappers.h.
Alternatively you can use the antFunction and osvPtr (shorten for OvSwValue::Ptr) macros, so that the above example becomes:
osvPtr antFunction([method name], osvPtr p1, osvPtr p2) { // TODO }
The method name should reflect the name used in the import section of the protocol definition. The number of parameters is free, although calls from the ant code must match the argument count of the defined method. The pointer 'owner' points to the object that manages the execution of ants (typically an Oversim overlay module).
To make a function available in the ant code, insert a proper definition in the import section of the protocol or of the specific ant. For example, if a function named sayHello
is defined in the C++ code, and it should be bound to a function say
the following import should be used:
import { "sayHello" as "say" }
The number of parameters passed when invoking say
in the ant's behavior must match the number of parameters defined in sayHello
(minus the mandatory arguments void* and OvSwStack*. To define a function with variable arguments use a variadic function definition in the ant behavior, and then accept it as a list parameter in the C++ code.
(define (func a b ...c) (realfunc a b c))
import { "cpprealfunc" as "realfunc" }
OvSwValue::Ptr cpprealfunc(void* owner, OvSwStack* st, OvSwValue::Ptr p1, OvSwValue::Ptr p2, OvSwValue::Ptr p3) { // p1 is a // p2 is b // p3 is a OvSwList with all the rest }
A function can also be defined in another class, referenced by the main class by means of a pointer. For example, if a pointer to utility class object is defined in field “utils”, to import functions use:
import { "utils->somefunction" as "somefunction" }
Argument conversion
All OverSwarm types are defined in OvSwTypes.h
. This header also contains macros to ease the conversion of
arguments and for type checking. To extract an OverSwarm value type from a generic OvSwValue::Ptr use the explode
macro:
explode(l, OvSwList*, p1, "Myfunction expects list as first parameter");
If the conversion is successful, the local variable 'l' will be a pointer to an OvSwList, if not an exception (of type OvSwException
) with the user defined message will be thrown. Please note that explode is only able to convert to a pointer.
Another way to extract a pointer to an actual object or a simple value is through wrap
methods defined in OvSwWrappers.h
. Additional wrappers targeted at OverSim development are available in OvSwBridgeUtils.h
.