/* * 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.AsmGen { /// /// Static information on assemblers supported by SourceGen. This is relevant for both /// assembly source generation and assembler execution. Nothing here is affected /// by whether or not the assembler in question is actually installed. /// public class AssemblerInfo { /// /// Enumeration of supported assemblers. Sorted alphabetically by human-readable name /// looks nicest. /// public enum Id { Unknown = 0, Tass64, Acme, Cc65, Merlin32, } /// /// Static information for all known assemblers. /// /// The AsmType argument may be null. This is useful for non-cross assemblers. /// private static AssemblerInfo[] sInfo = new AssemblerInfo[] { new AssemblerInfo(Id.Unknown, "???", null, null), new AssemblerInfo(Id.Tass64, "64tass", typeof(GenTass64), typeof(AsmTass64)), new AssemblerInfo(Id.Acme, "ACME", typeof(GenAcme), typeof(AsmAcme)), new AssemblerInfo(Id.Cc65, "cc65", typeof(GenCc65), typeof(AsmCc65)), new AssemblerInfo(Id.Merlin32, "Merlin 32", typeof(GenMerlin32), typeof(AsmMerlin32)), }; /// /// Identifier. /// public Id AssemblerId { get; private set; } /// /// Human-readable name. /// public string Name { get; private set; } /// /// Type of generator class. /// public Type GenType { get; private set; } /// /// Type of assembler class. /// public Type AsmType { get; private set; } private AssemblerInfo(Id id, string name, Type genType, Type asmType) { AssemblerId = id; Name = name; GenType = genType; AsmType = asmType; } /// /// Returns an AssemblerInfo object for the specified id. /// /// Assembler identifier. /// Reference to AssemblerInfo object. public static AssemblerInfo GetAssemblerInfo(Id id) { return sInfo[(int)id]; } /// /// Generator factory method. /// /// ID of assembler to return generator instance for. /// New source generator object. public static IGenerator GetGenerator(Id id) { Type genType = sInfo[(int)id].GenType; if (genType == null) { Debug.Assert(false); // unexpected for generator return null; } else { return (IGenerator)Activator.CreateInstance(genType); } } /// /// Assembler factory method. /// /// ID of assembler to return assembler instance for. /// New assembler interface object. public static IAssembler GetAssembler(Id id) { Type asmType = sInfo[(int)id].AsmType; if (asmType == null) { return null; } else { return (IAssembler)Activator.CreateInstance(asmType); } } /// /// Provides a way to iterate through the set of known assemblers. This is probably /// YAGNI -- we could just return the array -- but it would allow us to apply filters, /// e.g. strip out assemblers that don't support 65816 code when that's the selected /// CPU definition. /// private class AssemblerInfoIterator : IEnumerator { private int mIndex = -1; public AssemblerInfo Current { get { if (mIndex < 0) { // not started return null; } return sInfo[mIndex]; } } object IEnumerator.Current { get { return Current; } } public void Dispose() { } public bool MoveNext() { if (mIndex < 0) { // skip element 0 (Unknown) mIndex = 1; } else { mIndex++; if (mIndex >= sInfo.Length) { return false; } } return true; } public void Reset() { mIndex = -1; } } public static IEnumerator GetInfoEnumerator() { return new AssemblerInfoIterator(); } public override string ToString() { return "AsmInfo " + ((int)AssemblerId).ToString() + ": " + Name; } } }