示例#1
0
        public (Scope root, TypeChecker tc) Compile(CompilerOptionsBuild options)
        {
            CompilerOptionsBuild._i.lib_path.Add(Path.GetFullPath(Program.RelDir("..\\lib")));
            CompilerOptionsBuild._i.include_dirs.Add(Path.GetFullPath(Program.RelDir("..\\include")));

            Platform platform;

            if (System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows))
            {
                platform = Platform.WindowsX64;
                CompilerOptionsBuild._i.libs.Add("kernel32.lib");
            }
            else if (System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Linux))
            {
                platform = Platform.LinuxX64;
            }
            else
            {
                throw new Exception("Platform not supported");
            }

            var filename         = options.inputFilename;
            var buildExecuteable = options.buildExecuteable;

            var timer = new Stopwatch();

            Program.CompilerMessage("parsing...", CompilerMessageType.Info);
            timer.Start();

            Queue <(string, Token)> toImport = new Queue <(string, Token)>();
            HashSet <string>        imported = new HashSet <string>();

            Stack <Token[]> toCompile = new Stack <Token[]>();

            var ffn = filename;

            if (!Path.IsPathRooted(filename))
            {
                ffn = Path.GetFullPath(filename);
            }
            toImport.Enqueue((ffn, Token.Undefined));
            imported.Add(ffn);

            var scope     = AST.MakeRootScope();
            var rootToken = Token.UndefinedRoot(ffn);
            var root      = new AST.ProgramRoot(rootToken, scope);

            while (toImport.Count > 0)
            {
                var(fn, import_token) = toImport.Dequeue();
                string text;
                try
                {
                    if (GetFileText != null)
                    {
                        text = GetFileText(fn);
                    }
                    else
                    {
                        text = File.ReadAllText(fn);
                    }
                }
                catch (Exception)
                {
                    throw new CompilerError($"Could not read import file", import_token);
                }

                if (string.IsNullOrWhiteSpace(text))
                {
                    throw new CompilerError($"Empty import file!", import_token);
                }

                text = Preprocessor.Preprocess(text, platform);
                var tokens = Tokenize(text, fn);

                AST.ParseState ps = new ParseState();
                ps.pos    = 0;
                ps.tokens = tokens;

                List <(string, Token)> imports = null;

                imports = AST.ParseImports(ref ps, scope);

                toCompile.Push(tokens);
                foreach (var(import, token) in imports)
                {
                    var dir        = Path.GetDirectoryName(fn);
                    var importPath = ResolveImportPath(import, dir, options.include_dirs);
                    if (!imported.Contains(importPath))
                    {
                        toImport.Enqueue((importPath, token));
                        imported.Add(importPath);
                    }
                }
            }
            foreach (var tokens in toCompile)
            {
                AST.ParseState ps = new ParseState();
                ps.pos    = 0;
                ps.tokens = tokens;
                // Log($"parsing {ps.tokens[0].filename}...");
                var fileRoot = AST.ParseFileRoot(ref ps, scope) as FileRoot;
                root.files.Add(fileRoot);
            }

            var entry = CompilerOptionsBuild._i.entry;

            if (entry != null)
            {
                SetEntryPoint(entry);
            }

            timer.Stop();
            Program.CompilerMessage($"{timer.ElapsedMilliseconds}ms", CompilerMessageType.Timing);
            Program.CompilerMessage("type checking...", CompilerMessageType.Info);
            timer.Reset();
            timer.Start();


            var tc = new TypeChecker();

            tc.CheckTypes(root);

            timer.Stop();
            Program.CompilerMessage($"{timer.ElapsedMilliseconds}ms", CompilerMessageType.Timing);
            Program.CompilerMessage("de-sugar...", CompilerMessageType.Info);
            timer.Reset();
            timer.Start();

            ParseTreeTransformations.Init(root);
            ParseTreeTransformations.Desugar(tc.embeddings, tc);
            ParseTreeTransformations.Desugar(tc.namespaceAccesses, tc);

            timer.Stop();
            Program.CompilerMessage($"{timer.ElapsedMilliseconds}ms", CompilerMessageType.Timing);

            Program.CompilerMessage("backend...", CompilerMessageType.Info);
            timer.Reset();
            timer.Start();
            var backend = new Backend(tc, platform);

            if (buildExecuteable && entry == null)
            {
                throw new CompilerError("No entry point defined", root.token);
            }
            backend.Visit(root, entry);
            timer.Stop();
            Program.CompilerMessage($"{timer.ElapsedMilliseconds}ms", CompilerMessageType.Timing);
            if (buildExecuteable)
            {
                backend.AOT();
            }
            return(scope, tc);
        }
