diff --git a/KaleidoscopeTutorial/Chapter4/Kaleidoscope.sln b/KaleidoscopeTutorial/Chapter4/Kaleidoscope.sln index eae9808a..1bb9c05b 100644 --- a/KaleidoscopeTutorial/Chapter4/Kaleidoscope.sln +++ b/KaleidoscopeTutorial/Chapter4/Kaleidoscope.sln @@ -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 diff --git a/KaleidoscopeTutorial/Chapter4/Kaleidoscope/AST/ExprVisitor.cs b/KaleidoscopeTutorial/Chapter4/Kaleidoscope/AST/ExprVisitor.cs index a51f80cc..a357e1d4 100644 --- a/KaleidoscopeTutorial/Chapter4/Kaleidoscope/AST/ExprVisitor.cs +++ b/KaleidoscopeTutorial/Chapter4/Kaleidoscope/AST/ExprVisitor.cs @@ -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) diff --git a/KaleidoscopeTutorial/Chapter4/Kaleidoscope/BaseParserListener.cs b/KaleidoscopeTutorial/Chapter4/Kaleidoscope/BaseParserListener.cs index 9eb96731..6fb50254 100644 --- a/KaleidoscopeTutorial/Chapter4/Kaleidoscope/BaseParserListener.cs +++ b/KaleidoscopeTutorial/Chapter4/Kaleidoscope/BaseParserListener.cs @@ -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() @@ -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}); + } } } diff --git a/KaleidoscopeTutorial/Chapter4/Kaleidoscope/Lexer.cs b/KaleidoscopeTutorial/Chapter4/Kaleidoscope/Lexer.cs index fc321d68..f73d0612 100644 --- a/KaleidoscopeTutorial/Chapter4/Kaleidoscope/Lexer.cs +++ b/KaleidoscopeTutorial/Chapter4/Kaleidoscope/Lexer.cs @@ -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; } diff --git a/KaleidoscopeTutorial/Chapter4/Kaleidoscope/Parser.cs b/KaleidoscopeTutorial/Chapter4/Kaleidoscope/Parser.cs index 15954149..bd17834f 100644 --- a/KaleidoscopeTutorial/Chapter4/Kaleidoscope/Parser.cs +++ b/KaleidoscopeTutorial/Chapter4/Kaleidoscope/Parser.cs @@ -80,8 +80,8 @@ 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. { @@ -89,7 +89,7 @@ private ExprAST ParseIdentifierExpr() } // Call. - this.scanner.GetNextToken(); // eat ( + this.scanner.GetNextToken(); // eat ( List args = new List(); if (this.scanner.CurrentToken != ')') @@ -114,11 +114,11 @@ private ExprAST ParseIdentifierExpr() Console.WriteLine("Expected ')' or ',' in argument list"); return null; } - + this.scanner.GetNextToken(); } } - + // Eat the ')'. this.scanner.GetNextToken(); @@ -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) { @@ -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(); @@ -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(); @@ -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); } } @@ -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; @@ -253,7 +253,7 @@ private PrototypeAST ParsePrototype() } List argNames = new List(); - while (this.scanner.GetNextToken() == (int)Token.IDENTIFIER) + while (this.scanner.GetNextToken() == (int) Token.IDENTIFIER) { argNames.Add(this.scanner.GetLastIdentifier()); } @@ -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(); } } diff --git a/KaleidoscopeTutorial/Chapter4/KaleidoscopeLLVM/CodeGenParserListener.cs b/KaleidoscopeTutorial/Chapter4/KaleidoscopeLLVM/CodeGenParserListener.cs index 8648340c..d1cd661f 100644 --- a/KaleidoscopeTutorial/Chapter4/KaleidoscopeLLVM/CodeGenParserListener.cs +++ b/KaleidoscopeTutorial/Chapter4/KaleidoscopeLLVM/CodeGenParserListener.cs @@ -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) @@ -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) @@ -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()); } } diff --git a/KaleidoscopeTutorial/Chapter4/KaleidoscopeLLVM/CodeGenVisitor.cs b/KaleidoscopeTutorial/Chapter4/KaleidoscopeLLVM/CodeGenVisitor.cs index 13eeaa07..275b1796 100644 --- a/KaleidoscopeTutorial/Chapter4/KaleidoscopeLLVM/CodeGenVisitor.cs +++ b/KaleidoscopeTutorial/Chapter4/KaleidoscopeLLVM/CodeGenVisitor.cs @@ -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; @@ -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"); @@ -93,7 +93,7 @@ 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) @@ -101,7 +101,7 @@ protected override ExprAST VisitCallExprAST(CallExprAST node) 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) { @@ -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); @@ -145,7 +145,8 @@ 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); } @@ -153,7 +154,7 @@ protected override ExprAST VisitPrototypeAST(PrototypeAST node) { 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; diff --git a/KaleidoscopeTutorial/Chapter4/KaleidoscopeLLVM/Program.cs b/KaleidoscopeTutorial/Chapter4/KaleidoscopeLLVM/Program.cs index 53ba73b8..edfc659c 100644 --- a/KaleidoscopeTutorial/Chapter4/KaleidoscopeLLVM/Program.cs +++ b/KaleidoscopeTutorial/Chapter4/KaleidoscopeLLVM/Program.cs @@ -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) { @@ -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); @@ -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: diff --git a/KaleidoscopeTutorial/Chapter5/KaleidoscopeLLVM/Program.cs b/KaleidoscopeTutorial/Chapter5/KaleidoscopeLLVM/Program.cs index c8badd87..ea156bfd 100644 --- a/KaleidoscopeTutorial/Chapter5/KaleidoscopeLLVM/Program.cs +++ b/KaleidoscopeTutorial/Chapter5/KaleidoscopeLLVM/Program.cs @@ -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); @@ -111,4 +111,4 @@ private static void MainLoop(ILexer lexer, IParser parser) } } } -} \ No newline at end of file +} diff --git a/README.md b/README.md index de7c29c9..6d0e8f86 100644 --- a/README.md +++ b/README.md @@ -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. @@ -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. \ No newline at end of file +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.