Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to run Smalltalk scripts from the command line?

I found a (possibly outdated and incorrect) blog post from 2004 which claimed that it was impossible to run Smalltalk scripts from the command line. Has anything changed since then, and is it possible to run Smalltalk scripts from the command line? I've done a lot of Google searching, and I've found no information about this topic at all.

Is there any way to save a Smalltalk script (such as this one) as a file, and then run the script from the command line?

Transcript show: 'This should be printed to the standard output.' printString; cr.
like image 882
Anderson Green Avatar asked Jun 23 '13 00:06

Anderson Green


3 Answers

Pharo has decent command line support and a simple zeroconf script to install it:

curl get.pharo.org | bash
./pharo Pharo.image --help
./pharo Pharo.image eval "1+2"

We use these tools on a regular basis on our ci servers.

New command line handles can be installed easily by subclassing. You will find a partial documentation here.

Coral aims at more complex interfaces and supports complex parameter parsing. The default command line tools shipped with Pharo follow a rather simplistic approach and you have to check and process parameters manually.

like image 50
camillobruni Avatar answered Nov 14 '22 19:11

camillobruni


With gst, it's straightforward. Put this into hi.st:

Transcript show: 'Hi!'

Then run gst hi.st and you're done.

To pass arguments from the command line, you do as follows:

Transcript show: 'Hi ' , Smalltalk arguments first , '!'

Then run gst hi.st -a World

like image 28
Bernat Romagosa Avatar answered Nov 14 '22 21:11

Bernat Romagosa


Running a script from the command line is trivial with pretty much any Squeak version, certainly 5.3 or newer.

Basically {path/to/myVM} {path/to/myscript}

That myscript argument can be a URL pointing to a smalltalk code file or simply a filename. Since Smalltalk can read both code to install and code to run directly from a file, you can add some new code - consider it 'script functions' if you like - and then run whatever you want. So, at least on a unix machine, you can make a shell script that runs your VM and appends the filename of your intended script, and thus do sometihng like myshellscript mystuff.st

As an example, consider a script to work out and print the first Fibonacci number that requires one million digits.

#!/usr/bin/squeak /home/pi/Squeak/Squeak5.3-18560.image

!Integer methodsFor: 'mathematical functions' stamp: 'tpr 5/6/2019 12:22'!
fibonacci
"derived from https://www.nayuki.io/page/fast-fibonacci-algorithms"
"(1 to: 20) collect:[:i| i fastDoublingFib]"
"testing a quite large one - "
"8577 fibonacci= 13724780954457889052017147206983806244049002655849289934662148526555403650297300643609932653364630032094175733360509578504423049114004867523161091564824674600978308740378989479162611031273424686573759784740689516901416473328655422390895971263265867635819510949686102571388751758998017349379498918930220900180038324615253426530740473855269056304380498630108126734047701362218655030270360608989081398866489746698916626888016696892691933237089180504631788915650757757515944644732966345269202761471025651071790297611079540881155092137592980230998234868586211881093892491570520577408961869977892273540956424095750855208529072246641778982103984467921868950012668004047986803017482248992968482737462668300684879633714025755790485860328854796518843956263863014632532331145699658530054942590047273403691531821918862996422405159427262092477196755988981309029424760342802374213122162727840557722145891090413688461745240415668189577836068480363407847582529735341950500636735281963089675493707159434777756081146452522323681782226760627277553296721358921412115264845467834979154061137421532609247762981818564578019888974692581079593575783553856910367568474613323528337733872069223030834774749130478360574004172522316484339530942110067893000847800932306298725285623628731149337468217751734165148732164148285915275115006479682658150442259002271790547596033006363411193653337536041106069912826015502035140618407668385378737477702597473151509972754111640855347958033314453349633268543893894677097708945041254623018915871109789412793709229204261914803477697183287924195770678873001065036313926288444791424871512110658175954743584548831946767673488152740675550518235698898217693311515366329280005757014637854214769152690638778904780724293185353992279724740604674926819294787586671833537117545443846365508358918882"
    | a b c |
    a :=  0.
    b := 1.
    self highBit to: 1 by: -1 do:[:i||d e|
        d := ((b bitShift: 1) - a) * a.
        e := a squared + b squared.
        a := d.
        b := e.
        (self bitAt: i) = 1  ifTrue:[
            c := a + b.
            a := b.
            b := c]
        ].
    ^a! !


| t f|
t:= [f := 4784969 fibonacci] timeToRun.
FileStream stdout
    nextPutAll: 'fib(4784969) = '; 
    "nextPutAll: f asString; "
    cr; 
    nextPutAll: 'time = '; 
    nextPutAll: t asString; 
    nextPutAll: ' mS'; 
    cr.
Smalltalk snapshot: false andQuit: true

If you save this and set it to be executable the first line would run the script (this is from a Raspberry Pi and /usr/bin/squeak is a standard part of the distro) with the name of the script as the argument. It loads a bit of code to implement an interestingly clever algorithm, runs the test, outputs to stdout, and finally quits. It takes about 3 seconds on a Pi 4. Simply running the .st file will now work - ./myscript

It is, apparently, also possible to do clever tricks and register a magic pattern with the binfmt_misc facility so one could make st files have their own equivalent of the #! token.

like image 1
timRowledge Avatar answered Nov 14 '22 21:11

timRowledge