From: Alexander Goussas Date: Fri, 1 Nov 2024 00:56:19 +0000 (-0500) Subject: feat: evaluate call expressions X-Git-Url: http://git.frustrated-labs.net/?a=commitdiff_plain;h=9dd2f5f363c7f4a201c7878b7545bfbd039ea24e;p=so-test.git feat: evaluate call expressions --- diff --git a/interpreter.c b/interpreter.c index b5cf0c7..bcf33a6 100644 --- a/interpreter.c +++ b/interpreter.c @@ -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 index 0000000..d6e33f5 Binary files /dev/null and b/lib/libc.so.6 differ