Saturday, October 21, 2006

Boo Compilation Steps

This post contains notes about how booc compiles boo programs. The boo compilation process is not complicated, but it is mostly undocumented and therefore can only be understood by inspecting the source code. Also, boo's developer (Rodrigo B. de Oliveira) is, sadly, allergic to comments. Here are my detailed observations - more to come later. See also the boo build process. A useful thing to know about the boo codebase is that (so far as I've seen) it follows the java conventions of "one public class per file", "name the file after the class", and "the namespace name corresponds to the actual path in the directory tree". For example, src\Boo.Lang.Compiler\Resources\EmbeddedFileResource.cs contains a class called EmbeddedFileResource in the namespace Boo.Lang.Compiler.Resources. A source file may contain other classes, structs and enums, but they are either internal to the file where they are declared (not used elsewhere), or they have a minor role. BTW: this convention holds for the C# part of the compiler, but I don't yet know about the boo part.

App.Run():- I don't know what this is for: AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(AssemblyResolve);- CheckBooCompiler(): Emits warning if nonlocal Boo.Lang.Compiler.dll is being used- _options = new CompilerParameters(false)- ParseOptions(): - Builds "response file list" (App._responseFileList). It is empty when cmdline args is just a src file name - _responseFileList is related to args that start with '@'. The default response list is automatically loaded from booc.rsp by AddDefaultResponseFile(), unless -noconfig is specified. - Processes command-line arguments. Most cmdline args alter the configuration of _options; some alter flags/variables in App itself. - The list of input files is added (one at a time) with _options.Input.Add() - Assigns the _options.Pipeline (-p option), or makes default pipeline, CompileToFile(). In WSA mode, _options.Pipeline[0] = new Boo.Lang.Parser.WSABooParsingStep(); - debug-steps adds App.StepDebugger as AfterStep event handler. - prints header ("Boo Compiler version 0.7.6.2237 (CLR v2.0.50727.42)")- fragility: assumes there are two standard library paths (which are moved to the bottom of the lib path list)- creates a Boo.Lang.Compiler.BooCompiler (.cs), "The compiler: a facade to the CompilerParameters/CompilerContext/Pipeline subsystem."- Unless -nostdlib specified, calls _options.LoadDefaultReferences() to add default references. The default references are mscorlib, System, the currently loaded Boo.Lang, and the currently loaded Boo.Lang.Compiler.- LoadReferences(): loads assemblies previously requested with -r on cmd line; calls _options.References.Add() to add each assembly- CompilerContext context = compiler.Run(); This one line compiles the code and (I think) generates the output assembly, although Warnings/errors are not printed yet. Run() with no args creates a new CompileUnit (the top-level AST class) and passes it to public CompilerContext Run(CompileUnit compileUnit)- Prints warnings from context.Warnings (a Boo.Lang.Compiler.CompilerWarningCollection) and errors from context.Errors (a Boo.Lang.Compiler.CompilerErrorCollection)

-------------------------------------------------------------------------------ASTs:- Automatically generated classes are named Boo.Lang.Compiler.Ast.Impl.*Impl- Each has a derived class named Boo.Lang.Compiler.Ast.*- Boo.Lang.Compiler.Ast.Node is the base class for every node in the AST. Its data content is protected LexicalInfo _lexicalInfo = LexicalInfo.Empty; protected SourceLocation _endSourceLocation = LexicalInfo.Empty; protected Node _parent; protected string _documentation; protected System.Collections.Hashtable _annotations = new System.Collections.Hashtable(); protected bool _isSynthetic;- Top-level AST element is called CompileUnit. At this point I am assuming, since only one CompileUnit is created by Boo.Lang.Compiler.BooCompiler.Run(), that all boo source files given to booc are merged into the same CompileUnit object. Data: protected ModuleCollection _modules;

-------------------------------------------------------------------------------The standard set of compiler steps follows directly from the implementation ofCompileToFile and its base classes.

The job of NewParserStep() is to dynamically load Boo.Lang.Parser.dll (usingSystem.Reflection.Assembly.Load()/LoadFrom()) and to create an instance of Boo.Lang.Parser.BooParsingStep (using System.Activator). Fragility: the code relies on the fact that the current assembly is named Boo.Lang.Compiler.dll.

All of the above classes are compiler pipelines, defined in src\Boo.Lang.Compiler\Pipelines.

inherited from: CompilerPipeline, which serves as a collection of steps and includes functions to run the steps (Run(), RunStep())