Building Blocks

Building Software Better

Scratch Textual Language

Posted by Mark on September 17, 2008

Scratch is a visual programming language, but it might usefully have a textual version as well. Scratch in it’s graphical form can verify syntax intuitively & automatically, and the resulting graphics are definitely beautiful, but it took quite some effort to produce these diagrams when trying to document a program, and it is even harder to reference sections of the diagram.

This activity came out of producing a Scratch Player in Flash, and I wanted to see whether the parse of the file produced the correct program. A textual dump of the parse was an obvious solution, but then this ‘dump’ might as well be the same as a complete program declaration so it was clearly ‘complete’ and I wasn’t missing anything.

Scratch Textual

The core concepts in this proposed textual language for Scratch are:

  • It should match Scratch as closely as possible
  • It should be a readable and easily writeable textual language (vs. XML as an interchange format)
  • It should be translatable to other human languages for the blocks (as Scratch is)
  • It should be really simple to produce and parse
  • Given Scratch is graphical, visual indentation is reasonable
  • It is not a complete ‘dump’ of the Scratch project — no media resources are included.

The above concepts produced the following initial choices:

  • Different sections start with simple keywords: “stage:” and “sprite:” for the main objects, “vars:” and ‘listVars:” for declaring variables, “comment:” for a comment section, and “script:” for declaring a sequence of blocks.
  • Variables simply define their name and an initial value (if desired… otherwise it would be ‘0’)
  • Each block is written out textually with its ‘spec’ — a human readable description of the block and its parameters
  • The parameters to a block (if any) come immediately after, and are preferably indented [say 4 spaces] from the block they are parameters too. Note that the indentation is not necessary because you can tell the number of parameters from the block ‘spec’, but indenting makes it more readable.
  • If a block can contain other blocks, contained blocks _must be_ indented [say 4 spaces] so you can tell they are inside the block vs. after the block. This is in a fashion similar to Python.
  • There should be no blank line within a ‘script:’ section. The end of a script: section is the first blank (non-comment) line.
  • Comments within the textual blocks use ‘#’ to match with Python. Multi-line comments do not exist. Note that Textual Comments are not parsed at all (and do not round-trip), so they should be minimal and merely augment parsing the textual source — use ‘comment:’ for real documentation.
  • ‘script:’ and ‘comment:’ could have position information after them using the ‘loc’ property (e.g. “loc = 500@250”) but this is not likely to be useful since any edits would cause positions to be wrong

An Example

The following is a complete “normal expanded format” version. See further below for a possible optimization to make things more vertically compressed.


#===========================
#=== Morph: Stage 
#===========================
stage: Stage

#============
#=== Vars 
#============

vars:
talest-pole-height = 6
previous-moved-disk = 0
potential-disk = 1
num-disks = 5
next-disk = 0
base-disk = 0

listVars:
pole-1 = undefined
pole-2 = undefined
moveable-disks = undefined
pole-3 = undefined

#============
#=== Script 
#============
script:

when 'find-next-disk'
set next-disk to %n
    0
broadcast %e and wait
    propose-next-disk
repeat until %b  
    %n > %n
        next-disk  
        0
    set potential-disk to %n
    if %b  
        not %b
            %n = %n
                potential-disk  
                previous-moved-disk  
        set next-disk to %n
            potential-disk  
broadcast %e and wait
    move-next-disk

#============
#=== Script 
#============
script:

when 'Scratch-StartClicked'
set num-disks to %n
    5
set base-disk to %n
    %n + %n
        num-disks  
        1
set next-disk to %n
    num-disks  
repeat until %b  
    %n < %n
        next-disk  
        1
    set next-disk to %n
        %n - %n
            next-disk  
            1
broadcast %e and wait
    initialize
set previous-moved-disk to %n
    0
set talest-pole-height to %n
    0
repeat until %b  
    %n > %n
        talest-pole-height  
        num-disks  
    broadcast %e and wait
        find-next-disk
    set talest-pole-height to %n
    if %b  
        %n > %n
            talest-pole-height  
        set talest-pole-height to %n


#===========================
#=== Morph: Sprite1 
#===========================
sprite: Sprite1

#============
#=== Vars 
#============

vars:
can-move = 3
am-on-top = 1
disk-id = 1
pole = 3
height = 6
previous-pole = 1
pole-at-start = 1

#============
#=== Script 
#============
script:

