Modules & Files#

File name extensions and Markdown embedding#

Temper source files are identified by their file name extension. For now, these are:

In the former case, that's a plain Temper source file. In the latter case, it's Temper embedded in a Markdown document, enabling (semi-)literate programming. We might add other official file name extensions or document languages to embed Temper within in the future.

In Temper Markdown, the file starts out in comment mode. That is, the text of the document is a comment to the Temper compiler. Temper code goes inside code blocks:

# My Temper Markdown source file

This is text. You can treat it as a document.

```temper
// This is active Temper code.
let greet(name: String): Void {
  console.log("Hello, ${name}!");
}
```

Within `.temper.md` files, the default code block type is `temper`,
so you can leave off the label:

```
// Still Temper.
greet("world");
```

Or even use indented blocks:

    // And still Temper.
    greet("everyone");

If you want a block of Temper for documentation purposes but which you
don't want to be active, you can call it `inert`:

```temper inert
console.log("Inert code doesn't run.");
```

All Temper code blocks start and end on new lines. We might also require blocks to begin and end at statement boundaries.

Also, we plan to specify how specific class and function documentation can be extracted from Temper Markdown in the future.

Parts of a Temper source file#

In Temper, import, works on modules, not files or directories. Normally, there is a 1:1 relationship. Each directory (or folder) specifies one module, but that is not always the case. All Temper source files in a module directory are merged into a single module, irrespective of file names, except for library configuration files named "config.temper.md". Each such config file specifies the root of a library.

Further, a module preface allows you to specify definitions shared by all instances of the module's body. All preface content from all Temper source files in a module are merged together.

If a preface specifies no module parameters then there will be exactly one module instance, corresponding to the empty parameter set.

If it specifies parameters, then there may be zero or more instances.

Modules// preface;;;// body// bodyTemper File// preface;;;// body
Modules// preface;;;// body// bodyTemper File// preface;;;// body
Diagram source
flowchart LR
  subgraph File [Temper File]
  X[["// preface\n;;;\n// body"]]
  end
  subgraph Modules
  Preface[["// preface\n;;;"]]
  ModuleA[["// body"]]
  ModuleB[["// body"]]
  Preface --> ModuleA
  Preface --> ModuleB
  end
  File ---> Modules

The instances of a module are determined by the parameters passed when importing that module. There will be one instance for each distinct parameterization so if multiple modules import with the same parameters, they will share an instance.

Note: neither compiler implements module prefaces or module parameters today: both read one ;;; as separating code from JSON metadata after it, as the third row of the table below would have it without a preface (inconsistencies).

The parts of a Temper source file are separated by triple-semicolon ;;; tokens. Since this is token-based, ;;; character sequences inside a comment or string literal do not affect the structure of the file.

Body
Preface ;;; Body
Preface ;;; Body ;;; Metadata
Invalid ;;; Invalid ;;; Invalid ;;; Invalid