Previous Up Next

6  Abstract syntax

The structure Absynt contains the abstract syntax of the language. As the type pervades the whole front-end of the compiler, the structure of the type is visible. As usual, the abstract syntax is given by a large, mutually recursive type declaration.

To facilitate debugging and spotting parse errors, most of the syntactical constructs are sprinkled with annotations concerning the position in the source program (type lexposition).

The abstract syntax already works with symbols and not with strings. But an identifier as coming from the lexer (together with a position) in the constructor IDENT is a string. The transformation form strings to symbols is done in the parser.

[Differences [App98b]] The differences of our module to the one presented at page 98 of [App98b] are the following:

  1. I use a more elaborate form of determining the lexical position. Also the order of constructors is different here. Additionally, I use the type ident which is a symbol augmented with position information, where Appel directly uses Symbol.symbol. All of these are not real changes.
  2. I don’t use records (probably standard ML is more flexible here) but unlabled tuples.
  3. I introduced the type prelim_ty as abbreviation.
  4. The lexical positions for the SeqExpr case are handled here differently: only one position for the whole list is kept, not one for each substatement. Perhaps that’s ok considering that we keep more information that Appel does.
  5. ForExpr, ArrayExpr, and RecordExpr are different.

The case for function declaration is different: the clause singlefunctiondec has a result type not something from the Types module but

!?
To do:
Rename singlefunctiondec to fundec for compliance.
!?
To do:
Check the position stuff, expecially for the SeqExp case?

[Records] The syntax for record expressions is as follows. Declaring a record type and then using it is done as follows

   /* a record type and a record variable */
let
        type  rectype = {name:string, age:int}
        var rec1:rectype := rectype {name="Nobody", age=1000}
in
        rec1.name := "Somebody";
        rec1
end

The expression (i.e. Absynt.expr) left of the assignment is a record-expression which creates a record.

[For-loop] For loops are of the form.4

        for i:=0 to 100 do (a:=a+1;()) od

The second argument on the abstract syntax of type bool ref is used for escapes.

[Array expressions] Arrays are created and used as follows:

    var N := 8
    type intArray = array of int
    var row := intArray [ N ] of 0

[Type declarations] Type declarations are also a bit complex (cf. page 513 of [App98b]). The reason why a type declaration contains a list is to cater for recursive declarations. Allowed is

  type intlist = {hd: int, tl: intlist}

and also

 type tree = {key: int, children: treelist}
 type treelist = {hd: tree, tl: treelist}

One of these last lines is parsed into5

  TypeDec([
           ("tree",     RecordTy([("key",_,"int",_); ("children",_,"treelist",_)],_),_);
           ("treelist", RecordTy([("hd",_,"tree",_); ("tl",_,"treelist",_)],_),_)
          ])

In the abstract syntax, the type ty in one element of the list can itself be a symbol, i.e., a NameTy. But that’s not allowed, it must be a record type.

[Escapes] Why are the escape-field (for instance in the for-loop) references to booleans and not simply boolean values?

!?
To do:
I don’t like that the language doesn’t have booleans. Especially this makes the hack for & and | ugly. Well, in the meantime (or again) I do have booleans, so is the translation of it ok, anyway?
!?
To do:
What are the arguments of the for-loop

[Booleans] When introducing boolean as keywords, we are forced to add also a claues for true and false into the abstract syntax. In principle, they are translated into the integer constant 1 and 0, but cannot do this already by parsing, since otherwise the type-checker, working on the abstract syntax can no longer distinguish between the integers 0 and 1 and the boolean values. In a previous scheme, I used true and false as predefined “variables” from the prelude. This had the disadvantage that the translation to intermediate trees cannot elegantly react on the boolean constants. In [App98b], there are is no boolean type from the beginning.

 ,
Previous Up Next