From: nishi Date: Thu, 25 Apr 2024 03:36:56 +0000 (+0000) Subject: ffi kinda works X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=9cde387a765cbe8b00f0295ff18661239952f38a;p=serenade.git ffi kinda works git-svn-id: file:///raid/svn-main/nishi-serenade/trunk@31 0f02c867-ac3d-714e-8a88-971ba1f6efcf --- diff --git a/Serenade/ffi_binding.c b/Serenade/ffi_binding.c index d42aa99..51b9c22 100644 --- a/Serenade/ffi_binding.c +++ b/Serenade/ffi_binding.c @@ -47,7 +47,7 @@ ffi_cif cif; struct ffi_info { void* ptr; ffi_cif cif; - ffi_type** argtypes; + ffi_type** args; }; struct sn_generic* ffi_symbol_handler(struct sn_interpreter* sn, int args, struct sn_generic** gens) { @@ -68,15 +68,34 @@ struct sn_generic* ffi_symbol_handler(struct sn_interpreter* sn, int args, struc return gen; } +struct sn_generic* function_caller_handler(struct sn_interpreter* sn, int args, struct sn_generic** gens) { + struct sn_generic* gen = malloc(sizeof(struct sn_generic)); + gen->type = SN_TYPE_VOID; + struct ffi_info* info = (struct ffi_info*)gens[0]->ptr; + printf("%x\n", info); + ffi_call(&info->cif, FFI_FN(info->ptr), NULL, NULL); + return gen; +} + struct sn_generic* ffi_function_handler(struct sn_interpreter* sn, int args, struct sn_generic** gens) { struct sn_generic* gen = malloc(sizeof(struct sn_generic)); gen->type = SN_TYPE_VOID; - if(args > 1){ - if(gens[1]->type == SN_TYPE_PTR){ + if(args > 1) { + if(gens[1]->type == SN_TYPE_PTR) { struct ffi_info* info = malloc(sizeof(struct ffi_info)); int i; - for(i = 2; i < args; i++){ + gen->type = SN_TYPE_FUNCTION; + gen->handler = function_caller_handler; + gen->name = NULL; + + info->ptr = gens[1]->ptr; + info->args = malloc(sizeof(ffi_type*) * (args - 2)); + + for(i = 2; i < args; i++) { } + + ffi_prep_cif(&info->cif, FFI_DEFAULT_ABI, args - 2, &ffi_type_void, info->args); + gen->ptr = info; } } return gen; diff --git a/Serenade/interpreter.c b/Serenade/interpreter.c index e3e56dc..458a720 100644 --- a/Serenade/interpreter.c +++ b/Serenade/interpreter.c @@ -81,6 +81,7 @@ struct sn_generic* print_handler(struct sn_interpreter* sn, int args, struct sn_ printf("\n"); gen->type = SN_TYPE_FUNCTION; gen->name = sn_strdup("print"); + gen->handler = NULL; return gen; } @@ -172,6 +173,8 @@ void sn_set_variable(struct sn_interpreter* sn, const char* name, struct sn_gene sn->variables[i]->key = sn_strdup(name); sn->variables[i]->value = gen; sn->variables[i]->handler = NULL; + printf("%s %x\n", name, gen->ptr); + if(gen->type == SN_TYPE_FUNCTION) sn->variables[i]->handler = gen->handler; sn->variables[i + 1] = NULL; } } diff --git a/Serenade/parser.c b/Serenade/parser.c index c17ed1f..3fc2637 100644 --- a/Serenade/parser.c +++ b/Serenade/parser.c @@ -62,6 +62,8 @@ struct sn_generic* sn_generic_dup(struct sn_generic* g) { } else if(r->type == SN_TYPE_FUNCTION) { r->name = sn_strdup(g->name); } + r->ptr = g->ptr; + return r; } diff --git a/Serenade/parser.h b/Serenade/parser.h index a6a245b..f00b6d8 100644 --- a/Serenade/parser.h +++ b/Serenade/parser.h @@ -33,17 +33,23 @@ #include +#include "interpreter.h" + enum types { SN_TYPE_DOUBLE = 0, SN_TYPE_STRING, SN_TYPE_TREE, SN_TYPE_PTR, SN_TYPE_FUNCTION, SN_TYPE_VOID, SN_TYPE_VARIABLE }; +struct sn_interpreter; + struct sn_generic { int type; double number; char* string; unsigned long long string_length; void* ptr; + void* funcptr; char* name; struct sn_tree* tree; bool used; + struct sn_generic* (*handler)(struct sn_interpreter* sn, int, struct sn_generic**); }; struct sn_tree { diff --git a/Serenade/run.c b/Serenade/run.c index 44f7d95..4d18f1a 100644 --- a/Serenade/run.c +++ b/Serenade/run.c @@ -62,25 +62,34 @@ struct sn_generic* _sn_run(struct sn_interpreter* sn, struct sn_generic* gen) { for(j = 0; gen->tree->args[j]; j++) { args[j] = _sn_run(sn, gen->tree->args[j]); } - for(j = 0; sn->variables[j] != NULL; j++) { - if(strcmp(sn->variables[j]->key, op->name) == 0) { - called = true; - struct sn_generic* op_result = NULL; - if(sn->variables[j]->handler != NULL) { - op_result = sn->variables[j]->handler(sn, argc, args); - } else { - struct sn_generic* build = malloc(sizeof(struct sn_generic)); - build->tree = malloc(sizeof(struct sn_tree)); - build->tree->args = args; - build->tree->args[0] = sn->variables[j]->value; - op_result = _sn_run(sn, build); - free(build->tree); - } - if(op_result != NULL) { - free(r); - r = op_result; + if(args[0]->handler != NULL) { + free(r); + r = args[0]->handler(sn, argc, args); + called = true; + } else { + for(j = 0; sn->variables[j] != NULL; j++) { + if(strcmp(sn->variables[j]->key, op->name) == 0) { + called = true; + struct sn_generic* op_result = NULL; + if(sn->variables[j]->handler != NULL) { + if(sn->variables[j]->value != NULL) { + args[0] = sn->variables[j]->value; + } + op_result = sn->variables[j]->handler(sn, argc, args); + } else { + struct sn_generic* build = malloc(sizeof(struct sn_generic)); + build->tree = malloc(sizeof(struct sn_tree)); + build->tree->args = args; + build->tree->args[0] = sn->variables[j]->value; + op_result = _sn_run(sn, build); + free(build->tree); + } + if(op_result != NULL) { + free(r); + r = op_result; + } + break; } - break; } } if(!called) { diff --git a/Serenade/util.c b/Serenade/util.c index b5afb21..2e09aa1 100644 --- a/Serenade/util.c +++ b/Serenade/util.c @@ -57,7 +57,7 @@ void sn_print_to(FILE* f, struct sn_generic* gen) { } else if(gen->type == SN_TYPE_VOID) { fprintf(f, ""); } else if(gen->type == SN_TYPE_FUNCTION) { - fprintf(f, "", gen->name); + fprintf(f, "", gen->name == NULL ? "(anonymous)" : gen->name); } else if(gen->type == SN_TYPE_PTR) { fprintf(f, "", gen->ptr); } diff --git a/cmdline b/cmdline index ad74781..860c096 100644 --- a/cmdline +++ b/cmdline @@ -4,11 +4,11 @@ #ifdef LIBS #ifdef HAS_FFI_SUPPORT -lffi +#endif #ifdef __linux__ -ldl #endif #endif -#endif #ifdef OBJS #ifdef HAS_FFI_SUPPORT