// // location.cs: Keeps track of the location of source code entity // // Author: // Miguel de Icaza // // (C) 2001 Ximian, Inc. // using System; using System.IO; using System.Collections; using System.Diagnostics.SymbolStore; namespace Mono.MonoBASIC { /// /// Keeps track of the location in the program /// /// /// /// This uses a compact representation and a couple of auxiliary /// structures to keep track of tokens to (file,line) mappings. /// /// We could probably also keep track of columns by storing those /// in 8 bits (and say, map anything after char 255 to be `255+'). /// public struct Location { public int token; static Hashtable map; static Hashtable sym_docs; static ArrayList list; static int global_count; static int module_base; public readonly static Location Null; static Location () { map = new Hashtable (); list = new ArrayList (); sym_docs = new Hashtable (); global_count = 0; module_base = 0; Null.token = -1; } static public void Push (string name) { map.Remove (global_count); map.Add (global_count, name); list.Add (global_count); module_base = global_count; } public Location (int row, int col) { if (row < 0 || col < 0) token = -1; else { if (col > 255) col = 255; token = module_base + (row << 8) + col; if (global_count < token) global_count = token; } } public override string ToString () { return Name + ": (" + Row + ")"; } /// /// Whether the Location is Null /// static public bool IsNull (Location l) { return l.token == -1; } public string Name { get { int best = 0; if (token < 0) return "Internal"; foreach (int b in list){ if (token > b) best = b; } return (string) map [best]; } } public int Row { get { int best = 0; if (token < 0) return 1; foreach (int b in list){ if (token > b) best = b; } return (token - best) >> 8; } } public int Col { get { int best = 0; if (token < 0) return 1; foreach (int b in list){ if (token > b) best = b; } return (token - best) & 0xFF; } } // The ISymbolDocumentWriter interface is used by the symbol writer to // describe a single source file - for each source file there's exactly // one corresponding ISymbolDocumentWriter instance. // // This class has an internal hash table mapping source document names // to such ISymbolDocumentWriter instances - so there's exactly one // instance per document. // // This property returns the ISymbolDocumentWriter instance which belongs // to the location's source file. // // If we don't have a symbol writer, this property is always null. public ISymbolDocumentWriter SymbolDocument { get { ISymbolWriter sw = CodeGen.SymbolWriter; ISymbolDocumentWriter doc; if (token < 0) return null; // If we don't have a symbol writer, return null. if (sw == null) return null; string path = Path.GetFullPath (Name); if (sym_docs.Contains (path)) // If we already created an ISymbolDocumentWriter // instance for this document, return it. doc = (ISymbolDocumentWriter) sym_docs [path]; else { // Create a new ISymbolDocumentWriter instance and // store it in the hash table. doc = sw.DefineDocument (path, SymLanguageType.Basic, SymLanguageVendor.Microsoft, SymDocumentType.Text); sym_docs.Add (path, doc); } return doc; } } } }