Skip to content

Instantly share code, notes, and snippets.

@IngwiePhoenix
Created December 24, 2018 23:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save IngwiePhoenix/5961018980687b7670bbd16948301a32 to your computer and use it in GitHub Desktop.
Save IngwiePhoenix/5961018980687b7670bbd16948301a32 to your computer and use it in GitHub Desktop.
gravity c api - using xdata
// Based on gravity/api/exec_c.c
#include <stdio.h>
#include <math.h>
#include "gravity_compiler.h"
#include "gravity_macros.h"
#include "gravity_vm.h"
#include "gravity_core.h"
#include "gravity_value.h"
// error callback
static void report_error (gravity_vm *vm, error_type_t error_type, const char *message,
error_desc_t error_desc, void *xdata) {
#pragma unused(vm, xdata)
const char *type = "N/A";
switch (error_type) {
case GRAVITY_ERROR_NONE: type = "NONE"; break;
case GRAVITY_ERROR_SYNTAX: type = "SYNTAX"; break;
case GRAVITY_ERROR_SEMANTIC: type = "SEMANTIC"; break;
case GRAVITY_ERROR_RUNTIME: type = "RUNTIME"; break;
case GRAVITY_WARNING: type = "WARNING"; break;
case GRAVITY_ERROR_IO: type = "I/O"; break;
}
if (error_type == GRAVITY_ERROR_RUNTIME) printf("RUNTIME ERROR: ");
else printf("%s ERROR on %d (%d,%d): ", type, error_desc.fileid, error_desc.lineno, error_desc.colno);
printf("%s\n", message);
}
// Example source to execute.
const char* source =
"extern var xdataTest;\n"
"func main() { return xdataTest.greet(); }";
// Gravity has some nice value dumping capabilities.
// This macro "abuses" that. ;)
#define DUMP(_val) { \
char buffer[512]; \
gravity_value_dump(vm, _val, buffer, sizeof(buffer)); \
printf(#_val ": %s\n", buffer); \
}
// This could be anything - a class, or any other type. In this case, it's just
// a string...
typedef struct {
char* str_data;
int str_len;
} strData;
// Example method of xdataTest
static bool xdataTest_greet(gravity_vm *vm, gravity_value_t *argv, uint16_t argc, uint32_t rindex) {
// Pay attention to what the output of this prints!
DUMP(argv[0]);
DUMP(argv[-1]);
// And in fact, to this one as well.
printf("#argv[0]: %i\n", argc);
// Grab the current closure and pull it's wrapped gravity_function_t pointer.
gravity_function_t *fn = VALUE_AS_CLOSURE(argv[-1])->f;
// Cast the stored user data and print it out.
strData *ptr = (strData*)fn->xdata;
printf("String from xdata (%i): %s\n", ptr->str_len, ptr->str_data);
// Wny not actually return it, while we're at it?
gravity_vm_setslot(vm, VALUE_FROM_STRING(vm, ptr->str_data, ptr->str_len), rindex);
return true;
}
// Binding the above method...straight forward.
static void registerXdataTest(gravity_vm *vm) {
gravity_class_t *class, *meta;
class = gravity_class_new_pair(NULL, "xdataTest", NULL, 0, 0);
meta = gravity_class_get_meta(class);
// Store an example string.
strData *data = (strData*)malloc(sizeof(strData)+1);
data->str_data = "Hello";
data->str_len = 5;
gravity_function_t *fn;
gravity_closure_t *fnc;
fn = gravity_function_new_internal(NULL, NULL, xdataTest_greet, 0);
fnc = gravity_closure_new(NULL, fn);
// Either:
// fnc->f->xdata
// Or the below:
fn->xdata = (void*)data;
gravity_class_bind(meta, "greet", VALUE_FROM_OBJECT(fnc));
gravity_vm_setvalue(vm, "xdataTest", VALUE_FROM_OBJECT(class));
}
int main(int argc, const char * argv[]) {
gravity_delegate_t delegate = {
.error_callback = report_error
};
gravity_compiler_t *compiler = gravity_compiler_create(&delegate);
gravity_closure_t *closure = gravity_compiler_run(compiler, source, strlen(source), 0, true, false);
if (!closure) return -1;
gravity_vm *vm = gravity_vm_new(&delegate);
gravity_compiler_transfer(compiler, vm);
gravity_compiler_free(compiler);
registerXdataTest(vm);
if (gravity_vm_runmain(vm, closure)) {
gravity_value_t result = gravity_vm_result(vm);
DUMP(result);
}
if (vm) gravity_vm_free(vm);
gravity_core_free();
}
/*
Ingwie@Ingwies-MBP.fritz.box ~/W/G/g/out $ gcc -o ptrtest ptrtest.c libgravity.a -I ../src/shared/ -I ../src/compiler/ -I ../src/runtime/ -I ../src/utils/
Ingwie@Ingwies-MBP.fritz.box ~/W/G/g/out $ ./ptrtest
argv[0]: (CLASS) xdataTest (0x7ff008418c60)
argv[-1]: (CLOSURE) anon (0x7ff008402b00)
#argv[0]: 1
String from xdata (5): Hello
result: (STRING) Hello (0x7ff0084170c0)
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment