Skip to content

Syntactical Reference

xs-admin edited this page Feb 13, 2015 · 1 revision

Syntactical Reference

In the syntactical pass the compiler will create a syntax tree and iterate through it trying to find a match as injected. Once a match is found, the corresponding transformation is invoked and its results will replace the original nodes. Once this initial pass is performed all scheduled syntactical changes will be applied in a similar manner until no such changes remain.

By convention, the syntactical pass is accessed via the "syntax" variable. On the website this variable is automatically created and assigned. Outside of it, the lexical pass can be accessed through the compiler as in: compiler.Syntax()

Matching

The syntactical pass injects changes into the compilation process by either creating matches or scheduling changes for particular nodes. A match is created by calling the syntax.match() method, an extension can create as many matches as it deems necessary. Note that the scheduling changes can happen in prior passes.

At this point, the source code is quite more organized, and as such the matching is quite easier. We offer a couple of matching methods: one based on type and conditions and a free matching function. With the first option being by far the most common:

syntax
    .match<MethodDeclarationSyntax>(
        method => method.ReturnType.IsMissing 
               && method.Identifier.ToString() == "constructor")
    .then(ProcessConstructor);

This will match methods declaration without a return type and named "constructor". Once matched, ProcessConstructor will be called to transform the method node into a constructor node.

Transforming

Syntactical transformation consists in replacing a node in the tree by another, the engine does not provide any particular way of doing this and instead relies on the underlying implementation (Roslyn in this case). Alternatively, the then method accepts a semantical transform function, which schedules the transformation for a time where semantic information is available.

Extensions

The point made before about the source being more orderly at this point does not apply to extensions. Since extensions are not part of the underlying language, extension tend to introduce errors, sometimes difficult to detect. Therefore, the engine processes syntactical extensions before anything in order to offer the cleanest possible syntax tree. The API for extensions is:

syntax
    .extension("ext_name", kind, transform);

Where transform is a free function with signature Node function(Node input, Scope scope, SyntacticalExtension extension) Where SyntacticalExtension is an object containing the extension items (name, parameters, body).

Clone this wiki locally