Using Berp

bjpop edited this page Sep 14, 2010 · 40 revisions

Interactive interpreter

Berp provides an interactive command-line interpreter similar to CPython. On Unix you start the interpreter by running the berp command on its own:

$ berp
Berp version 0.0.1, type control-d to exit.
>>>

In the above example the $ indicates the Unix shell prompt, and >>> indicates the Berp interpreter prompt. You can type Python statements at the prompt and they will be executed by Berp:

>>> 6 * 7
42
>>>

Multi-line statements are handled just like CPython:

>>> def fac(n):
...    if n == 0: return 1
...    else:
...       return n * fac(n-1)
... 
>>>

When Berp expects more lines of input from the user it will print three dots ... at the start of a line. Multi-line statements can be terminated by entering a blank line.

Line continuations also work when there are unclosed parentheses in an expression, like so:

>>> (3 
...    +
...  4
... )
7
>>> 

Closing all parentheses (in the right order) terminates the input for an expression.

As in CPython, functions can be called from the command line like so:

>>> fac(6 * 7)
1405006117752879898543142606244511569936384000000000

and like so:

>>> for x in [1,2,3]:
...    print(fac(x))
... 
1
2
6
>>>

The command line supports GNU readline style editing with the arrow keys. The up and down arrow keys traverse backwards and forwards respectively through the command line history.

To exit the intepreter press the control key and the d key at the same time.

Compiler

Berp also provides a compiler which will generate machine code for a Python program. For example, suppose we have the following Python code in a file called Greetings.py:

# Print a simple greeting to the whole world
print("Hello World!")
The simplest way to use the compiler on Unix is to run the berp command with the name of a Python file as input.
$ berp Greetings.py 
Hello World!

As demonstrated above, by default Berp will compile the input program to machine code and then execute the resulting program immediately.

During compilation, Berp will produce an executable based on the name of the Python input file; in this case the executable is called Greetings. If you want to run the program again, and you haven’t made any changes to it, you can simply invoke the executable program. There is no need to re-run the compiler.

$ ./Greetings
Hello World!

In some cases it is useful to compile the program without running it immediately. This can be achieved by giving Berp the --compile flag:

$ berp --compile Greetings.py

Like before, this will generate an executable file called Greetings, however it will not be run immediately.

You can tell berp to use a particular version of ghc on your machine by specifying its path with the --with-ghc flag, like so:

$ berp --with-ghc /usr/local/bin/ghc-6.10.4 Greetings.py

During the compilation process Berp will generate a number of intermediate files in the current working directory. For our current example these files would be:

  • Greetings.hs – Haskell source code. The result of Berp’s translation of Python to Haskell.
  • Greetings – Machine code. The result of compiling Greetings.hs using a Haskell compiler.
  • Greetings.o – Object code. Generated by the Haskell compiler for Greetings.hs.
  • Greetings.hi – Haskell interface file. Generated by the Haskell compiler for Greetings.hs.

The intermediate files are generally of no interest to the user of Berp and they can be safely deleted. You can ask Berp to delete the intermediate files itself using the --clobber flag:

$ berp --clobber Greetings.py
Hello World!

This will cause Berp to clean up after it has run the program. Note that --clobber will remove all the intermediate files, including the executable. If you want to run the program again you will need to re-compile it. Berp also provides a --clean flag which causes it to delete all intermediate files except the generated executable.

If you are a developer, or just curious, you can ask Berp to print out the translated Haskell code to the standard output device:

$ berp --showhaskell Greetings.py 
module Main where
import Berp.Base
import qualified Prelude
main = runStmt init
init
  = do _t_0 <- read _s_print
       _t_0 @@ [string "Hello World!"]

In this case Berp will terminate immediately after printing the Haskell code; it will not generate an executable program.

As Unix convention dictates, Berp also provides a --help flag, which displays some information about correct usage:

$ berp --help
berp: usage: berp [options] [<input file>]
  [--with-ghc <filepath to ghc>]  Specify the filepath of ghc.
  [-h,--help]                     Display a help message.
  [--clobber]                     Remove all compiler generated files after the compiled program has run.
  [--clean]                       Remove all compiler generated files except the executable after the compiled program has run.
  [-t,--showhaskell]              Output translated Haskell code on standard output and exit.
  [-c,--compile]                  Compile the input program, but do not run it.
  [<input file>]                  Name of the input Python file.