You guys should appreciate this... About a month ago I had a vision and took it upon myself to write The Most Easily-Extensible Interpreted Scripting Language Ever (TMEEISLE). Just how easily-extensible is TMEEISLE? So extensible that it has no built-in standard-library-like functionality. Consider sort.c, a trivial TMEEISLE script which takes four integers as input and prints them out in sorted order:
#include <stdlib.h> #include <stdio.h>int
compar(void *a, void *b)
{
return *((int *)a) - *((int *)b);
}int
main(int argc, char **argv)
{
int a[4];
FILE *f;
int i;f = fopen("/dev/tty", "r"); for (i = 0; i < 4; i++) fscanf(f, "%i", &a[i]); qsort(a, 4, sizeof(int), compar); for (i = 0; i < 4; i++) printf("%i ", a[i]); printf(" \n"); fclose(f);
}
This can be compiled and run with:
./cpp -I/usr/include sort.c | ./ccom -L/usr/lib -lc
Believe it or not, this is fully interpreted. Also, keep in mind that the interpreted language has no standard library, so it has absolutely no knowledge of functions like fscanf, qsort, and printf. Here's how it works:
The preprocessor is plain old C preprocessor and does what one would expect it to do.
Then the real magic happens. First the "compiler" dlopens the shared libraries specified on the command line - in this case only libc.so. Then it interprets its input as one would expect, but it eventually encounters a prototyped yet undefined function, like fopen(). When this happens, it goes and looks in the shared libraries specified on the command line (in this case, only libc) to see if the symbol is defined there. In this case, fopen, of course, is defined, so it gets the address of the function. Then, referring to the prototype from stdio.h and using the magic of inline assembly, it pushes pointers to "/dev/tty" and "r" onto the stack, calls the address of the real fopen(), and fetches the returned pointer.
No big deal, right? But notice that the script later calls qsort() and passes it a pointer to a function defined in an interpreted language - how can the real qsort() possibly call a function that isn't even compiled? Thanks to the magic of inline assembly and some major wtfery, this actually works, but right now I don't feel like explaining how.
I haven't "finished" TMEEISLE, but it does run examples like the above. Forking in TMEEISLE is especially fun, because, like in perl, the whole interpreter forks. The difference is that perl calls fork() on purpose.
Maybe some day I'll use my spare time to write useful software. Until then, I have much more fun with stuff like this.