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) {
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;
printf("\n");
gen->type = SN_TYPE_FUNCTION;
gen->name = sn_strdup("print");
+ gen->handler = NULL;
return gen;
}
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;
}
}
} else if(r->type == SN_TYPE_FUNCTION) {
r->name = sn_strdup(g->name);
}
+ r->ptr = g->ptr;
+
return r;
}
#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 {
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) {
} 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);
}
#ifdef LIBS
#ifdef HAS_FFI_SUPPORT
-lffi
+#endif
#ifdef __linux__
-ldl
#endif
#endif
-#endif
#ifdef OBJS
#ifdef HAS_FFI_SUPPORT