digitalmars.D - Howto: D Apps ~ DMDScript
I spent a little time playing with DMDScript and added my own readf and writef functions. I noticed some people wondering how it was done so here is the quick and dirty way. You will need to edit two files - dglobal.d and text.d. Exactly what you are doing should be fairly self evident when you are actually looking at the files. In text.d you need to tell DMDScript what the function names will be: ---- text.d ---------------------------------------------------- char[] TEXT_readf = "readf"; char[] TEXT_writef = "writef"; ---------------------------------------------------------------- Now in dglobal we have to do two things. First we add the function implementations at the top of the file (so they are easy to find if you want to change/add anything): ---- dglobal.d : top ------------------------------------------- import std.stream; import std.file; void* Dglobal_readf(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) { std.stream.stdout.writeLine("Writing "~arglist[0].string); char[] buffer = cast(char[]) std.file.read(arglist[0].string); ret.putVstring(buffer); return null; } void* Dglobal_writef(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) { std.stream.stdout.writeLine("Writing "~arglist[0].string); std.file.write(arglist[0].string,arglist[1].string); return null; } ---------------------------------------------------------------- Finally with the script engine recognizing the function names in scripts and having an implementation we need to associate the implementation with the TEXT_ stuff. Notice the numbers. I suspect (but am not certain) they indicate the number of arguments expected: ---- dglobal.d : bottom ---------------------------------------- { &TEXT_readf, &Dglobal_readf, 1 }, { &TEXT_writef, &Dglobal_writef, 2 }, ---------------------------------------------------------------- Now for a main() function from which we will simply run a single script named on the command line: ---- main.d----------------------------------------------------- import std.file; import std.stream; import dmdscript.script; int main(char[][] args) { if( args.length != 2 ) { std.stream.stdout.writeLine("Expecting a script filename "); return 1; } char[] scriptText = cast(char[])std.file.read(filename); Program script = new Program(); script.compile(filename, scriptText, null); script.execute(null); return 0; } ---------------------------------------------------------------- Now we can run a test script to see what happens: ---- test.ds -------------------------------------------------- var scriptText = readf("test.ds"); write("test.ds", scriptText ~ "\n//it worked!"); ---------------------------------------------------------------- Now test.ds contains a comment it did not have before. So your scripts can persitently store variables or look deeply at themselves. Even better you can exploit IE size security holes!
Jan 22 2005
"parabolis" <parabolis softhome.net> wrote in message news:csuf29$1d90$1 digitaldaemon.com...Finally with the script engine recognizing the function names in scripts and having an implementation we need to associate the implementation with the TEXT_ stuff. Notice the numbers. I suspect (but am not certain) they indicate the number of arguments expected: ---- dglobal.d : bottom ---------------------------------------- { &TEXT_readf, &Dglobal_readf, 1 }, { &TEXT_writef, &Dglobal_writef, 2 }, ----------------------------------------------------------------You're right - the last argument gives the .length property for the function. This is part of the ECMA 262 spec, but the .length property is largely useless, because any number of arguments can be passed regardless.
Jan 23 2005