Indentation-based syntax

From Nemerle Homepage

(Redirected from Indentation syntax)

This was one of the open projects.

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
  public static 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

is translated to:

using System.Console;
 
[Qux]
class FooBar {
  public static 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
}
remember
You are very welcome to contribute to the documentation here!