1. riffraff
  2. shakespeare-parrot


shakespeare-parrot /

Filename Size Date modified Message
81 B
513 B
3.6 KB
5.2 KB
303 B
2.3 KB
1.6 KB
The Shakespeare Programming Language, on Parrot


SPL is a language designed to allow usage of the beatiful shakespear wording 
while writing executable code. 

The reference implementation is at [1] and you can see some more info in the 
archive.org page for the shakespeare frontend for GCC [2]

Quoting from the original project:

    The design goal was to make a language with beautiful source code that 
    resembled Shakespeare plays. There are no fancy data or control structures, 
    just basic arithmetic and gotos. You could say we have combined the ex- 
    pressiveness of BASIC with the user-friendliness of assembly language. 

How Reductive! SPL is a great achievement in unifying art and code, a noble
goal which must not be underestimated.

So, to try to learn a bit about Parrot[3], I did this. 

If you are reading this you must have obtained the shakespeare-parrot 
distribution, and I congratulate you. 
Put the files in a languages/shakespeare/ directory in a parrot source tree
and run make. 
make test will execute the test suite, to run your own file use
    ../../parrot shakespeare.pir filename.spl
since we used the standard parrot's HLLCompiler you can use the usual flags 
such as --target=(parse|pir) to see the parse three and the PIR output.

The original SPL project generates C code that con be compiled and linked with
libspl to generate executables, through SPLC.
The parser is built with yacc/bison and the lexer is flex. The Perl port[4] uses
the same parser and lexer.

This parrot version uses PGE to parse the grammar and generate an AST, 
The parrot toolchain allows automatic transformation of the PAST (Parrot AST) into
POST and then PIR (parrot's high level assembly).

When executed this intermediate code is translated into bytecode and it uses 
the functions defined in src/builtins/base.pir to operate. 

The runtime uses some global variables:
* the_cast contains a list of characters, each one a tuple 
  (value, stack, name, onstage flag)
* the_speaker refers the current speaker, so that the references "thou" and "me"
  are meaningful. Using objects was another option.
* the_condition is a boolean value that gets set from a 'question' statement 
  ("is foo better than bar?") and is refrenced later. Inlining of the 
  value would require a lot of work when building the AST, while the bytecode 
  compiler should have no problems doing it. 

Although I did not initially look at the original source code while writing 
the interpreter it seems that the behaviour of SPLC is the same.

The list of valid words was originally generated from a list of wordlist files 
with an AWK script I have lost track of. It's in the TODO list to fix it.

Notice that since PGE doesn't do (yet) longest token matching, a token like this
    token article  {
        | 'a'
        | 'an'
        | 'the'
would cause a failure to parse "an empty bottle" because the token 'a'
is matched and the token does not backtracks. The grammar goes on trying to 
match 'n' and thus fails. 
The cases words where I had test failures were hand fixed, some may still 
cause failures. 


Shakespeare did not originally support testing explicitly, but in the modern
world of software engineering this would have prohibited building large scale
dramatic-software projects. 

Thus, I've added two new instructions to the language to minimally support the
Test Anything Protocol (TAP)[5]
 * plan an evil thing!
   will print "1..2". Every valid value can be used after the word 'plan'.
   Suggestions for improving are welcome, I'm thinking of using 
   [othello plans an evil thing]
 * proove yourself!
   will print "ok x" where x is the value of the spoken character. 
   Every valid value can be used after the word 'proove'

Test failure is reached through out-of order printing, so for example

   Scene I: a test.
   juliet: art thou better than me?
   romeo: if so, let us proceed to scene ii.
   juliet: proove nothing.
   Scene II: the right branch.
   juliet: proove the joy!

Will print "ok 1" if juliet is better than romeo, which is fine.
If Romeo has an higher value than Juliet "ok 0" will be printed, and considered 
as a test failure from the test harness.

The grammar also ignores she-bang lines #!.


I wrote the parser trying not to look at the original grammar, using only the 
examples. This means that in some ways the parser is more restrictive and in 
some ways it is more loose. Until we have an ISO specification for SPL it is
assumed that this is ok. 

The files in example are the original files used in both Lingua::Shakespeare and
SPLC, and their operation is checked through the script t/test.rb.
To verify that everything works you can run "make fulltest" which will execute
both the standard test suite and the examples' test suite. 

[1] http://shakespearelang.sourceforge.net/ 
[2] http://web.archive.org/web/20080121104440/http://people.csa.iisc.ernet.in/sreejith/frontends/spl/spl.htm
[3] http://www.parrotcodr.org
[4] http://search.cpan.org/~gbarr/Lingua-Shakespeare-1.00/
[5] http://testanything.org/wiki/index.php/Main_Page