[Mono-list] Patch: integrating MonoBASIC compiler patches

Miguel de Icaza miguel@ximian.com
11 Oct 2001 18:13:18 -0400


These are the first set of patches from Rafael that I got into CVS
today.  These add support for his MonoBASIC parser.

miguel.

Index: mcs/cs-parser.jay
===================================================================
RCS file: /cvs/public/mcs/mcs/cs-parser.jay,v
retrieving revision 1.63
diff -u -r1.63 cs-parser.jay
--- mcs/cs-parser.jay	2001/10/11 16:46:46	1.63
+++ mcs/cs-parser.jay	2001/10/11 18:19:12
@@ -76,7 +76,7 @@
 		//   Used to record all types defined
 		// </summary>
 		Tree tree;
-		RootContext rc;
+		// RootContext rc; Now on GenericParser
 
 %}
 
@@ -3164,21 +3164,14 @@
 	}
 }		   
 
-public CSharpParser(RootContext rc, string name, System.IO.Stream input) 
+public override int parse ()
 {
 	current_namespace = new Namespace (null, "");
-	this.rc   = rc;
 	this.tree = rc.Tree;
-	this.name = name;
-	this.input = input;
 	current_container = tree.Types;
 	current_container.Namespace = current_namespace;
 
 	lexer = new Tokenizer (input, name);
-}
-
-public override int parse ()
-{
 	StringBuilder value = new StringBuilder ();
 
 	global_errors = 0;
Index: mcs/cs-tokenizer.cs
===================================================================
RCS file: /cvs/public/mcs/mcs/cs-tokenizer.cs,v
retrieving revision 1.14
diff -u -r1.14 cs-tokenizer.cs
--- mcs/cs-tokenizer.cs	2001/10/11 18:12:12	1.14
+++ mcs/cs-tokenizer.cs	2001/10/11 18:19:12
@@ -50,7 +50,7 @@
 
 	public class Tokenizer : yyParser.yyInput
 	{
-		StreamReader reader;
+		TextReader reader;
 		public string ref_name;
 		public int ref_line = 1;
 		public int line = 1;
@@ -242,10 +242,10 @@
 			}
 		}
 		
