-
Notifications
You must be signed in to change notification settings - Fork 89
Indentation based syntax
This was one of the open projects.
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!).
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
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.
Most of the comments in Python: Myths about Indentation also applies to our indentation syntax.
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
}
}
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
}