The Compiler-Convert library

The Compiler-Convert library acts as an adaptor between the Compiler-Parser library and the Compiler-Front library.

As a rule of thumb, the Compiler-Convert library implements those parts of the front end which know about the output of the parser.

The LexEnv Module

This module implements lexical environments (a formal term for "local namespaces"). This is the code that associates variable names with the correct bindings.

The Compile-Time-Eval Module

This module performs compile-time evaluation of constant expressions. It operates on the parsed representation of a Dylan program, not the front-end representation.

The Expanders Module

This module contains procedural macro expanders for basic, built-in macros such as make-if.

The FER-Convert Module

This module processes chunks of the parse tree and uses the <fer-builder> to produce the front-end representation.

Processing of Top-Level Definitions

The code to process top-level definitions is spread across several libraries. Most of the machinery actually lives here in the Compiler-Convert library.

Each top-level form must define methods on three generic functions:

process-top-level-form

When the parser finishes with a top-level form, it passes the form to this function, which produces the final parse tree and creates an object representing the top-level form. (See the Section called The Parser Module.)

finalize-top-level-form

This function is called by the compilation driver when all the top-level forms have been parsed. It's used to implement various kinds of foward references within a module. (See the Section called The Top-Level-Forms Module.)

convert-top-level-form

Once a top-level form has been processed and finalized, it can be converted to the appropriate front-end representation. Methods on this function use the <fer-builder> interface. (See the Section called The Top-Level-Forms Module and the Section called The Builder-Interface Module.)

Generally speaking, the parsed representation of a built-in define foo form would be named <define-foo-parse>. The object representing the top-level form itself would be named <define-foo-tlf>. There's also a <foo-definition> floating around in most cases. The relationships between these three representations need to be documented.

The Define-Macros Module

This module handles define macro forms and macro calls which appear at the top level.

The Define-Libraries-and-Modules Module

This module handles define library and define module forms.

The Define-Functions Module

This module handles define generic and define method forms. (define function forms are expanded by a macro defined in the runtime library.) Most of the logic for implicit generic functions lives here.

The Define-Constants-and-Variables Module

This module handles define generic and define method forms. It also includes code for constant methods, which may get used in a few strange places. More research is needed here.

This module contains an alarming number of "shouldn't happen" errors. Is this left-over code, safety checks for a fragile area of the compiler, or evidence of some fundamental confusion about what's going on?

The Define-Classes Module

This library handles define class forms. There's a lot in here, including ctype calculation for classes and creation of getter and setter methods. It's not immediately clear how this relates to the code in the module Classes.

The Top-Level-Expressions Module

This module handles actual code appearing at the top level. There's also something going on with <magic-interal-primitives-placeholder>, which is (of course) excessively magic. If you're the sort of person who likes to figure out how magicians do their tricks, feel free to figure this out for the rest of us.