Problem - Global Scope
A unit (a class or program) in Mynx is compiled, but the complexity is that an element in a unit--a method, attribute, or overload does not have to be declared before use. Effectively all elements in a unit are in a global scope with each other, so any attributes or methods are visible even if not declared before referenced.
Declaration before use would simplify type checking, the last stage of semantic analysis by avoiding the need to either store a unit element reference and verify the element exists, is unique, and is type compatible. In short, the problem is that global scope and visibility requires more than one pass. Looking at Pascal, the design of the programming language impacts the compiler, and Pascal was elegant for its one pass compilation.
But, the trade-off as Kernighan strongly points out in
"Why Pascal is not my Favorite Programming Language" is the declaration before use. It creates, to quote, "The result is that a typical Pascal program reads from the bottom up - all the procedures and functions are displayed before any of the code that calls them, at all levels."
An aside: I had a teacher in college who loved Pascal and detested C (it was funny to find for loops in C with an index starting at 1...and other statements Pascalized in a Unix software project) and pointed out "but you know where it [the declaration] is at..." (good for a learning language, and simplifies the compiler, but too rigid and sacrifices flexibility for software development; just for fun ((if you can call it that)) take a Java/C++/C# class and move all declarations to the beginning of a class or method, now you know where they are...). Kernighan makes the point of "This means that all declarations of one kind (types, for instance) must be grouped together for the convenience of the compiler, even when the programmer would like to keep together things that are logically related so as to understand the program better."
Convenience for the compiler writer, for the language designer impacts the software developer--but a programming language, once created is widely used, for better or worse.
MOXI
MOXI is an XML file that contains the semantic information of the Mynx class API--instead of a JVM .class file as Mynx is compiled to a .class or CLR assembly a platform neutral means is needed to store class API information.
Type checking utilizes a MOXI file, and a MOXI object; a MOXI file is read to create a MOXI object, which provides a searchable object to check for type, if a class contains an element, the mode and kind of the element, and operator overloads. Hence a MOXI file is the software object for external semantics of type checking.
Approach to Solution
There are two possible approaches to a solution:
- batch mode checking--store and check types.
- on-the-fly checking, with code synthesis.
Batch
The batch mode approach is problematic with memory usage and forward referencing. Every type that is deferred in checking but must be stored, and checked later. For a reference, if there is an error, the specific information of where at line and position must be tracked. Deferring type checks, and the external semantic checks while possible is unfeasible--complexity added for a single-pass compiler.
On the Fly
A workable solution is a two pass system. For each pass:
- 1st pass, create MOXI object, parse sentence, sentence semantic checks, buffer sentences.
- 2nd pass, unit type checks, code synthesis, store MOXI object for class.
After the first pass, any sentence semantic errors will terminate the second pass, if there are errors in the discrete sentences of the source code being compiled, no point to continue. In the first pass, a MOXI object is created. Another important step is to create a typeMap object, so that for a short, discrete name like Type, the overall complete namespace for the associated class such as com.williamgilreath.mynx.Type is available.
The second pass begins with the created MOXI object checked against the MOXI objects for any inherited classes with a class, if the classes are not mutually disjoint, compilation terminates. Compilation proceeds with no MOXI object errors, and using the own class's MOXI object for semantic checks. In tandem, code synthesis creates code for each sentence, appending it to the overall CodeStore object.
At the end of the second pass, type checking is complete, and code synthesis. The MOXI object is then exported to an external XML file. Compilation is not finished, the CodeStore object needs to be passed to the high-level language compiler, the underlying compiler that compiles the standard native code to the platform code.
If a compiler option to compile, analyze, synthesize, but not build (such as
-nobuild were passed at runtime, all the phases of the compiler, scanning, partitioning, parsing, analysis, synthesis would be complete, and a MOXI file and HLL source code would be the results from the compilation.
Labels: code synthesis, external semantics, moxi, mynx semantic, mynx semantic check