Skip to content

Commit

Permalink
Add doc link, fix a bug of execution (#62)
Browse files Browse the repository at this point in the history
* Add doc link

* fix bug of execution

* update
  • Loading branch information
Tesla Ice Zhang authored and Mukul Sabharwal committed Nov 10, 2017
1 parent c4fcf6c commit 4553bce
Show file tree
Hide file tree
Showing 10 changed files with 56 additions and 62 deletions.
6 changes: 0 additions & 6 deletions KaleidoscopeTutorial/Chapter4/Kaleidoscope.sln
Expand Up @@ -17,16 +17,10 @@ Global
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{CD23CB2E-951B-4FAD-A4CD-4048731DBA31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CD23CB2E-951B-4FAD-A4CD-4048731DBA31}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CD23CB2E-951B-4FAD-A4CD-4048731DBA31}.Debug|x64.ActiveCfg = Debug|x64
{CD23CB2E-951B-4FAD-A4CD-4048731DBA31}.Debug|x64.Build.0 = Debug|x64
{CD23CB2E-951B-4FAD-A4CD-4048731DBA31}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CD23CB2E-951B-4FAD-A4CD-4048731DBA31}.Release|Any CPU.Build.0 = Release|Any CPU
{CD23CB2E-951B-4FAD-A4CD-4048731DBA31}.Release|x64.ActiveCfg = Release|x64
{CD23CB2E-951B-4FAD-A4CD-4048731DBA31}.Release|x64.Build.0 = Release|x64
{C1147A13-4174-410A-A891-335D858703B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C1147A13-4174-410A-A891-335D858703B7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C1147A13-4174-410A-A891-335D858703B7}.Debug|x64.ActiveCfg = Debug|x64
{C1147A13-4174-410A-A891-335D858703B7}.Debug|x64.Build.0 = Debug|x64
{C1147A13-4174-410A-A891-335D858703B7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C1147A13-4174-410A-A891-335D858703B7}.Release|Any CPU.Build.0 = Release|Any CPU
{C1147A13-4174-410A-A891-335D858703B7}.Release|x64.ActiveCfg = Release|Any CPU
Expand Down
Expand Up @@ -8,12 +8,7 @@ protected ExprVisitor()

public virtual ExprAST Visit(ExprAST node)
{
if (node != null)
{
return node.Accept(this);
}

return null;
return node?.Accept(this);
}

protected internal virtual ExprAST VisitExtension(ExprAST node)
Expand Down
10 changes: 6 additions & 4 deletions KaleidoscopeTutorial/Chapter4/Kaleidoscope/BaseParserListener.cs
Expand Up @@ -28,8 +28,10 @@ public void EnterRule(string ruleName)
public void ExitRule(ExprAST argument)
{
string ruleName = this.descentStack.Pop();
this.ascentStack.Push(new ASTContext(IParserListenerType.GetMethod("Exit" + ruleName), this.listener, argument));
this.ascentStack.Push(new ASTContext(IParserListenerType.GetMethod("Enter" + ruleName), this.listener, argument));
this.ascentStack.Push(new ASTContext(IParserListenerType.GetMethod("Exit" + ruleName), this.listener,
argument));
this.ascentStack.Push(new ASTContext(IParserListenerType.GetMethod("Enter" + ruleName), this.listener,
argument));
}

public void Listen()
Expand All @@ -39,8 +41,8 @@ public void Listen()
while (this.ascentStack.Count != 0)
{
var context = this.ascentStack.Pop();
context.MethodInfo.Invoke(context.Instance, new object[] { context.Argument });
}
context.MethodInfo.Invoke(context.Instance, new object[] {context.Argument});
}
}
}

