Search code examples
smalltalksqueakpharo

Using Squeak from a shell


Can I launch Squeak as a REPL (no GUI), where I can enter and evaluate Smalltalk expressions? I know the default image don't allow this. Is there any documentation on how to build a minimum image that can be accessed from a command-line shell?


Solution

  • Here is a (hackish) solution: First, you need OSProcess, so run this in a Workspace:

    Gofer new squeaksource:'OSProcess'; package:'OSProcess';load.
    

    Next, put this in the file repl.st:

    OSProcess thisOSProcess stdOut 
      nextPutAll: 'Welcome to the simple Smalltalk REPL'; 
      nextPut: Character lf; nextPut: $>; flush.
    [ |input|
      [ input := OSProcess readFromStdIn.
        input size > 0 ifTrue: [
          OSProcess thisOSProcess stdOut 
            nextPutAll: ((Compiler evaluate: input) asString; 
            nextPut: Character lf; nextPut: $>; flush 
        ]
      ] repeat.
    ]forkAt: (Processor userBackgroundPriority)
    

    And last, run this command:

    squeak -headless path/to/squeak.image /absolute/path/to/repl.st
    

    You can now have fun with a Smalltalk REPL. Dont forget to type in the command:

    Smalltalk snapshot:true andQuit:true
    

    if you want to save your changes.

    Now, onto the explanation of this solution: OSProcess is a package that allows to run other processes, read from stdin, and write to stdout and stderr. You can access the stdout AttachableFileStream with OSProcess thisOSProcess (the current process, aka squeak).

    Next, you run an infinite loop at userBackgroundPriority (to let other processes run). In this infinite loop, you use Compiler evaluate: to execute the input.

    And you run this in a script with a headless image.