Skip to content

Commit

Permalink
Chapter 9 tutorial (#61)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
smaillet authored Apr 7, 2018
1 parent 52509fb commit 1df0651
Show file tree
Hide file tree
Showing 32 changed files with 609 additions and 411 deletions.
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
<IsTestProject>$(MSBuildProjectName.Contains('Test'))</IsTestProject>
</PropertyGroup>
<ItemGroup Condition="'$(NoCommonAnalyzers)'!='true' and '$(IsTestProject)' != 'true' and '$(SourceLinkEnabled)' != 'false'">
<PackageReference Include="SourceLink.Create.CommandLine" Version="2.7.4" PrivateAssets="All" />
<PackageReference Include="SourceLink.Create.CommandLine" Version="2.8.0" PrivateAssets="All" />
</ItemGroup>
<ItemGroup Condition="'$(NoCommonAnalyzers)'!='true'">
<PackageReference Include="Microsoft.AnalyzerPowerPack" Version="1.1.0" PrivateAssets="All" />
Expand Down
35 changes: 4 additions & 31 deletions Samples/Kaleidoscope/Chapter2/CodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,24 @@

using System;
using Antlr4.Runtime;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Tree;
using Kaleidoscope.Grammar;
using Kaleidoscope.Runtime;

using static Kaleidoscope.Grammar.KaleidoscopeParser;

namespace Kaleidoscope
{
/// <summary>Static extension methods to perform LLVM IR Code generation from the Kaleidoscope AST</summary>
/// <remarks>
/// This doesn't actually generate any code. The only thing it does is to record any user defined operators
/// in the <see cref="DynamicRuntimeState"/> so that subsequent parsing takes the operator precedence into
/// account. (If the language didn't support user defined precedence this would not be needed at all)
/// This doesn't actually generate any code. It simply satisfies the generator contract with an
/// effective NOP
/// </remarks>
internal sealed class CodeGenerator
: KaleidoscopeBaseVisitor<int>
, IDisposable
, IKaleidoscopeCodeGenerator<int>
{
public CodeGenerator( DynamicRuntimeState globalState )
public CodeGenerator( )
{
RuntimeState = globalState;
}

public void Dispose( )
Expand All @@ -37,34 +32,12 @@ public int Generate( Parser parser, IParseTree tree, DiagnosticRepresentations a
{
if( parser.NumberOfSyntaxErrors > 0 )
{
return 0;
}

return Visit( tree );
}

public override int VisitBinaryPrototype( [NotNull] BinaryPrototypeContext context )
{
if( !RuntimeState.TryAddOperator( context.OpToken, OperatorKind.InfixLeftAssociative, context.Precedence ) )
{
throw new CodeGeneratorException( "Cannot replace built-in operators" );
}

return 0;
}

public override int VisitUnaryPrototype( [NotNull] UnaryPrototypeContext context )
{
if( !RuntimeState.TryAddOperator( context.OpToken, OperatorKind.PreFix, 0 ) )
{
throw new CodeGeneratorException( "Cannot replace built-in operators" );
return 1;
}

return 0;
}

protected override int DefaultResult => 0;

private readonly DynamicRuntimeState RuntimeState;
}
}
4 changes: 2 additions & 2 deletions Samples/Kaleidoscope/Chapter2/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ public static void Main( string[ ] args )
// Using language level that includes the complete set
// of language features to allow exploring and verifying
// <generatorloop>
var parser = new ReplParserStack( LanguageLevel.MutableVariables );
using( var generator = new CodeGenerator( parser.GlobalState ) )
var parser = new ParserStack( LanguageLevel.MutableVariables );
using( var generator = new CodeGenerator( ) )
{
Console.WriteLine( "LLVM Kaleidoscope Syntax Viewer - {0}", parser.LanguageLevel );

Expand Down
2 changes: 1 addition & 1 deletion Samples/Kaleidoscope/Chapter3/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public static void Main( string[ ] args )
RegisterNative( );

// <generatorloop>
var parser = new ReplParserStack( LanguageLevel.SimpleExpressions );
var parser = new ParserStack( LanguageLevel.SimpleExpressions );
using( var generator = new CodeGenerator( parser.GlobalState ) )
{
Console.WriteLine( "Llvm.NET Kaleidoscope Interpreter - {0}", parser.LanguageLevel );
Expand Down
12 changes: 12 additions & 0 deletions Samples/Kaleidoscope/Chapter4/CodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public void Dispose( )
Context.Dispose( );
}

// <Generate>
public Value Generate( Parser parser, IParseTree tree, DiagnosticRepresentations additionalDiagnostics )
{
if( parser.NumberOfSyntaxErrors > 0 )
Expand All @@ -60,17 +61,21 @@ public Value Generate( Parser parser, IParseTree tree, DiagnosticRepresentations

return Visit( tree );
}
// </Generate>

public override Value VisitParenExpression( [NotNull] ParenExpressionContext context )
{
return context.Expression.Accept( this );
}

// <VisitConstExpression>
public override Value VisitConstExpression( [NotNull] ConstExpressionContext context )
{
return Context.CreateConstant( context.Value );
}
// </VisitConstExpression>

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

return value;
}
// </VisitVariableExpression>

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

// <FunctionDeclarations>
public override Value VisitExternalDeclaration( [NotNull] ExternalDeclarationContext context )
{
return context.Signature.Accept( this );
Expand All @@ -103,6 +110,7 @@ public override Value VisitFunctionPrototype( [NotNull] FunctionPrototypeContext
{
return GetOrDeclareFunction( new Prototype( context ) );
}
// </FunctionDeclarations>

// <VisitFunctionDefinition>
public override Value VisitFunctionDefinition( [NotNull] FunctionDefinitionContext context )
Expand All @@ -129,6 +137,7 @@ public override Value VisitTopLevelExpression( [NotNull] TopLevelExpressionConte
}
// </VisitTopLevelExpression>

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

return lhs;
}
// </VisitExpression>

protected override Value DefaultResult => null;

// <EmitBinaryOperator>
private Value EmitBinaryOperator( Value lhs, BinaryopContext op, IParseTree rightTree )
{
var rhs = rightTree.Accept( this );
Expand Down Expand Up @@ -185,6 +196,7 @@ private Value EmitBinaryOperator( Value lhs, BinaryopContext op, IParseTree righ
throw new CodeGeneratorException( $"Invalid binary operator {op.Token.Text}" );
}
}
// </EmitBinaryOperator>

// <InitializeModuleAndPassManager>
private void InitializeModuleAndPassManager( )
Expand Down
2 changes: 1 addition & 1 deletion Samples/Kaleidoscope/Chapter4/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public static void Main( string[ ] args )
RegisterNative( );

// <generatorloop>
var parser = new ReplParserStack( LanguageLevel.SimpleExpressions );
var parser = new ParserStack( LanguageLevel.SimpleExpressions );
using( var generator = new CodeGenerator( parser.GlobalState ) )
{
Console.WriteLine( "Llvm.NET Kaleidoscope Interpreter - {0}", parser.LanguageLevel );
Expand Down
24 changes: 18 additions & 6 deletions Samples/Kaleidoscope/Chapter5/CodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public void Dispose( )
Context.Dispose( );
}

// <Generate>
public Value Generate( Parser parser, IParseTree tree, DiagnosticRepresentations additionalDiagnostics )
{
if( parser.NumberOfSyntaxErrors > 0 )
Expand All @@ -60,17 +61,21 @@ public Value Generate( Parser parser, IParseTree tree, DiagnosticRepresentations

return Visit( tree );
}
// </Generate>

public override Value VisitParenExpression( [NotNull] ParenExpressionContext context )
{
return context.Expression.Accept( this );
}

// <VisitConstExpression>
public override Value VisitConstExpression( [NotNull] ConstExpressionContext context )
{
return Context.CreateConstant( context.Value );
}
// </VisitConstExpression>

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

return value;
}
// </VisitVariableExpression>

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

// <FunctionDeclarations>
public override Value VisitExternalDeclaration( [NotNull] ExternalDeclarationContext context )
{
return context.Signature.Accept( this );
Expand All @@ -103,6 +110,7 @@ public override Value VisitFunctionPrototype( [NotNull] FunctionPrototypeContext
{
return GetOrDeclareFunction( new Prototype( context ) );
}
// </FunctionDeclarations>

// <VisitFunctionDefinition>
public override Value VisitFunctionDefinition( [NotNull] FunctionDefinitionContext context )
Expand All @@ -129,6 +137,7 @@ public override Value VisitTopLevelExpression( [NotNull] TopLevelExpressionConte
}
// </VisitTopLevelExpression>

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

return lhs;
}
// </VisitExpression>

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

var thenBlock = Context.CreateBasicBlock( "then", function );
var elseBlock = Context.CreateBasicBlock( "else" );
var phiMergeBlock = Context.CreateBasicBlock( "ifcont" );
var continueBlock = Context.CreateBasicBlock( "ifcont" );
InstructionBuilder.Branch( condBool, thenBlock, elseBlock );

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

InstructionBuilder.Branch( phiMergeBlock );
InstructionBuilder.Branch( continueBlock );

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

InstructionBuilder.Branch( phiMergeBlock );
InstructionBuilder.Branch( continueBlock );
elseBlock = InstructionBuilder.InsertBlock;

// generate PHI merge block
function.BasicBlocks.Add( phiMergeBlock );
InstructionBuilder.PositionAtEnd( phiMergeBlock );
// generate continue block
function.BasicBlocks.Add( continueBlock );
InstructionBuilder.PositionAtEnd( continueBlock );
var phiNode = InstructionBuilder.PhiNode( function.Context.DoubleType )
.RegisterName( "iftmp" );

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

protected override Value DefaultResult => null;

// <EmitBinaryOperator>
private Value EmitBinaryOperator( Value lhs, BinaryopContext op, IParseTree rightTree )
{
var rhs = rightTree.Accept( this );
Expand Down Expand Up @@ -335,6 +346,7 @@ private Value EmitBinaryOperator( Value lhs, BinaryopContext op, IParseTree righ
throw new CodeGeneratorException( $"Invalid binary operator {op.Token.Text}" );
}
}
// </EmitBinaryOperator>

// <InitializeModuleAndPassManager>
private void InitializeModuleAndPassManager( )
Expand Down
2 changes: 1 addition & 1 deletion Samples/Kaleidoscope/Chapter5/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public static void Main( string[ ] args )
RegisterNative( );

// <generatorloop>
var parser = new ReplParserStack( LanguageLevel.ControlFlow );
var parser = new ParserStack( LanguageLevel.ControlFlow );
using( var generator = new CodeGenerator( parser.GlobalState ) )
{
Console.WriteLine( "Llvm.NET Kaleidoscope Interpreter - {0}", parser.LanguageLevel );
Expand Down
Loading

0 comments on commit 1df0651

Please sign in to comment.