Skip to content

Latest commit

 

History

History
64 lines (41 loc) · 2 KB

File metadata and controls

64 lines (41 loc) · 2 KB

Glint’s Templated Expressions

In Glint, templates look a lot like functions, BUT THEY ARE NOT FUNCTIONS. If you only remember one thing from this file, let it be that warning. Please heed; so on–so forth.

Template Expressions

The simplest valid template is the identity template. It effectively just applies a type constraint at compile time to whatever argument you pass to it.

template(x : int) x;

;; ends up as
;; TemplateExpr
;; |-- Body: NameRefExpr
;; `-- Parameters...: VarDecl

Now, the above source code represents a Template Expression. It is an expression that may be invoked to generate an actual, “concrete” expression. That is, the above template does not end up in the final code of the program.

Named Template Expressions

You may also assign a template expression to a name.

my_template :: template(x : int) x;

my_template 69;

;; ends up as
;; IntegerLiteral

type Type

It should be known that, since template invocations are expanded at compile-time, the type of a template parameter may be a type itself. That is, a template argument may be a type expression.

foo :: template(x : type) x;

bar : foo int; ;; expands to 'bar : int'

This is useful for Glint module authors to export templates instead of concrete types.

export vector :: template(elem_t : type)
    struct { data:elem_t.ptr; size:uint; capacity:uint; };

foo : vector int;

Invoking a Template Expression

In order to actually use a template to “stamp out” code, we must invoke it (by calling it). The arguments we pass to it will be checked against the parameters declared within it.

(template(x : int) x) 69;

;; ends up as
;; IntegerLiteral

As you can see, invoking a template expression removes the template expression from the program, and leaves just the body of the template with template parameters replaced with their argument counterparts.