|
@@ -17,36 +17,38 @@ func main () {
|
|
|
}
|
|
|
```
|
|
|
|
|
|
-The bare minimum C code to embed Gravity would be:
|
|
|
+The bare minimum C code to embed Gravity would be (to keep the code as simple as possible I skipped any error check condition that would be required):
|
|
|
```C
|
|
|
+#include "gravity_compiler.h"
|
|
|
+#include "gravity_macros.h"
|
|
|
+#include "gravity_core.h"
|
|
|
+#include "gravity_vm.h"
|
|
|
|
|
|
-const char *source_code = "
|
|
|
-func sum (a, b) {
|
|
|
- return a + b
|
|
|
-}
|
|
|
-
|
|
|
-func mul (a, b) {
|
|
|
- return a * b
|
|
|
-}
|
|
|
-
|
|
|
-func main () {
|
|
|
- var a = 10
|
|
|
- var b = 20
|
|
|
- return sum(a, b) + mul(a, b)
|
|
|
-}
|
|
|
+const char *source_code = " \
|
|
|
+func sum (a, b) { \
|
|
|
+ return a + b \
|
|
|
+} \
|
|
|
+ \
|
|
|
+func mul (a, b) { \
|
|
|
+ return a * b \
|
|
|
+} \
|
|
|
+ \
|
|
|
+func main () { \
|
|
|
+ var a = 10 \
|
|
|
+ var b = 20 \
|
|
|
+ return sum(a, b) + mul(a, b) \
|
|
|
+} \
|
|
|
";
|
|
|
|
|
|
// a very simple report error callback function
|
|
|
-void report_error (error_type_t error_type, const char *message, error_desc_t error_desc, void *xdata) {
|
|
|
+void report_error (gravity_vm *vm, error_type_t error_type, const char *message, error_desc_t error_desc, void *xdata) {
|
|
|
printf("%s\n", message);
|
|
|
exit(0);
|
|
|
}
|
|
|
|
|
|
-void main (void) {
|
|
|
+int main (void) {
|
|
|
// setup a delegate struct
|
|
|
- gravity_delegate_t delegate = {
|
|
|
- .error_callback = report_error
|
|
|
- };
|
|
|
+ gravity_delegate_t delegate = {.error_callback = report_error};
|
|
|
|
|
|
// allocate a new compiler
|
|
|
gravity_compiler_t *compiler = gravity_compiler_create(&delegate);
|
|
@@ -68,13 +70,106 @@ void main (void) {
|
|
|
// retrieve returned result
|
|
|
gravity_value_t result = gravity_vm_result(vm);
|
|
|
|
|
|
- // print result to stdout
|
|
|
- printf("RESULT: %s", t, VALUE_AS_CSTRING(result));
|
|
|
+ // dump result to a C string and print it to stdout
|
|
|
+ char buffer[512];
|
|
|
+ gravity_value_dump(vm, result, buffer, sizeof(buffer));
|
|
|
+ printf("RESULT: %s\n", buffer);
|
|
|
}
|
|
|
|
|
|
// free VM and core libraries (implicitly allocated by the VM)
|
|
|
gravity_vm_free(vm);
|
|
|
gravity_core_free();
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+```
|
|
|
+
|
|
|
+To load and execute a `myfile` Gravity source code from disk the required changes would be minimum:
|
|
|
+```C
|
|
|
+int main (void) {
|
|
|
+ size_t size = 0;
|
|
|
+ const char *source_code = file_read("myfile.gravity", &size);
|
|
|
+
|
|
|
+ ...
|
|
|
+
|
|
|
+ // compile Gravity source code into bytecode (embedded into a closure)
|
|
|
+ // notice the change of the is_static bool parameter to false
|
|
|
+ gravity_closure_t *closure = gravity_compiler_run(compiler, source_code, size, 0, false, true);
|
|
|
+
|
|
|
+ ...
|
|
|
}
|
|
|
+```
|
|
|
+
|
|
|
+To directly execute the `mul` Gravity function and pass some parameter from C to Gravity some minor changes need to be performed:
|
|
|
+```C
|
|
|
+#include "gravity_compiler.h"
|
|
|
+#include "gravity_macros.h"
|
|
|
+#include "gravity_core.h"
|
|
|
+#include "gravity_vm.h"
|
|
|
|
|
|
+const char *source_code = " \
|
|
|
+func sum (a, b) { \
|
|
|
+ return a + b \
|
|
|
+} \
|
|
|
+ \
|
|
|
+func mul (a, b) { \
|
|
|
+ return a * b \
|
|
|
+} \
|
|
|
+";
|
|
|
+
|
|
|
+int main (void) {
|
|
|
+ // setup a delegate struct
|
|
|
+ gravity_delegate_t delegate = {.error_callback = report_error};
|
|
|
+
|
|
|
+ // allocate a new compiler
|
|
|
+ gravity_compiler_t *compiler = gravity_compiler_create(&delegate);
|
|
|
+
|
|
|
+ // compile Gravity source code into bytecode
|
|
|
+ gravity_closure_t *closure = gravity_compiler_run(compiler, source_code, strlen(source_code), 0, true, true);
|
|
|
+
|
|
|
+ // allocate a new Gravity VM
|
|
|
+ gravity_vm *vm = gravity_vm_new(&delegate);
|
|
|
+
|
|
|
+ // transfer memory from the compiler (front-end) to the VM (back-end)
|
|
|
+ gravity_compiler_transfer(compiler, vm);
|
|
|
+
|
|
|
+ // once memory has been trasferred, you can get rid of the front-end
|
|
|
+ gravity_compiler_free(compiler);
|
|
|
+
|
|
|
+ // load closure into VM
|
|
|
+ gravity_vm_loadclosure(vm, closure);
|
|
|
+
|
|
|
+ // lookup a reference to the mul closure into the Gravity VM
|
|
|
+ gravity_value_t mul_function = gravity_vm_getvalue(vm, "mul", (uint32_t)strlen("mul"));
|
|
|
+ if (!VALUE_ISA_CLOSURE(mul_function)) {
|
|
|
+ printf("Unable to find mul function into Gravity VM.\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ // convert function to closure
|
|
|
+ gravity_closure_t *mul_closure = VALUE_AS_CLOSURE(mul_function);
|
|
|
+
|
|
|
+ // prepare parameters
|
|
|
+ gravity_value_t p1 = VALUE_FROM_INT(30);
|
|
|
+ gravity_value_t p2 = VALUE_FROM_INT(40);
|
|
|
+ gravity_value_t params[] = {p1, p2};
|
|
|
+
|
|
|
+ // execute mul closure
|
|
|
+ if (gravity_vm_runclosure (vm, mul_closure, VALUE_FROM_NULL, params, 2)) {
|
|
|
+ // retrieve returned result
|
|
|
+ gravity_value_t result = gravity_vm_result(vm);
|
|
|
+
|
|
|
+ // dump result to a C string and print it to stdout
|
|
|
+ char buffer[512];
|
|
|
+ gravity_value_dump(vm, result, buffer, sizeof(buffer));
|
|
|
+ printf("RESULT: %s\n", buffer);
|
|
|
+ }
|
|
|
+
|
|
|
+ // free VM and core libraries (implicitly allocated by the VM)
|
|
|
+ gravity_vm_free(vm);
|
|
|
+ gravity_core_free();
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
```
|