1
0
mirror of https://github.com/fadden/6502bench.git synced 2024-08-12 21:29:18 +00:00
6502bench/SourceGen/ProblemList.cs
Andy McFadden 2a41d70e04 Allow explicit widths in project/platform symbols, part 1
The ability to give explicit widths to local variables worked out
pretty well, so we're going to try adding the same thing to project
and platform symbols.

The first step is to allow widths to be specified in platform files,
and set with the project symbol editor.  The DefSymbol editor is
also used for local variables, so a bit of dancing is required.
For platform/project symbols the width is optional, and is totally
ignored for constants.  (For variables, constants are used for the
StackRel args, so the width is meaningful and required.)

We also now show the symbol's type (address or constant) and width
in the listing.  This gets really distracting when overused, so we
only show it when the width is explicitly set.  The default width
is 1, which most things will be, so users can make an aesthetic
choice there.  (The place where widths make very little sense is when
the symbol represents a code entry point, rather than a data item.)

The maximum width of a local variable is now 256, but it's not
allowed to overlap with other variables or run of the end of the
direct page.  The maximum width of a platform/project symbol is
65536, with bank-wrap behavior TBD.

The local variable table editor now refers to stack-relative
constants as such, rather than simply "constant", to make it clear
that it's not just defining an 8-bit constant.

Widths have been added to a handful of Apple II platform defs.
2019-10-01 16:00:08 -07:00

129 lines
3.9 KiB
C#

/*
* Copyright 2019 faddenSoft
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
namespace SourceGen {
/// <summary>
/// List of problems noted during analysis of the project.
/// </summary>
/// <remarks>
/// Could also make a place for load-time problems, though those tend to be resolved by
/// discarding the offending data, so not much value in continuing to report them.
/// </remarks>
public class ProblemList : IEnumerable<ProblemList.ProblemEntry> {
/// <summary>
/// One problem entry.
///
/// Instances are immutable.
/// </summary>
public class ProblemEntry {
public enum SeverityLevel {
Unknown = 0,
Info,
Warning,
Error
}
public SeverityLevel Severity { get; private set; }
public int Offset { get; private set; }
public enum ProblemType {
Unknown = 0,
HiddenLabel,
UnresolvedWeakRef,
}
public ProblemType Problem { get; private set; }
// Context object. Could be a label string, a format descriptor, etc.
public object Context { get; private set; }
public enum ProblemResolution {
Unknown = 0,
LabelIgnored,
FormatDescriptorIgnored,
}
public ProblemResolution Resolution { get; private set; }
public ProblemEntry(SeverityLevel severity, int offset, ProblemType problem,
object context, ProblemResolution resolution) {
Severity = severity;
Offset = offset;
Problem = problem;
Context = context;
Resolution = resolution;
}
public override string ToString() {
return Severity.ToString() + " +" + Offset.ToString("x6") + " " +
Problem + "(" + Context.ToString() + "): " + Resolution;
}
}
/// <summary>
/// Maximum file offset. Used to flag offsets as invalid.
/// </summary>
public int MaxOffset { get; set; }
/// <summary>
/// List of problems. This is not kept in sorted order, because the DataGrid used to
/// display it will do the sorting for us.
/// </summary>
private List<ProblemEntry> mList;
/// <summary>
/// Constructor.
/// </summary>
public ProblemList() {
mList = new List<ProblemEntry>();
}
// IEnumerable
public IEnumerator<ProblemEntry> GetEnumerator() {
// .Values is documented as O(1)
return mList.GetEnumerator();
}
// IEnumerable
IEnumerator IEnumerable.GetEnumerator() {
return mList.GetEnumerator();
}
public int Count {
get { return mList.Count; }
}
public void Add(ProblemEntry entry) {
mList.Add(entry);
}
public void Clear() {
mList.Clear();
}
public void DebugDump() {
Debug.WriteLine("Problem list (" + mList.Count + " entries):");
foreach (ProblemEntry entry in mList) {
Debug.WriteLine(entry);
}
}
}
}