]> git.frustrated-labs.net Git - so-test.git/commitdiff
feat: evaluate call expressions
authorAlexander Goussas <[email protected]>
Fri, 1 Nov 2024 00:56:19 +0000 (19:56 -0500)
committerAlexander Goussas <[email protected]>
Fri, 1 Nov 2024 00:56:19 +0000 (19:56 -0500)
interpreter.c
lib/libc.so.6 [new file with mode: 0755]

index b5cf0c7a61fcc31cd292e4c9d2d8e625de81ef59..bcf33a6d85fa6f5fde4eee5fd74dccbfd61c6ceb 100644 (file)
@@ -63,4 +63,57 @@ void eval_load_expr(so_interpreter *interp, so_expr_load *load, so_expr *expr) {
 }
 
 void eval_call_expr(so_interpreter *interp, so_expr_call *call, so_expr *expr) {
+    void *function_handle = NULL;
+
+    for (int i = 0; i < interp->loaded_libraries; i++) {
+        function_handle = dlsym(interp->library_handles[i], call->name);
+        if (function_handle)
+            break;
+    }
+
+    if (!function_handle) {
+        fprintf(stderr, "error: could not find the function: %s\n", call->name);
+        free_ast(expr);
+        so_interpreter_deinit(interp);
+        exit(EXIT_FAILURE);
+    }
+
+    ffi_cif cif;
+
+    ffi_type **argument_types = malloc(sizeof(ffi_type *) * call->nargs);
+    void **argument_values = malloc(sizeof(void *) * call->nargs);
+
+    for (int i = 0; i < call->nargs; i++) {
+        if (call->args[i]->tag == SO_EXPR_INT) {
+            argument_types[i] = &ffi_type_sint;
+            argument_values[i] = &call->args[i]->as.number;
+        }
+
+        if (call->args[i]->tag == SO_EXPR_STRING) {
+            argument_types[i] = &ffi_type_pointer;
+            argument_values[i] = &call->args[i]->as.string;
+        }
+    }
+
+    ffi_status status = ffi_prep_cif(
+        &cif,
+        FFI_DEFAULT_ABI,
+        call->nargs,
+        &ffi_type_void,
+        argument_types);
+
+    if (status != FFI_OK) {
+        fprintf(stderr, "error: failed to prepare ffi call: %s\n", call->name);
+        free_ast(expr);
+        so_interpreter_deinit(interp);
+        free(argument_types);
+        free(argument_values);
+        exit(EXIT_FAILURE);
+    }
+
+    // At this point is to the caller to have provided the right arguments
+    ffi_call(&cif, function_handle, NULL, argument_values);
+
+    free(argument_types);
+    free(argument_values);
 }
diff --git a/lib/libc.so.6 b/lib/libc.so.6
new file mode 100755 (executable)
index 0000000..d6e33f5
Binary files /dev/null and b/lib/libc.so.6 differ