Documentation edit
Tools edit
- GDC
- an open-source D compiler for GCC
- LDC
- an open-source D compiler based on LLVM
- Tkd v1.0.0-beta, 2014-05-04
See also edit
Examples edit
Pat Thoyts' example (D1)
It is fairly simple to call Tcl from D. In fact, it looks a lot like C++ in most places. The main issue is to generate an import symbol file for the Tcl API, which can be done by using the genStubs script file.Under Microsoft Windows I had to convert the standard ActiveTcl tcl83.lib to an OMF format library. To do this we convert to COFF format using Microsoft's LINK program and then Digital Mars' COFF2OMF utilitylink /lib /convert tcl83.lib coff2omd tcl83.libTo illustrate, here is an initial stab. Build this using
dmd simple.d tcl83.lib (Using Windows)or
dmd simple.d -L-ltcl (Using UNIX)
// simple.d - Copyright (C) 2003 Pat Thoyts <patthoyts@users.sf.net> // // Demonstrate linking to Tcl from the D programming language. // See http://dlang.org/ for information // about ``D'' // // $Id: 6261,v 1.28 2006-11-20 19:00:16 jcw Exp $ import std.stream; import std.string; import std.compiler; // ---------------------------------------------------------------------- // Define the bits we need for interfacing to Tcl API // extern (C) { alias void* ClientData; alias void (*Tcl_FreeProc)(char* blockPtr); alias void (*Tcl_CmdDeleteProc)(ClientData clientData); alias int (*Tcl_CmdProc)(ClientData clientData, Tcl_Interp* interp, int argc, char* argv[]); alias void* Tcl_Command; struct Tcl_Interp { char* result; Tcl_FreeProc blockPtr; int errorLine; } enum { TCL_OK = 0, TCL_ERROR = 1, TCL_RETURN = 2, TCL_BREAK = 3, TCL_CONTINUE = 4, } const Tcl_FreeProc TCL_VOLATILE = cast(Tcl_FreeProc)1; const Tcl_FreeProc TCL_STATIC = cast(Tcl_FreeProc)0; const Tcl_FreeProc TCL_DYNAMIC = cast(Tcl_FreeProc)3; Tcl_Interp* Tcl_CreateInterp(); Tcl_Command Tcl_CreateCommand(Tcl_Interp* interp, char* cmdName, Tcl_CmdProc proc, ClientData clientData, Tcl_CmdDeleteProc deleteProc); int Tcl_Eval (Tcl_Interp* interp, char* string); int Tcl_EvalFile (Tcl_Interp* interp, char* fileName); char* Tcl_GetStringResult(Tcl_Interp* interp); void Tcl_SetResult (Tcl_Interp* interp, char* str, Tcl_FreeProc freeProc); } // ---------------------------------------------------------------------- int main(char[][] args) { Tcl_Interp* interp = Tcl_CreateInterp(); Tcl_CreateCommand(interp, "ddemo", &DDemoCmd, null, null); int r; if( args.length < 2 ) { r = Tcl_Eval(interp, "puts \"Tcl version: [info tcl]\"; ddemo"); } else { r = Tcl_EvalFile(interp, args[1]); } printf(Tcl_GetStringResult(interp)); return r; } // Add a new command to the Tcl interpreter. // In this case: return some information about the D compiler. extern (C): int DDemoCmd(ClientData clientData, Tcl_Interp *interp, int argc, char* argv[]) { MemoryStream stm = new MemoryStream; stm.printf(std.compiler.name); stm.printf(" %d.%d", std.compiler.version_major, std.compiler.version_minor); Tcl_SetResult(interp, toStringz(stm.toString()), TCL_STATIC); return TCL_OK; } // ---------------------------------------------------------------------- // // Local variables: // mode: c // compile-command: "dmd simple.d tcl83.lib" // cygwin: "gdc simple.d -ltcl" // End:
nedbrek's example (D1)
nedbrek - I've updated the code for a later D compiler (cygming special, gdc 0.24, using dmd 1.020). You can then extract the Tcl declarations into a separate file (call it 'tcl.d'). To create an extension for Tcl, called 'test', put this in a file 'test.d':import std.compiler; import std.stream; import std.string; import std.c.windows.windows; import tcl; HINSTANCE g_hInst; extern (C) { void gc_init(); void gc_term(); void _moduleCtor(); } extern (Windows) BOOL DllMain(HINSTANCE hinst, ULONG reason, LPVOID rsvd) { switch( reason ) { case DLL_PROCESS_ATTACH: gc_init(); _moduleCtor(); break; case DLL_PROCESS_DETACH: gc_term(); break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: return FALSE; } g_hInst = hinst; return TRUE; } extern (C) int Test_Init(Tcl_Interp* interp) { Tcl_CreateCommand(interp, "ddemo", &DDemoCmd, null, null); return TCL_OK; } extern (C) int DDemoCmd(ClientData clientData, Tcl_Interp *interp, int argc, char* argv[]) { auto stm = new MemoryStream; stm.printf(std.compiler.name); stm.printf(" %d.%d", std.compiler.version_major, std.compiler.version_minor); Tcl_SetResult(interp, toStringz(stm.toString()), TCL_STATIC); return TCL_OK; }This can be built with:
gdc -shared -otest.so test.d -ltclIt then works like a regular tcl extension:
$ tclsh % load test.so % ddemo
Discussion edit
SYStems: I would say C not used more because of competition, D is trying to compete a pretty saturated market.- For the open source croud, it will compete with C, C++, Java, possibly C# (mono and stuff)
- For the commercial croud, it's mainly Java and C# and possibly C/C++
- For somekind of croud, it's Haskell, OCaml, Scheme etc ...
- For the looking for fun new languages to learn croud it's JavaScript (because of AJAX), Ruby, Perl 6 and Tcl 8.5 OO new features ;)
As of October 2006, D is on the verge of being listed with Languages with a Tk binding[1].RLH: That isn't how I read that thread.LWV: After reading through the thread a bit, I see http://www.algonet.se/~afb/d/TK.zip is a beginning of a binding between D and Tk. Some of the issues are people wanting a D GUI that is designed with D philosophies, and later in the thread, concern about the fact that Tk requires X11 headers in some cases. I do not get the feeling that the D community itself is embracing Tk. Instead, there appears to be a number of people thinking about the possibility, with a larger number looking at alternatives.