shakespeare-parrot / README

The Shakespeare Programming Language, on Parrot

INTRO
-----

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.

BUILD
-----

    $ parrot setup.pir
    $ parrot setup.pir test
    $ parrot setup.pir spectest
    $ sudo parrot setup.pir install

USING
-----
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.

INTERACTIVE PROMPT
------------------
You can also access the interpreter interactively.
Since setting up a whole play would be useless, you can input single sentences
and see how they will be parsed:
$ parrot shakespeare.pir
Thou hast entered the interactive sentence verifier
Enter a Sentence to see How It Parses
>lol
no match
>king
: <king @ 0> 0
<value>: <king @ 0> 0
<value><immediate>: <king @ 0> 0
<value><immediate><noun>: <king @ 0> 0
<value><immediate><noun><positive_noun>: <king @ 0> 0

>twice a pretty king
: <twice a pretty king @ 0> 0
<value>: <twice a pretty king @ 0> 0
<value><computation>: <twice a pretty king @ 0> 0
<value><computation><unary>: <twice a pretty king @ 0> 0
<value><computation><unary><value>: <a pretty king @ 6> 0
<value><computation><unary><value><immediate>: <a pretty king @ 6> 0
<value><computation><unary><value><immediate><article>[0]: <a @ 6> 0
<value><computation><unary><value><immediate><adjective>[0]: <pretty @ 8> 0
<value><computation><unary><value><immediate><adjective>[0]<positive_adjective>: <pretty @ 8> 0
<value><computation><unary><value><immediate><noun>: <king @ 15> 0
<value><computation><unary><value><immediate><noun><positive_noun>: <king @ 15> 0

>let us proceed to scene III
: <let us proceed to scene iii @ 0> 0
<branch>: <let us proceed to scene iii @ 0> 0
<branch><roman>: <iii @ 24> 0




IMPLEMENTATION
--------------
The original SPL project generates C code through spl2c that con
be compiled and linked and linked with libspl to generate executables.
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 referenced 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 spl2c+libspl 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 words where I had test failures were hand fixed, some may still
cause failurese the interactive loop to check.


LANGUAGE EXTENSIONS
-------------------

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 #!.

DIFFERENCES FROM OTHER IMPLEMENTATIONS
--------------------------------------

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.


EXAMPLES
--------
The files in example are the original files used in both Lingua::Shakespeare and
spl2c, 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.parrotcode.org
[4] http://search.cpan.org/~gbarr/Lingua-Shakespeare-1.00/
[5] http://testanything.org/wiki/index.php/Main_Page
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.