The reference API of Agate is written in C99. In order to run Agate scripts in your application, you have to configure and create a virtual machine. Then you can interpret scripts, get variables from the virtual machine and interact with the virtual machine thanks to slots.

Configuration

AgateConfig type

typedef struct {
  AgateReallocFunc reallocate;

  AgateUnitHandlerFunc unit_handler;

  AgateForeignClassHandlerFunc foreign_class_handler;
  AgateForeignMethodHandlerFunc foreign_method_handler;

  AgateParseIntFunc parse_int;
  AgateParseFloatFunc parse_float;

  AgateAssertHandling assert_handling;
  AgatePrintFunc print;
  AgateWriteFunc write;
  AgateErrorFunc error;
  AgateInputFunc input;

  void *user_data;
} AgateConfig;

AgateConfig is a type to handle all the configuration of the virtual machine. It has a user_data field that will be passed to different functions throughout the API.

AgateReallocFunc type

typedef void * (*AgateReallocFunc)(void *ptr, ptrdiff_t size, void *user_data);

AgateReallocFunc is a function type for allocating memory. It has a behavior similar to realloc in C. It takes a pointer ptr and change the size of the pointed area to size. If ptr is NULL, it is similar to a new allocation. If size is 0, it is similar to a release of the memory from ptr.

If not given in the configuration, a default implementation using realloc is provided.

AgateUnitHandlerFunc type

typedef const char *(*AgateUnitLoadFunc)(const char *name, void *user_data);
typedef void (*AgateUnitReleaseFunc)(const char *source, void *user_data);

typedef struct {
  AgateUnitLoadFunc load;
  AgateUnitReleaseFunc release;
  void *user_data;
} AgateUnitHandler;

typedef AgateUnitHandler (*AgateUnitHandlerFunc)(AgateVM *vm, const char *name);

AgateForeignClassHandlerFunc type

typedef ptrdiff_t (*AgateForeignAllocateFunc)(AgateVM *vm, const char *unit_name, const char *class_name);
typedef void (*AgateForeignDestroyFunc)(AgateVM *vm, const char *unit_name, const char *class_name, void *data);


typedef struct {
  AgateForeignAllocateFunc allocate;
  AgateForeignDestroyFunc destroy;
} AgateForeignClassHandler;

typedef AgateForeignClassHandler (*AgateForeignClassHandlerFunc)(AgateVM *vm, const char *unit_name, const char *class_name);

AgateForeignMethodHandlerFunc type

typedef void (*AgateForeignMethodFunc)(AgateVM *vm);

typedef enum {
  AGATE_FOREIGN_METHOD_INSTANCE,
  AGATE_FOREIGN_METHOD_CLASS,
} AgateForeignMethodKind;

typedef AgateForeignMethodFunc (*AgateForeignMethodHandlerFunc)(AgateVM *vm, const char *unit_name, const char *class_name, AgateForeignMethodKind kind, const char *signature);

AgateParseIntFunc and AgateParseFloatFunc types

typedef bool (*AgateParseIntFunc)(const char *text, ptrdiff_t size, int base, int64_t *result);
typedef bool (*AgateParseFloatFunc)(const char *text, ptrdiff_t size, double *result);

AgateAssertHandling type

typedef enum {
  AGATE_ASSERT_ABORT,
  AGATE_ASSERT_NIL,
  AGATE_ASSERT_NONE,
} AgateAssertHandling;

The AgateAssertHandling type describes the behavior of the virtual machine when compiling assert statements. Three behaviors are available:

  • AGATE_ASSERT_ABORT: failed asserts abort the script (default)

  • AGATE_ASSERT_NIL: failed asserts return nil

  • AGATE_ASSERT_NONE: asserts are not compiled

AGATE_ASSERT_ABORT is useful when developping your script, for defensive programming. AGATE_ASSERT_NONE is useful for release, where all `assert`s are deleted from the resulting bytecode.

AgatePrintFunc type

typedef void (*AgatePrintFunc)(AgateVM *vm, const char* text);

AgateErrorFunc type

typedef enum {
  AGATE_ERROR_COMPILE,
  AGATE_ERROR_RUNTIME,
  AGATE_ERROR_STACKTRACE,
} AgateErrorKind;

typedef void (*AgateErrorFunc)(AgateVM *vm, AgateErrorKind kind, const char *unit_name, int line, const char *message);

agateConfigInitialize function

void agateConfigInitialize(AgateConfig *config);

Virtual Machine

AgateVM type

typedef struct AgateVM AgateVM;

AgateVM is an opaque type.

agateNewVM function

AgateVM *agateNewVM(const AgateConfig *config);

agateDeleteVM function

void agateDeleteVM(AgateVM *vm);

Slots

Slot management

typedef enum {
  AGATE_TYPE_UNKNOWN,
  AGATE_TYPE_ARRAY,
  AGATE_TYPE_BOOL,
  AGATE_TYPE_CHAR,
  AGATE_TYPE_FLOAT,
  AGATE_TYPE_FOREIGN,
  AGATE_TYPE_INT,
  AGATE_TYPE_MAP,
  AGATE_TYPE_NIL,
  AGATE_TYPE_STRING,
} AgateType;
ptrdiff_t agateSlotCount(AgateVM *vm);
AgateType agateSlotType(AgateVM *vm, ptrdiff_t slot);
void agateSlotCopy(AgateVM *vm, ptrdiff_t dest, ptrdiff_t orig);

