- Notifications
You must be signed in to change notification settings - Fork 90
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 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 } }
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 }