when 'move-next-disk'
if %b  
    %n = %n
        disk-id  
        next-disk  
    set previous-moved-disk to %n
        disk-id  
    set pole-at-start to %n
        pole  
    if %b  
        %b and %b
            not %b
                %b or %b
                    %n = %n
                        previous-pole  
                        1
                    %n = %n
                        pole  
                        1
            %n < %n
                disk-id  
        set pole to %n
            1
    if %b  
        %b and %b
            not %b
                %b or %b
                    %n = %n
                        previous-pole  
                        2
                    %n = %n
                        pole  
                        2
            %n < %n
                disk-id  
        set pole to %n
            2
    if %b  
        %b and %b
            not %b
                %b or %b
                    %n = %n
                        previous-pole  
                        3
                    %n = %n
                        pole  
                        3
            %n < %n
                disk-id  
        set pole to %n
            3
    set previous-pole to %n
        pole-at-start  
    if %b  
        %n = %n
            previous-pole  
            1
    if %b  
        %n = %n
            previous-pole  
            2
    if %b  
        %n = %n
            previous-pole  
            3
    if %b  
        %n = %n
            pole  
            1
        set height to %n
    if %b  
        %n = %n
            pole  
            2
        set height to %n
    if %b  
        %n = %n
            pole  
            3
        set height to %n

#============
#=== Script 
#============
script:

when 'propose-next-disk'
set am-on-top to %n
    0
set can-move to %n
    0
if %b  
    %b and %b
        %n = %n
            pole  
            1
        %n = %n
            disk-id  
    set am-on-top to %n
        1
if %b  
    %b and %b
        %n = %n
            pole  
            2
        %n = %n
            disk-id  
    set am-on-top to %n
        1
if %b  
    %b and %b
        %n = %n
            pole  
            3
        %n = %n
            disk-id  
    set am-on-top to %n
        1
if %b  
    %n > %n
        am-on-top  
        0
    if %b  
        %b and %b
            not %b
                %b or %b
                    %n = %n
                        previous-pole  
                        1
                    %n = %n
                        pole  
                        1
            %n < %n
                disk-id  
        set can-move to %n
            1
    if %b  
        %b and %b
            not %b
                %b or %b
                    %n = %n
                        previous-pole  
                        2
                    %n = %n
                        pole  
                        2
            %n < %n
                disk-id  
        set can-move to %n
            2
    if %b  
        %b and %b
            not %b
                %b or %b
                    %n = %n
                        previous-pole  
                        3
                    %n = %n
                        pole  
                        3
            %n < %n
                disk-id  
        set can-move to %n
            3
    if %b  
        %n > %n
            can-move  
            0

#============
#=== Script 
#============
script:

when 'initialize'
set disk-id to %n
    1
set pole to %n
    1
set previous-pole to %n
    0
set can-move to %n
    0
set am-on-top to %n
    0
set height to %n
    %n + %n
        %n - %n
            base-disk  
            disk-id  
        1

Vertical Compression

The format above has every block on its own line. This is readable and informative (you can see the argument types) but is vertically expansive. Assuming parentheses or some other paired delimiter are not used for anything else in names, we could replace the argument placeholders with parentheses like below. This gives a more lisp-like feel, at least for the inner evaluations. If you leave one or more placeholders off, they would come from the next lines in ‘missing’ order, kind of like a macro.

script:

when 'find-next-disk'
set next-disk to (0)
broadcast (propose-next-disk) and wait
repeat until ((next-disk) > (0))
    set potential-disk to (0)
    if (not ( (potential-disk) = (previous-moved-disk)) )
        set next-disk to (potential-disk)
broadcast (move-next-disk) and wait

One Response to “Scratch Textual Language”

  1. redware said

    One of the great things about Scratch is the visual programming so that young programmers can avoid having to deal with syntax errors. I know that modern compilers will catch these as you go – but they were a real pain in the old days and I would not want to go back to that with a scratch textual language.

    I think the representation of scratch as a language might be a good idea so that it might escape it’s environment a little like java bytecode or microsoft clr. I am not sure of the format of the scratch sb files – maybe they could be usefully represented as a textual language as you describe or at least something more open that could be parsed by, for example, a flash program as you describe.

    So I would love to see the sratch textual language (or other representation) that could be parsed by other applications but would not like young programmers to be exposed to it. Once they are ready to write code I would move them on to JavaScript or Java/C#.

Leave a comment