Ejemplo n.º 1
0
        static void Main(string[] args)
        {
            try
            {
                var assemblyPath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
                var commandLine  = new CommandLineParser();
                commandLine.Parse(args);

                if (commandLine.Has("help"))
                {
                    Console.WriteLine("编译器可使用下列参数:");
                    Console.Write("-S");
                    Console.WriteLine("\t[编译选项][必选],输入的源程序路径。");
                    Console.WriteLine();

                    Console.Write("-RUN");
                    Console.WriteLine("\t[运行选项][可选],使用该选项后,源程序将不会被编译(忽略编译参数),直接解析运行源程序。");
                    Console.WriteLine();

                    Console.Write("-ARCH");
                    Console.WriteLine("\t[编译选项][可选][默认值:x86],选择目标运行平台的机器架构,可用架构系统:");
                    {
                        var files = Directory.GetFiles(assemblyPath, "*.Loader");
                        var archs = files.Select((s) =>
                        {
                            var temp = Path.GetFileNameWithoutExtension(s).Split('.');
                            if (temp.Length == 3)
                            {
                                return(temp[2]);
                            }
                            return(string.Empty);
                        }).Distinct();
                        foreach (var a in archs)
                        {
                            Console.WriteLine($"\t\t{a}");
                        }
                    }
                    Console.WriteLine();

                    Console.Write("-OS");
                    Console.WriteLine("\t[编译选项][可选][默认值:windows],选择目标运行平台的操作系统,可用系统名称:");
                    {
                        var files = Directory.GetFiles(assemblyPath, "*.Loader");
                        var archs = files.Select((s) =>
                        {
                            var temp = Path.GetFileNameWithoutExtension(s).Split('.');
                            if (temp.Length == 3)
                            {
                                return(temp[1]);
                            }
                            return(string.Empty);
                        }).Distinct();
                        foreach (var a in archs)
                        {
                            Console.WriteLine($"\t\t{a}");
                        }
                    }
                    Console.WriteLine();

                    Console.Write("-I");
                    Console.WriteLine("\t[链接选项][可选][默认值:根据选择的OS和ARCH自动选择],选择函数导入表文件,可用名称:");
                    {
                        var files = Directory.GetFiles(assemblyPath, "*.def");
                        var archs = files.Select((s) => Path.GetFileName(s)).Distinct();
                        foreach (var a in archs)
                        {
                            Console.WriteLine($"\t\t{a}");
                        }
                    }
                    Console.WriteLine();

                    Console.Write("-T");
                    Console.WriteLine("\t[链接选项][可选][默认值:EXE],选择输出文件类型,可用类型:");
                    {
                        Console.WriteLine("\t\tASM\t字节码汇编文件。");
                        Console.WriteLine("\t\tBIN\t字节码文件。");
                        Console.WriteLine("\t\tEXE\t可执行文件。");
                    }
                    Console.WriteLine();

                    Console.Write("-O");
                    Console.WriteLine("\t[链接选项][可选][默认值:output],选择输出文件路径。");
                    Console.WriteLine();


                    Console.Write("-help");
                    Console.WriteLine("\t[帮助选项][可选],显示本页信息。");
                    Console.WriteLine();
                }
                else if (commandLine.Has("S"))
                {
                    var source = commandLine.GetValue("S", "");
                    if (!Path.IsPathRooted(source))
                    {
                        source = Path.GetFullPath(source);
                    }

                    Lexer         lexer  = new Lexer(new SourceInputStream(source));
                    GrammarParser parser = new GrammarParser();
                    var           ast    = parser.ParseProgram(lexer);

                    if (commandLine.Has("RUN"))
                    {
                        Console.Clear();
                        DemoActuator vm    = new DemoActuator();
                        var          vargs = new ArrayValue(args.Length, 1);
                        for (int i = 0; i < args.Length; ++i)//命令行参数
                        {
                            vargs.SetValue(i, 0, new StringValue(args[i]));
                        }
                        vm.GVariableTable["命令行参数"] = vargs;
                        ast.Execute(vm);
                    }
                    else
                    {
                        Compiler compiler   = new Compiler();
                        var      arch       = commandLine.GetValue("ARCH", "x86");
                        var      os         = commandLine.GetValue("OS", "windows");
                        var      importFile = commandLine.GetValue("I", $"import.{arch}.{os}.def");
                        var      type       = commandLine.GetValue("T", "EXE");
                        var      output     = commandLine.GetValue("O", "output");

                        if (!Path.IsPathRooted(importFile))
                        {
                            importFile = Path.Combine(assemblyPath, importFile);
                        }

                        if (!Path.IsPathRooted(output))
                        {
                            output = Path.Combine(Path.GetDirectoryName(source), output);
                        }

                        compiler.LoadImportDefine(importFile);
                        ast.Compile(compiler);

                        if (string.Compare(type, "ASM") == 0)
                        {
                            if (!Path.HasExtension(output))
                            {
                                output += ".asm";
                            }
                            compiler.LinkProgram(output, Compiler.OutputType.ASM, string.Empty);
                        }
                        else if (string.Compare(type, "BIN", true) == 0)
                        {
                            if (!Path.HasExtension(output))
                            {
                                output += ".bin";
                            }
                            compiler.LinkProgram(output, Compiler.OutputType.BIN, string.Empty);
                        }
                        else
                        {
                            if (!Path.HasExtension(output))
                            {
                                if (os == "windows")
                                {
                                    output += ".exe";
                                }
                                else if (os == "linux")
                                {
                                    output += ".elf";
                                }
                            }
                            string loaderPath = Path.Combine(assemblyPath, $"link.{os}.{arch}.Loader");
                            compiler.LinkProgram(output, Compiler.OutputType.EXE, loaderPath);
                        }
                    }
                }
                else
                {
                    throw new ArgumentNullException("S", "必需输入源程序路径.");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }