| What | '''Picol''' | | Where | https://chiselapp.com/user/dbohdan/repository/picol/ (version 0.1.25, [dbohdan]'s fork) | | | http://wiki.tcl.tk/_repo/wiki_images/picol0-1-22.zip (version 0.1.22) | | Description | A tiny Tcl interpreter. | | Updated | 2016-02-07 (version 0.1.25) | | | 2007-05-01 (version 0.1.22) | | License | 2-clause BSD | [SS]: [http://oldblog.antirez.com/page/picol.html%|%Picol%|%] is a Tcl interpreter in 500 lines of C code! If you like it vote [http://programming.reddit.com/info/1aft9/comments%|%my entry on reddit%|%] (the reddit url changed because of a reddit bug). [RS] Since 2007-04-01, I'm playing with Picol at home - it's been a long while that I prefer to do a breakfast fun project in C :) Basically I'm adding features to bring it closer to Tcl (7.x - [everything is a string] really). Linecount is at about 1700 now. Latest additions focused on 8.5 features like [apply] (see below), [{*}], [in]/[ni] etc. DISCLAIMER: This is an educational toy model only, it is weaker and slower that real [Tcl]. I'm not planning to add [regexp], [Unicode], full [expr] parsing etc... But it's great for experimenting with C, I've had weeks of fun with it. As the regular Wiki is read-only, I made my first report [http://wfr.tcl.tk/Picol%|%in French%|%]. Build it with either of: ======none gcc -O2 -Wall -o picol picol.c cl /O2 /W3 -o picol.exe picol.c ====== '''Version 0.1.22''' is zipped, together with test suite, at http://wiki.tcl.tk/_repo/wiki_images/picol0-1-22.zip - new: unknown, auto_path, tclIndex, auto_index, uplevel #0. The currently supported command set (some only partially) is ======none /Tcl/Picol $ picol -e 'lsort [info commands]' ! != % && * ** + - / < <= == > >= _l abs append array break catch clock close concat continue eof eq error eval exec exit expr file flush for foreach format gets glob global if in incr info interp join lappend lindex linsert list llength lrange lreplace lsearch lset lsort ne ni open pid proc puts pwd rand read rename return scan seek set setenv source split string subst switch tell time trace unset uplevel variable while || ====== [dbohdan] 2016-01-23: A slightly refactored '''version 0.1.23''' of Picol is available at https://chiselapp.com/user/dbohdan/repository/picol/. The difference from version 0.1.22 above is that the interpreter has been separated from the REPL making it possible to use it as a library in your own C code. It includes two examples of such use: a "Hello, World!" and a custom command example. ---- Here's an example how I extended Picol for simple file I/O, implementing [open], [gets] and [close]: ====== int picolCommandOpen(struct picolInterp *i, int argc, char **argv, void *pd) { char* mode = "r"; FILE* fp = NULL; char buf[64]; if (argc != 2 && argc != 3) return picolArityErr(i,argv[0]); if(argc == 3) mode = argv[2]; fp = fopen(argv[1], mode); if(!fp) {return picolError1(i, "could not open file %s", argv[1]);} sprintf(buf,"%p",fp); return picolSetResult(i,buf); } int picolCommandGets(struct picolInterp *i, int argc, char **argv, void *pd) { char buf[1024]; char* getsrc; FILE* fp = stdin; if (argc != 2 && argc != 3) return picolArityErr(i,argv[0]); if(!STREQ(argv[1],"stdin")) { sscanf(argv[1],"%p", &fp); /* caveat usor */ } if(!feof(fp)) { getsrc = fgets(buf,sizeof(buf), fp); buf[strlen(buf)-1] = '\0'; /* chomp last newline */ if (argc == 2) { picolSetResult(i,buf); } else { if(getsrc) { picolSetVar(i,argv[2],buf); picolSetIntResult(i,strlen(buf)); } else {picolSetResult(i,"-1");} } } else {picolSetResult(i,"-1");} return PICOL_OK; } int picolCommandClose(struct picolInterp *i, int argc, char **argv, void *pd) { FILE *fp = NULL; if (argc != 2) return picolArityErr(i,argv[0]); sscanf(argv[1],"%p", &fp); /* caveat usor */ fclose(fp); return PICOL_OK; } # ... picolRegisterCommand(i,"open", picolCommandOpen,NULL); picolRegisterCommand(i,"gets", picolCommandGets,NULL); picolRegisterCommand(i,"close",picolCommandClose,NULL); ====== ---- ====== int picolCommandList(struct picolInterp *i, int argc, char **argv, void *pd) { char buf[1024] = ""; int a; for(a=1; a= 2, "apply {argl body} ?arg ...?"); cp = picolParseList(argv[1],buf); if(!cp) return picolErr(i,"bad apply usage"); picolParseList(cp,buf2); procdata[0] = buf; procdata[1] = buf2; return picolCallProc(i, argc-1, argv+1, (void*)procdata); } ====== ---- [TP] 2009-06-29 - Here is a patch for picol0-1.22. For arrays and other things, Picol stores a string representation of a pointer to the internal structure(s), and parses the pointer from the string representation when retrieving values. The corresponding sprintf() / sscanf() uses the '''%p''' format character and assumes that the pointer string representation is at least 8 bytes long. On some machines, pointers are low addresses and the '''%p''' format is less than 8 bytes. This patch simply lowers the expected length of the pointer string representation from 8 bytes to 3. At line 462, replace the '''picolIsPtr()''' function with this implementation: ====== void* picolIsPtr(char* str) { void* p = NULL; sscanf(str,"%p",&p); return (p && strlen(str)>=3? p: NULL); } ====== With this patch, Picol has been ported to the Java Virtual Machine (JVM) using NestedVM [http://nestedvm.ibex.org/]. ---- '''[FB] - 2011-11-30 09:09:42''' Picolibri is a straight port of Picol (in its current version 0.1.22) to the [Colibri] library (version 0.12), replacing plain C strings with Colibri [rope]s, and malloc'd memory management with automatic garbage collection. The modified source is about 50 lines longer than the original (1735 vs 1701 for picol.c, and 147 vs. 127 for picol.h). Most changes involve replacing C calls such as strlen by their Colibri counterparts, mostly through macros for readability, and also providing string to Colibri structure conversions (ropes, lists, maps...). The modified Picol source is part of the [http://sourceforge.net/projects/tcl9/files/colibri/colibri0.12/colibri0.12.src.zip/download%|%Colibri source distribution%|%]. A pre-compiled Windows library is available [http://sourceforge.net/projects/tcl9/files/colibri/colibri0.12/picolibri0.1.win32.zip/download%|%here%|%]. It includes the command-line executable along with Colibri DLL and the original Picol scripts: <> Language | Tcl Implementations