Slots for primitive types

bool agateSlotGetBool(AgateVM *vm, ptrdiff_t slot);
uint32_t agateSlotGetChar(AgateVM *vm, ptrdiff_t slot);
int64_t agateSlotGetInt(AgateVM *vm, ptrdiff_t slot);
double agateSlotGetFloat(AgateVM *vm, ptrdiff_t slot);
void *agateSlotGetForeign(AgateVM *vm, ptrdiff_t slot);

const char *agateSlotGetString(AgateVM *vm, ptrdiff_t slot);
const char *agateSlotGetStringSize(AgateVM *vm, ptrdiff_t slot, ptrdiff_t *size);
void agateSlotSetNil(AgateVM *vm, ptrdiff_t slot);
void agateSlotSetBool(AgateVM *vm, ptrdiff_t slot, bool value);
void agateSlotSetChar(AgateVM *vm, ptrdiff_t slot, uint32_t value);
void agateSlotSetInt(AgateVM *vm, ptrdiff_t slot, int64_t value);
void agateSlotSetFloat(AgateVM *vm, ptrdiff_t slot, double value);

void *agateSlotSetForeign(AgateVM *vm, ptrdiff_t slot, ptrdiff_t class_slot);

void agateSlotSetString(AgateVM *vm, ptrdiff_t slot, const char *text);
void agateSlotSetStringSize(AgateVM *vm, ptrdiff_t slot, const char *text, ptrdiff_t size);

Slots for Array

void agateSlotArrayNew(AgateVM *vm, ptrdiff_t slot);
ptrdiff_t agateSlotArraySize(AgateVM *vm, ptrdiff_t slot);
void agateSlotArrayGet(AgateVM *vm, ptrdiff_t array_slot, ptrdiff_t index, ptrdiff_t element_slot);
void agateSlotArraySet(AgateVM *vm, ptrdiff_t array_slot, ptrdiff_t index, ptrdiff_t element_slot);
void agateSlotArrayInsert(AgateVM *vm, ptrdiff_t array_slot, ptrdiff_t index, ptrdiff_t element_slot);
void agateSlotArrayErase(AgateVM *vm, ptrdiff_t array_slot, ptrdiff_t index, ptrdiff_t element_slot);

Slots for Map

void agateSlotMapNew(AgateVM *vm, ptrdiff_t slot);
ptrdiff_t agateSlotMapSize(AgateVM *vm, ptrdiff_t slot);
bool agateSlotMapContains(AgateVM *vm, ptrdiff_t map_slot, ptrdiff_t key_slot);
void agateSlotMapGet(AgateVM *vm, ptrdiff_t map_slot, ptrdiff_t key_slot, ptrdiff_t value_slot);
void agateSlotMapSet(AgateVM *vm, ptrdiff_t map_slot, ptrdiff_t key_slot, ptrdiff_t value_slot);
void agateSlotMapErase(AgateVM *vm, ptrdiff_t map_slot, ptrdiff_t key_slot, ptrdiff_t value_slot);

Handles

agateSlotGetHandle and agateSlotSetHandle functions

AgateHandle *agateSlotGetHandle(AgateVM *vm, ptrdiff_t slot);
void agateSlotSetHandle(AgateVM *vm, ptrdiff_t slot, AgateHandle *handle);

agateReleaseHandle function

void agateReleaseHandle(AgateVM *vm, AgateHandle *handle);

agateMakeCallHandle function

AgateHandle *agateMakeCallHandle(AgateVM *vm, const char *signature);

Calling

AgateStatus type

typedef enum {
  AGATE_STATUS_OK,
  AGATE_STATUS_COMPILE_ERROR,
  AGATE_STATUS_RUNTIME_ERROR,
} AgateStatus;

agateCallString function

AgateStatus agateCallString(AgateVM *vm, const char *unit, const char *source);

Stack

void agateStackStart(AgateVM *vm);
void agateStackFinish(AgateVM *vm);

Slot allocation

ptrdiff_t agateSlotAllocate(AgateVM *vm);
ptrdiff_t agateSlotForArg(AgateVM *vm, ptrdiff_t i);
ptrdiff_t agateSlotForReturn(AgateVM *vm);

agateCallHandle function

AgateStatus agateCallHandle(AgateVM *vm, AgateHandle *method);

Units and variables

agateHasUnit function

bool agateHasUnit(AgateVM *vm, const char *unit_name);

agateHasVariable function

bool agateHasVariable(AgateVM *vm, const char *unit_name, const char *variable_name);

agateGetVariable function

void agateGetVariable(AgateVM *vm, const char *unit_name, const char *variable_name, ptrdiff_t slot);

Other functions

agateAbort function

void agateAbort(AgateVM *vm, ptrdiff_t slot);

User data

void *agateGetUserData(AgateVM *vm);
void agateSetUserData(AgateVM *vm, void *user_data);