]> Nishi Git Mirror - serenade.git/commitdiff
ffi kinda works
authornishi <nishi@0f02c867-ac3d-714e-8a88-971ba1f6efcf>
Thu, 25 Apr 2024 03:36:56 +0000 (03:36 +0000)
committernishi <nishi@0f02c867-ac3d-714e-8a88-971ba1f6efcf>
Thu, 25 Apr 2024 03:36:56 +0000 (03:36 +0000)
git-svn-id: file:///raid/svn-main/nishi-serenade/trunk@31 0f02c867-ac3d-714e-8a88-971ba1f6efcf

Serenade/ffi_binding.c
Serenade/interpreter.c
Serenade/parser.c
Serenade/parser.h
Serenade/run.c
Serenade/util.c
cmdline

index d42aa99a2850ca5d8b357d210fa6fd168a0a0a7f..51b9c22095b50a63b8f804901bcb6ba814cda956 100644 (file)
@@ -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;
index e3e56dcfe5c1fa05e682f75f5849f4e5e787d556..458a720f665bd7196e3e6bdb5a7d05e59350541e 100644 (file)
@@ -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;
        }
 }
index c17ed1f5b9794a61e3524891888d4b75667a2ac9..3fc2637274b5eea61d9117568a508d251f4e0317 100644 (file)
@@ -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;
 }
 
index a6a245bf050d877c47c17770e11e3e9f3c80c6e1..f00b6d8513261347cb139f92ff4ac9c113e41029 100644 (file)
 
 #include <stdbool.h>
 
+#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 {
index 44f7d9560324d3e03e417cb644c10304d18a38a6..4d18f1a3c7e651139e6ef1c30d5bce5ae307a49e 100644 (file)
@@ -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) {
index b5afb212e1fb3631ae832ccef20397ef7952bcdb..2e09aa116118c5d8b143f23a67838e70ca52a9d2 100644 (file)
@@ -57,7 +57,7 @@ void sn_print_to(FILE* f, struct sn_generic* gen) {
        } else if(gen->type == SN_TYPE_VOID) {
                fprintf(f, "<void>");
        } else if(gen->type == SN_TYPE_FUNCTION) {
-               fprintf(f, "<function %s>", gen->name);
+               fprintf(f, "<function %s>", gen->name == NULL ? "(anonymous)" : gen->name);
        } else if(gen->type == SN_TYPE_PTR) {
                fprintf(f, "<pointer %x>", gen->ptr);
        }
diff --git a/cmdline b/cmdline
index ad747819e1d5e661394ab2e82417dc683e5a5f12..860c096b5c66f9ab5ec08670ee07455a1de5b160 100644 (file)
--- 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