// (C) 2001 Ximian, Inc (http://www.ximian.com)\r
//\r
\r
-namespace CSC\r
+namespace CIR\r
{\r
using System;\r
using System.Reflection;\r
using System.IO;\r
using CIR;\r
using Generator;\r
- using CSC;\r
\r
/// <summary>\r
/// The compiler driver.\r
/// </summary>\r
public class Driver\r
{\r
+\r
+ enum Target {\r
+ Library, Exe, Module, WinExe\r
+ };\r
+ \r
//\r
// Assemblies references to be linked. Initialized with\r
// mscorlib.dll here.\r
\r
int error_count = 0;\r
\r
- public int parse (Tree context, string input_file)\r
+ string first_source;\r
+\r
+ Target target = Target.Exe;\r
+ \r
+ public int parse (string input_file)\r
{\r
CSharpParser parser;\r
System.IO.Stream input;\r
public void Usage ()\r
{\r
Console.WriteLine (\r
- "compiler [-v] [-t tree] [-o output] [-L path] [-r reference] sources.cs\n" +\r
- "-v Verbose parsing\n"+\r
- "-o Specifies output file\n" +\r
- "-L Specifies path for loading assemblies\n" +\r
- "-r References an assembly\n");\r
+ "compiler [options] source-files\n\n" +\r
+ "-v Verbose parsing\n"+\r
+ "-o Specifies output file\n" +\r
+ "-L Specifies path for loading assemblies\n" +\r
+ "--nostdlib Does not load core libraries\n" +\r
+ "--target Specifies the target (exe, winexe, library, module)\n" +\r
+ "--dumper Specifies a tree dumper\n" +\r
+ "-r References an assembly\n");\r
\r
}\r
\r
string full_path = dir + "/" + assembly;\r
\r
try {\r
+ Console.WriteLine ("Loading: " + assembly);\r
a = Assembly.Load (assembly);\r
} catch (FileNotFoundException f) {\r
error ("// File not found: " + full_path);\r
//\r
// Setup defaults\r
//\r
- references.Add ("mscorlib");\r
link_paths.Add ("file:///C:/WINNT/Microsoft.NET/Framework/v1.0.2914");\r
\r
for (i = 0; i < args.Length; i++){\r
continue;\r
}\r
\r
- if (arg.StartsWith ("-t")){\r
+ if (arg.StartsWith ("--dumper")){\r
generator = lookup_dumper (args [++i]);\r
continue;\r
}\r
continue;\r
}\r
\r
+ if (arg.StartsWith ("--target")){\r
+ string type = args [++i];\r
+\r
+ switch (type){\r
+ case "library":\r
+ target = Target.Library;\r
+ break;\r
+ \r
+ case "exe":\r
+ target = Target.Exe;\r
+ break;\r
+\r
+ case "winexe":\r
+ target = Target.WinExe;\r
+ break;\r
+ \r
+ case "module":\r
+ target = Target.Module;\r
+ break;\r
+ }\r
+ }\r
+ \r
if (arg.StartsWith ("-r")){\r
references.Add (args [++i]);\r
continue;\r
continue;\r
}\r
\r
+ if (arg == "--nostdlib"){\r
+ context.StdLib = false;\r
+ }\r
+\r
Usage ();\r
error_count++;\r
return;\r
}\r
\r
if (!arg.EndsWith (".cs")){\r
+ \r
error ("Do not know how to compile " + arg);\r
errors++;\r
continue;\r
}\r
\r
- errors += parse (context.Tree, arg);\r
+ if (first_source == null)\r
+ first_source = arg;\r
+ \r
+ errors += parse (arg);\r
}\r
+\r
+ if (first_source == null){\r
+ context.Report.Error (2008, "No files to compile were specified");\r
+ return;\r
+ }\r
+ \r
+ //\r
+ // Load Core Library for default compilation\r
+ //\r
+ if (context.StdLib)\r
+ references.Insert (0, "mscorlib");\r
+\r
if (errors > 0){\r
- error ("// Parsing failed");\r
+ error ("Parsing failed");\r
return;\r
} else\r
- notice ("// Parsing successful");\r
+ notice ("Parsing successful");\r
\r
//\r
// Load assemblies required\r
errors += LoadReferences ();\r
\r
if (errors > 0){\r
- error ("// Could not load one or more assemblies");\r
+ error ("Could not load one or more assemblies");\r
return;\r
}\r
\r
// Dumping the parsed tree.\r
//\r
// This code generation interface is only here\r
- // for debugging purposes, it will change as we\r
- // move to the new tree. \r
+ // for debugging the parser. \r
//\r
if (generator != null){\r
if (output_file == null){\r
errors += generator.Dump (context.Tree, output);\r
\r
if (errors > 0){\r
- error ("// Compilation failed");\r
+ error ("Compilation failed");\r
return;\r
} else\r
- notice ("// Compilation successful");\r
+ notice ("Compilation successful");\r
\r
output.Flush ();\r
output.Close ();\r
//\r
// Quick hack\r
//\r
- if (output_file == null)\r
- output_file = "a.exe";\r
+ if (output_file == null){\r
+ int pos = first_source.LastIndexOf (".");\r
+\r
+ output_file = first_source.Substring (0, pos) + ".exe";\r
+ }\r
\r
- context.CodeGen = new CilCodeGen (output_file, output_file);\r
+ context.CodeGen = new CodeGen (output_file, output_file);\r
\r
//\r
// The second pass of the compiler\r
//\r
- context.ResolveInterfaceBases ();\r
- context.ResolveClassBases ();\r
+ context.ResolveTree ();\r
+ context.PopulateTypes ();\r
\r
- context.CodeGen.Save (output_file);\r
- }\r
+ //\r
+ // Before emitting, we need to get the core\r
+ // types emitted from the user defined types\r
+ // or from the system ones.\r
+ //\r
+ context.TypeManager.InitCoreTypes ();\r
\r
- }\r
-}\r
+ //\r
+ // The code generator\r
+ //\r
+ context.EmitCode ();\r
+ \r
+ if (context.Report.Errors > 0){\r
+ error ("Compilation failed");\r
+ return;\r
+ }\r
+ \r
+ context.CloseTypes ();\r
\r
+ PEFileKinds k = PEFileKinds.ConsoleApplication;\r
+ \r
+ if (target == Target.Library || target == Target.Module)\r
+ k = PEFileKinds.Dll;\r
+ else if (target == Target.Exe)\r
+ k = PEFileKinds.ConsoleApplication;\r
+ else if (target == Target.WinExe)\r
+ k = PEFileKinds.WindowApplication;\r
+\r
+ if (target == Target.Exe || target == Target.WinExe){\r
+ MethodInfo ep = context.EntryPoint;\r
+\r
+ if (ep == null){\r
+ context.Report.Error (5001, "Program " + output_file +\r
+ " does not have an entry point defined");\r
+ return;\r
+ }\r
+ \r
+ context.CodeGen.AssemblyBuilder.SetEntryPoint (ep, k);\r
+ }\r
+ \r
+ context.CodeGen.Save (context.Report, output_file);\r
+\r
+ if (context.Report.Errors > 0){\r
+ error ("Compilation failed");\r
+ return;\r
+ }\r
\r
+ notice ("Success");\r
+ }\r
\r
+ }\r
+}\r