Skip to content
EricGebhart edited this page Sep 27, 2021 · 2 revisions

The interpreter/REPL

This is defined in repl.py. It has help, persistent history, and tab completion. It has the idea of namespaces and it knows how to import python modules.

There are two help systems. SPR's and python's. They have two different presentations of the same thing, both are very useful. help and pyhelp will give you the documentation for every namespace and command available, even the ones you just created.

  • help will show a short summary, followed by an ls
  • help / will show full namespace help for the Root namespace.
  • help ns will show full namespace help for the ns namespace.
  • help ns/name will show full function help for the ns/name function.

The same rules apply to the pyhelp command, but what it shows is different.

Additionally each SPR module can have it's own help function which can be invoked as any other function, and which will be used by namespace help if it exists. Extensions use a template which contains a help template showing SPR information in a pretty way.

The help text is usually placed in as data /help/ if there is no python module to go with the spr.

Both the module's yaml datastore and spr code are shown in the help if they exist.

The ls command will navigate both the Namespaces of SPR and the yaml datastore. Any path that starts with a / looks in the yaml datastore. Anything that does not start with a / is looked up in the Namespaces.

This is lisp 2 ish, purely from evolution, for anyone interested.

The interpreter does it's best to call the python functions you tell it to. It recognizes, words, strings and numbers. ie. foo "this is a string" 10, it will do it's best to bind the parameters to the matching names in the data if you don't give it all that it needs.

Well almost non existant syntax.

  • ' by itself to read the YAML that follows, terminated with two blank lines.
  • in the first character of the line is a comment.

  • ~ causes variable expansion.
  • . is the current with path
  • / is an absolute path in the data.

YAML code.

Yaml is the easiest way to create data, it will be placed in the current with when it is loaded.

A single quote on a line by it's self, followed by yaml, and another 2 Blank lines will cause the interpreter to switch parsers and merge the yaml it finds there into the yaml data store at the current with.

Here is an example from bar_qr.spr:

'
# this is the bar qr data store and configuration settings.
'
config:
    BQ:
        input_please: Please input a code to be encoded.
        QRcode:
            code_type: QRcode
            result_name: qrc
            filename_suffix: 'QR'
            prefix: 'K1'
            suffix: 'A'
            save_path: 'qrcodes'
            font: DejaVuSans.ttf
            font_size: 18
            filename_extension: '.png'
        barcode:
            code_type: barcode
            result_name: bc
            filename_suffix: 'BC'
            prefix: ''
            suffix: ''
            save_path: 'barcodes'
            auto_filename_extension: '.png'
            filename_extension: ''
            font: ''
            font_size: ''
            save_options:
                module_height: 8
                text_distance: 2
        type-menu:
            barcode: bq/with-bc
            QR-code: bq/with-qr


def with-bc
    "Add the barcode config to the with stack."
    with /config/BQ/barcode

def with-qr
    "Add the QR code config to the with stack."
    with /config/BQ/QRcode
    
...

The REPL is fun to use. It makes it super easy to interactively create/execute a process step by step. help at the REPL prompt.

On startup, there are only a dozen or so commands imported directly into the repl. The rest of the initialization is done by core.spr which imports the rest of the extensions into their namespaces.

Clone this wiki locally