In an effort to showcase my MSc work, I have developed an applet that contains the π-calculus compiler along with the MIL interpreter. You can try out either MIL our the simply-typed π-calculus and run it online. Our article about compiling the π-calculus into a multithreaded typed assembly language is an useful reference.
The π-calculus consists of processes that run concurrently—you may read processes as tasks or threads, although they sit at a much higher level. The simplest process is the inactive one that finishes, we represent it by a zero 0. The basis of the π-calculus is communication; it is so important that the fundamental step of computation is the communication of sequences of values (integers, strings, and channels). Processes synchronize (and communicate) by message-passing, using channels. To send a message 10 through a channel x we write the output process x<10>. To receive a message through a channel x and store it in a name y that is visible in process P we write the input process x(y).P, notice that process P is not a variable, it must be replaced with an actual process, like the inactive process 0. If we want to receive a message repeatedly, like a server does, we just write a bang (!) in front of an input process, for example !x(y).P. To execute process P in parallel with process Q we write the parallel process P | Q, or to remove ambiguity we may use parenthesis (P | Q). To use a channel x in a process P, we must first declare it along with its type T by writing new x:T P. A type T is not a variable, it can be either an integer type int, a string type str, or a channel ^[T1,...,Tn] (the parameters ranging from T1,...,Tn are a possibly empty sequence of types, like the empty channel type ^[] or the channel that communicate two integers ^[int,int]. Channels may themselves send channels, for example channel type ^[int,^[int]] types channels that communicates two values, one of the integer type, another a channel that communicates integers.
A quick example of an echo server:
new echo:^[int,^[int]] (
!echo(x,y).y<x>
|
new print:^[int] (
!print(m).printInt<m>
|
echo<10,print>
)
)
