summaryrefslogtreecommitdiffhomepage
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/CMakeLists.txt7
-rw-r--r--examples/exception-handler.c100
-rw-r--r--examples/execute-file.c118
-rw-r--r--examples/execute-string.c128
-rw-r--r--examples/native-function.c104
-rw-r--r--examples/state-reset.c94
-rw-r--r--examples/state-reuse.c98
7 files changed, 649 insertions, 0 deletions
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
new file mode 100644
index 0000000..12d32ba
--- /dev/null
+++ b/examples/CMakeLists.txt
@@ -0,0 +1,7 @@
+FILE(GLOB examples "*.c")
+FOREACH(example ${examples})
+ GET_FILENAME_COMPONENT(example ${example} NAME_WE)
+ SET(CLI_SOURCES main.c)
+ ADD_EXECUTABLE(${example} ${example}.c)
+ TARGET_LINK_LIBRARIES(${example} libucode ${json})
+ENDFOREACH(example)
diff --git a/examples/exception-handler.c b/examples/exception-handler.c
new file mode 100644
index 0000000..e2b1058
--- /dev/null
+++ b/examples/exception-handler.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2021 Jo-Philipp Wich <jo@mein.io>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+
+#include <ucode/compiler.h>
+#include <ucode/lib.h>
+#include <ucode/vm.h>
+
+
+#define MULTILINE_STRING(...) #__VA_ARGS__
+
+static const char *program = MULTILINE_STRING(
+ {%
+ function fail() {
+ /* invoke not existing function to raise runtime error */
+ doesnotexist();
+ }
+
+ fail();
+ %}
+);
+
+static uc_parse_config_t config = {
+ .strict_declarations = false,
+ .lstrip_blocks = true,
+ .trim_blocks = true
+};
+
+static void
+log_exception(uc_vm_t *vm, uc_exception_t *ex)
+{
+ char *trace = ucv_to_jsonstring_formatted(vm, ex->stacktrace, ' ', 2);
+
+ printf("Program raised an exception:\n");
+ printf(" type=%d\n", ex->type);
+ printf(" message=%s\n", ex->message);
+ printf(" stacktrace=%s\n", trace);
+
+ free(trace);
+}
+
+int main(int argc, char **argv)
+{
+ int exit_code = 0;
+
+ /* create a source buffer containing the program code */
+ uc_source_t *src = uc_source_new_buffer("my program", strdup(program), strlen(program));
+
+ /* compile source buffer into function */
+ char *syntax_error = NULL;
+ uc_function_t *progfunc = uc_compile(&config, src, &syntax_error);
+
+ /* release source buffer */
+ uc_source_put(src);
+
+ /* check if compilation failed */
+ if (!progfunc) {
+ fprintf(stderr, "Failed to compile program: %s\n", syntax_error);
+
+ return 1;
+ }
+
+ /* initialize VM context */
+ uc_vm_t vm = { 0 };
+ uc_vm_init(&vm, &config);
+
+ /* load standard library into global VM scope */
+ uc_load_stdlib(uc_vm_scope_get(&vm));
+
+ /* register custom exception handler */
+ uc_vm_exception_handler_set(&vm, log_exception);
+
+ /* execute program function */
+ int return_code = uc_vm_execute(&vm, progfunc, NULL);
+
+ /* handle return status */
+ if (return_code == ERROR_COMPILE || return_code == ERROR_RUNTIME) {
+ printf("An error occurred while running the program\n");
+ exit_code = 1;
+ }
+
+ /* free VM context */
+ uc_vm_free(&vm);
+
+ return exit_code;
+}
diff --git a/examples/execute-file.c b/examples/execute-file.c
new file mode 100644
index 0000000..2e86f7d
--- /dev/null
+++ b/examples/execute-file.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2021 Jo-Philipp Wich <jo@mein.io>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+
+#include <ucode/compiler.h>
+#include <ucode/lib.h>
+#include <ucode/vm.h>
+
+
+static uc_parse_config_t config = {
+ .strict_declarations = false,
+ .lstrip_blocks = true,
+ .trim_blocks = true
+};
+
+int main(int argc, char **argv)
+{
+ int exit_code = 0;
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s sourcefile.uc\n", argv[0]);
+
+ return 1;
+ }
+
+ /* create a source buffer from the given input file */
+ uc_source_t *src = uc_source_new_file(argv[1]);
+
+ /* check if source file could be opened */
+ if (!src) {
+ fprintf(stderr, "Unable to open source file %s\n", argv[1]);
+
+ return 1;
+ }
+
+ /* compile source buffer into function */
+ char *syntax_error = NULL;
+ uc_function_t *progfunc = uc_compile(&config, src, &syntax_error);
+
+ /* release source buffer */
+ uc_source_put(src);
+
+ /* check if compilation failed */
+ if (!progfunc) {
+ fprintf(stderr, "Failed to compile program: %s\n", syntax_error);
+
+ return 1;
+ }
+
+ /* initialize VM context */
+ uc_vm_t vm = { 0 };
+ uc_vm_init(&vm, &config);
+
+ /* load standard library into global VM scope */
+ uc_load_stdlib(uc_vm_scope_get(&vm));
+
+ /* add global variables x and y to VM scope */
+ ucv_object_add(uc_vm_scope_get(&vm), "x", ucv_int64_new(123));
+ ucv_object_add(uc_vm_scope_get(&vm), "y", ucv_int64_new(456));
+
+ /* execute compiled program function */
+ uc_value_t *last_expression_result = NULL;
+ int return_code = uc_vm_execute(&vm, progfunc, &last_expression_result);
+
+ /* handle return status */
+ switch (return_code) {
+ case STATUS_OK:
+ exit_code = 0;
+
+ char *s = ucv_to_string(&vm, last_expression_result);
+
+ printf("Program finished successfully.\n");
+ printf("Function return value is %s\n", s);
+ free(s);
+ break;
+
+ case STATUS_EXIT:
+ exit_code = (int)ucv_int64_get(last_expression_result);
+
+ printf("The invoked program called exit().\n");
+ printf("Exit code is %d\n", exit_code);
+ break;
+
+ case ERROR_COMPILE:
+ exit_code = 1;
+
+ printf("A compilation error occurred while running the program\n");
+ break;
+
+ case ERROR_RUNTIME:
+ exit_code = 2;
+
+ printf("A runtime error occurred while running the program\n");
+ break;
+ }
+
+ /* free last expression result */
+ ucv_put(last_expression_result);
+
+ /* free VM context */
+ uc_vm_free(&vm);
+
+ return exit_code;
+}
diff --git a/examples/execute-string.c b/examples/execute-string.c
new file mode 100644
index 0000000..c51a600
--- /dev/null
+++ b/examples/execute-string.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2021 Jo-Philipp Wich <jo@mein.io>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Example to compile a C string into an ucode program.
+ * Build with gcc -o execute-string -lucode execute-string.c
+ */
+
+#include <stdio.h>
+
+#include <ucode/compiler.h>
+#include <ucode/lib.h>
+#include <ucode/vm.h>
+
+
+#define MULTILINE_STRING(...) #__VA_ARGS__
+
+static const char *program = MULTILINE_STRING(
+ {%
+ function add(a, b) {
+ c = a + b;
+
+ return c;
+ }
+
+ result = add(x, y);
+
+ printf('%d + %d is %d\n', x, y, result);
+
+ return result;
+ %}
+);
+
+static uc_parse_config_t config = {
+ .strict_declarations = false,
+ .lstrip_blocks = true,
+ .trim_blocks = true
+};
+
+int main(int argc, char **argv)
+{
+ int exit_code = 0;
+
+ /* create a source buffer containing the program code */
+ uc_source_t *src = uc_source_new_buffer("my program", strdup(program), strlen(program));
+
+ /* compile source buffer into function */
+ char *syntax_error = NULL;
+ uc_function_t *progfunc = uc_compile(&config, src, &syntax_error);
+
+ /* release source buffer */
+ uc_source_put(src);
+
+ /* check if compilation failed */
+ if (!progfunc) {
+ fprintf(stderr, "Failed to compile program: %s\n", syntax_error);
+
+ return 1;
+ }
+
+ /* initialize VM context */
+ uc_vm_t vm = { 0 };
+ uc_vm_init(&vm, &config);
+
+ /* load standard library into global VM scope */
+ uc_load_stdlib(uc_vm_scope_get(&vm));
+
+ /* add global variables x and y to VM scope */
+ ucv_object_add(uc_vm_scope_get(&vm), "x", ucv_int64_new(123));
+ ucv_object_add(uc_vm_scope_get(&vm), "y", ucv_int64_new(456));
+
+ /* execute compiled program function */
+ uc_value_t *last_expression_result = NULL;
+ int return_code = uc_vm_execute(&vm, progfunc, &last_expression_result);
+
+ /* handle return status */
+ switch (return_code) {
+ case STATUS_OK:
+ exit_code = 0;
+
+ char *s = ucv_to_string(&vm, last_expression_result);
+
+ printf("Program finished successfully.\n");
+ printf("Function return value is %s\n", s);
+ free(s);
+ break;
+
+ case STATUS_EXIT:
+ exit_code = (int)ucv_int64_get(last_expression_result);
+
+ printf("The invoked program called exit().\n");
+ printf("Exit code is %d\n", exit_code);
+ break;
+
+ case ERROR_COMPILE:
+ exit_code = 1;
+
+ printf("A compilation error occurred while running the program\n");
+ break;
+
+ case ERROR_RUNTIME:
+ exit_code = 2;
+
+ printf("A runtime error occurred while running the program\n");
+ break;
+ }
+
+ /* free last expression result */
+ ucv_put(last_expression_result);
+
+ /* free VM context */
+ uc_vm_free(&vm);
+
+ return exit_code;
+}
diff --git a/examples/native-function.c b/examples/native-function.c
new file mode 100644
index 0000000..89b3d15
--- /dev/null
+++ b/examples/native-function.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2021 Jo-Philipp Wich <jo@mein.io>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+
+#include <ucode/compiler.h>
+#include <ucode/lib.h>
+#include <ucode/vm.h>
+
+
+#define MULTILINE_STRING(...) #__VA_ARGS__
+
+static const char *program = MULTILINE_STRING(
+ {%
+ print("add() = " + add(5, 3.1, 2) + "\n");
+ print("multiply() = " + multiply(7.3, 5) + "\n");
+ %}
+);
+
+static uc_parse_config_t config = {
+ .strict_declarations = false,
+ .lstrip_blocks = true,
+ .trim_blocks = true
+};
+
+static uc_value_t *
+multiply_two_numbers(uc_vm_t *vm, size_t nargs)
+{
+ uc_value_t *x = uc_get_arg(0);
+ uc_value_t *y = uc_get_arg(1);
+
+ return ucv_double_new(ucv_to_double(x) * ucv_to_double(y));
+}
+
+static uc_value_t *
+add_all_numbers(uc_vm_t *vm, size_t nargs)
+{
+ double res = 0.0;
+
+ for (size_t n = 0; n < nargs; n++)
+ res += ucv_to_double(uc_get_arg(n));
+
+ return ucv_double_new(res);
+}
+
+int main(int argc, char **argv)
+{
+ int exit_code = 0;
+
+ /* create a source buffer containing the program code */
+ uc_source_t *src = uc_source_new_buffer("my program", strdup(program), strlen(program));
+
+ /* compile source buffer into function */
+ char *syntax_error = NULL;
+ uc_function_t *progfunc = uc_compile(&config, src, &syntax_error);
+
+ /* release source buffer */
+ uc_source_put(src);
+
+ /* check if compilation failed */
+ if (!progfunc) {
+ fprintf(stderr, "Failed to compile program: %s\n", syntax_error);
+
+ return 1;
+ }
+
+ /* initialize VM context */
+ uc_vm_t vm = { 0 };
+ uc_vm_init(&vm, &config);
+
+ /* load standard library into global VM scope */
+ uc_load_stdlib(uc_vm_scope_get(&vm));
+
+ /* register our native functions as "add" and "multiply" */
+ uc_add_function(uc_vm_scope_get(&vm), "add", add_all_numbers);
+ uc_add_function(uc_vm_scope_get(&vm), "multiply", multiply_two_numbers);
+
+ /* execute program function */
+ int return_code = uc_vm_execute(&vm, progfunc, NULL);
+
+ /* handle return status */
+ if (return_code == ERROR_COMPILE || return_code == ERROR_RUNTIME) {
+ printf("An error occurred while running the program\n");
+ exit_code = 1;
+ }
+
+ /* free VM context */
+ uc_vm_free(&vm);
+
+ return exit_code;
+}
diff --git a/examples/state-reset.c b/examples/state-reset.c
new file mode 100644
index 0000000..893ea26
--- /dev/null
+++ b/examples/state-reset.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2021 Jo-Philipp Wich <jo@mein.io>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+
+#include <ucode/compiler.h>
+#include <ucode/lib.h>
+#include <ucode/vm.h>
+
+
+#define MULTILINE_STRING(...) #__VA_ARGS__
+
+static const char *program = MULTILINE_STRING(
+ {%
+ /* the global test variable should've been reset since the previous run */
+ print("Global variable is null? " + (global.test == null) + "\n");
+
+ global.test = true;
+ %}
+);
+
+static uc_parse_config_t config = {
+ .strict_declarations = false,
+ .lstrip_blocks = true,
+ .trim_blocks = true
+};
+
+int main(int argc, char **argv)
+{
+ int exit_code = 0;
+
+ /* create a source buffer containing the program code */
+ uc_source_t *src = uc_source_new_buffer("my program", strdup(program), strlen(program));
+
+ /* compile source buffer into function */
+ char *syntax_error = NULL;
+ uc_function_t *progfunc = uc_compile(&config, src, &syntax_error);
+
+ /* release source buffer */
+ uc_source_put(src);
+
+ /* check if compilation failed */
+ if (!progfunc) {
+ fprintf(stderr, "Failed to compile program: %s\n", syntax_error);
+
+ return 1;
+ }
+
+ /* execute compiled program function five times */
+ for (int i = 0; i < 5; i++) {
+ /* initialize VM context */
+ uc_vm_t vm = { 0 };
+ uc_vm_init(&vm, &config);
+
+ /* load standard library into global VM scope */
+ uc_load_stdlib(uc_vm_scope_get(&vm));
+
+ printf("Iteration %d: ", i + 1);
+
+ /* take additional reference to progfunc to avoid freeing it after execution */
+ ucv_get(&progfunc->header);
+
+ /* execute program function */
+ int return_code = uc_vm_execute(&vm, progfunc, NULL);
+
+ /* handle return status */
+ if (return_code == ERROR_COMPILE || return_code == ERROR_RUNTIME) {
+ printf("An error occurred while running the program\n");
+ exit_code = 1;
+ break;
+ }
+
+ /* free VM context */
+ uc_vm_free(&vm);
+ }
+
+ /* release program function */
+ ucv_put(&progfunc->header);
+
+ return exit_code;
+}
diff --git a/examples/state-reuse.c b/examples/state-reuse.c
new file mode 100644
index 0000000..4ebf556
--- /dev/null
+++ b/examples/state-reuse.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2021 Jo-Philipp Wich <jo@mein.io>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+
+#include <ucode/compiler.h>
+#include <ucode/lib.h>
+#include <ucode/vm.h>
+
+
+#define MULTILINE_STRING(...) #__VA_ARGS__
+
+static const char *program = MULTILINE_STRING(
+ {%
+ let n = global.value || 1;
+
+ print("Current value is " + n + "\n");
+
+ global.value = n * 2;
+ %}
+);
+
+static uc_parse_config_t config = {
+ .strict_declarations = false,
+ .lstrip_blocks = true,
+ .trim_blocks = true
+};
+
+int main(int argc, char **argv)
+{
+ int exit_code = 0;
+
+ /* create a source buffer containing the program code */
+ uc_source_t *src = uc_source_new_buffer("my program", strdup(program), strlen(program));
+
+ /* compile source buffer into function */
+ char *syntax_error = NULL;
+ uc_function_t *progfunc = uc_compile(&config, src, &syntax_error);
+
+ /* release source buffer */
+ uc_source_put(src);
+
+ /* check if compilation failed */
+ if (!progfunc) {
+ fprintf(stderr, "Failed to compile program: %s\n", syntax_error);
+
+ return 1;
+ }
+
+ /* initialize VM context */
+ uc_vm_t vm = { 0 };
+ uc_vm_init(&vm, &config);
+
+ /* load standard library into global VM scope */
+ uc_load_stdlib(uc_vm_scope_get(&vm));
+
+ /* execute compiled program function five times */
+ for (int i = 0; i < 5; i++) {
+ printf("Iteration %d: ", i + 1);
+
+ /* take additional reference to progfunc to avoid freeing it after execution */
+ ucv_get(&progfunc->header);
+
+ /* execute program function */
+ int return_code = uc_vm_execute(&vm, progfunc, NULL);
+
+ /* handle return status */
+ if (return_code == ERROR_COMPILE || return_code == ERROR_RUNTIME) {
+ printf("An error occurred while running the program\n");
+ exit_code = 1;
+ break;
+ }
+
+ /* perform GC step */
+ ucv_gc(&vm);
+ }
+
+ /* release program function */
+ ucv_put(&progfunc->header);
+
+ /* free VM context */
+ uc_vm_free(&vm);
+
+ return exit_code;
+}