| Documentation |
| Download |
| FAQ |
| Feedback |
| Installation |
| Licensing |
| System requirements |
Pint is a π-calculus language platform which provides a translator written in SML/NJ and a hardware emulator written in Erlang. The platform is intended for investigation at the microprogramming level rather than for use as yet another high level language.
The language is similar to, but simpler than, Vasconcelos' TyCO, or Wojciechowski's Nomadic Pict which is based on Turner and Pierce's Pict; it is automatically typed, asynchronous, higher-order, concurrent and distributed. It is not deterministic or sequenced. It is non-linear and has no polymorphism except for a few list operations. The semantics are taken from Pict.
The Pint language includes document type definition facilities for recursive element and attribute declarations but these are type based rather than syntax based as in SGML/XML. Pint supports the Oasis catalogue. The library provides a graphics system which offers functionality similar to Erlang's GS through an interface based on passing elements to six built-in paths. A demonstration microprogram simulates and displays an ant raiding party.
The emulated hardware offers up to 227 hardware channels on which the program's paths are to be placed. We show examples of programming for the small footprint imposed by this hardware. The emulator provides trace and debugging facilities and will operate at up to 10000 reductions per second on a 1GHz PC. The translator, emulator and documentation, a 260 page book, are GPLed.
Here is that favourite among favourites: Hello World.
<!DOCTYPE Pint PUBLIC "-//Pint//NOTATION Pint//EN" >
import "-//Pint//DTD Input output library//EN"
%%%%% hello.pint %%%%%
new c
offer
( io.file.uwrite!«Uwrite stdOut "Hello World\n" c c»
|| c?_ = ¶die
)
Let's look at this line by line.
"Why", you may ask, "do we need an SGML/XML declaration on top of something which is neither SGML nor XML?" Pint shares a lot of characteristics with SGML and XML: it allows the declaration of elements and their attributes in a structured way. It calls for conformance of the elements to a DTD, and may be used to markup structured documents. Yet it is does not conform to SGML/XML and is not designed to do so — on the contrary, it is intended as a vehicle to explore alternative markup techniques. The formal declaration at the top of every Pint program says that this is not SGML/XML and that it cannot be processed by an SGML/XML processor. It requires a Pint processor. This makes it clear to all markup specialists that Pint is not to be confused with SGML or XML.
The ">" terminates the document type declaration.
The library is identified by a formal public indentifier (FPI). What this FPI means is specified by a site specific OASIS catalogue which associates a local file name with the FPI. Pint includes a suggested OASIS catalogue which you can adapt to your needs.
Let's take a closer look at the value:
The U in Uwrite means "Unicode" since the characters are represented internally by their Unicode numbers.
When the "send" and "receive" successfully communicate on path c, we say that a π-calculus reduction occurs, and this is the basic action of the π-calculus machine. During the reduction, the process written after the "=" is offered in turn to the hardware. In this case it's the pre-defined process ¶die which means "stop the machine".
It should be clear by now that Pint is a lower level language than say C, Scheme, ML or TyCO. That's why it's better to think of working in Pint as microprogramming — low level coding very close to the hardware, providing the hardware with a personality which in turn may allow further higher-level "programming" or other human use.
Here is another old favourite: Factorial n. This is a naïve program which is very inefficient in its use of the "hardware". The book explains why, and gives the correct solution.
<!DOCTYPE Pint PUBLIC "-//Pint//NOTATION Pint//EN" >
import "-//Pint//NONSGML Formatted input output library//EN"
%%%%% fac.pint %%%%%
%% Template fac receives a pair containing the argument:
%% a positive integer n, and a path on which to send the result.
def fac {n r} =
let new neq0 new ngt0 % Paths for n=0, n>0
val nlt0 = neq0 % Path for n<0
out ( alu.int.comp!{n 0 nlt0 neq0 ngt0} % Choose n<0 n=0 n>0
|| neq0 ? {} = r!1 % If n=0 then send 1 on path r
|| ngt0 ? {} =
let new kn1 % Path for n-1
new kf1 % Path for fac(n-1)
out ( % Send n-1 on path kn1
alu.int.- ! {n 1 kn1}
% When n-1 is available, send fac(n-1) on kf1
|| kn1 ? n1 = fac ! {n1 kf1}
% When fac(n-1)is ready, send product on r
|| kf1 ? f1 = alu.int.× ! {n f1 r}
)
end
)
end
The Pint language and platform are documented in a 270 page book, available as a PDF download, 1.4 MBytes.
For the brave, there is an alternative version of the same book in PostScript, as a set of 4 sheet (16 page) signatures. The PostScript files for the language description, 3.6 MBytes and the library, 9.9 Mbyte, are to be printed recto-verso on ISO A4 paper. You then have to peel off the signatures, 4 sheets (16 pages) at a time, and fold the four sheets together with the consecutive page numbers on the inside of the fold. Finally you have to bind the signatures together to get an ISO A5 sized book. Hint: Practice on a few pages before sending the whole file to the printer; it will save you a lot of ink.
Although the book is intended for ISO A4 paper, it should still be readable when printed on US letter.
It's free, as in "freedom". The translator and the emulator are available under the terms of the GNU General Public License (GPL). The book is available under the terms of the GNU Free Documentation License (FDL).
The Pint translator and emulator have been developed and tested on SuSE Linux 8.1 and 9.1. The principal prerequisites are
The current version is 0.3.2 2009-10-26. No previous versions have been published.
Download the Pint translator, emulator and documentation from http://rogerprice.org/pint/pint-0.3.2.tar.gz. 2.8MByte.
The translator and emulator are currently installed in user space, but if one day Pint becomes more stable and (gasp!) more widely used, this may change.
Since the installation is into user space, no root privileges are needed to install and run Pint, but if several people on a system are using Pint, there are at least as many copies of Pint on the system.
The Pint system is built by attempting to run it. The shell detects that pieces are missing and builds them as required. Maybe, one day when the language becomes more stable, the translator and run-time emulator will be pre-built, but that hasn't happened yet.
wget -O pint-0.3.2.tar.gz http://rogerprice.org/pint/pint-0.3.2.tar.gz
Remember that if you have already downloaded pint-0.3.2.tar.gz, wget will create new files with suffixes .1, .2, etc. If you want to overwrite file pint-0.3.2.tar.gz use wget option -O pint-0.3.2.tar.gz. That's an upper case letter "O".
gunzip -cd pint-0.3.2.tar.gz | tar -xvf -
This will create a subdirectory "pint-0.3.2" which we call the Pint working directory, and place the source into that directory.
BASE /mnt/home/rprice/pint-0.3.2/examples
Change the address in each of the BASE specifications to suit your account. Change the entry
etc hosts 'joe.org' 'josephine.fr'
to point to the hosts you wish to use in distributed applications. If you do not intend to use distributed Pint, comment out this catalogue entry.
Start the Pint "hardware" using the command ./pint The "./" is needed only if you do not have "." in your PATH environment variable. The first time that the hardware is started, the shell will detect that the translator and the utility programs are missing, and build them. In the following output, we see that the translator has not yet been built. If it had been built, the output would be much less voluminous.
joe@olive:~> cd pint-0.3.2
joe@olive:~/pint-0.3.2> ./pint
Compiling pint.erl ...
Erlang (BEAM) emulator version 5.3.6.2 [source] [hipe]
Eshell V5.3.6.2 (abort with ^G)
(joe@olive.rogerprice.org)1>
joe 35:38 Compiling the Pint translator...
Standard ML of New Jersey v110.44 [FLINT v1.5]
...
joe 37:57 Compiling user_default.erl ...
joe 37:57 Compiling ./lib/utility.erl ...
joe 37:57 Compiling ./lib/avl.erl ...
joe 37:57 Compiling ./lib/avl_accel.erl ...
joe 37:57 Compiling ./lib/fifo.erl ...
joe 37:58 Translating OASIS catalogue ...
joe 37:58 Compiling build_catalogue.erl ...
joe 37:59 Compiling ./lib/alu.erl ...
joe 37:59 Compiling ./lib/io_for_Pint.erl ...
joe 38:00 Compiling ./lib/cat.erl ...
joe 38:00 Compiling ./lib/GS.erl ...
joe 38:03 Compiling ./lib/hash.erl ...
joe 38:03 Compiling ./lib/maths.erl ...
joe 38:04 Compiling ./lib/sysdata.erl ...
joe 38:04 Compiling ./lib/time.erl ...
joe 38:04 Compiling ./lib/tok.erl ...
joe 38:04 Compiling ./lib/rng.erl ...
Pint machine now available.` \\
Run program: pi(myprog). pi(myprog,N).
Quit: quit(). or Ctl-g q Don't forget the "."
Emergency: killall -i run.x86-linux
Since the translator had not been found, the Pint shell calls the SML/NJ compiler manager to build it. A complete build takes about 2 minutes 30 seconds on a 1GHz PC. Your mileage may vary.
Now press "enter" and you will see the Pint command line:
(joe@joe.org)3>
which reports your user name and host name in the Pint network.
(joe@joe.org)2> pi(hello) .
joe 45:06 Translating OASIS catalogue ...
joe 45:07 Compiling build_catalogue.erl ...
joe 45:07 Updating OASIS catalogue server ...
joe 45:08 Translating ~joe/pint-0.3.2/examples/hello.pint
val it = true : bool
- val it = () : unit
joe 45:08 Reading ~joe/pint-0.3.2/catalog ...
joe 45:08 Reading ~joe/pint-0.3.2/examples/ants.config ...
joe 45:08 Translating hello
from ~joe/pint-0.3.2/examples/hello.pint ...
joe 45:08 Translating -//Pint//DTD Input output library
from ~joe/pint-0.3.2/lib/io.dtd ...
val it = () : unit
-
joe 45:09 Compiling ~joe/pint-0.3.2/examples/hello.erl ...
joe 45:09 Module hello recompiled.
ok
Hello World
Load for: 'joe@joe.org'.
hello: 5 pi-reductions on 5 channels in 0.141 secs.
Hardware: 5 cycles at 35.5 Hz, avg concurrency 1.00.
(joe@joe.org)3>
You type "pi(hello) ." to translate program "hello". Note the period which terminates the command. Following a Prolog habit, I place a space before the terminating period.
You see which catalogue(s) are used to resolve the name of your program, and you see which file the catalogue has identified as "hello". You also see which file the catalogue has identified as the input/output library. If you get the reply:
09:34 Is the log file available? - no. I am unable to open log file '~joe/pint-0.3.2/examples/hello.log'. Reason: eacces You are now leaving Pint through door 55. Goodbye
then this is probably because you have not set up your OASIS catalogue correctly. See the previous steps in this installation procedure.
At the end of the session, you see the output from Pint program "hello".
It's intended to be a small, "pint sized" language.
Debugging concurrent microcode is difficult — you need all the help you can get.
Because of an ongoing contract, I needed a copyright assignment to publish this work. I received the copyright assignment for release 0.3.1.
My first implementation, version 0.1, was back in 1999. It was a denotational semantics based interpreter in SML/NJ at 30 reductions/sec on a 1GHz Intel PC. Version 0.2 was when I re-wrote the interpreter in John Reppy's Concurrent ML and achieved 300-500 reductions/sec. To be fair, Concurrent ML is a synchronous language and the additional engineering I added for asynchronous one-way communication really slowed things down.
For version 0.3, I again re-wrote the translator to issue Erlang source code and achieved 10000 reductions per second for simple programs such as factorial(n), n=1000. On a more ambitious program with heavy animated graphics such as ant raids, version 0.3 gets up to 3000 reductions per second.
I needed a very low level language platform, so low that all the language bigots out there could truly say "My language is better", and I could happily agree with them. I could then demonstrate a proposal avoiding all emotional reaction. We could all agree that the XYZ language would be even better — for the same idea.
Pint is an ISO Latin 9 language in that the source programs are encoded in the ISO Latin 9 character set. ISO Latin 9 is a slight modification of the familiar ISO Latin 1 with the currency symbol replaced by the Euro symbol and seven other changes.
If your printer or screen shows character U+00a4, "¤", as a Euro symbol, then you are using ISO Latin 9, no matter what that pull-down menu said when you selected your character set. It is common to find ISO Latin 1 announced when what is implemented is ISO Latin 9, since a lot of programmers seem to treat ISO Latin 9 as a "bug fix" release for ISO Latin 1. Maybe this is what the ISO should have done, but ISO politics are such that is is sometimes easier to produce a new standard that to fix an existing one,
ISO Latin 9 is intended for general purpose applications in typical office environments in at least the following languages of European origin: Albanian, Basque, Breton, Catalan, Danish, Dutch, English, Estonian, Faeroese, Finnish, French, Frisian, Galician, German, Greenlandic, Icelandic, Irish Gaelic (new orthography), Italian, Latin, Luxemburgish, Norwegian, Portuguese, Rhaeto-Romanic, Scottish Gaelic, Spanish, and Swedish. There are several official written languages outside Europe that are covered by Latin alphabet No. 9. Examples are Indonesian/Malay, Tagalog (Philippines), Swahili, Afrikaans.
The Emacs editor and others provide techniques for entering ISO Latin 9 characters which are not on your keyboard. The simplest way for Emacs users is to use Mule and toggle the input method to ISO Latin 9. However this does not cover all the possible ISO Latin 9 characters. The remaining characters such as ¶ may be entered by following the instructions given for "Inserting text" by the Emacs documentation:
If you need to insert a control character or a character whose code is above 200 octal, you must "quote" it by typing the character `Control-q' (`quoted-insert') first. (This character's name is normally written `C-q' for short.) There are two ways to use `C-q':
- `C-q' followed by any non-graphic character (even `C-g') inserts that character.
- `C-q' followed by a sequence of octal digits inserts the character with the specified octal character code. You can use any number of octal digits; any non-digit terminates the sequence. If the terminating character is RET, it serves only to terminate the sequence; any other non-digit is itself used as input after terminating the sequence.
When multibyte characters are enabled, the octal codes 0200 through 0377 are not valid as characters; if you specify a code in this range, `C-q' assumes that you intend to use some ISO Latin-N character set, and converts the specified code to the corresponding Emacs character code. You select which ISO Latin character set though your choice of language environment.
To use decimal or hexadecimal instead of octal, you should set the variable `read-quoted-char-radix' to 10 or 16. If the radix is greater than 10, some letters starting with `a' serve as part of a character code, just like digits.
A numeric argument to `C-q' specifies how many copies of the quoted character should be inserted.
If you are an Emacs user and you wish to enter ISO Latin 9 characters in hexadecimal rather than octal, add the following lines to your file .emacs.
;; Enter hexadecimal characters using C-q (setq read-quoted-char-radix 16)
For further details, see the documentation for Emacs.
I shall fix bugs in the current release, but further work depends on the level and direction of interest. Further work on the Pint language system might include
Please send comments, suggestions and bug reports to rprice at cs dot uml dot edu.
© Copyright 2005 Roger Price
In order to facilitate access from all browsers, now and in the future,
these pages conform to the International Standard ISO/IEC 15445 and the
corresponding W3C Recommendations. Last change:
lun. oct. 26 22:12:42 CET 2009

http://rogerprice.org/pint