Skip to content

Commit 1df0651

Browse files
authored
Chapter 9 tutorial (#61)
* added fullsrc target in the grammar so that the parse tree covers the entire input file and source locations accurately reflect the original source. * reworked handling of anonymous functions for AOT all-up * moved user operator table management into custom parserlistener so it is easily shared amongst the multiple uses (the operators are enabled for chapters 2 and 6-9) * re-synced the chapters samples to minimize differences. * Added assembly file generation to AOT samples * Added debug info for local variables along with parameters
1 parent 52509fb commit 1df0651

32 files changed

+609
-411
lines changed

Directory.Build.props

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
<IsTestProject>$(MSBuildProjectName.Contains('Test'))</IsTestProject>
6262
</PropertyGroup>
6363
<ItemGroup Condition="'$(NoCommonAnalyzers)'!='true' and '$(IsTestProject)' != 'true' and '$(SourceLinkEnabled)' != 'false'">
64-
<PackageReference Include="SourceLink.Create.CommandLine" Version="2.7.4" PrivateAssets="All" />
64+
<PackageReference Include="SourceLink.Create.CommandLine" Version="2.8.0" PrivateAssets="All" />
6565
</ItemGroup>
6666
<ItemGroup Condition="'$(NoCommonAnalyzers)'!='true'">
6767
<PackageReference Include="Microsoft.AnalyzerPowerPack" Version="1.1.0" PrivateAssets="All" />

Samples/Kaleidoscope/Chapter2/CodeGenerator.cs

+4-31
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,24 @@
44

55
using System;
66
using Antlr4.Runtime;
7-
using Antlr4.Runtime.Misc;
87
using Antlr4.Runtime.Tree;
98
using Kaleidoscope.Grammar;
109
using Kaleidoscope.Runtime;
1110

12-
using static Kaleidoscope.Grammar.KaleidoscopeParser;
13-
1411
namespace Kaleidoscope
1512
{
1613
/// <summary>Static extension methods to perform LLVM IR Code generation from the Kaleidoscope AST</summary>
1714
/// <remarks>
18-
/// This doesn't actually generate any code. The only thing it does is to record any user defined operators
19-
/// in the <see cref="DynamicRuntimeState"/> so that subsequent parsing takes the operator precedence into
20-
/// account. (If the language didn't support user defined precedence this would not be needed at all)
15+
/// This doesn't actually generate any code. It simply satisfies the generator contract with an
16+
/// effective NOP
2117
/// </remarks>
2218
internal sealed class CodeGenerator
2319
: KaleidoscopeBaseVisitor<int>
2420
, IDisposable
2521
, IKaleidoscopeCodeGenerator<int>
2622
{
27-
public CodeGenerator( DynamicRuntimeState globalState )
23+
public CodeGenerator( )
2824
{
29-
RuntimeState = globalState;
3025
}
3126

3227
public void Dispose( )
@@ -37,34 +32,12 @@ public int Generate( Parser parser, IParseTree tree, DiagnosticRepresentations a
3732
{
3833
if( parser.NumberOfSyntaxErrors > 0 )
3934
{
40-
return 0;
41-
}
42-
43-
return Visit( tree );
44-
}
45-
46-
public override int VisitBinaryPrototype( [NotNull] BinaryPrototypeContext context )
47-
{
48-
if( !RuntimeState.TryAddOperator( context.OpToken, OperatorKind.InfixLeftAssociative, context.Precedence ) )
49-
{
50-
throw new CodeGeneratorException( "Cannot replace built-in operators" );
51-
}
52-
53-
return 0;
54-
}
55-
56-
public override int VisitUnaryPrototype( [NotNull] UnaryPrototypeContext context )
57-
{
58-
if( !RuntimeState.TryAddOperator( context.OpToken, OperatorKind.PreFix, 0 ) )
59-
{
60-
throw new CodeGeneratorException( "Cannot replace built-in operators" );
35+
return 1;
6136
}
6237

6338
return 0;
6439
}
6540

6641
protected override int DefaultResult => 0;
67-
68-
private readonly DynamicRuntimeState RuntimeState;
6942
}
7043
}

Samples/Kaleidoscope/Chapter2/Program.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ public static void Main( string[ ] args )
2323
// Using language level that includes the complete set
2424
// of language features to allow exploring and verifying
2525
// <generatorloop>
26-
var parser = new ReplParserStack( LanguageLevel.MutableVariables );
27-
using( var generator = new CodeGenerator( parser.GlobalState ) )
26+
var parser = new ParserStack( LanguageLevel.MutableVariables );
27+
using( var generator = new CodeGenerator( ) )
2828
{
2929
Console.WriteLine( "LLVM Kaleidoscope Syntax Viewer - {0}", parser.LanguageLevel );
3030

Samples/Kaleidoscope/Chapter3/Program.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public static void Main( string[ ] args )
3939
RegisterNative( );
4040

4141
// <generatorloop>
42-
var parser = new ReplParserStack( LanguageLevel.SimpleExpressions );
42+
var parser = new ParserStack( LanguageLevel.SimpleExpressions );
4343
using( var generator = new CodeGenerator( parser.GlobalState ) )
4444
{
4545
Console.WriteLine( "Llvm.NET Kaleidoscope Interpreter - {0}", parser.LanguageLevel );

Samples/Kaleidoscope/Chapter4/CodeGenerator.cs

+12
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public void Dispose( )
5151
Context.Dispose( );
5252
}
5353

54+
// <Generate>
5455
public Value Generate( Parser parser, IParseTree tree, DiagnosticRepresentations additionalDiagnostics )
5556
{
5657
if( parser.NumberOfSyntaxErrors > 0 )
@@ -60,17 +61,21 @@ public Value Generate( Parser parser, IParseTree tree, DiagnosticRepresentations
6061

6162
return Visit( tree );
6263
}
64+
// </Generate>
6365

6466
public override Value VisitParenExpression( [NotNull] ParenExpressionContext context )
6567
{
6668
return context.Expression.Accept( this );
6769
}
6870

71+
// <VisitConstExpression>
6972
public override Value VisitConstExpression( [NotNull] ConstExpressionContext context )
7073
{
7174
return Context.CreateConstant( context.Value );
7275
}
76+
// </VisitConstExpression>
7377

78+
// <VisitVariableExpression>
7479
public override Value VisitVariableExpression( [NotNull] VariableExpressionContext context )
7580
{
7681
string varName = context.Name;
@@ -81,6 +86,7 @@ public override Value VisitVariableExpression( [NotNull] VariableExpressionConte
8186

8287
return value;
8388
}
89+
// </VisitVariableExpression>
8490

8591
public override Value VisitFunctionCallExpression( [NotNull] FunctionCallExpressionContext context )
8692
{
@@ -94,6 +100,7 @@ public override Value VisitFunctionCallExpression( [NotNull] FunctionCallExpress
94100
return InstructionBuilder.Call( function, args ).RegisterName( "calltmp" );
95101
}
96102

103+
// <FunctionDeclarations>
97104
public override Value VisitExternalDeclaration( [NotNull] ExternalDeclarationContext context )
98105
{
99106
return context.Signature.Accept( this );
@@ -103,6 +110,7 @@ public override Value VisitFunctionPrototype( [NotNull] FunctionPrototypeContext
103110
{
104111
return GetOrDeclareFunction( new Prototype( context ) );
105112
}
113+
// </FunctionDeclarations>
106114

107115
// <VisitFunctionDefinition>
108116
public override Value VisitFunctionDefinition( [NotNull] FunctionDefinitionContext context )
@@ -129,6 +137,7 @@ public override Value VisitTopLevelExpression( [NotNull] TopLevelExpressionConte
129137
}
130138
// </VisitTopLevelExpression>
131139

140+
// <VisitExpression>
132141
public override Value VisitExpression( [NotNull] ExpressionContext context )
133142
{
134143
// Expression: PrimaryExpression (op expression)*
@@ -141,9 +150,11 @@ public override Value VisitExpression( [NotNull] ExpressionContext context )
141150

142151
return lhs;
143152
}
153+
// </VisitExpression>
144154

145155
protected override Value DefaultResult => null;
146156

157+
// <EmitBinaryOperator>
147158
private Value EmitBinaryOperator( Value lhs, BinaryopContext op, IParseTree rightTree )
148159
{
149160
var rhs = rightTree.Accept( this );
@@ -185,6 +196,7 @@ private Value EmitBinaryOperator( Value lhs, BinaryopContext op, IParseTree righ
185196
throw new CodeGeneratorException( $"Invalid binary operator {op.Token.Text}" );
186197
}
187198
}
199+
// </EmitBinaryOperator>
188200

189201
// <InitializeModuleAndPassManager>
190202
private void InitializeModuleAndPassManager( )

Samples/Kaleidoscope/Chapter4/Program.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public static void Main( string[ ] args )
3939
RegisterNative( );
4040

4141
// <generatorloop>
42-
var parser = new ReplParserStack( LanguageLevel.SimpleExpressions );
42+
var parser = new ParserStack( LanguageLevel.SimpleExpressions );
4343
using( var generator = new CodeGenerator( parser.GlobalState ) )
4444
{
4545
Console.WriteLine( "Llvm.NET Kaleidoscope Interpreter - {0}", parser.LanguageLevel );

Samples/Kaleidoscope/Chapter5/CodeGenerator.cs

+18-6
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public void Dispose( )
5151
Context.Dispose( );
5252
}
5353

54+
// <Generate>
5455
public Value Generate( Parser parser, IParseTree tree, DiagnosticRepresentations additionalDiagnostics )
5556
{
5657
if( parser.NumberOfSyntaxErrors > 0 )
@@ -60,17 +61,21 @@ public Value Generate( Parser parser, IParseTree tree, DiagnosticRepresentations
6061

6162
return Visit( tree );
6263
}
64+
// </Generate>
6365

6466
public override Value VisitParenExpression( [NotNull] ParenExpressionContext context )
6567
{
6668
return context.Expression.Accept( this );
6769
}
6870

71+
// <VisitConstExpression>
6972
public override Value VisitConstExpression( [NotNull] ConstExpressionContext context )
7073
{
7174
return Context.CreateConstant( context.Value );
7275
}
76+
// </VisitConstExpression>
7377

78+
// <VisitVariableExpression>
7479
public override Value VisitVariableExpression( [NotNull] VariableExpressionContext context )
7580
{
7681
string varName = context.Name;
@@ -81,6 +86,7 @@ public override Value VisitVariableExpression( [NotNull] VariableExpressionConte
8186

8287
return value;
8388
}
89+
// </VisitVariableExpression>
8490

8591
public override Value VisitFunctionCallExpression( [NotNull] FunctionCallExpressionContext context )
8692
{
@@ -94,6 +100,7 @@ public override Value VisitFunctionCallExpression( [NotNull] FunctionCallExpress
94100
return InstructionBuilder.Call( function, args ).RegisterName( "calltmp" );
95101
}
96102

103+
// <FunctionDeclarations>
97104
public override Value VisitExternalDeclaration( [NotNull] ExternalDeclarationContext context )
98105
{
99106
return context.Signature.Accept( this );
@@ -103,6 +110,7 @@ public override Value VisitFunctionPrototype( [NotNull] FunctionPrototypeContext
103110
{
104111
return GetOrDeclareFunction( new Prototype( context ) );
105112
}
113+
// </FunctionDeclarations>
106114

107115
// <VisitFunctionDefinition>
108116
public override Value VisitFunctionDefinition( [NotNull] FunctionDefinitionContext context )
@@ -129,6 +137,7 @@ public override Value VisitTopLevelExpression( [NotNull] TopLevelExpressionConte
129137
}
130138
// </VisitTopLevelExpression>
131139

140+
// <VisitExpression>
132141
public override Value VisitExpression( [NotNull] ExpressionContext context )
133142
{
134143
// Expression: PrimaryExpression (op expression)*
@@ -141,6 +150,7 @@ public override Value VisitExpression( [NotNull] ExpressionContext context )
141150

142151
return lhs;
143152
}
153+
// </VisitExpression>
144154

145155
// <VisitConditionalExpression>
146156
public override Value VisitConditionalExpression( [NotNull] ConditionalExpressionContext context )
@@ -158,7 +168,7 @@ public override Value VisitConditionalExpression( [NotNull] ConditionalExpressio
158168

159169
var thenBlock = Context.CreateBasicBlock( "then", function );
160170
var elseBlock = Context.CreateBasicBlock( "else" );
161-
var phiMergeBlock = Context.CreateBasicBlock( "ifcont" );
171+
var continueBlock = Context.CreateBasicBlock( "ifcont" );
162172
InstructionBuilder.Branch( condBool, thenBlock, elseBlock );
163173

164174
// generate then block
@@ -169,7 +179,7 @@ public override Value VisitConditionalExpression( [NotNull] ConditionalExpressio
169179
return null;
170180
}
171181

172-
InstructionBuilder.Branch( phiMergeBlock );
182+
InstructionBuilder.Branch( continueBlock );
173183

174184
// capture the insert in case generating else adds new blocks
175185
thenBlock = InstructionBuilder.InsertBlock;
@@ -183,12 +193,12 @@ public override Value VisitConditionalExpression( [NotNull] ConditionalExpressio
183193
return null;
184194
}
185195

186-
InstructionBuilder.Branch( phiMergeBlock );
196+
InstructionBuilder.Branch( continueBlock );
187197
elseBlock = InstructionBuilder.InsertBlock;
188198

189-
// generate PHI merge block
190-
function.BasicBlocks.Add( phiMergeBlock );
191-
InstructionBuilder.PositionAtEnd( phiMergeBlock );
199+
// generate continue block
200+
function.BasicBlocks.Add( continueBlock );
201+
InstructionBuilder.PositionAtEnd( continueBlock );
192202
var phiNode = InstructionBuilder.PhiNode( function.Context.DoubleType )
193203
.RegisterName( "iftmp" );
194204

@@ -294,6 +304,7 @@ public override Value VisitForExpression( [NotNull] ForExpressionContext context
294304

295305
protected override Value DefaultResult => null;
296306

307+
// <EmitBinaryOperator>
297308
private Value EmitBinaryOperator( Value lhs, BinaryopContext op, IParseTree rightTree )
298309
{
299310
var rhs = rightTree.Accept( this );
@@ -335,6 +346,7 @@ private Value EmitBinaryOperator( Value lhs, BinaryopContext op, IParseTree righ
335346
throw new CodeGeneratorException( $"Invalid binary operator {op.Token.Text}" );
336347
}
337348
}
349+
// </EmitBinaryOperator>
338350

339351
// <InitializeModuleAndPassManager>
340352
private void InitializeModuleAndPassManager( )

Samples/Kaleidoscope/Chapter5/Program.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public static void Main( string[ ] args )
3939
RegisterNative( );
4040

4141
// <generatorloop>
42-
var parser = new ReplParserStack( LanguageLevel.ControlFlow );
42+
var parser = new ParserStack( LanguageLevel.ControlFlow );
4343
using( var generator = new CodeGenerator( parser.GlobalState ) )
4444
{
4545
Console.WriteLine( "Llvm.NET Kaleidoscope Interpreter - {0}", parser.LanguageLevel );

0 commit comments

Comments
 (0)