## MLton 20241230

# AST

AST is the IntermediateLanguage produced by the FrontEnd and translated by Elaborate to CoreML.

## Description

The abstract syntax tree produced by the FrontEnd.

## Implementation

- `ast-programs.sig`

- `ast-programs.fun`

- `ast-modules.sig`

- `ast-modules.fun`

- `ast-core.sig`

- `ast-core.fun`

- `ast`

## Type Checking

The AST IntermediateLanguage has no independent type checker. Type inference is performed on an AST program as part of Elaborate.

## Details and Notes

### Source locations

MLton makes use of a relatively clean method for annotating the abstract syntax tree with source location information. Every source program phrase is "wrapped" with the `WRAPPED` interface:

    signature WRAPPED =
       sig
          type node'
          type obj

          val dest: obj -> node' * Region.t
          val makeRegion': node' * SourcePos.t * SourcePos.t -> obj
          val makeRegion: node' * Region.t -> obj
          val node: obj -> node'
          val region: obj -> Region.t
       end

The key idea is that `node'` is the type of an unannotated syntax phrase and `obj` is the type of its annotated counterpart. In the implementation, every `node'` is annotated with a `Region.t` (`region.sig`, `region.sml`), which describes the syntax phrase’s left source position and right source position, where `SourcePos.t` (`source-pos.sig`, `source-pos.sml`) denotes a particular file, line, and column. A typical use of the `WRAPPED` interface is illustrated by the following code:

    datatype node =
       App of {con: Longcon.t, arg: t, wasInfix: bool}
     | Const of Const.t
     | Constraint of t * Type.t
     | FlatApp of t vector
     | Layered of {constraint: Type.t option,
                   fixop: Fixop.t,
                   pat: t,
                   var: Var.t}
     | List of t vector
     | Paren of t
     | Or of t vector
     | Record of {flexible: bool,
                  items: (Record.Field.t * Region.t * Item.t) vector}
     | Tuple of t vector
     | Var of {fixop: Fixop.t,
               name: Longvid.t}
     | Vector of t vector
     | Wild

    include WRAPPED sharing type node' = node
                    sharing type obj = t

Thus, AST nodes are cleanly separated from source locations. By way of contrast, consider the approach taken by SML/NJ (and also by the CKit Library). Each datatype denoting a syntax phrase dedicates a special constructor for annotating source locations:

    datatype pat = WildPat                             (* empty pattern *)
                 | AppPat of {constr:pat,argument:pat} (* application *)
                 | MarkPat of pat * region             (* mark a pattern *)

The main drawback of this approach is that static type checking is not sufficient to guarantee that the AST emitted from the front-end is properly annotated.