Picol

 

Richard Suchenwirth 2007-04-02 - Picol est un petit logiciel en C qui implémente une langage similaire à Tcl, très simplement. Il est beaucoup intéressant pour étudier les internels d'un interpreteur.

La première version est de Salvatore Sanfilippo - son article (en anglais) à http://antirez.com/page/picol contient un soin pour le code source - environ 550 lignes, aux quels sont implémentées les commandes set, proc, puts, if, while, break, continue et return. Il n'a pas expr avec sa sous-langage différente, mais plusieurs des opérateurs sont fournis comme commandes, e.g. pour

 [expr ($a+$b)*$c]

on écrit

 [* [+ $a $b] $c]

comme au Lisp. Nombres sont integers (entiers) seulement. Tous valeurs sont chaînes de caractères, pour faire l'arithmétique ils sont parsés avec atoi, et le résultat est reformatté avec sprintf.

La langage est beaucoup similaire à Tcl, mais pas égale - les conditions de if et while sont evaluées, et non traitées comme expressions. Par exemple, òu Tcl a

 if {[string equal foo $bar]} ... ## if {$x > 1} ...

en Picol on écrit

 if {string equal foo $bar} ...   ## if {> $x 1} ...

Code qui contient invocations de if ou while est alors pas compatible entre les deux languages. Par conséquence, je nomme les fichiers Picol avec l'extension .pcl.

La version de RS est à http://whim.linuxsys.net/files/picol-0.1.10.c - un peu plus long, à 837 lignes, mais extendée avec des commandes append, catch, concat, error, eval, exit, gets (seulement de stdin), incr, info (partiel, mais inclusif info exists, info body, etc.), rename, source, string (partiel), unset, et l'opérateur de negation "!".

Beaucoup plus en version 0.1.22 - voir http://mini.net/files/picol0-1-22.zip . L'ensemble de commandes en 0.1.22 est:

 /Tcl/Picol $ picol -e 'lsort [info commands]'
 ! != % && * ** + - / < <= == > >= _l abs append apply array break catch clock close concat continue
 eof eq error eval exec exec2 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 source split string subst switch tell time
 trace unknown unset uplevel variable while ||

Comme illustration, voilà ma "test suite" qui marche presq'à parfaitement - seulement le test str.range fait un problème que je ne pouvais pas resoudre, à minuit la Dimanche...

 # test.pcl - test suite for the Picol interpreter
 # with extensions by suchenwi

 puts "begin test [info script]...(argv:$argv),argc:$argc"

 proc test {name cmd -> expected} {
    set res [eval $cmd]
    if {! [string equal $res $expected]} {
        puts "$name failed: $cmd -> $res, expected $expected"
	return 1 ;# increment error counter
    } else {return 0}
 }

 incr n;incr r [test add       {+ 3 4} -> 7]
 incr n;incr r [test mul       {* 3 4} -> 12]
 incr n;incr r [test set       {set x 42; set x} -> 42]
 incr n;incr r [test eval_mul.1 {eval * 6 7} -> 42]
 incr n;incr r [test eval_mul.2 {eval {* 6 7}} -> 42]
 incr n;incr r [test catch.1   {catch {* 6 7}} -> 0]
 incr n;incr r [test catch.2   {catch {/ 1 0}} -> 1]
 incr n;incr r [test catch.3   {catch {/ 1 0} res; set res} -> "divide by zero"]
 incr n;incr r [test str.index {string index hello 1} -> e]
 incr n;incr r [test str.length {string length hello} -> 5]
 incr n;incr r [test str.range {string range abcde 1 3} -> bcd]
 incr n;incr r [test append.1  {set foo hello; append foo world} -> helloworld]
 incr n;incr r [test append.2  {set foo 47;append foo 11;set foo} -> 4711]
 incr n;incr r [test str.lower {string tolower FOO} -> foo]
 incr n;incr r [test str.upper {string toupper foo} -> FOO]
 incr n;incr r [test str.rev   {string reverse picol} -> locip]
 incr n;incr r [test unset  {set foo 1;unset foo;info exists foo} -> 0]
 incr n;incr r [test proc   {proc f x {* $x $x}; f 5} -> 25]
 incr n;incr r [test rename {rename f g; g 6} -> 36]

 puts "[info script]: tested $n, failed $r"

AM (13 avril 2007) A l'occasion du premier avril, j'ai ecrit une version de Picol en FORTRAN 77, appele FEMTOL. On trouve les sources ici: http://ftcl.sourceforge.net - dans le repositoire CVS.

Note bien: cette version ne sera pas corrigee - et je connais un ou deux faux (et bien de limitations et d'omissions).