If a language can be implemented as a module (see module for details), then the simplest and best way to use the language is via the “Use the language declared the in source” checkbox in the Language dialog. In this case, DrRacket’s appearance can still be customized to the language; it uses read-language with these arguments as the key argument to the get-info function to do so:
When a language’s get-info procedure responds to 'color-lexer, it is expected to return a procedure suitable to pass as the get-token argument to start-colorer.
drscheme-language-modules: This must be bound to a list of collection path specifications or strings, one for each language in the collection. Each collection path specification is the quoted form of what might appear as an argument to require, using the lib argument (but without the lib). The strings represent relative paths starting at the directory containing the info.rkt file. They are interpreted like string arguments to require.
drscheme-language-positions: This must be bound to a list of language positions. Each language position corresponds to the position of the language in language dialog. Each language position is a list of strings whose length must be at least two.
If the first string is the same as (string-constant teaching-languages), then it is put into the “Teaching Languages” section of the dialog. Otherwise, it goes into the “Other Languages” section of the dialog.
get-drscheme-language-positions: This must be bound to a list that contains a module path followed by a symbol. The module path and symbol are combined with dynamic-require to obtain a list that is appended to the one from drscheme-language-positions, which allows access to string-constants to specify language positions.
drscheme-language-numbers: This is optional. If present, it must be a list of a list of numbers. Each list corresponds to a single language from this collection. Each number indicates a sorting order in the language dialog for the corresponding string in drscheme-language-positions. If absent, it defaults to a list of zeros that has the same length as drscheme-language-positions. This will rarely be correct.
drscheme-language-one-line-summaries: This is optional. If present, it must be a list of strings. Each string is displayed at the bottom of the language dialog when the corresponding language is selected.
drscheme-language-urls: This is optional. If present, it must be a list whose elements are either strings or #f. Clicking the corresponding language’s name in the interactions window opens a web browser to the url.
drscheme-language-readers: This is optional. If present, it must be bound to a quoted list of module specifications (that is, a quoted version of the argument to require). Each specification must be a module that exports a function named read-syntax. Each of these read-syntax functions must match Racket’s read-syntax primitive’s contract, but may read different concrete syntax.
If the module specification is a plain string, it represents a relative path starting at the directory containing the info.rkt file. It is interpreted like the string arguments to require.
'("My Text" "First Language")
'("My Text" "Second Language")
With some additional work, any language that can be compiled to Racket is supported by the tools interface, not just those that use standard configurations and module.
Each language is a class that implement the drracket:language:language<%> interface. DrRacket also provides two simpler interfaces: drracket:language:module-based-language<%> and drracket:language:simple-module-based-language<%>, and mixins drracket:language:simple-module-based-language->module-based-language-mixin and drracket:language:module-based-language->language-mixin that build implementations of drracket:language:language<%>s from these simpler interfaces.
Each language comes with its own type, called settings. This can be any type the language designer chooses, but to aid documentation, we call it settings here. The settings type is expected to contain parameters of the language, such as case sensitivity, etc. The implementor of the language provides a GUI so the user can configure the settings and all of the language’s operations accept a setting. DrRacket maintains the current settings for each language.
Some tools may require additional functionality from the drracket:language:language<%> interface. The drracket:language:extend-language-interface function and the drracket:language:get-default-mixin mixin make this possible.
For example, the MrFlow tool expands a program, analyzes it and then displays sets of values for each program point. These sets of values should be rendered in the syntax of the language that MrFlow analyzes. Since MrFlow doesn’t know which languages are available, it can call drracket:language:extend-language-interface to extend the drracket:language:language<%> interface with a method for rendering sets of values and provide a default implementation of that method. Tools that know about MrFlow can then override the value rendering method to provide a language-specific implementation of value rendering. Additionally, since the drracket:language:get-default-mixin adds the default implementation for the value-set rendering method, all languages at least have some form of value-set rendering.
In some cases, it is important for one tool to avoid depending on another in the manner above. For example, if a tool that provides a new language provides an implementation for the MrFlow-specific method, that tool may fail to load if MrFlow is not present (Indeed, with the tool manager, this can happen to any tool that depends on another in this manner.)
(define (my-language-mixin %) (if (implementation? % mrflow:render-value<%>) (class % (define/override ...) (super-new)) %))
To help test your tool, use the PLTONLYTOOL environment variable to load it in isolation.