Skip to content

Indentation based syntax

Alex Zimin edited this page Jul 11, 2011 · 3 revisions

This was one of the open projects.

Table of Contents

Enabling

There are two ways of enabling the indentation syntax. One is to use the -i compiler option. This enables it for all the files passed to the compiler.

The other is to use #pragma indent at the top of the file (comments and whitespace before are OK, anything else is NOT!).

The algorithm

We maintain a stack of indentation strings. Whenever a new, non-empty line is processed we check if:

  • its indentation is the same as the one on the top of the stack, in which case we add a semicolon to close the previous line
  • otherwise the indentation has the top-one as prefix, in which case we push it on the stack and add an open brace
  • otherwise, if the new indentation is somewhere on the stack, we pop elements looking for it and generate a close brace for each indentation popped
  • otherwise it is an error

Exceptions

When the line ends with backslash, in which case it is effectively merged with the next one.

When the line ends with ; or the next one begins with {, the ; is not added.

Inside [], () and {} the indentation processing is off.

Further reading

Most of the comments in Python: Myths about Indentation also applies to our indentation syntax.

Example

using System.Console [Qux] \ class FooBar publicstatic Main () : void WriteLine ("Hello") static Foo (x : int) : voidif (x == 3) def y = x *42 Foo (x) else [x].Map (fun (x) { x *2 }) static Bar () : intdef foo = 2 \ +7 \ *13 foo

is translated to:

using System.Console; [Qux] class FooBar { publicstatic Main () : void { WriteLine ("Hello") } static Foo (x : int) : void { if (x == 3) { def y = x *42; Foo (x) } else { [x].Map (fun (x) { x *2 }) } } static Bar () : int { def foo = 2+7*13; foo } }

Alternative clauses in a match

If you use alternative clauses in a match, to match multiple cases to one result,

match (s) { | "a" | "aa" => 1 | "b" | "bb" => 2 | _ => 0 }

in indententation based syntax :

match (s) | "a" | "aa" => 1 | "b" | "bb" => 2 | _ => 0

it won't compile, you need to use line continuation ('\')

match (s) | "a" \ | "aa" => 1 | "b" \ | "bb" => 2 | _ => 0

or just use standard syntax with { .. } for this specific match:

match (s) { | "a" | "aa" => 1 | "b" | "bb" => 2 | _ => 0 }
Clone this wiki locally
close