-		public Tokenizer (System.IO.Stream input, string fname)
+		public Tokenizer (System.IO.TextReader input, string fname)
 		{
 			this.ref_name = fname;
-			reader = new System.IO.StreamReader (input);
+			reader = input;
 			putback_char = -1;
 
 			Location.Push (fname);
Index: mcs/driver.cs
===================================================================
RCS file: /cvs/public/mcs/mcs/driver.cs,v
retrieving revision 1.29
diff -u -r1.29 driver.cs
--- mcs/driver.cs	2001/10/11 18:02:55	1.29
+++ mcs/driver.cs	2001/10/11 18:19:12
@@ -17,6 +17,7 @@
 	using System.IO;
 	using CIR;
 	using Generator;
+	using Mono.Languages;
 
 	/// <summary>
 	///    The compiler driver.
@@ -49,23 +50,22 @@
 
 		bool parse_only = false;
 		
-		public int parse (string input_file)
+		public int parse (string inputFileName)
 		{
-			CSharpParser parser;
-			System.IO.Stream input;
+			GenericParser parser;
 			int errors;
 			
-			try {
-				input = System.IO.File.OpenRead (input_file);
-			} catch {
-				Report.Error (2001, "Source file '" + input_file + "' could not be opened");
+			// find a suitable parser
+			parser = GenericParser.GetSpecificParserFor(inputFileName);
+			if (parser == null) 			
+			{
+				Report.Error (2001, "Source file '" + inputFileName + "' could not be parsed");
 				return 1;
 			}
 
-			parser = new CSharpParser (context, input_file, input);
 			parser.yacc_verbose = yacc_verbose;
 			try {
-				errors = parser.parse ();
+				errors = parser.ParseFile(inputFileName, context);
 			} catch (Exception ex) {
 				Console.WriteLine (ex);
 				Console.WriteLine ("Compilation aborted");
@@ -301,13 +301,6 @@
 					Usage ();
 					error_count++;
 					return;
-				}
-				
-				if (!arg.EndsWith (".cs")){
-						
-					error ("Do not know how to compile " + arg);
-					errors++;
-					continue;
 				}
 
 				if (first_source == null)
Index: mcs/genericparser.cs
===================================================================
RCS file: /cvs/public/mcs/mcs/genericparser.cs,v
retrieving revision 1.3
diff -u -r1.3 genericparser.cs
--- mcs/genericparser.cs	2001/10/02 00:00:09	1.3
+++ mcs/genericparser.cs	2001/10/11 18:19:12
@@ -7,35 +7,147 @@
 //
 // Copyright (C) 2001 A Rafael D Teixeira
 //
-using System;
-using System.Text;
 
+#define TRACE
+
 namespace Mono.Languages
 {
+	using System;
+	using System.Reflection;
+	using System.Diagnostics;
 	using System.Collections;
+	using System.IO;
+	using CIR; // FIXME: renaming to Mono.Languages still pending
+
 
 	/// <summary>
 	/// Base class to support multiple Jay generated parsers
 	/// </summary>
 	public abstract class GenericParser
 	{
+		// ---------------------------------------------------
+		// Class state
+
+		// Count of errors found while parsing
 		static protected int global_errors;
 
+		// Indicates if parsing should be verbose
+		static private Hashtable mapOfParsers;
+
+		// ---------------------------------------------------
+		// Instance state
+
+		// Indicates if parsing should be verbose
+		protected bool yacc_verbose_flag = false;
+
 		// Name of the file we are parsing
-		public string name;
+		protected string name;
 
 		// Input stream to parse from.
-		public System.IO.Stream input;
+		protected System.IO.TextReader input;
+
+		// Context to use
+		protected RootContext rc;
+
+		// ---------------------------------------------------
+		// What the descendants MUST reimplement
 
+		/// <summary>
+		/// Parses the current "input"
+		/// </summary>
 		public abstract int parse ();
 
-		public virtual string[] extensions()
+		/// <summary>
+		/// Lists the extensions this parser can work
+		/// </summary>
+		public virtual string[] GetExtensions()
 		{
 			string [] list = { ".cs" };
 			return list;
 		}
 
+		// ---------------------------------------------------
+		// What the descendants DONT HAVE to reimplement
+
+		/// <summary>
+		/// Initializes this parser from a file and parses it
+		/// </summary>
+		/// <param name="fileName">Name of the file to be parsed</param>
+		/// <param name="context">Context to output the parsed tree</param>
+		public int ParseFile(string fileName, RootContext context)
+		{
+			// file exceptions must be caught by caller
+
+			global_errors = 0;
+			name = fileName;
+			// TODO: Encoding switching as needed
+			//       We are here forcing StreamReader to assume current system codepage,
+			//		 because normally it defaults to UTF-8
+			input = new StreamReader(fileName, System.Text.Encoding.Default); 
+			rc = context;
+			return parse();
+		}
+
+		/// <summary>
+		/// Initializes this parser from a string and parses it
+		/// </summary>
+		/// <param name="source">String to be parsed</param>
+		/// <param name="sourceName">Name of the source to be parsed (just for error reporting)</param>
+		/// <param name="context">Context to output the parsed tree</param>
+		public int ParseString(string source, string sourceName, RootContext context)
+		{
+			global_errors = 0;
+			name = sourceName;
+			input = new StringReader(source);
+			rc = context;
+			return parse();
+		}
+
+		// ---------------------------------------------------
+		// Class methods
+
+		static private void MapParsers()
+		{    		
+			mapOfParsers = new Hashtable();
+
+			Assembly thisAssembly = Assembly.GetExecutingAssembly();
+			foreach(Type type in thisAssembly.GetTypes())
+			{
+				if (type.BaseType != null)
+					if (type.BaseType.FullName == "Mono.Languages.GenericParser")
+					{
+						GenericParser parser = (GenericParser)Activator.CreateInstance(type);
+						foreach(string fileExtension in parser.GetExtensions())
+						{												
+							string theFileExtension = fileExtension.ToLower();
+							if (mapOfParsers.Contains(theFileExtension))
+								Trace.WriteLine("[TRACE] " + type.FullName + " can't try to parse '" + theFileExtension + "' files too");
+							else
+							{
+								mapOfParsers.Add(theFileExtension, parser);
+								Trace.WriteLine("[TRACE] " + type.FullName + " parses '" + theFileExtension + "' files");
+							}
+						}
+					}
+			}
+		}
+
 		/// <summary>
+		/// Find the descendant parser that knows how to parse the specified file
+		/// based on the files extension
+		/// </summary>
+		/// <param name="fileName">Name of the file to be parsed</param>
+		public static GenericParser GetSpecificParserFor(string fileName)
+		{
+			if (mapOfParsers == null)
+				MapParsers();
+			
+			string fileExtension = fileName.Substring(fileName.LastIndexOf(".")).ToLower();
+
+			return (GenericParser)mapOfParsers[fileExtension];
+		}
+
+		/// <summary>
 		/// Emits error messages and increments a global count of them
 		/// </summary>
 		/// <param name="code"></param>
@@ -52,19 +164,21 @@
 		// method everywhere you need it ?
 		static public void error (int code, CIR.Location l, string text)
 		{
-			Console.WriteLine (l.Name + "(" + l.Row + "," + 
+			Console.WriteLine (l.Name + "(" + l.Row + /* "," + l.Col + */
 					   "): Error CS" + code + ": " + text);
 			global_errors++;
 		}
 		
+		// ---------------------------------------------------
+		// Constructors
+
 		public GenericParser()
 		{
-			//
-			// DO NOTHING: Derived classes should do their iniatilization here duties
-			//
+			// DO NOTHING
 		}
 
-		protected bool yacc_verbose_flag = false;
+		// ---------------------------------------------------
+		// Properties
 
 		public bool yacc_verbose
 		{
Index: mcs/makefile
===================================================================
RCS file: /cvs/public/mcs/mcs/makefile,v
retrieving revision 1.25
diff -u -r1.25 makefile
--- mcs/makefile	2001/10/11 18:12:12	1.25
+++ mcs/makefile	2001/10/11 18:19:15
@@ -4,7 +4,7 @@
 
 VERSION=0.13
 
-COMMON_SOURCES = cs-parser.cs cs-tokenizer.cs tree.cs  
+COMMON_SOURCES = cs-parser.cs cs-tokenizer.cs tree.cs location.cs
 
 COMPILER_SOURCES = \
 	assign.cs			\
@@ -37,6 +37,7 @@
 all: cs-parser.cs
 	$(CSC) $(CSCFLAGS) /target:exe /r:System.dll /out:mcs.exe $(COMPILER_SOURCES)
 	-rm compiler.exe
+	-rm mcs.pdb
 
 windows: all
 
@@ -86,4 +87,13 @@
 	done
 
 clean:
-	rm -f mcs.exe cs-parser.cs y.output compiler.pdb *~ .*~
+	rm -f mcs.exe cs-parser.cs y.output mcs.pdb *~ .*~ MonoBASIC.Parser.cs mcs.log
+
+MBAS_SOURCES = MonoBASIC.Parser.cs MonoBASIC.Tokenizer.cs
+
+mbas: cs-parser.cs MonoBASIC.Parser.cs
+	$(CSC) $(CSCFLAGS) /target:exe /r:System.dll /out:mcs.exe $(COMPILER_SOURCES) $(MBAS_SOURCES)
+
+MonoBASIC.Parser.cs: MonoBASIC.Parser.jay
+	../jay/jay -ctv < ../jay/skeleton.cs MonoBASIC.Parser.jay > MonoBASIC.Parser.cs
+