A bootstrap compiler for the Azoth language. That is, a compiler for a subset of the language that will be used to write the Azoth compiler in Azoth. The compiler currently compiles a small subset of the Azoth language to C.
The compiler is under active development. It is in a very early stage, and there are likely issues and limitations. APIs are subject to frequent breaking changes.
The current plan is to get a basic object-oriented subset of the language working. The inspiration for this is the feature set of Java 1.0. While Java 1.0 was very limiting, it demonstrates a viable language for general purpose development. This subset of the language should provide experience with the viability of developing with compile-time memory management. It will also provide a platform for experimenting with how to best support language features like asynchronous programming, class extension, closures, exceptions, and effect types.
The basic object-oriented subset is planned to include a minimal set of features to support programming. The list below should be taken as a general guideline. Some very basic language features have been omitted. For features that are listed, often only a very basic version of them will be supported. At the end of the list are some features that may be necessary to include, but will be omitted if possible.
The compiler will be simplified to include code only for these features. No attempt will be made to structure code for features that aren't currently present. For example, function types will not be used internally because function types aren't supported in this version of the language. Additionally, the compiler will be multi-phase with errors in any phase preventing subsequent phases from running. It is expected the phases will be lexing and parsing; name binding and type checking; and borrow checking.
- Stand-alone Functions - no generics
- Simple Types -
int
,uint
,size
,offset
- Simple Class Declarations - no base class, no generics (see below for supported members)
- Fields - no initializers
- Constructors
- Basic Methods - no generics
- Optional Types
- Basic Control Flow -
if
,while
,loop
break
,next
- [~] Conversions and Casts -
as
,as!
,as?
(not including unboxing) - Namespaces
- Strings
-
foreach n in 1..100
- basic loop iteration may need to be hard-coded because the final version will depend on features not yet available. - Basic
List[T]
- Basic Traits? - no generics, classes directly implement like interfaces
-
foreach
in Iterator? -
string
as primitive type - Use
get_
andset_
instead of properties. (Avoids conflict with field names and allows for the exploration of the proper types for getters and setters.)
These features should allow a number of basic programs and katas to be implemented. Note that the lack of generics will mean that future versions won't be backwards compatible with the standard library of this version.
As this subset is developed, the plan will be to:
- Make the Azoth source code as correct as possible given all current ideas on the design of the language with the exception of what isn't possible due to missing features (for example, generics).
- Ensure any language features used are in the language reference.
- If needed, parts of what will be the standard library can be created as compiler intrinsics at first, but they should be replaced with correct standard library code when possible.
The following features will not be implemented by this compiler even though they are described in the language reference.
- Loop Labels
- Document Comment Validation
- Full Type Inference: Variable types can be inferred from the type of their initializer only.
A number of language features are planned for the future but not yet included in the language. For quick reference, SOME of those features are:
- Global and Package Qualifiers
- Additional Types
- Aliases
- Additional Expressions
- Operator Features
- Compile-time Function Execution
- Language-Oriented Programming
The full list can be found in the language reference planned features section.
None Currently
- Unit tests are in projects named
Tests.Unit.*
. This way, it is not inconsistent when further namespaces are nested inside them. IfTests
were at the end of the name, then many namespaces would have it at the end, while nested ones would have it in the middle. This also allows conformance and integration tests to be grouped with them by placing them all under theTests
namespace. - Namespace hierarchies are kept fairly flat. This is to avoid issues of needing too many
using
statements and moving types between them. A namespace should contain all classes that represent the same "kind" of entity without much regard to sub-kinds. Originally, this was not the case. Types were separated into many sub-namespaces, but this ended up being more trouble than it was worth. In practice, one still just used the go to type functionality to find types. - For many classes, there isn't a single string representation that makes the most sense. For these,
a
ToILString()
andToSourceCodeString()
method have been added. Originally, theToString()
would throwNotSupportedException
. However, there are cases with the .NET framework callsToString()
in order to create some exception message. As a result, throwingNotSupportedException
causes problems. So instead, it should forward toToILString()
since that is the developer relevant string. Likewise,ToILString()
is used as the debug representation.
A line count can be obtained from Visual Studio 2019 using the "Code Metrics" feature. An alternate
approximation can be found in other versions of Visual Studio by running "Find All" with regular
expressions across all *.cs
files using the regex ^.*[^\s{}].*.$
. This matches all lines that
aren't blank or only curly braces. Note that this does match lines that are only comments and
includes a few generated code files.