Пример #1
0
        private CallerInformation GetCallInfo(CalcLocation location)
        {
            CallerInformation info;

            _callerInformation.TryGetValue(location, out info);
            return(info);
        }
Пример #2
0
        public CallerInformation CheckValidCall(CalcLocation location)
        {
            CallerInformation info = GetCallInfo(location);

            if (location.IsRam || info != null)
            {
                return(info);
            }

            for (byte page = 0; page < 0x20; page++)
            {
                if (page == location.Page)
                {
                    continue;
                }

                location = new CalcLocation(location.Address, page, false);
                info     = GetCallInfo(location);
                if (info != null)
                {
                    return(info);
                }
            }

            return(null);
        }
Пример #3
0
        public DocumentLocation GetFileLocation(int page, int address, bool isRam)
        {
            CalcLocation     value = new CalcLocation((ushort)address, (byte)page, isRam);
            DocumentLocation key;

            _calcToFile.TryGetValue(value, out key);
            return(key);
        }
Пример #4
0
        /// <summary>
        /// Maps a filename and line number to a page and address greater than the GetCalcLocation mapping
        /// </summary>
        /// <param name="fileName">The absolute path of the file</param>
        /// <param name="lineNumber">The 1-indexed line number</param>
        /// <returns>The absolute location on the calculator the file and line number map to. If
        /// it does not map absolutely, it returns the next closest location. Returns null if
        /// the file never maps to a location on calc</returns>
        public CalcLocation GetNextNearestCalcLocation(FilePath fileName, int lineNumber)
        {
            var initialListing = _fileToCalc.Where(s => s.Key.FileName == fileName);
            // we shouldn't ever call this when we are adding more, but just to be sure,
            // we'll avoid multiple enumeration
            var listInFile      = initialListing.ToList();
            var smallerListings = listInFile.Where(s => s.Key.LineNumber < lineNumber).ToList();
            var largerListings  = listInFile.Where(s => s.Key.LineNumber >= lineNumber).ToList();

            if (largerListings.Any())
            {
                int min = largerListings.Min(s => s.Key.LineNumber);
                return(largerListings.Single(s => s.Key.LineNumber == min).Value);
            }

            if (!smallerListings.Any())
            {
                // no listing in this file
                return(null);
            }

            int          max             = smallerListings.Max(s => s.Key.LineNumber);
            CalcLocation smallerLocation = smallerListings.Single(s => s.Key.LineNumber == max).Value;
            ushort       address         = smallerLocation.Address;

            do
            {
                address++;
                if ((address % 0x4000) == 0)
                {
                    // crossing page boundaries means we have no clue where its going
                    return(null);
                }
            } while (GetFileLocation(smallerLocation.Page, address, smallerLocation.IsRam) == null);
            return(new CalcLocation(address, smallerLocation.Page, smallerLocation.IsRam));
        }
Пример #5
0
        public void ParseListFile(string listFileContents)
        {
            var               calcToFile         = new Dictionary <CalcLocation, DocumentLocation>(700000);
            var               fileToCalc         = new Dictionary <DocumentLocation, CalcLocation>(700000);
            var               callerInfo         = new Dictionary <CalcLocation, CallerInformation>();
            FcreateFile       currentFcreateFile = null;
            FilePath          currentFile        = new FilePath(string.Empty);
            var               lines          = listFileContents.Split('\n');
            var               fcreateForFile = new Dictionary <FilePath, FcreateFile>();
            CallerInformation callInfoToAdd  = null;

            for (int i = 0; i < lines.Length; i++)
            {
                var line = lines[i];
                if (string.IsNullOrWhiteSpace(line))
                {
                    continue;
                }

                Match fileMatch = FileRegex.Match(line);
                if (fileMatch.Success)
                {
                    string file = fileMatch.Groups["file"].Value.Trim();
                    if (file == "fcreate")
                    {
                        if (!fcreateForFile.TryGetValue(currentFile, out currentFcreateFile))
                        {
                            currentFcreateFile          = new FcreateFile();
                            fcreateForFile[currentFile] = currentFcreateFile;
                        }
                        currentFile = new FilePath(currentFile + ".fcreate");
                    }
                    else
                    {
                        currentFile        = new FilePath(file);
                        currentFcreateFile = null;
                    }
                }
                else
                {
                    Match listingMatch = ListingRegex.Match(line);
                    if (!listingMatch.Success)
                    {
                        continue;
                    }

                    string stringLineNumber = listingMatch.Groups["lineNum"].Value.Trim();
                    int    lineNumber       = int.Parse(stringLineNumber);
                    ushort address          = ushort.Parse(listingMatch.Groups["addr"].Value, NumberStyles.HexNumber);
                    byte   page             = byte.Parse(listingMatch.Groups["page"].Value, NumberStyles.HexNumber);
                    string codeLine         = listingMatch.Groups["line"].Value;

                    // correction for ram pages
                    if (page == 0 && address >= 0x8000 && address < 0xC000)
                    {
                        page = 1;
                    }

                    if (currentFcreateFile != null)
                    {
                        lineNumber += currentFcreateFile.Lines;
                        currentFcreateFile.Builder.AppendLine(listingMatch.Groups["line"].Value.TrimEnd());
                        currentFcreateFile.Lines++;
                    }

                    if (listingMatch.Groups["byte1"].Value.Contains("-") || string.IsNullOrWhiteSpace(listingMatch.Groups["byte1"].Value))
                    {
                        continue;
                    }

                    DocumentLocation key   = new DocumentLocation(currentFile, lineNumber);
                    CalcLocation     value = new CalcLocation(address, page, address >= 0x8000);

                    do
                    {
                        line         = lines[i + 1];
                        listingMatch = ListingContRegex.Match(line);
                        if (!listingMatch.Success)
                        {
                            continue;
                        }

                        i++;
                        codeLine = listingMatch.Groups["line"].Value;
                    } while (listingMatch.Success);

                    if (callInfoToAdd != null)
                    {
                        callerInfo.Add(value, callInfoToAdd);
                    }

                    callInfoToAdd = ParseCallLine(codeLine, key);

                    if (!calcToFile.ContainsKey(value))
                    {
                        calcToFile.Add(value, key);
                    }

                    if (!fileToCalc.ContainsKey(key))
                    {
                        fileToCalc.Add(key, value);
                    }
                }
            }

            foreach (var file in fcreateForFile)
            {
                var filePath = new FilePath(file.Key + ".fcreate");
                using (var writer = new StreamWriter(filePath))
                {
                    writer.Write(file.Value.Builder.ToString());
                }
            }

            _fileToCalc        = fileToCalc;
            _calcToFile        = calcToFile;
            _callerInformation = callerInfo;
        }
Пример #6
0
        public CallerInformation CheckValidCall(ushort callerLocation, bool isCallerInRam, byte calleePage)
        {
            CalcLocation location = new CalcLocation(callerLocation, calleePage, isCallerInRam);

            return(CheckValidCall(location));
        }