Expand Down
3 changes: 1 addition & 2 deletions KaleidoscopeTutorial/Chapter4/Kaleidoscope/Lexer.cs
Expand Up @@ -45,8 +45,7 @@ public double GetLastNumber()
public int GetTokPrecedence()
{
// Make sure it's a declared binop.
int tokPrec;
if (this.binopPrecedence.TryGetValue((char)this.CurrentToken, out tokPrec))
if (this.binopPrecedence.TryGetValue((char)this.CurrentToken, out var tokPrec))
{
return tokPrec;
}
Expand Down
26 changes: 13 additions & 13 deletions KaleidoscopeTutorial/Chapter4/Kaleidoscope/Parser.cs
Expand Up @@ -80,16 +80,16 @@ public void HandleTopLevelExpression()
private ExprAST ParseIdentifierExpr()
{
string idName = this.scanner.GetLastIdentifier();
this.scanner.GetNextToken(); // eat identifier.

this.scanner.GetNextToken(); // eat identifier.

if (this.scanner.CurrentToken != '(') // Simple variable ref.
{
return new VariableExprAST(idName);
}

// Call.
this.scanner.GetNextToken(); // eat (
this.scanner.GetNextToken(); // eat (
List<ExprAST> args = new List<ExprAST>();

if (this.scanner.CurrentToken != ')')
Expand All @@ -114,11 +114,11 @@ private ExprAST ParseIdentifierExpr()
Console.WriteLine("Expected ')' or ',' in argument list");
return null;
}

this.scanner.GetNextToken();
}
}

// Eat the ')'.
this.scanner.GetNextToken();

Expand All @@ -136,7 +136,7 @@ private ExprAST ParseNumberExpr()
// parenexpr ::= '(' expression ')'
private ExprAST ParseParenExpr()
{
this.scanner.GetNextToken(); // eat (.
this.scanner.GetNextToken(); // eat (.
ExprAST v = this.ParseExpression();
if (v == null)
{
Expand All @@ -162,9 +162,9 @@ private ExprAST ParsePrimary()
{
switch (this.scanner.CurrentToken)
{
case (int)Token.IDENTIFIER:
case (int) Token.IDENTIFIER:
return this.ParseIdentifierExpr();
case (int)Token.NUMBER:
case (int) Token.NUMBER:
return this.ParseNumberExpr();
case '(':
return this.ParseParenExpr();
Expand Down Expand Up @@ -192,7 +192,7 @@ private ExprAST ParseBinOpRHS(int exprPrec, ExprAST lhs)

// Okay, we know this is a binop.
int binOp = this.scanner.CurrentToken;
this.scanner.GetNextToken(); // eat binop
this.scanner.GetNextToken(); // eat binop

// Parse the primary expression after the binary operator.
ExprAST rhs = this.ParsePrimary();
Expand All @@ -214,7 +214,7 @@ private ExprAST ParseBinOpRHS(int exprPrec, ExprAST lhs)
}

// Merge LHS/RHS.
lhs = new BinaryExprAST((char)binOp, lhs, rhs);
lhs = new BinaryExprAST((char) binOp, lhs, rhs);
}
}

Expand All @@ -236,7 +236,7 @@ private ExprAST ParseExpression()
// ::= id '(' id* ')'
private PrototypeAST ParsePrototype()
{
if (this.scanner.CurrentToken != (int)Token.IDENTIFIER)
if (this.scanner.CurrentToken != (int) Token.IDENTIFIER)
{
Console.WriteLine("Expected function name in prototype");
return null;
Expand All @@ -253,7 +253,7 @@ private PrototypeAST ParsePrototype()
}

List<string> argNames = new List<string>();
while (this.scanner.GetNextToken() == (int)Token.IDENTIFIER)
while (this.scanner.GetNextToken() == (int) Token.IDENTIFIER)
{
argNames.Add(this.scanner.GetLastIdentifier());
}
Expand Down Expand Up @@ -306,7 +306,7 @@ private FunctionAST ParseTopLevelExpr()
/// external ::= 'extern' prototype
private PrototypeAST ParseExtern()
{
this.scanner.GetNextToken(); // eat extern.
this.scanner.GetNextToken(); // eat extern.
return this.ParsePrototype();
}
}
Expand Down
Expand Up @@ -30,10 +30,10 @@ public void ExitHandleDefinition(FunctionAST data)
{
this.visitor.Visit(data);
var function = this.visitor.ResultStack.Pop();
LLVM.DumpValue(function);
// LLVM.DumpValue(function);

LLVM.RunFunctionPassManager(this.passManager, function);
LLVM.DumpValue(function); // Dump the function for exposition purposes.
// LLVM.DumpValue(function); // Dump the function for exposition purposes.
}

public void EnterHandleExtern(PrototypeAST data)
Expand All @@ -43,7 +43,7 @@ public void EnterHandleExtern(PrototypeAST data)
public void ExitHandleExtern(PrototypeAST data)
{
this.visitor.Visit(data);
LLVM.DumpValue(this.visitor.ResultStack.Pop());
// LLVM.DumpValue(this.visitor.ResultStack.Pop());
}

public void EnterHandleTopLevelExpression(FunctionAST data)
Expand All @@ -54,11 +54,12 @@ public void ExitHandleTopLevelExpression(FunctionAST data)
{
this.visitor.Visit(data);
var anonymousFunction = this.visitor.ResultStack.Pop();
LLVM.DumpValue(anonymousFunction); // Dump the function for exposition purposes.
var dFunc = (Program.D)Marshal.GetDelegateForFunctionPointer(LLVM.GetPointerToGlobal(this.ee, anonymousFunction), typeof(Program.D));
// LLVM.DumpValue(anonymousFunction); // Dump the function for exposition purposes.
var dFunc = (Program.D) Marshal.GetDelegateForFunctionPointer(
LLVM.GetPointerToGlobal(this.ee, anonymousFunction), typeof(Program.D));
LLVM.RunFunctionPassManager(this.passManager, anonymousFunction);

LLVM.DumpValue(anonymousFunction); // Dump the function for exposition purposes.
// LLVM.DumpValue(anonymousFunction); // Dump the function for exposition purposes.
Console.WriteLine("Evaluated to " + dFunc());
}
}
Expand Down
23 changes: 12 additions & 11 deletions KaleidoscopeTutorial/Chapter4/KaleidoscopeLLVM/CodeGenVisitor.cs
Expand Up @@ -40,16 +40,14 @@ protected override ExprAST VisitNumberExprAST(NumberExprAST node)

