예제 #1
0
        private void ExecuteCode()
        {
            var                    globals = new Dictionary <string, GCHandle>();
            LLVMModuleRef          mod;
            LLVMExecutionEngineRef engine = null;

            try {
                SymbolTable.IsReadOnly = true;
                mod = LLVMModuleRef.CreateWithName("main");
                var options = LLVMMCJITCompilerOptions.Create();
                engine = mod.CreateMCJITCompiler(ref options);
                var builder      = mod.Context.CreateBuilder();
                var globalSource = SymbolTable.ItemsSource as ICollection <SymbolEntry>;
                var globalStore  = new Dictionary <string, object>();
                foreach (var k in globalSource)
                {
                    globalStore.Add(k.Name, k.Value);
                }

                foreach (var kv in globalStore)
                {
                    globals.Add(kv.Key, GCHandle.Alloc(kv.Value, GCHandleType.Pinned));
                }

                var fpm = mod.CreateFunctionPassManager();
                fpm.AddPromoteMemoryToRegisterPass();
                fpm.AddInstructionCombiningPass();
                fpm.AddReassociatePass();
                fpm.AddGVNPass();
                fpm.AddCFGSimplificationPass();
                fpm.InitializeFunctionPassManager();
                var symT     = ProcessGlobals(mod, engine, globals);
                var lexicals = new List <LexicalElement>();
                try {
                    using (var ms = new MemoryStream()) {
                        var writer = new StreamWriter(ms);
                        writer.Write(Editor.Document.CurrentSnapshot.GetText(LineTerminator.Newline));
                        writer.Flush();
                        ms.Seek(0L, SeekOrigin.Begin);
                        var reader = new StreamReader(ms);
                        var l      = new LexerStateMachine(reader);
                        l.AdvanceChar();
                        LexicalElement t;
                        while ((t = l.NextToken()) != null)
                        {
                            if (t is LineFeedElement)
                            {
                                continue;
                            }
                            lexicals.Add(t);
                        }
                    }
                } catch (Exception ex) {
                    MessageBox.Show(ex.Message, "词法错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }

                var        exceptions = new List <SyntaxException>();
                SyntaxNode treeRoot;
                try {
                    treeRoot = slr1Driver.Parse(new Queue <LexicalElement>(lexicals),
                                                CommonUtils.Closure(
                                                    new HashSet <Item>()
                    {
                        new Item()
                        {
                            ProductionRule = PascalDefinition.ProductionRules[0], Cursor = 0
                        }
                    },
                                                    generator.ProductionDict), typeof(SNode), null, exceptions);
                    if (exceptions.Count > 0)
                    {
                        StringBuilder sb = new StringBuilder();
                        sb.Append($"语法分析器共检测到{exceptions.Count}个错误\n\n");
                        foreach (var exception in exceptions)
                        {
                            sb.Append(exception.Message);
                            sb.Append('\n');
                        }

                        MessageBox.Show(sb.ToString(), "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                        return;
                    }
                } catch (SyntaxException ex) {
                    StringBuilder sb = new StringBuilder();
                    sb.Append($"语法分析器共检测到{exceptions.Count}个错误,无法恢复\n\n");
                    foreach (var exception in exceptions)
                    {
                        sb.Append(exception.Message);
                        sb.Append('\n');
                    }

                    MessageBox.Show(sb.ToString(), $"语法分析错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }

                var translator = new LLVMTranslator.LLVMTranslator(mod, engine, builder, symT);
                translator.Visit(treeRoot);
                fpm.RunFunctionPassManager(translator.func);
                IrBox.Text = mod.PrintToString();
                PM main = engine.GetPointerToGlobal <PM>(translator.func);
                main();
                foreach (var symbolEntry in globalSource)
                {
                    symbolEntry.Value = (int)globalStore[symbolEntry.Name];
                }
            } catch (Exception e) {
                MessageBox.Show(e.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            } finally {
                SymbolTable.IsReadOnly = false;
                if (engine != null)
                {
                    engine.Dispose();
                }
                foreach (var kv in globals)
                {
                    kv.Value.Free();
                }
            }
        }
예제 #2
0
        public void LLVMTest2()
        {
            LLVM.LinkInMCJIT();
            LLVM.InitializeX86TargetMC();
            LLVM.InitializeX86Target();
            LLVM.InitializeX86TargetInfo();
            LLVM.InitializeX86AsmParser();
            LLVM.InitializeX86AsmPrinter();
            var mod     = LLVMModuleRef.CreateWithName("Test1");
            var options = LLVMMCJITCompilerOptions.Create();

            options.NoFramePointerElim = 1;
            var engine   = mod.CreateMCJITCompiler(ref options);
            var builder  = mod.Context.CreateBuilder();
            var lexicals = new List <LexicalElement>();
            var globals  = new LLVMSymbolTable(null);

            globals.Add("z", mod.AddGlobal(LLVMTypeRef.Int32, "z"));
            object z      = 0;
            var    handle = GCHandle.Alloc(z, GCHandleType.Pinned);

            engine.AddGlobalMapping(globals["z"], handle.AddrOfPinnedObject());
            using (var fs = new FileStream("D:\\Repos\\PascalCompiler\\SyntaxAnalyzerTest\\test_source2.txt", FileMode.Open)) {
                using (var ss = new StreamReader(fs)) {
                    var l = new LexerStateMachine(ss);
                    l.AdvanceChar();
                    LexicalElement t;
                    while ((t = l.NextToken()) != null)
                    {
                        if (t is LineFeedElement)
                        {
                            continue;
                        }
                        lexicals.Add(t);
                    }
                }
            }
            var        history    = new List <ParserConfiguration>();
            var        exceptions = new List <SyntaxException>();
            SyntaxNode treeRoot;
            var        generator = new Generator(PascalDefinition.ProductionRules);
            var        slr1Table = generator.Generate(PascalDefinition.NonTerminalKey.Start);

            slr1Table.AllowedErrorRecoveryKey.Add(PascalDefinition.NonTerminalKey.Statement, () => new StatementNode(new SyntaxNode[0]));
            var slr1Driver = new Slr1Driver(slr1Table);

            treeRoot = slr1Driver.Parse(new Queue <LexicalElement>(lexicals),
                                        CommonUtils.Closure(
                                            new HashSet <Item>()
            {
                new Item()
                {
                    ProductionRule = PascalDefinition.ProductionRules[0], Cursor = 0
                }
            },
                                            generator.ProductionDict), typeof(SNode), history, exceptions);
            var translator =
                new LLVMTranslator.LLVMTranslator(mod, engine, builder, globals);

            translator.Visit(treeRoot);
            if (!mod.TryVerify(LLVMVerifierFailureAction.LLVMPrintMessageAction, out var error))
            {
                Trace.WriteLine(error);
            }
            Trace.WriteLine(mod.PrintToString());
            PM a = engine.GetPointerToGlobal <PM>(translator.func);

            a();
            builder.Dispose();
            engine.Dispose();
            handle.Free();
        }