[ prog / sol / mona ]

prog


Marvin Minsky - The Beauty of the Lisp Language

118 2020-10-10 10:33

Turns out you can do true dynamic eval in C via library loading objects(compiled by GCC),
but its incredibly ugly vs writing "pre-compiled" lambdas.
https://stackoverflow.com/questions/39091681/writing-eval-in-c

#include <dlfcn.h>
#include <stdio.h>

typedef void (*fevalvd)(int arg);

/* We need one of these per function signature */
/* Disclaimer: does not support currying; attempting to return functions -> undefined behavior */
/* The function to be called must be named fctn or this does not work. */
void evalvd(const char *function, int arg)
{
char buf1[50];
char buf2[50];
char buf3[100];
void *ctr;
fevalvd fc;
snprintf(buf1, 50, "/tmp/dl%d.c", getpid());
snprintf(buf2, 50, "/tmp/libdl%d.so", getpid());
FILE *f = fopen(buf1, "w");
if (!f) { fprintf (stderr, "can't open temp file\n"); }
fprintf(f, "%s", function);
fclose(f);
snprintf(buf3, 100, "gcc -shared -fpic -o %s %s", buf2, buf1);
if (system(buf3)) { unlink(buf1); return ; /* oops */ }

ctr = dlopen(buf2, RTLD_NOW | RTLD_LOCAL);
if (!ctr) { fprintf(stderr, "can't open\n"); unlink(buf1); unlink(buf2); return ; }
fc = (fevalvd)dlsym(ctr, "fctn");
if (fc) {
fc(arg);
} else {
fprintf(stderr, "Can't find fctn in dynamic code\n");
}
dlclose(ctr);
unlink(buf2);
unlink(buf1);
}

int main(int argc, char **argv)
{
evalvd("#include <stdio.h>\nvoid fctn(int a) { printf(\"%d\\n\", a); }\n", 10);
}

301


VIP:

do not edit these