# Expressions

## Lexical tokens

Premon ignores C-style comments, delimited by /*...*/ or line-delimited comments starting //.

The following are keywords:

> central fn let local proc rec return val

Premon identifiers are either alphanumerics (strings including a-z, A-Z, digits and underscore beginning with a letter) or symbolics (strings made up of the following characters):

> ! # $ & * + - . / : < = > ? @ [ \ ] ^ | ~

For example the phrase `f_1=++([[y]])' consists of tokens:

> f_1 = ++ ( [[ y ]] )

Premon literals are strings delimited by "..." or '...', integers or doubles.

## Simple expressions

Simple expressions are:

- Identifiers, such as name or ^.

- Literals, such as 'Hello, '.

- Prefix function application M(M1,...,Mn), for example ^('Hello, ', name).

- Infix function application M x M' for example 'Hello, ' ^ name.

- Tuples (M1,...,Mn), for example the pair ('Hello, ', name).

- Sequential composition M; M' for example println ('Hello'); println ('World').

All identifiers used in a simple expression must be typed, either in the context or the constructors. For example the graph:
is given by the expression:

> print ('What is your name?');
> print ('Hello, ' ^ read () ^ '.')

with the constructors:

> proc print (string);
> proc read() : string;
> val ^ (string,string) : string;

## Declarations

As well as simple expressions, we can bind variables. The simplest form of declaration binds a variable, for example we can change the above graph slightly:

by declaraing a variable for the user's name:

> print ('What is your name?');
> let name:string = read();
> print ('Hello, ' ^ name ^ '.')

Variables can be used more than once in an expression, introducing forks into the resulting flow graph, for example four ways to write the same expression are:

(1 + 1) * (1 + 1) | let x:int = (1 + 1); x*x | let y:int = 1; (y+y)*(y+y) | let y:int = 1; let x:int = (y + y); x*x

Variables can also be declared but never used. This can result in disconnected subgraphs, for example:

let y:int = 1; let x:int = (y + y); 4

Premon functions can return more than one result, so let-expressions can bind more than one variable. For example the function coords takes a point and returns its coordinates as two floating point numbers:

val coords (point) : (double,double);

We can find the distance between two points as:

let (x1:double,y1:double) = coords (p1); let (x2:double,y2:double) = coords(p2); ( let x:double = x1-x2; let y:double = y1-y2; sqrt ((x*x) + (y*y)) )

Previous | Next