Skip to content

Commit c1914e0

Browse files
authored
Editorial clean up of docs (#171)
1 parent 4581af6 commit c1914e0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+1091
-983
lines changed

Packages.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<PackageReference Update="System.Memory" Version="4.5.4" />
1616
<PackageReference Update="CppSharp" Version="0.10.1" />
1717
<PackageReference Update="Antlr4" Version="4.6.6"/>
18-
<PackageReference Update="OpenSoftware.DgmlBuilder" Version="1.13.0" Condition="'$(TargetFramework)'=='net47'" />
18+
<PackageReference Update="OpenSoftware.DgmlBuilder" Version="1.14.0" />
1919
<PackageReference Update="System.Collections.Immutable" Version="1.7.0" />
2020
<!-- See: https://github.com/dotnet/docfx/issues/5536 before updating...-->
2121
<PackageReference Update="docfx.console" Version="2.48.1" />

Samples/CodeGenWithDebugInfo/CortexM3Details.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,18 @@
88
using System.Collections.Generic;
99

1010
using Ubiquity.NET.Llvm;
11+
using Ubiquity.NET.Llvm.Interop;
1112
using Ubiquity.NET.Llvm.Types;
1213
using Ubiquity.NET.Llvm.Values;
1314

14-
using static Ubiquity.NET.Llvm.Interop.Library;
15-
1615
namespace TestDebugInfo
1716
{
1817
internal class CortexM3Details
1918
: ITargetDependentDetails
2019
{
21-
public CortexM3Details( )
20+
public CortexM3Details( ILibLlvm libLLVM )
2221
{
23-
RegisterARM( );
22+
libLLVM.RegisterTarget( CodeGenTarget.ARM );
2423
}
2524

2625
public string ShortName => "M3";

Samples/CodeGenWithDebugInfo/Program.cs

Lines changed: 131 additions & 132 deletions
Large diffs are not rendered by default.

Samples/CodeGenWithDebugInfo/X64Details.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,18 @@
88
using System.Collections.Generic;
99

1010
using Ubiquity.NET.Llvm;
11+
using Ubiquity.NET.Llvm.Interop;
1112
using Ubiquity.NET.Llvm.Types;
1213
using Ubiquity.NET.Llvm.Values;
1314

14-
using static Ubiquity.NET.Llvm.Interop.Library;
15-
1615
namespace TestDebugInfo
1716
{
1817
internal class X64Details
1918
: ITargetDependentDetails
2019
{
21-
public X64Details( )
20+
public X64Details( ILibLlvm libLLVM )
2221
{
23-
RegisterX86( );
22+
libLLVM.RegisterTarget( CodeGenTarget.X86 );
2423
}
2524

2625
public string ShortName => "x86";

docfx/articles/Samples/codegeneration.md renamed to Samples/CodeGenWithDebugInfo/codegeneration.md

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
---
2+
uid: code-generation-with-debug-info
3+
---
4+
15
# CodeGenWithDebugInfo
26
Sample application to generate target machine code. The sample is
37
provided in the [source tree](https://github.com/UbiquityDotNET/Llvm.NET/tree/master/Samples/CodeGenWithDebugInfo).
@@ -15,7 +19,7 @@ The CodeGenWithDebugInfo sample will generate LLVM IR and machine code for the f
1519
>are expected to be minor. Updating the sample to replicate the latest Clang version is left as an exercise for
1620
>the reader :grin:
1721
18-
[!code-c[Main](../../../Samples/CodeGenWithDebugInfo/Support Files/test.c)]
22+
[!code-c[Main](Support Files/test.c)]
1923

2024
This sample supports targeting two different processor types x64 and ARM Cortex-M3
2125

@@ -46,14 +50,14 @@ In this sample that is handled in the constructor of the target dependent detail
4650
would allow command line options for the CPU target variants and feature sets. For this sample those are just
4751
hard coded into the target details class to keep things simple and focused on the rest of the code generation.
4852

49-
[!code-csharp[Main](../../../Samples/CodeGenWithDebugInfo/ITargetDependentDetails.cs#ITargetDependentDetails)]
53+
[!code-csharp[Main](ITargetDependentDetails.cs#ITargetDependentDetails)]
5054

5155
This interface isolates the rest of the code from knowing which architecture is used, and theoretically
5256
could include support for additional targets beyond the two in the sample source.
5357

5458
The sample determines which target to use based on the second command line argument to the application
5559

56-
[!code-csharp[Main](../../../Samples/CodeGenWithDebugInfo/Program.cs#TargetDetailsSelection)]
60+
[!code-csharp[Main](Program.cs#TargetDetailsSelection)]
5761

5862
## Creating the BitcodeModule
5963
To generate code in Ubiquity.NET.Llvm a [BitcodeModule](xref:Ubiquity.NET.Llvm.BitcodeModule) is required as
@@ -80,7 +84,7 @@ the target and a target specific [DataLayout](xref:Ubiquity.NET.Llvm.DataLayout)
8084
extracts these from the [TargetMachine](xref:Ubiquity.NET.Llvm.TargetMachine) provided by the target
8185
details interface for the selected target.
8286

83-
[!code-csharp[Main](../../../Samples/CodeGenWithDebugInfo/Program.cs#CreatingModule)]
87+
[!code-csharp[Main](Program.cs#CreatingModule)]
8488

8589
## Creating the DICompileUnit
8690
LLVM Debug information is all scoped to a top level [DICompileUnit](xref:Ubiquity.NET.Llvm.DebugInfo.DICompileUnit).
@@ -104,7 +108,7 @@ to expose types in a consistent fashion. Ubiquity.NET.Llvm provides a set of cla
104108
This sample uses the [DebugBasicType](xref:Ubiquity.NET.Llvm.DebugInfo.DebugBasicType). To define the basic types
105109
used in the generated code with appropriate debug information.
106110

107-
[!code-csharp[Main](../../../Samples/CodeGenWithDebugInfo/Program.cs#CreatingBasicTypesWithDebugInfo)]
111+
[!code-csharp[Main](Program.cs#CreatingBasicTypesWithDebugInfo)]
108112

109113
This constructs several basic types and assigns them to variables:
110114

@@ -120,7 +124,7 @@ Creating qualified (const, volatile, etc...) and pointers is just as easy as cre
120124
The sample needs a pointer to a const instance of the struct foo. A qualified type for constant foo is
121125
created first, then a pointer type is created for the const type.
122126

123-
[!code-csharp[Main](../../../Samples/CodeGenWithDebugInfo/Program.cs#CreatingQualifiedTypes)]
127+
[!code-csharp[Main](Program.cs#CreatingQualifiedTypes)]
124128

125129
## Creating structure types
126130
As previously mentioned, the LLVM types only contain basic layout information and not full source
@@ -133,7 +137,7 @@ metadata. A collection of these is then used to create the final composite type
133137
data in a simple single call. The sample only needs to create one such type for the `struct foo`
134138
in the example source code.
135139

136-
[!code-csharp[Main](../../../Samples/CodeGenWithDebugInfo/Program.cs#CreatingStructureTypes)]
140+
[!code-csharp[Main](Program.cs#CreatingStructureTypes)]
137141

138142
## Creating module metadata and global variables
139143
The sample code contains two global instances of `struct foo` `bar` and `baz`. Furthermore, bar
@@ -142,9 +146,9 @@ forms the initialized value of `bar.c`, the source only provides const values fo
142146
entries of a 32 element array. The const data is created via [ConstArray](xref:Ubiquity.NET.Llvm.Values.ConstantArray).
143147
The full initialized const data for bar is the created from [Context.CreateNamedConstantStruct](xref:Ubiquity.NET.Llvm.Context.CreateNamedConstantStruct*)
144148

145-
[!code-csharp[Main](../../../Samples/CodeGenWithDebugInfo/Program.cs#CreatingGlobalsAndMetadata)]
149+
[!code-csharp[Main](Program.cs#CreatingGlobalsAndMetadata)]
146150

147-
[!code-csharp[Main](../../../Samples/CodeGenWithDebugInfo/Program.cs#AddModuleFlags)]
151+
[!code-csharp[Main](Program.cs#AddModuleFlags)]
148152

149153
Once the constant data is available an LLVM global is created for it with a name that matches the source name
150154
via [AddGlobal](xref:Ubiquity.NET.Llvm.BitcodeModule.AddGlobal*). To ensure the linker lays out the structure
@@ -158,15 +162,15 @@ For the `baz` instance the process is almost identical. The major difference is
158162
structure is initialized to all zeros. That is the initialized data for the structure is created with
159163
[NullValueFor](xref:Ubiquity.NET.Llvm.Values.Constant.NullValueFor*), which creates an all zero value of a type.
160164

161-
[!code-csharp[Main](../../../Samples/CodeGenWithDebugInfo/Program.cs#CreatingGlobalsAndMetadata)]
165+
[!code-csharp[Main](Program.cs#CreatingGlobalsAndMetadata)]
162166

163167
LLVM modules may contain additional module flags as metadata that describe how the module is generated
164168
or how the code generation/linker should treat the code. In this sample the dwarf version and debug metadata
165169
versions are set along with a VersionIdentString that identifies the application that generated the module.
166170
Additionally, any target specific metadata is added to the module. The ordering of these is generally not
167171
relevant, however it is very specific in the sample to help ensure the generated IR is as close to the
168172
Clang version as possible making it possible to run llvm-dis to generate the textual IR files and compare them.
169-
[!code-csharp[Main](../../../Samples/CodeGenWithDebugInfo/Program.cs#AddModuleFlags)]
173+
[!code-csharp[Main](Program.cs#AddModuleFlags)]
170174

171175
## Declaring the functions
172176
The function declarations for both of the two function's is mostly the same, following a common pattern:
@@ -189,7 +193,7 @@ registers). For the two processors this sample supports Clang only uses this for
189193
calls the TargetDetails.AddABIAttributesForByValueStructure) to add the appropriate attributes for the target
190194
as needed.
191195

192-
[!code-csharp[Main](../../../Samples/CodeGenWithDebugInfo/Program.cs#FunctionDeclarations)]
196+
[!code-csharp[Main](Program.cs#FunctionDeclarations)]
193197

194198
## Generating function bodies
195199
This is where things really get interesting as this is where the actual code is generated for the functions. Up
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// -----------------------------------------------------------------------
2+
// <copyright file="CodeGenerator.cs" company="Ubiquity.NET Contributors">
3+
// Copyright (c) Ubiquity.NET Contributors. All rights reserved.
4+
// </copyright>
5+
// -----------------------------------------------------------------------
6+
7+
using Kaleidoscope.Grammar.AST;
8+
using Kaleidoscope.Runtime;
9+
10+
namespace Kaleidoscope.Chapter2
11+
{
12+
internal sealed class CodeGenerator
13+
: IKaleidoscopeCodeGenerator<IAstNode>
14+
{
15+
public void Dispose( )
16+
{
17+
}
18+
19+
public OptionalValue<IAstNode> Generate( IAstNode ast )
20+
{
21+
return OptionalValue.Create( ast );
22+
}
23+
}
24+
}

docfx/articles/Samples/Kaleidoscope-ch2.md renamed to Samples/Kaleidoscope/Chapter2/Kaleidoscope-ch2.md

Lines changed: 44 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1+
---
2+
uid: Kaleidoscope-ch2
3+
---
4+
15
# 2. Kaleidoscope: Implementing the parser
26
The chapter 2 sample doesn't actually generate any code. Instead it focuses on the general
37
structure of the samples and parsing of the language. The sample for this chapter enables all
48
language features to allow exploring the language and how it is parsed to help better understand
59
the rest of the chapters better. It is hoped that users of this library find this helpful.
610

7-
The LUbiquity.NET.Llvm version of Kaleidoscope leverages ANTLR4 to parse the language into a parse tree.
11+
The Ubiquity.NET.Llvm version of Kaleidoscope leverages ANTLR4 to parse the language into a parse tree.
812
This has several advantages including logical isolation of the parsing and code generation.
913
Additionally, it provides a single formal definition of the grammar for the language. Understanding
1014
the language grammar from reading the LVM tutorials and source was a difficult task since it isn't
@@ -262,7 +266,7 @@ This is a simple rule for sub-expressions within parenthesis for example: `(1+2)
262266
the addition so that it occurs before the division since, normally the precedence of division is higher.
263267
The parse tree for that expression looks like this:
264268

265-
![Parse Tree](parsetree-paren-expr.svg)
269+
![Parse Tree](./parsetree-paren-expr.svg)
266270

267271
### FunctionCallExpression
268272
```antlr
@@ -271,7 +275,7 @@ Identifier LPAREN (expression[0] (COMMA expression[0])*)? RPAREN
271275
This rule covers a function call which can have 0 or more comma delimited arguments. The parse tree
272276
for the call `foo(1, 2, 3);` is:
273277

274-
![Parse Tree](parsetree-func-call.svg)
278+
![Parse Tree](./parsetree-func-call.svg)
275279

276280
### VarInExpression
277281
```antlr
@@ -366,20 +370,21 @@ classes so they are extensible from the parser assembly without needing to deriv
366370
methods etc. Thus, the Kaleidoscope.Grammar assembly contains partial class extensions that provide simpler
367371
property accessors and support methods to aid is generating the AST.
368372

369-
See [Kaleidoscope Parse Tree Examples](Kaleidoscope-Parsetree-examples.md) for more information and example
373+
See [Kaleidoscope Parse Tree Examples](xref:Kaleidoscope-Parsetree-examples) for more information and example
370374
diagrams of the parse tree for various language constructs.
371375

372376
## Abstract Syntax Tree (AST)
373377
To further simplify code generators the Kaleidoscope.Runtime library contains the AstBuilder type that is
374-
an ANTLR parse tree visitor. AstBuilder will convert a raw ANTLR IParseTree into an `IEnumerable<IFunctionNode>`.
375-
That is, it visits the declarations and definitions in the parse tree to produce an ordered sequence of declarations
376-
and definitions as they appeared in the source. For interactive modes - the sequence will have only a single element.
377-
However, when parsing a whole source file, the parse tree may contain multiple declarations and definitions.
378+
an ANTLR parse tree visitor. AstBuilder will convert a raw ANTLR IParseTree into a a tree of `IAstNode` elements.
379+
That is, it visits the declarations and definitions in the parse tree to produce a full tree of declarations
380+
and definitions as they appeared in the source. For interactive modes - the tree will have only one top level node.
381+
However, when parsing a whole source file, the parse tree may contain multiple declarations and definitions under
382+
a RootNode.
378383

379-
The [Kaleidoscope AST](Kaleidoscope-AST.md) is a means of simplifying the original parse tree into
380-
constructs that are easy for the code generation to use directly. In the case of Kaleidoscope there are
381-
a few types of nodes that are used to generate LLVM IR. The AstBuilder class is responsible for
382-
generating an AST from an ANTLR4 parse tree.
384+
The [Kaleidoscope AST](xref:Kaleidoscope-AST) is a means of simplifying the original parse tree into
385+
constructs that are easy for the code generation to use directly and to validate the syntax of the input source.
386+
In the case of Kaleidoscope there are a few types of nodes that are used to generate LLVM IR. The AstBuilder class
387+
is responsible for generating an AST from an ANTLR4 parse tree.
383388

384389
The major simplifying transformations performed in building the AST are:
385390
* Convert top-level functions to a pair of FunctionDeclaration and FunctionDefinition
@@ -391,52 +396,60 @@ The major simplifying transformations performed in building the AST are:
391396
>operators no longer exists in the AST! The AST only deals in function declarations, definitions and the built-in
392397
>operators. All issues of precedence are implicitly resolved in the ordering of the nodes in the AST.
393398
>Thus, the code generation doesn't need to consider the issue of user defined operators or operator
394-
>precedence at all. ([Chapter 6](Kaleidoscope-ch6.md) covers the details of user defined operators)
395-
>
396-
399+
>precedence at all. ([Chapter 6](xref:Kaleidoscope-ch6) covers the details of user defined operators and how
400+
>the Kaleidoscope sample language uses ANTLR to implement them.)
401+
397402
## Basic Application Architecture
398403

399-
Generally speaking there are four main components to all of the sample chapter applications.
404+
Generally speaking, there are four main components to most of the sample chapter applications.
400405

401406
1. The main driver application (e.g. program.cs)
402-
2. The parser (e.g. Kaleidoscope.Grammar assembly)
403-
3. Runtime support (e.g. Kaliedoscope.Runtime)
407+
2. The Read-Evaluate-Print-Loop (e.g. ReplEngine.cs)
408+
3. Runtime support (e.g. Kaliedoscope.Runtime and Kaleidoscope.Parser libraries)
404409
4. The code generator (e.g. CodeGenerator.cs)
405410

406411
### Driver
407412
While each chapter is a bit different from the others. Many of the chapters are virtually identical for
408-
the driver. In particular Chapters 3-7 only really differ in the language level support.
413+
the driver. In particular Chapters 3-7 only really differ in the name of the app and window title etc...
414+
415+
[!code-csharp[Program.cs](Program.cs)]
416+
417+
### Read, Evaluate, Print loop
418+
The Kaleidoscope.Runtime library contains an abstract base class for building a standard REPL engine from an
419+
input TextReader. The base class handles converting the input reader into a sequence of statements, and
420+
parsing them into AST nodes. The nodes are provided to an application provided generator that produces the
421+
output result. The REPL engine base uses the abstract ShowResults method to actually show the results.
409422

410-
[!code-csharp[Program.cs](../../../Samples/Kaleidoscope/Chapter2/Program.cs#generatorloop)]
423+
[!code-csharp[Program.cs](ReplEngine.cs)]
411424

425+
### Runtime Support
412426
The Parser contains the support for parsing the Kaleidoscope language from the REPL loop interactive
413427
input. The parser stack also maintains the global state of the runtime, which controls the language features
414428
enabled, and if user defined operators are enabled, contains the operators defined along with their
415429
precedence.
416430

417-
After the parser is created an async enumerable sequence of statements is created for the parser to process.
431+
After the parser is created an enumerable sequence of statements is created for the parser to process.
418432
This results in a sequence of AST nodes. After construction, the sequence is used to iterate over all of
419433
the nodes generated from the user input.
420434

421-
This use of an Async enumerator sequences is a bit of a different approach to things for running an interpreter Read,
435+
This use of an enumerator sequences is a bit of a different approach to things for running an interpreter Read,
422436
Evaluate Print Loop, but once you get your head around it, the sequence provides a nice clean and flexible
423437
mechanism for building a pipeline of transformations from the text input into the result output.
424438

425-
### Processing generated results
426-
The calling application will generally subscribe to the observable sequence with a `ShowResults` function to show the
427-
results of the generation in some fashion. For the basic samples (Chapter 3-7) it indicates the value of any JITed
428-
and executed top level expressions, or the name of any functions defined. Chapter 2 has additional support for
429-
showing an XML representation of the tree but the same basic pattern applies. This, helps to keep the samples
439+
### CodeGenerator
440+
The code generator will transform the AST node into the final output for the program. For the basic samples
441+
(Chapter 3-7) it indicates the value of any JITed and executed top level expressions, or the name of any functions
442+
defined. Chapter 2 uses a generator that simply produces the node it was given as the app doesn't actually use LLVM
443+
(it focuses on parsing the language only and the REPL infrastructure). This, helps to keep the samples
430444
consistent and as similar as possible to allow direct file comparisons to show the changes for a particular feature.
431445
The separation of concerns also aids in making the grammar, runtime and code generation unit-testable without the
432-
driver. (Although that isn't implemented yet - it is intended for the future to help broaden testing of Ubiquity.NET.Llvm to
433-
more scenarios and catch breaking issues quicker.)
446+
driver.
434447

435-
[!code-csharp[ShowResults](../../../Samples/Kaleidoscope/Chapter2/Program.cs#ShowResults)]
448+
[!code-csharp[ShowResults](CodeGenerator.cs)]
436449

437450
### Special case for Chapter 2
438451
Chapter 2 sample code, while still following the general patterns used in all of the chapters, is a bit
439-
unique, it doesn't actually use LUbiquity.NET.Llvm at all! Instead, it is only focused on the language and parsing.
452+
unique, it doesn't actually use Ubiquity.NET.Llvm at all! Instead, it is only focused on the language and parsing.
440453
This helps in understanding the basic patterns of the code. Furthermore, this chapter serves as an aid in
441454
understanding the language itself. Of particular use is the ability to generate DGML and [blockdiag](http://blockdiag.com)
442455
representations of the parse tree for a given parse.

0 commit comments

Comments
 (0)