示例#2
0
        int GetDICompileUnit(AST.ProgramRoot root)
        {
            if (!debugInfoScopeLookup.TryGetValue(root, out int compileUnitIdx))
            {
                string emptyArray    = "!{}";
                var    emptyArrayIdx = AddDebugInfoNode(emptyArray);

                // HACK: TODO(pragma): remove
                var placeholder = System.Guid.NewGuid().ToString();
                var debugGlobalVariableArrayIdx = AddDebugInfoNode(placeholder);
                debugGlobalVariableArrayPlaceholder = placeholder;

                string producer   = "\"pragma version 0.2 (build 8)\"";
                string nodeString = $"distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !{GetDIFile(root)}, producer: {producer}, isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !{emptyArrayIdx}, enums: !{emptyArrayIdx}, globals: !{debugGlobalVariableArrayIdx}, imports: !{emptyArrayIdx})";
                compileUnitIdx = AddDebugInfoNode(nodeString);
                debugInfoScopeLookup.Add(root, compileUnitIdx);
                debugInfoCompileUnitIdx = compileUnitIdx;

                if (platform == Platform.WindowsX64)
                {
                    string debugInfoVersion    = "!{i32 2, !\"Debug Info Version\", i32 3}";
                    var    debugInfoVersionIdx = AddDebugInfoNode(debugInfoVersion);
                    debugInfoModuleFlags.Add(debugInfoVersionIdx);

                    string codeViewVersion    = "!{i32 2, !\"CodeView\", i32 1}";
                    var    codeViewVersionIdx = AddDebugInfoNode(codeViewVersion);
                    debugInfoModuleFlags.Add(codeViewVersionIdx);

                    string wcharSize    = "!{i32 1, !\"wchar_size\", i32 2}";
                    var    wcharSizeIdx = AddDebugInfoNode(wcharSize);
                    debugInfoModuleFlags.Add(wcharSizeIdx);

                    string picLevel    = "!{i32 7, !\"PIC Level\", i32 2}";
                    var    picLevelIdx = AddDebugInfoNode(picLevel);
                    debugInfoModuleFlags.Add(picLevelIdx);
                }
                else if (platform == Platform.LinuxX64)
                {
                    string debugInfoVersion    = "!{i32 2, !\"Debug Info Version\", i32 3}";
                    var    debugInfoVersionIdx = AddDebugInfoNode(debugInfoVersion);
                    debugInfoModuleFlags.Add(debugInfoVersionIdx);

                    string codeViewVersion    = "!{i32 7, !\"Dwarf Version\", i32 4}";
                    var    codeViewVersionIdx = AddDebugInfoNode(codeViewVersion);
                    debugInfoModuleFlags.Add(codeViewVersionIdx);

                    string wcharSize    = "!{i32 1, !\"wchar_size\", i32 2}";
                    var    wcharSizeIdx = AddDebugInfoNode(wcharSize);
                    debugInfoModuleFlags.Add(wcharSizeIdx);
                }


                // TODO(pragma): versions??
                string ident = $"!{{!{producer}}}";
                debugInfoIdentFlag = AddDebugInfoNode(ident);


                debugRootNode = root;
            }
            return(compileUnitIdx);
        }
 public static void Init(AST.ProgramRoot root)
 {
     fixupParents(null, root);
 }