示例#1
0
        static Microsoft.CodeAnalysis.SyntaxTree GetLibraryModuleSyntaxTree(string filename)
        {
            if (Path.GetExtension(filename) == ".mylang")
            {
                if (MakeSyntaxAnalysis(filename, out Node syntaxTree))
                {
                    //initialize visitor
                    RoslynTreeBuilderVisitor visitor = new RoslynTreeBuilderVisitor(Path.GetFileNameWithoutExtension(filename));

                    //run visitor
                    syntaxTree.Visit(visitor);

                    return(visitor.UnitNode.SyntaxTree);
                }
                else
                {
                    throw new Exception($"Error in standard library: {Path.GetFileNameWithoutExtension(filename)}");
                }
            }
            else if (Path.GetExtension(filename) == ".cs")
            {
                try
                {
                    return(CSharpSyntaxTree.ParseText(File.ReadAllText(filename)));
                }
                catch
                {
                    throw new Exception($"Error in standard library: {Path.GetFileNameWithoutExtension(filename)}");
                }
            }
            else
            {
                throw new Exception($"Unknow item in standard library: {Path.GetFileNameWithoutExtension(filename)}");
            }
        }
示例#2
0
        /// <summary>
        /// Compile the program which is setted by syntax tree
        /// </summary>
        /// <param name="syntaxTree">Syntax tree</param>
        static void Compile(Node syntaxTree, string outputFileName)
        {
            //initialize visitor
            RoslynTreeBuilderVisitor visitor = new RoslynTreeBuilderVisitor();

            //run visitor
            syntaxTree.Visit(visitor);

            //get unit which prepared for compilation
            var programUnit = visitor.UnitNode;

            //get all location annotations and build location map
            var locationAnnotations = visitor.LocationAnnotations;
            var locationMap         = GetLocationMap(programUnit, locationAnnotations);

            //get syntax trees of standard library
            var arraySyntaxTree = CSharpSyntaxTree.ParseText(File.ReadAllText("../../../MyCompilerLibrary/Array.cs"));

            var syntaxTrees = new List <Microsoft.CodeAnalysis.SyntaxTree> {
                programUnit.SyntaxTree
            };

            foreach (var file in Directory.GetFiles("../../../MyCompilerLibrary/"))
            {
                syntaxTrees.Add(GetLibraryModuleSyntaxTree(file));
            }

            CSharpCompilation compilation = CSharpCompilation.Create(
                "assemblyName",
                syntaxTrees,
                new[] {
                MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
                MetadataReference.CreateFromFile(Assembly.Load("System.Runtime").Location),
                MetadataReference.CreateFromFile(Assembly.Load("System.Console").Location),
                MetadataReference.CreateFromFile(Assembly.Load("System.Linq").Location),
                MetadataReference.CreateFromFile(typeof(System.Diagnostics.Stopwatch).Assembly.Location),
            },
                new CSharpCompilationOptions(
                    outputKind: OutputKind.ConsoleApplication,   //set application type as console app
                    optimizationLevel: OptimizationLevel.Release //set optimization level for Release mode
                    )
                );

            string configPath = Path.GetDirectoryName(outputFileName) + "/" + Path.GetFileNameWithoutExtension(outputFileName) + ".runtimeconfig.json";

            GenerateRuntimeConfig(configPath.TrimStart('/')); //generate runtime config

            //generate program to file
            using var exeStream = new FileStream(outputFileName, FileMode.Create);
            var emitResult = compilation.Emit(exeStream); //compile

            //if we have warnings, print them
            foreach (var error in emitResult.Diagnostics.Where(diagnostic => diagnostic.WarningLevel > 0 && diagnostic.WarningLevel < 4))
            {
                Console.WriteLine(errorFormatter.GetErrorString(error, locationMap));
            }

            if (!emitResult.Success)
            {
                //if we have errors, print them
                foreach (var error in emitResult.Diagnostics.Where(diagnostic => diagnostic.WarningLevel == 0))
                {
                    Console.WriteLine(errorFormatter.GetErrorString(error, locationMap));
                }
            }

            //print C# source code which matches to builded Roslyn's syntax tree
            //Console.WriteLine("========== SOURCE CODE ==========");
            //Console.WriteLine(programUnit.NormalizeWhitespace().ToFullString());
        }