Freon Documentation (version 0.5.0)

Generic Types: an Example Typer Definition

This example shows how generic types and unit of measurements can be defined.

The Example Language

The language is very simple, its units consists of lists of expression - declared type pairs. Ultimately, we want to compare the declared type with the type of the expression. Below is an example of a model unit of this language.

UnitA correctExps

12 : NUMBER;
"string" : STRING;
2345: NUMBER;
"this is a large string": STRING;
true : BOOLEAN;
false: BOOLEAN;

Set{ true, true, false } : Set<BOOLEAN>;
Bag { Set { 12, 13, 14 }, Set { 12, 13, 14, 15, 16 } } : Bag<Set<NUMBER>>;

124 Meters : Meters<NUMBER>;
45 kWh : kWh<NUMBER>;

The Structure Definition of the Example Language

To explain the type definition, we first need a structure definition of the example language. Below is the complete .ast file. But first, let’s explain some highlights.

Every type in the list of expression - declared type pairs is an instance of the AST concept TypeUsage, which comes in two flavours: a type declaration, and a type reference, that holds a reference to another AST node.

// typer-example/defs/projectY.ast#L18-L26

abstract concept TypeUsage { // to be used wherever a type can be used, either a referred type of or declared type is correct
}

concept TypeRef base TypeUsage  {
    reference type: NamedType;
}

abstract concept TypeDecl base TypeUsage {
}

There are also two options for a type declaration, a generic type, and a unit of measurement. For this example, we have used the names of the generic types from the Object Constraint Language: Set, Bag, Sequence, and Collection. Note that these declarations are part of the AST. They are not type concepts themselves.

// typer-example/defs/projectY.ast#L37-L47

concept GenericType base TypeDecl {
    baseType: TypeUsage;
    kind: GenericKind; // is it a set, sequence, bag, or anything else
}
limited GenericKind { Set; Sequence; Bag; Collection; }

concept UnitOfMeasurement base TypeDecl {
    reference baseType: PredefinedType; // is always NUMBER!!
    unit: UnitKind; // is it measured in km, kWh, grams, or anything else
}
limited UnitKind { Meters; Grams; kWh; Hours; }

The definitions of the expressions in the example language are straightforward. There are literal expressions for strings, booleans, and number, as well as generic literals and unit literals.

// typer-example/defs/projectY.ast#L61-L75

expression BooleanLiteral base Exp {
    xx: boolean;
}

expression UnitLiteral base Exp {
    // 62 kilogram, or 112 miles
    inner: NumberLiteral;
    unit: UnitKind;
}

expression GenericLiteral base Exp {
    // Set{ 12, 14, 16, 18 }
    content: Exp[];
    kind: GenericKind;
}

The complete Structure Definition

// typer-example/defs/projectY.ast

language projectY

model XX {
    units: XXunit[];
}

modelunit XXunit {
    lines: ExpWithType[];
    file-extension = "expr";
}

concept ExpWithType {
    expr: Exp;
    type: TypeUsage;
}

// definitions of types
abstract concept TypeUsage { // to be used wherever a type can be used, either a referred type of or declared type is correct
}

concept TypeRef base TypeUsage  {
    reference type: NamedType;
}

abstract concept TypeDecl base TypeUsage {
}

interface TopType {
}

concept NamedType implements TopType {
    name: identifier;
}

limited PredefinedType base NamedType { NUMBER; BOOLEAN; STRING; ANY; NULL; }

concept GenericType base TypeDecl {
    baseType: TypeUsage;
    kind: GenericKind; // is it a set, sequence, bag, or anything else
}
limited GenericKind { Set; Sequence; Bag; Collection; }

concept UnitOfMeasurement base TypeDecl {
    reference baseType: PredefinedType; // is always NUMBER!!
    unit: UnitKind; // is it measured in km, kWh, grams, or anything else
}
limited UnitKind { Meters; Grams; kWh; Hours; }

// definitions of expressions
abstract expression Exp {
}

expression NumberLiteral base Exp {
    xx: number;
}

expression StringLiteral base Exp {
    xx: string;
}

expression BooleanLiteral base Exp {
    xx: boolean;
}

expression UnitLiteral base Exp {
    // 62 kilogram, or 112 miles
    inner: NumberLiteral;
    unit: UnitKind;
}

expression GenericLiteral base Exp {
    // Set{ 12, 14, 16, 18 }
    content: Exp[];
    kind: GenericKind;
}


expression NamedExp base Exp {
    inner: Exp;
    myType: NamedType;
}

expression PlusExp base Exp {
    left: Exp;
    right: Exp;
}