protected override ExprAST VisitVariableExprAST(VariableExprAST node)
{
LLVMValueRef value;

// Look this variable up in the function.
if (this.namedValues.TryGetValue(node.Name, out value))
if (this.namedValues.TryGetValue(node.Name, out var value))
{
this.valueStack.Push(value);
}
else
{
throw new Exception("Unknown variable name");
throw new Exception($"Unknown variable name {node.Name}");
}

return node;
Expand Down Expand Up @@ -78,7 +76,9 @@ protected override ExprAST VisitBinaryExprAST(BinaryExprAST node)
break;
case ExprType.LessThanExpr:
// Convert bool 0/1 to double 0.0 or 1.0
n = LLVM.BuildUIToFP(this.builder, LLVM.BuildFCmp(this.builder, LLVMRealPredicate.LLVMRealULT, l, r, "cmptmp"), LLVM.DoubleType(), "booltmp");
n = LLVM.BuildUIToFP(this.builder,
LLVM.BuildFCmp(this.builder, LLVMRealPredicate.LLVMRealULT, l, r, "cmptmp"), LLVM.DoubleType(),
"booltmp");
break;
default:
throw new Exception("invalid binary operator");
Expand All @@ -93,15 +93,15 @@ protected override ExprAST VisitCallExprAST(CallExprAST node)
var calleeF = LLVM.GetNamedFunction(this.module, node.Callee);
if (calleeF.Pointer == IntPtr.Zero)
{
throw new Exception("Unknown function referenced");
throw new Exception($"Unknown function referenced {node.Callee}");
}

if (LLVM.CountParams(calleeF) != node.Arguments.Count)
{
throw new Exception("Incorrect # arguments passed");
}

var argumentCount = (uint)node.Arguments.Count;
var argumentCount = (uint) node.Arguments.Count;
var argsV = new LLVMValueRef[Math.Max(argumentCount, 1)];
for (int i = 0; i < argumentCount; ++i)
{
Expand All @@ -117,8 +117,8 @@ protected override ExprAST VisitCallExprAST(CallExprAST node)
protected override ExprAST VisitPrototypeAST(PrototypeAST node)
{
// Make the function type: double(double,double) etc.
var argumentCount = (uint)node.Arguments.Count;
var arguments = new LLVMTypeRef[Math.Max(argumentCount, 1)];
var argumentCount = (uint) node.Arguments.Count;
var arguments = new LLVMTypeRef[Math.Max(argumentCount, 0)];

var function = LLVM.GetNamedFunction(this.module, node.Name);

Expand All @@ -145,15 +145,16 @@ protected override ExprAST VisitPrototypeAST(PrototypeAST node)
arguments[i] = LLVM.DoubleType();
}

function = LLVM.AddFunction(this.module, node.Name, LLVM.FunctionType(LLVM.DoubleType(), arguments, LLVMBoolFalse));
function = LLVM.AddFunction(this.module, node.Name,
LLVM.FunctionType(LLVM.DoubleType(), arguments, LLVMBoolFalse));
LLVM.SetLinkage(function, LLVMLinkage.LLVMExternalLinkage);
}

for (int i = 0; i < argumentCount; ++i)
{
var argumentName = node.Arguments[i];

LLVMValueRef param = LLVM.GetParam(function, (uint)i);
LLVMValueRef param = LLVM.GetParam(function, (uint) i);
LLVM.SetValueName(param, argumentName);

this.namedValues[argumentName] = param;
Expand Down
20 changes: 10 additions & 10 deletions KaleidoscopeTutorial/Chapter4/KaleidoscopeLLVM/Program.cs
Expand Up @@ -2,24 +2,24 @@
{
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Kaleidoscope;
using LLVMSharp;

public sealed class Program
{
public delegate double D();
private static void Main(string[] args)

public static void Main(string[] args)
{
// Make the module, which holds all the code.
LLVMModuleRef module = LLVM.ModuleCreateWithName("my cool jit");
LLVMBuilderRef builder = LLVM.CreateBuilder();

LLVM.LinkInMCJIT();
LLVM.InitializeX86TargetInfo();
LLVM.InitializeX86Target();
LLVM.InitializeX86TargetMC();
LLVM.InitializeX86Target();
LLVM.InitializeX86TargetInfo();
LLVM.InitializeX86AsmParser();
LLVM.InitializeX86AsmPrinter();

if (LLVM.CreateExecutionEngineForModule(out var engine, module, out var errorMessage).Value == 1)
{
Expand All @@ -33,7 +33,7 @@ private static void Main(string[] args)

// Set up the optimizer pipeline. Start with registering info about how the
// target lays out data structures.
LLVM.DisposeTargetData(LLVM.GetExecutionEngineTargetData(engine));
// LLVM.DisposeTargetData(LLVM.GetExecutionEngineTargetData(engine));

// Provide basic AliasAnalysis support for GVN.
LLVM.AddBasicAliasAnalysisPass(passManager);
Expand Down Expand Up @@ -90,15 +90,15 @@ private static void MainLoop(ILexer lexer, IParser parser)
Console.Write("ready> ");
switch (lexer.CurrentToken)
{
case (int)Token.EOF:
case (int) Token.EOF:
return;
case ';':
lexer.GetNextToken();
break;
case (int)Token.DEF:
case (int) Token.DEF:
parser.HandleDefinition();
break;
case (int)Token.EXTERN:
case (int) Token.EXTERN:
parser.HandleExtern();
break;
default:
Expand Down
4 changes: 2 additions & 2 deletions KaleidoscopeTutorial/Chapter5/KaleidoscopeLLVM/Program.cs
Expand Up @@ -33,7 +33,7 @@ private static void Main(string[] args)

// Set up the optimizer pipeline. Start with registering info about how the
// target lays out data structures.
LLVM.DisposeTargetData(LLVM.GetExecutionEngineTargetData(engine));
// LLVM.DisposeTargetData(LLVM.GetExecutionEngineTargetData(engine));

// Provide basic AliasAnalysis support for GVN.
LLVM.AddBasicAliasAnalysisPass(passManager);
Expand Down Expand Up @@ -111,4 +111,4 @@ private static void MainLoop(ILexer lexer, IParser parser)
}
}
}
}
}
6 changes: 4 additions & 2 deletions README.md
Expand Up @@ -32,7 +32,9 @@ On Windows using .NET Core
* Type safe (LLVMValueRef and LLVMTypeRef are different types, despite being pointers internally)
* Nearly identical to LLVM C APIs, e.g. LLVMModuleCreateWithName in C, vs. LLVM.ModuleCreateWithName (notice the . in the C# API)

## Kaleidoscope Tutorial
## Kaleidoscope Tutorials

There's a [C# translation of the LLVM official Kaleidoscope Tutorial](http://ice1000.org/llvm-cs/en/).

Much of the tutorial is already implemented here, and has some nice improvements like the Visitor pattern for code generation to make the LLVM code stand out and help you bootstrap your compiler.

Expand Down Expand Up @@ -118,4 +120,4 @@ The tutorials have been tested to run on Windows and Linux, however the build (u

## Microsoft Open Source Code of Conduct

This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.

0 comments on commit 4553bce

Please sign in to comment.