Created
December 24, 2018 23:42
-
-
Save IngwiePhoenix/5961018980687b7670bbd16948301a32 to your computer and use it in GitHub Desktop.
gravity c api - using xdata
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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