Koog
1 Concept
2 Terminology
3 Features
4 API
4.1 Code Generator
koog-expand
4.2 Code-Generation Context Information
4.3 Command-Line Program Module
5 CLI
6 Examples
7 Installation
7.1 Editor Integration
8 Source Code
9 Hardly Ever Asked Questions (HEAQ)
10 License
6.10.1

Koog

Tero Hasu

1 Concept

Mixed-code generation is a form of template-based code generation where the template file is overwritten with the generated file, with the code generation directives intact. The term was (as far as we know) introduced by Jack Herrington in his book Code Generation in Action (Manning, 2003).

Koog can function as a traditional mixed-code generator for a host language that uses one of the supported code styles (currently C and Racket block comments, or Lisp, Ruby, or TeX line comments). Koog also supports a restricted form of mixed-code generation where only specific regions of the source file are actually regenerated.

2 Terminology

Definition. A mixed-code generator is a compiler that modifies its input based on instructions found in the input itself, and produces output which can be (repeatedly) re-fed to the compiler as valid input.

Definition. The instructions, which are given in a (generator-dictated) generator language, are retained in the output.

Definition. The input may also include some (potentially foreign) host language text, and the goal typically is for the entire generator output to be a valid host language document.

Definition. Specially formatted host language comments in the input function both as: directives specifying what text to generate; and as markers identifying the regions of host language text that are allowed to be replaced.

Definition. A region and its enclosing markers together constitute a section.

3 Features

4 API

The provided APIs are fairly self-explanatory, so look at the source code for the details of the provided functionality.

4.1 Code Generator

 (require koog/koog) package: koog

The primary module of Koog is koog/koog, which exports the koog-expand function (for expanding file regions with generated code), and some parameters affecting its behavior.

procedure

(koog-expand input output filename)  boolean?

  input : (or/c input-port? #f)
  output : (or/c output-port #f)
  filename : path-string?
Expands input regions as specified by directives, and produces resulting output. Non-regions are generally copied as is, but the exact behavior of the expansion process may be modified through the relevant koog/koog parameters (e.g., only-on-line and remove-markers?). The input port may be #f, in which case input is read from the file named by filename. The output port may likewise be #f, in which case the output is written to the file filename. If both input and output ports are given, filename is only used for informational purposes. The function returns #f if the generated output differs from the read input, and #t otherwise.

4.2 Code-Generation Context Information

 (require koog/runtime) package: koog

The koog/runtime module exports parameters that make context information available to code generation directives. It is not necessary to explicitly require this module, as its variables get set and bound for directives automatically by Koog.

4.3 Command-Line Program Module

 (require koog/cli) package: koog

The koog/cli module has no exports. It just contains code for parsing command-line options and accordingly setting parameters for koog-expand prior to invoking it.

5 CLI

The command-line interface is provided by the koog program, and it has various options whose combinations can cater for a number of use cases.

For example, to modify the file "cli.rkt" in place, expanding its regions, we can
  koog -c racket cli.rkt

To merely check what would be done, we can simulate the expansion with
  koog -c racket -s cli.rkt
which shows any changes that would be made, or any error in the input.

To only expand within markers enclosing line 42:
  koog -c racket -l 42 cli.rkt

To pipe input through the program to get it expanded, we can
  cat cli.rkt | koog -c racket -io -f cli.rkt
where the -f cli.rkt option is only present for possible informational use.

To see how "cli.rkt" would look with any markers at line 42 removed, we can issue
  koog -c racket -l 42 -ro cli.rkt | less

6 Examples

Here are some real-world Koog-based code generation examples from the ContextLogger2 codebase:

We can also find a Koog use example from within Koog itself. A help-spec for the command-line macro must be a literal string (or a list thereof), but in Koog’s "cli.rkt" we wanted to use a contant expression to build that string. One way to do that is with Koog:

#|***koog

(require racket/list koog/koog)

(write (format "~a (default: ~a)"

               (apply string-append

                      (add-between

                       (map symbol->string (comment-style-names))

                       ", "))

               (default-comment-style-name)))

***|# "c, lisp, racket, sh, tex (default: c)" #|***end***|

This solution in effect creates yet another phase of code expansion, happening already before macroexpansion, but only when we choose to trigger it. (An example of a macro-based solution would be to macro-generate our command-line use, inserting the computed help-spec string within it).

7 Installation

The pre-requisites for installing the software are:
  • Racket. Version 6.0 (or higher) of Racket is required; a known-compatible version is 6.10.1.

The software and the documentation can be built from source, or installed directly using the Racket package manager. With Racket and its tools available, Koog can be installed with the raco command:
  raco pkg install git://github.com/hasu/koog

The above commands should install the library, the koog command-line program, and a HTML version of the manual.

To check that the library has been installed, you can use the command
  racket --eval '(require koog/koog)'

To check that the command-line program has been installed and is on your executable search PATH, you might query for program usage information with
  koog --help

To check that the Koog manual has been incorporated into your local copy of the Racket documentation, try searching for “koog” with
  raco docs koog

7.1 Editor Integration

For information about configuring Emacs and Vim to use Koog, see the readme files in the "emacs" and "vim" directories of the source distribution.

8 Source Code

The Koog source code Git repository is hosted at:

9 Hardly Ever Asked Questions (HEAQ)

Q: Where does the name "Koog" come from?
A: It is short for the Finnish word "koodigeneraattori" (code generator).

10 License

Except where otherwise noted, the following license applies:

Copyright 2008 Helsinki Institute for Information Technology HIIT and the authors. All rights reserved.

Authors: Tero Hasu

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.