From d821e25fdb0e97e3405595cf2e0f7d3f94ac5b1d Mon Sep 17 00:00:00 2001 From: Olivier Guinart Date: Fri, 30 Dec 2016 16:46:52 -0800 Subject: [PATCH] First commit --- .../Classification/ClassificationFormat.cs | 84 ++ Coloring/Classification/ClassificationType.cs | 48 + .../Classification/Merlin32sClassifier.cs | 79 ++ Coloring/Data/SnapshotHelper.cs | 16 + Coloring/Merlin32CodeHelper.cs | 130 +++ Coloring/Merlin32TokenTag.cs | 79 ++ Coloring/Merlin32TokenTypes.cs | 108 ++ Intellisense/CompletionController.cs | 176 ++++ Intellisense/CompletionSource.cs | 148 +++ Intellisense/Merlin32QuickInfoSource.cs | 107 ++ Intellisense/QuickInfoController.cs | 105 ++ Intellisense/QuickInfoControllerProvider.cs | 41 + License.txt | 21 + Merlin32Language.csproj | 210 ++++ Merlin32Language.sln | 31 + Merlin32LanguageService.gif | Bin 0 -> 55916 bytes Properties/AssemblyInfo.cs | 33 + README.md | 17 + Resources/data.Designer.cs | 234 +++++ Resources/data.resx | 177 ++++ Resources/directives.Designer.cs | 450 ++++++++ Resources/directives.resx | 249 +++++ Resources/opcodes.Designer.cs | 972 ++++++++++++++++++ Resources/opcodes.resx | 423 ++++++++ Test/HelloWorld.s | 11 + VSLanguageServiceIcon.jpg | Bin 0 -> 21190 bytes VSLanguageServicePreviewImage.jpg | Bin 0 -> 38372 bytes source.extension.vsixmanifest | 36 + 28 files changed, 3985 insertions(+) create mode 100644 Coloring/Classification/ClassificationFormat.cs create mode 100644 Coloring/Classification/ClassificationType.cs create mode 100644 Coloring/Classification/Merlin32sClassifier.cs create mode 100644 Coloring/Data/SnapshotHelper.cs create mode 100644 Coloring/Merlin32CodeHelper.cs create mode 100644 Coloring/Merlin32TokenTag.cs create mode 100644 Coloring/Merlin32TokenTypes.cs create mode 100644 Intellisense/CompletionController.cs create mode 100644 Intellisense/CompletionSource.cs create mode 100644 Intellisense/Merlin32QuickInfoSource.cs create mode 100644 Intellisense/QuickInfoController.cs create mode 100644 Intellisense/QuickInfoControllerProvider.cs create mode 100644 License.txt create mode 100644 Merlin32Language.csproj create mode 100644 Merlin32Language.sln create mode 100644 Merlin32LanguageService.gif create mode 100644 Properties/AssemblyInfo.cs create mode 100644 README.md create mode 100644 Resources/data.Designer.cs create mode 100644 Resources/data.resx create mode 100644 Resources/directives.Designer.cs create mode 100644 Resources/directives.resx create mode 100644 Resources/opcodes.Designer.cs create mode 100644 Resources/opcodes.resx create mode 100644 Test/HelloWorld.s create mode 100644 VSLanguageServiceIcon.jpg create mode 100644 VSLanguageServicePreviewImage.jpg create mode 100644 source.extension.vsixmanifest diff --git a/Coloring/Classification/ClassificationFormat.cs b/Coloring/Classification/ClassificationFormat.cs new file mode 100644 index 0000000..2810d6e --- /dev/null +++ b/Coloring/Classification/ClassificationFormat.cs @@ -0,0 +1,84 @@ +using System.ComponentModel.Composition; +using System.Windows.Media; +using Microsoft.VisualStudio.Text.Classification; +using Microsoft.VisualStudio.Utilities; +//using Microsoft.VisualStudio.Language.StandardClassification; + +namespace VSMerlin32.Coloring.Classification +{ + #region Format definition + + [Export(typeof(EditorFormatDefinition))] + [ClassificationType(ClassificationTypeNames = Merlin32TokenHelper.Merlin32Comment)] + [Name("Merlin32CommentFormat")] + [UserVisible(false)] + [Order(Before = Priority.Default)] + internal sealed class CommentFormat : ClassificationFormatDefinition + { + public CommentFormat() + { + this.DisplayName = "This is a comment"; //human readable version of the name + this.ForegroundColor = Colors.Green; + } + } + + [Export(typeof(EditorFormatDefinition))] + [ClassificationType(ClassificationTypeNames = Merlin32TokenHelper.Merlin32Opcode)] + [Name("Merlin32OpcodeFormat")] + [UserVisible(false)] + [Order(Before = Priority.Default)] + internal sealed class OpcodeFormat : ClassificationFormatDefinition + { + public OpcodeFormat() + { + this.DisplayName = "This is an opcode"; //human readable version of the name + this.ForegroundColor = Colors.Blue; + // this.IsBold = true; + } + } + + [Export(typeof(EditorFormatDefinition))] + [ClassificationType(ClassificationTypeNames = Merlin32TokenHelper.Merlin32Directive)] + [Name("Merlin32DirectiveFormat")] + [UserVisible(false)] + [Order(Before = Priority.Default)] + internal sealed class DirectiveFormat : ClassificationFormatDefinition + { + public DirectiveFormat() + { + this.DisplayName = "This is an directive"; //human readable version of the name + this.ForegroundColor = Colors.DarkCyan; + // this.IsBold = true; + } + } + + [Export(typeof(EditorFormatDefinition))] + [ClassificationType(ClassificationTypeNames = Merlin32TokenHelper.Merlin32DataDefine)] + [Name("Merlin32DataDefineFormat")] + [UserVisible(false)] + [Order(Before = Priority.Default)] + internal sealed class DataDefineFormat : ClassificationFormatDefinition + { + public DataDefineFormat() + { + this.DisplayName = "This is data definition"; //human readable version of the name + this.ForegroundColor = Colors.DarkOrchid; + // this.IsBold = true; + } + } + + [Export(typeof(EditorFormatDefinition))] + [ClassificationType(ClassificationTypeNames = Merlin32TokenHelper.Merlin32Text)] + [Name("Merlin32TextFormat")] + [UserVisible(false)] + [Order(Before = Priority.Default)] + internal sealed class TextFormat : ClassificationFormatDefinition + { + public TextFormat() + { + this.DisplayName = "This is a text"; //human readable version of the name + this.ForegroundColor = Colors.DarkRed; + } + } + #endregion //Format definition +} diff --git a/Coloring/Classification/ClassificationType.cs b/Coloring/Classification/ClassificationType.cs new file mode 100644 index 0000000..aa99655 --- /dev/null +++ b/Coloring/Classification/ClassificationType.cs @@ -0,0 +1,48 @@ +using System.ComponentModel.Composition; +using Microsoft.VisualStudio.Text.Classification; +using Microsoft.VisualStudio.Utilities; + +namespace VSMerlin32.Coloring.Classification +{ + internal static class OrdinaryClassificationDefinition + { + #region Type definition + + /// + /// Defines the "opcode" classification type. + /// + [Export(typeof(ClassificationTypeDefinition))] + [Name(Merlin32TokenHelper.Merlin32Opcode)] + internal static ClassificationTypeDefinition opcode = null; + + /// + /// Defines the "directive" classification type. + /// + [Export(typeof(ClassificationTypeDefinition))] + [Name(Merlin32TokenHelper.Merlin32Directive)] + internal static ClassificationTypeDefinition directive = null; + + /// + /// Defines the "datadefine" classification type. + /// + [Export(typeof(ClassificationTypeDefinition))] + [Name(Merlin32TokenHelper.Merlin32DataDefine)] + internal static ClassificationTypeDefinition datadefine = null; + + /// + /// Defines the "text" classification type. + /// + [Export(typeof(ClassificationTypeDefinition))] + [Name(Merlin32TokenHelper.Merlin32Text)] + internal static ClassificationTypeDefinition text = null; + + /// + /// Defines the "comment" classification type. + /// + [Export(typeof(ClassificationTypeDefinition))] + [Name(Merlin32TokenHelper.Merlin32Comment)] + internal static ClassificationTypeDefinition comment = null; + + #endregion + } +} diff --git a/Coloring/Classification/Merlin32sClassifier.cs b/Coloring/Classification/Merlin32sClassifier.cs new file mode 100644 index 0000000..332dbeb --- /dev/null +++ b/Coloring/Classification/Merlin32sClassifier.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using Microsoft.VisualStudio.Text; +using Microsoft.VisualStudio.Text.Classification; +using Microsoft.VisualStudio.Text.Tagging; +using Microsoft.VisualStudio.Utilities; + +namespace VSMerlin32.Coloring.Classification +{ + [Export(typeof(ITaggerProvider))] + [ContentType("Merlin32")] + [TagType(typeof(ClassificationTag))] + internal sealed class Merlin32ClassifierProvider : ITaggerProvider + { + + [Export] + [Name("Merlin32")] + [BaseDefinition("code")] + internal static ContentTypeDefinition Merlin32ContentType = null; + + [Export] + [FileExtension(".s")] + [ContentType("Merlin32")] + internal static FileExtensionToContentTypeDefinition Merlin32FileType = null; + + [Import] + internal IClassificationTypeRegistryService ClassificationTypeRegistry = null; + + [Import] + internal IBufferTagAggregatorFactoryService aggregatorFactory = null; + + public ITagger CreateTagger(ITextBuffer buffer) where T : ITag + { + + ITagAggregator Merlin32TagAggregator = + aggregatorFactory.CreateTagAggregator(buffer); + + return new Merlin32Classifier(buffer, Merlin32TagAggregator, ClassificationTypeRegistry) as ITagger; + } + } + + internal sealed class Merlin32Classifier : ITagger + { + ITextBuffer _buffer; + ITagAggregator _aggregator; + IDictionary _Merlin32Types; + + internal Merlin32Classifier(ITextBuffer buffer, + ITagAggregator Merlin32TagAggregator, + IClassificationTypeRegistryService typeService) + { + _buffer = buffer; + _aggregator = Merlin32TagAggregator; + _Merlin32Types = new Dictionary(); + + foreach (Merlin32TokenTypes token in Enum.GetValues(typeof(Merlin32TokenTypes))) + _Merlin32Types[token] = typeService.GetClassificationType(token.ToString()); + } + + public event EventHandler TagsChanged + { + add { } + remove { } + } + + public IEnumerable> GetTags(NormalizedSnapshotSpanCollection spans) + { + + foreach (var tagSpan in this._aggregator.GetTags(spans)) + { + var tagSpans = tagSpan.Span.GetSpans(spans[0].Snapshot); + yield return + new TagSpan(tagSpans[0], + new ClassificationTag(_Merlin32Types[tagSpan.Tag.Tokentype])); + } + } + } +} diff --git a/Coloring/Data/SnapshotHelper.cs b/Coloring/Data/SnapshotHelper.cs new file mode 100644 index 0000000..e5057a3 --- /dev/null +++ b/Coloring/Data/SnapshotHelper.cs @@ -0,0 +1,16 @@ +using Microsoft.VisualStudio.Text; + +namespace VSMerlin32.Coloring.Data +{ + internal class SnapshotHelper + { + public SnapshotSpan Snapshot { get; private set; } + public Merlin32TokenTypes TokenType { get; private set; } + + public SnapshotHelper(SnapshotSpan span, Merlin32TokenTypes type) + { + Snapshot = span; + TokenType = type; + } + } +} diff --git a/Coloring/Merlin32CodeHelper.cs b/Coloring/Merlin32CodeHelper.cs new file mode 100644 index 0000000..dbc095f --- /dev/null +++ b/Coloring/Merlin32CodeHelper.cs @@ -0,0 +1,130 @@ +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using Microsoft.VisualStudio.Text; +using VSMerlin32.Coloring.Data; + +namespace VSMerlin32.Coloring +{ + internal class Merlin32CodeHelper + { + const string COMMENT_REG = @"((\u003B)|(\u002A))(.*)"; // ; + //const string KEYLINE_REG = @"\u0023([\w]*)"; // # + //const string HEAD_REG = @"^(\w)+(.*)\u003a\u002d"; // :- + const string TEXT_REG = @"(""|')[^']*(""|')"; + //const string PUBLIC_REG = @"^\u003a\u002d+(.)*"; + // const string OPCODE_REG = @"(org)|(ldy)"; + // OPCODE_REG is initialized dynamically below. + static string OPCODE_REG = ""; + //const string TEXT2_REG = @"\$[^']*\$"; + static string DIRECTIVE_REG = ""; + static string DATADEFINE_REG = ""; + + public static IEnumerable GetTokens(SnapshotSpan span) + { + string strTempRegex; // temp var string + ITextSnapshotLine containingLine = span.Start.GetContainingLine(); + int curLoc = containingLine.Start.Position; + string formattedLine = containingLine.GetText(); + + int commentMatch = int.MaxValue; + Regex reg = new Regex(COMMENT_REG); + foreach (Match match in reg.Matches(formattedLine)) + { + commentMatch = match.Index < commentMatch ? match.Index : commentMatch; + yield return new SnapshotHelper(new SnapshotSpan(new SnapshotPoint(span.Snapshot, match.Index + curLoc), match.Length), Merlin32TokenTypes.Merlin32Comment); + } + + /* + reg = new Regex(KEYLINE_REG); + foreach (Match match in reg.Matches(formattedLine)) + { + if (match.Index < commentMatch) + yield return new SnapshotHelper(new SnapshotSpan(new SnapshotPoint(span.Snapshot, match.Index + curLoc), match.Length), Merlin32TokenTypes.Merlin32Keyline); + } + + reg = new Regex(HEAD_REG); + foreach (Match match in reg.Matches(formattedLine)) + { + if (match.Index < commentMatch) + { + int length = formattedLine.IndexOf("("); + yield return new SnapshotHelper(new SnapshotSpan(new SnapshotPoint(span.Snapshot, match.Index + curLoc), length != -1 ? length : match.Length), Merlin32TokenTypes.Merlin32Keyline); + } + } + */ + + reg = new Regex(TEXT_REG); + foreach (Match match in reg.Matches(formattedLine)) + { + if (match.Index < commentMatch) + yield return new SnapshotHelper(new SnapshotSpan(new SnapshotPoint(span.Snapshot, match.Index + curLoc), match.Length), Merlin32TokenTypes.Merlin32Text); + } + + // OG NEW + // OPCODES + strTempRegex = ""; + foreach (Merlin32Opcodes token in Enum.GetValues(typeof(Merlin32Opcodes))) + { + strTempRegex += (token.ToString() + ("|")); + } + // we remove the last "|" added + strTempRegex = strTempRegex.Remove(strTempRegex.LastIndexOf("|")); + OPCODE_REG = string.Format(@"\b({0})\b", strTempRegex); + + reg = new Regex(OPCODE_REG,RegexOptions.IgnoreCase); + foreach (Match match in reg.Matches(formattedLine)) + { + if (match.Index < commentMatch) + yield return new SnapshotHelper(new SnapshotSpan(new SnapshotPoint(span.Snapshot, match.Index + curLoc), match.Length), Merlin32TokenTypes.Merlin32Opcode); + } + + // OG NEW + // DIRECTIVES + strTempRegex = ""; + foreach (Merlin32Directives token in Enum.GetValues(typeof(Merlin32Directives))) + { + if (token.ToString() != Resources.directives.ELUP) + strTempRegex += (token.ToString() + ("|")); + } + // we remove the last "|" added + // strTempRegex = strTempRegex.Remove(strTempRegex.LastIndexOf("|")); + // DIRECTIVE_REG = string.Format(@"\b({0})\b", strTempRegex); + DIRECTIVE_REG = string.Format(@"\b({0})\b|{1}", strTempRegex, Resources.directives.ELUPRegex); + + reg = new Regex(DIRECTIVE_REG, RegexOptions.IgnoreCase); + foreach (Match match in reg.Matches(formattedLine)) + { + if (match.Index < commentMatch) + yield return new SnapshotHelper(new SnapshotSpan(new SnapshotPoint(span.Snapshot, match.Index + curLoc), match.Length), Merlin32TokenTypes.Merlin32Directive); + } + + // OG NEW + // DATADEFINES + strTempRegex = ""; + foreach (Merlin32DataDefines token in Enum.GetValues(typeof(Merlin32DataDefines))) + { + strTempRegex += (token.ToString() + ("|")); + } + // we remove the last "|" added + strTempRegex = strTempRegex.Remove(strTempRegex.LastIndexOf("|")); + DATADEFINE_REG = string.Format(@"\b({0})\b", strTempRegex); + + reg = new Regex(DATADEFINE_REG, RegexOptions.IgnoreCase); + foreach (Match match in reg.Matches(formattedLine)) + { + if (match.Index < commentMatch) + yield return new SnapshotHelper(new SnapshotSpan(new SnapshotPoint(span.Snapshot, match.Index + curLoc), match.Length), Merlin32TokenTypes.Merlin32DataDefine); + } + + /* + reg = new Regex(PUBLIC_REG); + foreach (Match match in reg.Matches(formattedLine)) + { + if (match.Index < commentMatch) + yield return new SnapshotHelper(new SnapshotSpan(new SnapshotPoint(span.Snapshot, match.Index + curLoc), match.Length), Merlin32TokenTypes.Merlin32Publictoken); + } + */ + } + } +} diff --git a/Coloring/Merlin32TokenTag.cs b/Coloring/Merlin32TokenTag.cs new file mode 100644 index 0000000..d225c1c --- /dev/null +++ b/Coloring/Merlin32TokenTag.cs @@ -0,0 +1,79 @@ +// Copyright (c) Microsoft Corporation +// All rights reserved +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using Microsoft.VisualStudio.Text; +using Microsoft.VisualStudio.Text.Tagging; +using Microsoft.VisualStudio.Utilities; +using VSMerlin32.Coloring.Data; + +namespace VSMerlin32.Coloring +{ + + [Export(typeof(ITaggerProvider))] + [ContentType("Merlin32")] + [TagType(typeof(Merlin32TokenTag))] + internal sealed class Merlin32TokenTagProvider : ITaggerProvider + { + + public ITagger CreateTagger(ITextBuffer buffer) where T : ITag + { + return new Merlin32TokenTagger(buffer) as ITagger; + } + } + + public class Merlin32TokenTag : ITag + { + public Merlin32TokenTypes Tokentype { get; private set; } + + public Merlin32TokenTag(Merlin32TokenTypes type) + { + this.Tokentype = type; + } + } + + internal sealed class Merlin32TokenTagger : ITagger + { + + ITextBuffer _buffer; + IDictionary _Merlin32Types; + + internal Merlin32TokenTagger(ITextBuffer buffer) + { + _buffer = buffer; + _Merlin32Types = new Dictionary(); + + foreach (Merlin32TokenTypes token in Enum.GetValues(typeof(Merlin32TokenTypes))) + _Merlin32Types.Add(token.ToString(), token); + } + + public event EventHandler TagsChanged + { + add { } + remove { } + } + + // OG !!! + public IEnumerable> GetTags(NormalizedSnapshotSpanCollection spans) + { + foreach (SnapshotSpan curSpan in spans) + { + ITextSnapshotLine containingLine = curSpan.Start.GetContainingLine(); + int curLoc = containingLine.Start.Position; + + string formattedLine = containingLine.GetText(); + + foreach (SnapshotHelper item in Merlin32CodeHelper.GetTokens(curSpan)) + { + if (item.Snapshot.IntersectsWith(curSpan)) + yield return new TagSpan(item.Snapshot, + new Merlin32TokenTag(item.TokenType)); + } + + //add an extra char location because of the space + curLoc += formattedLine.Length + 1; + } + } + } +} diff --git a/Coloring/Merlin32TokenTypes.cs b/Coloring/Merlin32TokenTypes.cs new file mode 100644 index 0000000..f41693b --- /dev/null +++ b/Coloring/Merlin32TokenTypes.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Resources; +using System.Reflection; +using System.Collections; + +namespace VSMerlin32 +{ + public enum Merlin32Opcodes + { + ADC, ADCL, AND, ANDL, ASL, + BCC, BLT, BCS, BGE, BEQ, BIT, BMI, BNE, BPL, BRA, BRK, BRL, BVC, BVS, + CLC, CLD, CLI, CLV, CMP, CMPL, COP, CPX, CPY, + DEC, DEX, DEY, + EOR, EORL, + INC, INX, INY, + JMP, JML, JMPL, JSR, JSL, + LDA, LDAL, LDX, LDY, LSR, + MVN, MVP, + NOP, + ORA, ORAL, + PEA, PEI, PER, PHA, PHB, PHD, PHK, PHP, PHX, PHY, PLA, PLB, PLD, PLP, PLX, PLY, + REP, ROL, ROR, RTI, RTL, RTS, + SBC, SBCL, SEC, SED, SEI, SEP, STA, STAL, STP, STX, STY, STZ, + TAX, TAY, TCD, TCS, TDC, TRB, TSB, TSC, TSX, TXA, TXS, TXY, TYA, TYX, + WAI, WDM, + XBA, XCE + } + + public enum Merlin32Directives + { + EQU, + ANOP, ORG, PUT, PUTBIN, /* PUTBIN n'existe pas dans Merlin 16+ */ + START, END, + DUM, DEND, + MX, XC, LONGA, LONGI, + USE, USING, + REL, DSK, LNK, SAV, + TYP, + IF, DO, ELSE, FIN, + LUP, ELUP, // --^, ignored for now (invalid enum) + ERR, DAT, + AST, CYC, EXP, LST, LSTDO, PAG, TTL, SKP, TR, KBD, PAU, SW, USR + } + + public enum Merlin32DataDefines + { + DA, DW, DDB, DFB, DB, ADR, ADRL, HEX, DS, + DC, DE, /* ? */ + ASC, DCI, INV, FLS, REV, STR, STRL, + CHK + } + + class Merlin32KeywordsHelper + { + /* The regex for opcodes is now defined in Merlin32CodeHelper.cs + public const string strMerlin32OpcodesRegex = +@"\b(ADC(L?)|AND(L?)|ASL|BCC|BCS|BEQ|BIT|BMI|BNE|BPL|BRA|BRK|BRL|BVC|BVS|CLC|CLD|CLI|CLV|CMP(L?)|COP|CPX|CPY|DEC|DEX|DEY|EOR(L?)|INC|INX|INY|JMP(L?)|JML|JSR|JSL|LDA(L?)|LDX|LDY|LSR|MVN|MVP|NOP|ORA(L?)|ORG|PEA|PEI|PER|PHA|PHB|PHD|PHK|PHP|PHX|PHY|PLA|PLB|PLD|PLP|PLX|PLY|REP|ROL|ROR|RTI|RTL|RTS|SBC(L?)|SEC|SED|SEI|SEP|STA(L?)|STP|STX|STY|STZ|TAX|TAY|TCD|TCS|TDC|TRB|TSB|TSC|TSX|TXA|TXS|TXY|TYA|TYX|WAI|WDM|XBA|XCE)\b"; + */ + + public IDictionary _Merlin32KeywordsQuickInfo; + + public Merlin32KeywordsHelper() + { + // Read the resources for opcodes, all of them... + ResourceSet rsOpcodes = VSMerlin32.Resources.opcodes.ResourceManager.GetResourceSet(System.Globalization.CultureInfo.CurrentCulture, true, true); + // Read the resources for directives too, all of them... + ResourceSet rsDirectives = VSMerlin32.Resources.directives.ResourceManager.GetResourceSet(System.Globalization.CultureInfo.CurrentCulture, true, true); + // Read the resources for datadefines too, all of them... + ResourceSet rsData = VSMerlin32.Resources.data.ResourceManager.GetResourceSet(System.Globalization.CultureInfo.CurrentCulture, true, true); + + _Merlin32KeywordsQuickInfo = new Dictionary(); + foreach (Merlin32Opcodes token in Enum.GetValues(typeof(Merlin32Opcodes))) + { + // _Merlin32OpcodesQuickInfo[token.ToString()] = token.ToString(); + _Merlin32KeywordsQuickInfo[token.ToString()] = rsOpcodes.GetString(token.ToString()); + } + foreach (Merlin32Directives token in Enum.GetValues(typeof(Merlin32Directives))) + { + _Merlin32KeywordsQuickInfo[token.ToString()] = rsDirectives.GetString(token.ToString()); + } + foreach (Merlin32DataDefines token in Enum.GetValues(typeof(Merlin32DataDefines))) + { + _Merlin32KeywordsQuickInfo[token.ToString()] = rsData.GetString(token.ToString()); + } + /* + _Merlin32OpcodesQuickInfo[Merlin32Opcodes.ORG.ToString()] = VSMerlin32.strings.ORG; + */ + } + } + + internal sealed class Merlin32TokenHelper + { + public const string Merlin32Opcode = "Merlin32Opcode"; + public const string Merlin32Directive = "Merlin32Directive"; + public const string Merlin32DataDefine = "Merlin32DataDefine"; + public const string Merlin32Text = "Merlin32Text"; + public const string Merlin32Comment = "Merlin32Comment"; + } + + public enum Merlin32TokenTypes + { + Merlin32Opcode, Merlin32Directive, Merlin32DataDefine, Merlin32Text, Merlin32Comment + } +} diff --git a/Intellisense/CompletionController.cs b/Intellisense/CompletionController.cs new file mode 100644 index 0000000..7539b47 --- /dev/null +++ b/Intellisense/CompletionController.cs @@ -0,0 +1,176 @@ +using System; +using System.ComponentModel.Composition; +using System.Runtime.InteropServices; +using Microsoft.VisualStudio; +using Microsoft.VisualStudio.Editor; +using Microsoft.VisualStudio.Language.Intellisense; +using Microsoft.VisualStudio.OLE.Interop; + +using Microsoft.VisualStudio.Shell; + +using Microsoft.VisualStudio.Text; +using Microsoft.VisualStudio.Text.Editor; +using Microsoft.VisualStudio.TextManager.Interop; +using Microsoft.VisualStudio.Utilities; + +using Microsoft.VisualStudio.Text.Operations; + + +namespace VSMerlin32 +{ + #region Command Filter + + [Export(typeof(IVsTextViewCreationListener))] + [Name("Merlin32CompletionController")] + [ContentType("Merlin32")] + [TextViewRole(PredefinedTextViewRoles.Editable)] + internal sealed class VsTextViewCreationListener : IVsTextViewCreationListener + { + [Import] + internal IVsEditorAdaptersFactoryService AdaptersFactory = null; + [Import] + internal ICompletionBroker CompletionBroker { get; set; } + [Import] + internal SVsServiceProvider ServiceProvider { get; set; } + + public void VsTextViewCreated(IVsTextView textViewAdapter) + { + ITextView textView = AdaptersFactory.GetWpfTextView(textViewAdapter); + if (textView == null) + return; + + Func createCommandHandler = delegate() { return new CommandFilter(textViewAdapter, textView, this); }; + textView.Properties.GetOrCreateSingletonProperty(createCommandHandler); + } + } + + internal sealed class CommandFilter : IOleCommandTarget + { + private IOleCommandTarget m_nextCommandHandler; + private ITextView m_textView; + private VsTextViewCreationListener m_provider; + private ICompletionSession m_session; + + internal CommandFilter(IVsTextView textViewAdapter, ITextView textView, VsTextViewCreationListener provider) + { + this.m_textView = textView; + this.m_provider = provider; + + //add the command to the command chain + textViewAdapter.AddCommandFilter(this, out m_nextCommandHandler); + } + + public int QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText) + { + return m_nextCommandHandler.QueryStatus(ref pguidCmdGroup, cCmds, prgCmds, pCmdText); + } + + public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) + { + if (VsShellUtilities.IsInAutomationFunction(m_provider.ServiceProvider)) + { + return m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); + } + //make a copy of this so we can look at it after forwarding some commands + uint commandID = nCmdID; + char typedChar = char.MinValue; + //make sure the input is a char before getting it + if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR) + { + typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn); + } + + //check for a commit character + if (nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN + || nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB + || char.IsWhiteSpace(typedChar) + || char.IsPunctuation(typedChar)) + { + //check for a a selection + if (m_session != null && !m_session.IsDismissed) + { + //if the selection is fully selected, commit the current session + if (m_session.SelectedCompletionSet.SelectionStatus.IsSelected) + { + m_session.Commit(); + //also, don't add the character to the buffer + return VSConstants.S_OK; + } + else + { + //if there is no selection, dismiss the session + m_session.Dismiss(); + } + } + } + + //pass along the command so the char is added to the buffer + int retVal = m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); + bool handled = false; + if (!typedChar.Equals(char.MinValue) && ((char.IsLetterOrDigit(typedChar)) || ((typedChar == '\'') || (typedChar == '"')))) + { + if (m_session == null || m_session.IsDismissed) // If there is no active session, bring up completion + { + this.TriggerCompletion(); + // No need to filter for single and double-quotes, the choice IS the characted, just doubled, and already populated in a single completionset if we're here... + if ((typedChar == '\'') || (typedChar == '"')) + { + // We need to save the currect caret position because we'll position it in between the single/double quotes after the commit... + ITextCaret CaretBeforeCommit = m_session.TextView.Caret; + m_session.Commit(); + this.m_textView.Caret.MoveTo(CaretBeforeCommit.Position.BufferPosition - 1); + } + else + { + m_session.Filter(); + } + } + else //the completion session is already active, so just filter + { + m_session.Filter(); + } + handled = true; + } + else if (commandID == (uint)VSConstants.VSStd2KCmdID.BACKSPACE //redo the filter if there is a deletion + || commandID == (uint)VSConstants.VSStd2KCmdID.DELETE) + { + if (m_session != null && !m_session.IsDismissed) + m_session.Filter(); + handled = true; + } + + if (handled) return VSConstants.S_OK; + return retVal; + } + + private bool TriggerCompletion() + { + //the caret must be in a non-projection location + SnapshotPoint? caretPoint = + m_textView.Caret.Position.Point.GetPoint( + textBuffer => (!textBuffer.ContentType.IsOfType("projection")), PositionAffinity.Predecessor); + if (!caretPoint.HasValue) + { + return false; + } + + m_session = m_provider.CompletionBroker.CreateCompletionSession(m_textView, + caretPoint.Value.Snapshot.CreateTrackingPoint(caretPoint.Value.Position, PointTrackingMode.Positive), + true); + + //subscribe to the Dismissed event on the session + m_session.Dismissed += this.OnSessionDismissed; + m_session.Start(); + + return true; + } + + private void OnSessionDismissed(object sender, EventArgs e) + { + m_session.Dismissed -= this.OnSessionDismissed; + m_session = null; + } + } + + #endregion +} \ No newline at end of file diff --git a/Intellisense/CompletionSource.cs b/Intellisense/CompletionSource.cs new file mode 100644 index 0000000..52380a5 --- /dev/null +++ b/Intellisense/CompletionSource.cs @@ -0,0 +1,148 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.ComponentModel.Composition; +using Microsoft.VisualStudio.Language.Intellisense; +using Microsoft.VisualStudio.Text; +using Microsoft.VisualStudio.Text.Operations; +using Microsoft.VisualStudio.Utilities; + +namespace VSMerlin32 +{ + [Export(typeof(ICompletionSourceProvider))] + [ContentType("Merlin32")] + [Name("Merlin32Completion")] + internal class Merlin32CompletionSourceProvider : ICompletionSourceProvider + { + [Import] + internal ITextStructureNavigatorSelectorService NavigatorService { get; set; } + + public ICompletionSource TryCreateCompletionSource(ITextBuffer textBuffer) + { + return new Merlin32CompletionSource(this, textBuffer); + } + } + + internal class Merlin32CompletionSource : ICompletionSource + { + private Merlin32CompletionSourceProvider m_sourceprovider; + private ITextBuffer m_buffer; + private List m_compList; + private bool m_isDisposed = false; + + public Merlin32CompletionSource(Merlin32CompletionSourceProvider sourceprovider, ITextBuffer buffer) + { + m_sourceprovider = sourceprovider; + m_buffer = buffer; + } + + public void AugmentCompletionSession(ICompletionSession session, IList completionSets) + { + if (m_isDisposed) + throw new ObjectDisposedException("Merlin32CompletionSource"); + + List strList = new List(); + char chTyped = ((session.TextView.Caret.Position.BufferPosition) - 1).GetChar(); + // Testing for single and double quotes because these will be autocompleted... + if ((chTyped == '\'') || (chTyped == '"')) + { + strList.Add(chTyped.ToString() + chTyped.ToString()); + } + else + { + // If the user has been typing lowercase, we'll present a lowercase list of keywords/opcodes... + if (char.IsLower(chTyped)) + { + foreach (Merlin32Opcodes token in Enum.GetValues(typeof(Merlin32Opcodes))) + { + strList.Add(token.ToString().ToLower()); + } + foreach (Merlin32Directives token in Enum.GetValues(typeof(Merlin32Directives))) + { + if (token.ToString().ToLower() == Merlin32Directives.ELUP.ToString().ToLower()) + { + strList.Add(Resources.directives.ELUPValue); + } + else + { + strList.Add(token.ToString().ToLower()); + } + } + foreach (Merlin32DataDefines token in Enum.GetValues(typeof(Merlin32DataDefines))) + { + strList.Add(token.ToString().ToLower()); + } + } + else + { + foreach (Merlin32Opcodes token in Enum.GetValues(typeof(Merlin32Opcodes))) + { + strList.Add(token.ToString()); + } + foreach (Merlin32Directives token in Enum.GetValues(typeof(Merlin32Directives))) + { + if (token.ToString() == Merlin32Directives.ELUP.ToString()) + { + strList.Add(Resources.directives.ELUPValue); + } + else + { + strList.Add(token.ToString()); + } + } + foreach (Merlin32DataDefines token in Enum.GetValues(typeof(Merlin32DataDefines))) + { + strList.Add(token.ToString()); + } + } + + // OG We also need to replace "ELUP" with "--^" + // OG 2015/10/21 + strList.Sort(); + // strList[strList.IndexOf(Merlin32Directives.ELUP.ToString())] = "--^"; + // OG + } + m_compList = new List(); + foreach (string str in strList) + m_compList.Add(new Completion(str, str, str, null, null)); + /* + ITextSnapshot snapshot = _buffer.CurrentSnapshot; + var triggerPoint = (SnapshotPoint)session.GetTriggerPoint(snapshot); + + if (triggerPoint == null) + return; + + var line = triggerPoint.GetContainingLine(); + SnapshotPoint start = triggerPoint; + + while (start > line.Start && !char.IsWhiteSpace((start - 1).GetChar())) + { + start -= 1; + } + + var applicableTo = snapshot.CreateTrackingSpan(new SnapshotSpan(start, triggerPoint), SpanTrackingMode.EdgeInclusive); + */ + + completionSets.Add(new CompletionSet("All", "All", FindTokenSpanAtPosition(session.GetTriggerPoint(m_buffer), session), m_compList, null)); + } + + private ITrackingSpan FindTokenSpanAtPosition(ITrackingPoint point, ICompletionSession session) + { + SnapshotPoint currentPoint = (session.TextView.Caret.Position.BufferPosition) - 1; + ITextStructureNavigator navigator = m_sourceprovider.NavigatorService.GetTextStructureNavigator(m_buffer); + TextExtent extent = navigator.GetExtentOfWord(currentPoint); + return currentPoint.Snapshot.CreateTrackingSpan(extent.Span, SpanTrackingMode.EdgeInclusive); + } + + public void Dispose() + { + if (!m_isDisposed) + { + GC.SuppressFinalize(this); + m_isDisposed = true; + } + } + } +} + diff --git a/Intellisense/Merlin32QuickInfoSource.cs b/Intellisense/Merlin32QuickInfoSource.cs new file mode 100644 index 0000000..cfc18ed --- /dev/null +++ b/Intellisense/Merlin32QuickInfoSource.cs @@ -0,0 +1,107 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.VisualStudio.Language.Intellisense; +using System.Collections.ObjectModel; +using Microsoft.VisualStudio.Text; +using Microsoft.VisualStudio.Text.Tagging; +using System.ComponentModel.Composition; +using Microsoft.VisualStudio.Utilities; +using VSMerlin32.Coloring; + +namespace VSMerlin32 +{ + + [Export(typeof(IQuickInfoSourceProvider))] + [ContentType("Merlin32")] + [Name("Merlin32QuickInfo")] + class Merlin32QuickInfoSourceProvider : IQuickInfoSourceProvider + { + + [Import] + IBufferTagAggregatorFactoryService aggService = null; + + public IQuickInfoSource TryCreateQuickInfoSource(ITextBuffer textBuffer) + { + return new Merlin32QuickInfoSource(textBuffer, aggService.CreateTagAggregator(textBuffer)); + } + } + + class Merlin32QuickInfoSource : IQuickInfoSource + { + private ITagAggregator _aggregator; + private ITextBuffer _buffer; + private Merlin32KeywordsHelper _Merlin32OpcodesHelper = new Merlin32KeywordsHelper(); + private bool _disposed = false; + + + public Merlin32QuickInfoSource(ITextBuffer buffer, ITagAggregator aggregator) + { + _aggregator = aggregator; + _buffer = buffer; + } + + public void AugmentQuickInfoSession(IQuickInfoSession session, IList quickInfoContent, out ITrackingSpan applicableToSpan) + { + applicableToSpan = null; + + if (_disposed) + throw new ObjectDisposedException("TestQuickInfoSource"); + + var triggerPoint = (SnapshotPoint) session.GetTriggerPoint(_buffer.CurrentSnapshot); + + if (triggerPoint == null) + return; + + foreach (IMappingTagSpan curTag in _aggregator.GetTags(new SnapshotSpan(triggerPoint, triggerPoint))) + { + if ((curTag.Tag.Tokentype == Merlin32TokenTypes.Merlin32Opcode) || (curTag.Tag.Tokentype == Merlin32TokenTypes.Merlin32Directive) || (curTag.Tag.Tokentype == Merlin32TokenTypes.Merlin32DataDefine)) + { + var tagSpan = curTag.Span.GetSpans(_buffer).First(); + // Before + //if (tagSpan.GetText() == Merlin32Opcodes.ORG.ToString()) + //{ + // applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(tagSpan, SpanTrackingMode.EdgeExclusive); + // quickInfoContent.Add("Must be followed by the program's origin, e.g. org $800"); + //} + // OG After + applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(tagSpan, SpanTrackingMode.EdgeExclusive); + if (tagSpan.GetText() == Resources.directives.ELUPValue) + { + quickInfoContent.Add(_Merlin32OpcodesHelper._Merlin32KeywordsQuickInfo[Merlin32Directives.ELUP.ToString()]); + } + else + { + // TODO: why do I get an exception here if I don't test for string.Empty!? + /* + System.Collections.Generic.KeyNotFoundException was unhandled by user code + HResult=-2146232969 + Message=The given key was not present in the dictionary. + Source=mscorlib + StackTrace: + at System.Collections.Generic.Dictionary`2.get_Item(TKey key) + at VSMerlin32.Merlin32QuickInfoSource.AugmentQuickInfoSession(IQuickInfoSession session, IList`1 quickInfoContent, ITrackingSpan& applicableToSpan) in c:\Users\Olivier\Documents\Visual Studio 2013\Projects\Merlin32 Language Service\Merlin32Language\Intellisense\Merlin32QuickInfoSource.cs:line 77 + at Microsoft.VisualStudio.Language.Intellisense.Implementation.QuickInfoSession.Recalculate() + at Microsoft.VisualStudio.Language.Intellisense.Implementation.QuickInfoSession.Start() + at Microsoft.VisualStudio.Language.Intellisense.Implementation.DefaultQuickInfoController.OnTextView_MouseHover(Object sender, MouseHoverEventArgs e) + at Microsoft.VisualStudio.Text.Editor.Implementation.WpfTextView.RaiseHoverEvents() + InnerException: + */ + // Compare with changeset 151, you'll see why I ask... + if (string.Empty != tagSpan.GetText()) + { + quickInfoContent.Add(_Merlin32OpcodesHelper._Merlin32KeywordsQuickInfo[tagSpan.GetText().ToUpper()]); + } + } + } + } + } + + public void Dispose() + { + _disposed = true; + } + } +} + diff --git a/Intellisense/QuickInfoController.cs b/Intellisense/QuickInfoController.cs new file mode 100644 index 0000000..35aa42b --- /dev/null +++ b/Intellisense/QuickInfoController.cs @@ -0,0 +1,105 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Copyright (c) Microsoft Corporation. All rights reserved. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.Windows.Input; +using Microsoft.VisualStudio.Language.Intellisense; +using Microsoft.VisualStudio.Text; +using Microsoft.VisualStudio.Text.Editor; +using Microsoft.VisualStudio.Utilities; + +namespace VSLTK.Intellisense +{ + #region IIntellisenseController + + internal class TemplateQuickInfoController : IIntellisenseController + { + #region Private Data Members + + private ITextView _textView; + private IList _subjectBuffers; + private TemplateQuickInfoControllerProvider _componentContext; + + private IQuickInfoSession _session; + + #endregion + + #region Constructors + + internal TemplateQuickInfoController(ITextView textView, IList subjectBuffers, TemplateQuickInfoControllerProvider componentContext) + { + _textView = textView; + _subjectBuffers = subjectBuffers; + _componentContext = componentContext; + + _textView.MouseHover += this.OnTextViewMouseHover; + } + + #endregion + + #region IIntellisenseController Members + + public void ConnectSubjectBuffer(ITextBuffer subjectBuffer) + { + } + + public void DisconnectSubjectBuffer(ITextBuffer subjectBuffer) + { + } + + public void Detach(ITextView textView) + { + if (_textView == textView) + { + _textView.MouseHover -= this.OnTextViewMouseHover; + _textView = null; + } + } + + #endregion + + #region Event Handlers + + private void OnTextViewMouseHover(object sender, MouseHoverEventArgs e) + { + SnapshotPoint? point = this.GetMousePosition(new SnapshotPoint(_textView.TextSnapshot, e.Position)); + + if (point != null) + { + ITrackingPoint triggerPoint = point.Value.Snapshot.CreateTrackingPoint(point.Value.Position, + PointTrackingMode.Positive); + + // Find the broker for this buffer + + if (!_componentContext.QuickInfoBroker.IsQuickInfoActive(_textView)) + { + _session = _componentContext.QuickInfoBroker.CreateQuickInfoSession(_textView, triggerPoint, true); + _session.Start(); + } + } + } + + #endregion + + #region Private Implementation + + private SnapshotPoint? GetMousePosition(SnapshotPoint topPosition) + { + // Map this point down to the appropriate subject buffer. + + return _textView.BufferGraph.MapDownToFirstMatch + ( + topPosition, + PointTrackingMode.Positive, + snapshot => _subjectBuffers.Contains(snapshot.TextBuffer), + PositionAffinity.Predecessor + ); + } + + #endregion + } + + #endregion +} \ No newline at end of file diff --git a/Intellisense/QuickInfoControllerProvider.cs b/Intellisense/QuickInfoControllerProvider.cs new file mode 100644 index 0000000..73081e0 --- /dev/null +++ b/Intellisense/QuickInfoControllerProvider.cs @@ -0,0 +1,41 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Copyright (c) Microsoft Corporation. All rights reserved. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +using System.Collections.Generic; +using System.ComponentModel.Composition; +using Microsoft.VisualStudio.Language.Intellisense; +using Microsoft.VisualStudio.Text; +using Microsoft.VisualStudio.Text.Editor; +using Microsoft.VisualStudio.Utilities; + +namespace VSLTK.Intellisense +{ + #region IIntellisenseControllerProvider + + [Export(typeof(IIntellisenseControllerProvider))] + [Name("Template QuickInfo Controller")] + [ContentType("text")] + internal class TemplateQuickInfoControllerProvider : IIntellisenseControllerProvider + { + #region Asset Imports + + [Import] + internal IQuickInfoBroker QuickInfoBroker { get; set; } + + #endregion + + #region IIntellisenseControllerFactory Members + + public IIntellisenseController TryCreateIntellisenseController(ITextView textView, + IList subjectBuffers) + { + return new TemplateQuickInfoController(textView, subjectBuffers, this); + } + + #endregion + + } + + #endregion +} \ No newline at end of file diff --git a/License.txt b/License.txt new file mode 100644 index 0000000..c5d10c5 --- /dev/null +++ b/License.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 OlivierGuinart + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Merlin32Language.csproj b/Merlin32Language.csproj new file mode 100644 index 0000000..1f21300 --- /dev/null +++ b/Merlin32Language.csproj @@ -0,0 +1,210 @@ + + + + 14.0 + 14.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + SAK + SAK + SAK + SAK + + + + + 4.0 + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + false + + + + Debug + AnyCPU + 10.0.20305 + 2.0 + {82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + {F091221E-FD10-41A7-AAC4-C9359178BDB1} + Library + Properties + VSMerlin32 + Merlin32Language + v4.5.2 + 512 + false + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + Program + $(ProgramFiles)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe + /rootsuffix Exp + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + Program + $(ProgramFiles)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe + /rootsuffix Exp + + + + False + + + False + + + False + + + False + + + + + + + + true + + + + + + + False + + + False + + + False + + + False + + + + + + + + + + + + + + + + + + + True + True + data.resx + + + True + True + directives.resx + + + + + + + + + + + + + True + True + opcodes.resx + + + + + Designer + + + + + true + + + + true + + + true + + + + + ResXFileCodeGenerator + data.Designer.cs + + + ResXFileCodeGenerator + directives.Designer.cs + + + ResXFileCodeGenerator + opcodes.Designer.cs + + + + + False + Microsoft .NET Framework 4.5 %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + + + + + + + + + + \ No newline at end of file diff --git a/Merlin32Language.sln b/Merlin32Language.sln new file mode 100644 index 0000000..3d53302 --- /dev/null +++ b/Merlin32Language.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.24720.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Merlin32Language", "Merlin32Language.csproj", "{F091221E-FD10-41A7-AAC4-C9359178BDB1}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F091221E-FD10-41A7-AAC4-C9359178BDB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F091221E-FD10-41A7-AAC4-C9359178BDB1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F091221E-FD10-41A7-AAC4-C9359178BDB1}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {F091221E-FD10-41A7-AAC4-C9359178BDB1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F091221E-FD10-41A7-AAC4-C9359178BDB1}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(TeamFoundationVersionControl) = preSolution + SccNumberOfProjects = 2 + SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C} + SccTeamFoundationServer = https://aito.visualstudio.com/ + SccLocalPath0 = . + SccProjectUniqueName1 = Merlin32Language.csproj + SccLocalPath1 = . + EndGlobalSection +EndGlobal diff --git a/Merlin32LanguageService.gif b/Merlin32LanguageService.gif new file mode 100644 index 0000000000000000000000000000000000000000..59667796a8ed158da3e465e5035b17b354964e9b GIT binary patch literal 55916 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 Dd#ZxT literal 0 HcmV?d00001 diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..07b2c64 --- /dev/null +++ b/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("VSMerlin32")] +[assembly: AssemblyDescription("Merlin32 classifier extension to the Visual Studio Editor")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("VSMerlin32")] +[assembly: AssemblyCopyright("Copyright © Olivier Guinart")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/README.md b/README.md new file mode 100644 index 0000000..75c478e --- /dev/null +++ b/README.md @@ -0,0 +1,17 @@ +# Merlin32 Visual Studio Language Service +Visual Studio language service for 6502 Merlin32 cross-assembler (http://brutaldeluxe.fr/products/crossdevtools/merlin/index.html). + + +Provides the ability to develop 6502 assembly programs within a modern IDE. + +Features: + +* Syntax coloring +* Statement completion +* Opcodes tooltip + +![](https://github.com/OlivierGuinart/Merlin32Language/blob/master/Merlin32LanguageService.gif) + +Visual Studio extension available in the Visual Studio gallery: https://marketplace.visualstudio.com/vsgallery/4f84ade5-b04b-451f-92fc-272c06f31359 + + diff --git a/Resources/data.Designer.cs b/Resources/data.Designer.cs new file mode 100644 index 0000000..8b580cd --- /dev/null +++ b/Resources/data.Designer.cs @@ -0,0 +1,234 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace VSMerlin32.Resources { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class data { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal data() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("VSMerlin32.Resources.data", typeof(data).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Define ADdRess (3 bytes). + /// + internal static string ADR { + get { + return ResourceManager.GetString("ADR", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Define ADdRess Long (4 bytes). + /// + internal static string ADRL { + get { + return ResourceManager.GetString("ADRL", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Define ASCii ("" positive, '' negative). + /// + internal static string ASC { + get { + return ResourceManager.GetString("ASC", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Place a CHecKsum in object code. + /// + internal static string CHK { + get { + return ResourceManager.GetString("CHK", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Define Address (2 bytes). + /// + internal static string DA { + get { + return ResourceManager.GetString("DA", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Define Byte (1 byte). + /// + internal static string DB { + get { + return ResourceManager.GetString("DB", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ???. + /// + internal static string DC { + get { + return ResourceManager.GetString("DC", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Define Dextral Character Inverted. + /// + internal static string DCI { + get { + return ResourceManager.GetString("DCI", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Define Double Byte (2 bytes). + /// + internal static string DDB { + get { + return ResourceManager.GetString("DDB", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ???. + /// + internal static string DE { + get { + return ResourceManager.GetString("DE", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to DeFine Byte (1 byte). + /// + internal static string DFB { + get { + return ResourceManager.GetString("DFB", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Define Storage (x bytes) (e.g. DS 10 (put $00 in 10 bytes), DS 10,$80 (put $80 in 10 bytes)). + /// + internal static string DS { + get { + return ResourceManager.GetString("DS", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Define Word (2 bytes). + /// + internal static string DW { + get { + return ResourceManager.GetString("DW", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Define FLaShing text. + /// + internal static string FLS { + get { + return ResourceManager.GetString("FLS", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Define HEX data (1 byte). + /// + internal static string HEX { + get { + return ResourceManager.GetString("HEX", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Define INVerse text. + /// + internal static string INV { + get { + return ResourceManager.GetString("INV", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Define REVerse. + /// + internal static string REV { + get { + return ResourceManager.GetString("REV", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Define STRing with leading length (1 byte). + /// + internal static string STR { + get { + return ResourceManager.GetString("STR", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Define STRing Long with leading length (2 bytes). + /// + internal static string STRL { + get { + return ResourceManager.GetString("STRL", resourceCulture); + } + } + } +} diff --git a/Resources/data.resx b/Resources/data.resx new file mode 100644 index 0000000..61a26f9 --- /dev/null +++ b/Resources/data.resx @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Define ADdRess (3 bytes) + + + Define ADdRess Long (4 bytes) + + + Define ASCii ("" positive, '' negative) + + + Place a CHecKsum in object code + + + Define Address (2 bytes) + + + Define Byte (1 byte) + + + ??? + + + Define Dextral Character Inverted + + + Define Double Byte (2 bytes) + + + ??? + + + DeFine Byte (1 byte) + + + Define Storage (x bytes) (e.g. DS 10 (put $00 in 10 bytes), DS 10,$80 (put $80 in 10 bytes)) + + + Define Word (2 bytes) + + + Define FLaShing text + + + Define HEX data (1 byte) + + + Define INVerse text + + + Define REVerse + + + Define STRing with leading length (1 byte) + + + Define STRing Long with leading length (2 bytes) + + \ No newline at end of file diff --git a/Resources/directives.Designer.cs b/Resources/directives.Designer.cs new file mode 100644 index 0000000..eff2724 --- /dev/null +++ b/Resources/directives.Designer.cs @@ -0,0 +1,450 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace VSMerlin32.Resources { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class directives { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal directives() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("VSMerlin32.Resources.directives", typeof(directives).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to ???. + /// + internal static string ANOP { + get { + return ResourceManager.GetString("ANOP", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Send a line of ASTerisks. + /// + internal static string AST { + get { + return ResourceManager.GetString("AST", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Calculate and print CYCle times for the code. + /// + internal static string CYC { + get { + return ResourceManager.GetString("CYC", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to DATe stamp assembly listing. + /// + internal static string DAT { + get { + return ResourceManager.GetString("DAT", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Dummy section END. + /// + internal static string DEND { + get { + return ResourceManager.GetString("DEND", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to DO directive. + /// + internal static string DO { + get { + return ResourceManager.GetString("DO", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Define the name of the output binary after the directive. + /// + internal static string DSK { + get { + return ResourceManager.GetString("DSK", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to DUMmy section start. + /// + internal static string DUM { + get { + return ResourceManager.GetString("DUM", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ELSE condition. + /// + internal static string ELSE { + get { + return ResourceManager.GetString("ELSE", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to End of LUP. + /// + internal static string ELUP { + get { + return ResourceManager.GetString("ELUP", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to (--\^). + /// + internal static string ELUPRegex { + get { + return ResourceManager.GetString("ELUPRegex", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to --^. + /// + internal static string ELUPValue { + get { + return ResourceManager.GetString("ELUPValue", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to END of source file. + /// + internal static string END { + get { + return ResourceManager.GetString("END", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Define constant values (same as =). + /// + internal static string EQU { + get { + return ResourceManager.GetString("EQU", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Force ERRor. + /// + internal static string ERR { + get { + return ResourceManager.GetString("ERR", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Macro EXPand control. + /// + internal static string EXP { + get { + return ResourceManager.GetString("EXP", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mandatory ENDdirective for IF and DO . + /// + internal static string FIN { + get { + return ResourceManager.GetString("FIN", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to IF condition. + /// + internal static string IF { + get { + return ResourceManager.GetString("IF", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Define label from KeyBoarD. + /// + internal static string KBD { + get { + return ResourceManager.GetString("KBD", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Relocate code (same as DSK in Merlin 32). + /// + internal static string LNK { + get { + return ResourceManager.GetString("LNK", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ???. + /// + internal static string LONGA { + get { + return ResourceManager.GetString("LONGA", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ???. + /// + internal static string LONGI { + get { + return ResourceManager.GetString("LONGI", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to LiSTing control. + /// + internal static string LST { + get { + return ResourceManager.GetString("LST", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to LiSTDO OFF areas of code. + /// + internal static string LSTDO { + get { + return ResourceManager.GetString("LSTDO", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Repeat portions of the code (until the --^ directive). + /// + internal static string LUP { + get { + return ResourceManager.GetString("LUP", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Set the size for M (Accumulator) and X (X and Y Registers). + /// + internal static string MX { + get { + return ResourceManager.GetString("MX", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Must be followed by the program's origin, e.g. org $800. + /// + internal static string ORG { + get { + return ResourceManager.GetString("ORG", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to New PAGe. + /// + internal static string PAG { + get { + return ResourceManager.GetString("PAG", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to PAUse. + /// + internal static string PAU { + get { + return ResourceManager.GetString("PAU", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Insert the content of a source file. + /// + internal static string PUT { + get { + return ResourceManager.GetString("PUT", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ???. + /// + internal static string PUTBIN { + get { + return ResourceManager.GetString("PUTBIN", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use at the start of the program to write 16 bit relocatable code. + /// + internal static string REL { + get { + return ResourceManager.GetString("REL", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Define the name of the output binary before the directive. + /// + internal static string SAV { + get { + return ResourceManager.GetString("SAV", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to SKiP lines. + /// + internal static string SKP { + get { + return ResourceManager.GetString("SKP", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ???. + /// + internal static string START { + get { + return ResourceManager.GetString("START", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to SWeet16 opcodes. + /// + internal static string SW { + get { + return ResourceManager.GetString("SW", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to TRuncate control. + /// + internal static string TR { + get { + return ResourceManager.GetString("TR", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to TiTLe heading. + /// + internal static string TTL { + get { + return ResourceManager.GetString("TTL", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Set the output file type (one byte: $00-$FF). + /// + internal static string TYP { + get { + return ResourceManager.GetString("TYP", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Insert macros. + /// + internal static string USE { + get { + return ResourceManager.GetString("USE", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ???. + /// + internal static string USING { + get { + return ResourceManager.GetString("USING", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ???. + /// + internal static string USR { + get { + return ResourceManager.GetString("USR", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ???. + /// + internal static string XC { + get { + return ResourceManager.GetString("XC", resourceCulture); + } + } + } +} diff --git a/Resources/directives.resx b/Resources/directives.resx new file mode 100644 index 0000000..07d9f1f --- /dev/null +++ b/Resources/directives.resx @@ -0,0 +1,249 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ??? + + + Send a line of ASTerisks + + + Calculate and print CYCle times for the code + + + DATe stamp assembly listing + + + Dummy section END + + + DO directive + + + Define the name of the output binary after the directive + + + DUMmy section start + + + ELSE condition + + + End of LUP + + + (--\^) + + + --^ + + + END of source file + + + Define constant values (same as =) + + + Force ERRor + + + Macro EXPand control + + + Mandatory ENDdirective for IF and DO + + + IF condition + + + Define label from KeyBoarD + + + Relocate code (same as DSK in Merlin 32) + + + ??? + + + ??? + + + LiSTing control + + + LiSTDO OFF areas of code + + + Repeat portions of the code (until the --^ directive) + + + Set the size for M (Accumulator) and X (X and Y Registers) + + + Must be followed by the program's origin, e.g. org $800 + + + New PAGe + + + PAUse + + + Insert the content of a source file + + + ??? + + + Use at the start of the program to write 16 bit relocatable code + + + Define the name of the output binary before the directive + + + SKiP lines + + + ??? + + + SWeet16 opcodes + + + TRuncate control + + + TiTLe heading + + + Set the output file type (one byte: $00-$FF) + + + Insert macros + + + ??? + + + ??? + + + ??? + + \ No newline at end of file diff --git a/Resources/opcodes.Designer.cs b/Resources/opcodes.Designer.cs new file mode 100644 index 0000000..b1bd9ea --- /dev/null +++ b/Resources/opcodes.Designer.cs @@ -0,0 +1,972 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace VSMerlin32.Resources { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class opcodes { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal opcodes() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("VSMerlin32.Resources.opcodes", typeof(opcodes).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to ADd with Carry. + /// + internal static string ADC { + get { + return ResourceManager.GetString("ADC", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ADd with Carry Long. + /// + internal static string ADCL { + get { + return ResourceManager.GetString("ADCL", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Bitwise AND with accumulator. + /// + internal static string AND { + get { + return ResourceManager.GetString("AND", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Bitwise AND with accumulator, Long. + /// + internal static string ANDL { + get { + return ResourceManager.GetString("ANDL", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ASL shifts all bits left one position. 0 is shifted into bit 0 and the original bit 7 is shifted into the Carry. + /// + internal static string ASL { + get { + return ResourceManager.GetString("ASL", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Branch if Carry Clear. + /// + internal static string BCC { + get { + return ResourceManager.GetString("BCC", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Branch if Carry Set. + /// + internal static string BCS { + get { + return ResourceManager.GetString("BCS", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Branch if EQual/Branch if zero. + /// + internal static string BEQ { + get { + return ResourceManager.GetString("BEQ", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to BIt Test. + /// + internal static string BIT { + get { + return ResourceManager.GetString("BIT", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Branch if MInus value. + /// + internal static string BMI { + get { + return ResourceManager.GetString("BMI", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Branch if Not Equal/Branch if not zero. + /// + internal static string BNE { + get { + return ResourceManager.GetString("BNE", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Branch if PLus value. + /// + internal static string BPL { + get { + return ResourceManager.GetString("BPL", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to BRanch Always. + /// + internal static string BRA { + get { + return ResourceManager.GetString("BRA", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Software BReaK. + /// + internal static string BRK { + get { + return ResourceManager.GetString("BRK", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to BRanch always Long. + /// + internal static string BRL { + get { + return ResourceManager.GetString("BRL", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Branch if oVerflow Clear. + /// + internal static string BVC { + get { + return ResourceManager.GetString("BVC", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Branch if oVerflow Set. + /// + internal static string BVS { + get { + return ResourceManager.GetString("BVS", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to CLear Carry flag. + /// + internal static string CLC { + get { + return ResourceManager.GetString("CLC", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to CLear Decimal flag. + /// + internal static string CLD { + get { + return ResourceManager.GetString("CLD", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to CLear Interrupt flag. + /// + internal static string CLI { + get { + return ResourceManager.GetString("CLI", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to CLear oVerflow flag. + /// + internal static string CLV { + get { + return ResourceManager.GetString("CLV", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to CoMPare accumulator with memory. + /// + internal static string CMP { + get { + return ResourceManager.GetString("CMP", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to CoMPare accumulator with memory, Long. + /// + internal static string CMPL { + get { + return ResourceManager.GetString("CMPL", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to COProcessor empowerment (interrupt). + /// + internal static string COP { + get { + return ResourceManager.GetString("COP", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ComPare X with memory. + /// + internal static string CPX { + get { + return ResourceManager.GetString("CPX", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ComPare Y with memory. + /// + internal static string CPY { + get { + return ResourceManager.GetString("CPY", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to DECrement accumulator or memory. + /// + internal static string DEC { + get { + return ResourceManager.GetString("DEC", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to DEcrement X. + /// + internal static string DEX { + get { + return ResourceManager.GetString("DEX", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Decrement Y. + /// + internal static string DEY { + get { + return ResourceManager.GetString("DEY", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Exclusive OR accumulator with memory. + /// + internal static string EOR { + get { + return ResourceManager.GetString("EOR", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Exclusive OR accumulator with memory, Long. + /// + internal static string EORL { + get { + return ResourceManager.GetString("EORL", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to INCrement accumulator or memory. + /// + internal static string INC { + get { + return ResourceManager.GetString("INC", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to INcrement X. + /// + internal static string INX { + get { + return ResourceManager.GetString("INX", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to INcrement Y. + /// + internal static string INY { + get { + return ResourceManager.GetString("INY", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to JuMp, Long. + /// + internal static string JML { + get { + return ResourceManager.GetString("JML", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to JuMP. + /// + internal static string JMP { + get { + return ResourceManager.GetString("JMP", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to JuMP, Long. + /// + internal static string JMPL { + get { + return ResourceManager.GetString("JMPL", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Jump to Subroutine, Long. + /// + internal static string JSL { + get { + return ResourceManager.GetString("JSL", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Jump to SubRoutine. + /// + internal static string JSR { + get { + return ResourceManager.GetString("JSR", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to LoaD Accumulator. + /// + internal static string LDA { + get { + return ResourceManager.GetString("LDA", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to LoaD Accumulator, Long. + /// + internal static string LDAL { + get { + return ResourceManager.GetString("LDAL", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to LoaD X register. + /// + internal static string LDX { + get { + return ResourceManager.GetString("LDX", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to LoaD Y register. + /// + internal static string LDY { + get { + return ResourceManager.GetString("LDY", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to LSR shifts all bits right one position. 0 is shifted into bit 7 and the original bit 0 is shifted into the Carry. + /// + internal static string LSR { + get { + return ResourceManager.GetString("LSR", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Block MoVe Negative. + /// + internal static string MVN { + get { + return ResourceManager.GetString("MVN", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Block MoVe Positive. + /// + internal static string MVP { + get { + return ResourceManager.GetString("MVP", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No OPeration. + /// + internal static string NOP { + get { + return ResourceManager.GetString("NOP", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Bitwise OR Accumulator with memory. + /// + internal static string ORA { + get { + return ResourceManager.GetString("ORA", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Bitwise OR Accumulator with memory, Long. + /// + internal static string ORAL { + get { + return ResourceManager.GetString("ORAL", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Push Effective Address. + /// + internal static string PEA { + get { + return ResourceManager.GetString("PEA", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Push Effective Indirect address. + /// + internal static string PEI { + get { + return ResourceManager.GetString("PEI", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Push program countEr Relative. + /// + internal static string PER { + get { + return ResourceManager.GetString("PER", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to PusH Accumulator. + /// + internal static string PHA { + get { + return ResourceManager.GetString("PHA", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to PusH data Bank register. + /// + internal static string PHB { + get { + return ResourceManager.GetString("PHB", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to PusH Direct page register. + /// + internal static string PHD { + get { + return ResourceManager.GetString("PHD", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to PusH program banK register. + /// + internal static string PHK { + get { + return ResourceManager.GetString("PHK", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to PusH Processor status flags. + /// + internal static string PHP { + get { + return ResourceManager.GetString("PHP", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to PusH X. + /// + internal static string PHX { + get { + return ResourceManager.GetString("PHX", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to PusH Y. + /// + internal static string PHY { + get { + return ResourceManager.GetString("PHY", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Pull Accumulator. + /// + internal static string PLA { + get { + return ResourceManager.GetString("PLA", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Pull data Bank register. + /// + internal static string PLB { + get { + return ResourceManager.GetString("PLB", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Pull Direct page register. + /// + internal static string PLD { + get { + return ResourceManager.GetString("PLD", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Pull Processor status flags. + /// + internal static string PLP { + get { + return ResourceManager.GetString("PLP", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Pull X. + /// + internal static string PLX { + get { + return ResourceManager.GetString("PLX", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Pull Y. + /// + internal static string PLY { + get { + return ResourceManager.GetString("PLY", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to REset Processor status flag. + /// + internal static string REP { + get { + return ResourceManager.GetString("REP", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ROtate Left accumulator or memory. + /// + internal static string ROL { + get { + return ResourceManager.GetString("ROL", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ROtate Right accumulator or memory. + /// + internal static string ROR { + get { + return ResourceManager.GetString("ROR", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ReTurn from Interrupt. + /// + internal static string RTI { + get { + return ResourceManager.GetString("RTI", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ReTurn from subroutine, Long. + /// + internal static string RTL { + get { + return ResourceManager.GetString("RTL", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ReTurn from Subroutine; pulls the top two bytes off the stack (low byte first) and transfers program control to that address+1. + /// + internal static string RTS { + get { + return ResourceManager.GetString("RTS", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to SuBtract with Carry. + /// + internal static string SBC { + get { + return ResourceManager.GetString("SBC", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to SuBtract with Carry Long. + /// + internal static string SBCL { + get { + return ResourceManager.GetString("SBCL", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to SEt Carry flag. + /// + internal static string SEC { + get { + return ResourceManager.GetString("SEC", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to SEt Decimal flag. + /// + internal static string SED { + get { + return ResourceManager.GetString("SED", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to SEt Interrupt flag. + /// + internal static string SEI { + get { + return ResourceManager.GetString("SEI", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to SEt Processor status flag. + /// + internal static string SEP { + get { + return ResourceManager.GetString("SEP", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to STore Accumulator to memory. + /// + internal static string STA { + get { + return ResourceManager.GetString("STA", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to STore Accumulator to memory, Long. + /// + internal static string STAL { + get { + return ResourceManager.GetString("STAL", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to SToP the clock. + /// + internal static string STP { + get { + return ResourceManager.GetString("STP", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to STore X to memory. + /// + internal static string STX { + get { + return ResourceManager.GetString("STX", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to STore Y to memory. + /// + internal static string STY { + get { + return ResourceManager.GetString("STY", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to STore Zero to memory. + /// + internal static string STZ { + get { + return ResourceManager.GetString("STZ", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Transfer Accumulator to X. + /// + internal static string TAX { + get { + return ResourceManager.GetString("TAX", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Transfer Accumulator to Y. + /// + internal static string TAY { + get { + return ResourceManager.GetString("TAY", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Transfer aCcumulator to Direct page. + /// + internal static string TCD { + get { + return ResourceManager.GetString("TCD", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Transfer aCcumulator to Stack page. + /// + internal static string TCS { + get { + return ResourceManager.GetString("TCS", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Transfer Direct page to aCcumulator. + /// + internal static string TDC { + get { + return ResourceManager.GetString("TDC", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Test and Reset Bit. + /// + internal static string TRB { + get { + return ResourceManager.GetString("TRB", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Test and Set Bit. + /// + internal static string TSB { + get { + return ResourceManager.GetString("TSB", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Transfer Stack pointer to aCcumulator. + /// + internal static string TSC { + get { + return ResourceManager.GetString("TSC", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Transfer Stack pointer to X. + /// + internal static string TSX { + get { + return ResourceManager.GetString("TSX", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Transfer X to Accumulator. + /// + internal static string TXA { + get { + return ResourceManager.GetString("TXA", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Transfer X to Stack pointer. + /// + internal static string TXS { + get { + return ResourceManager.GetString("TXS", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Transfer X to Y. + /// + internal static string TXY { + get { + return ResourceManager.GetString("TXY", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Transfer Y to Accumulator. + /// + internal static string TYA { + get { + return ResourceManager.GetString("TYA", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Transfer Y to X. + /// + internal static string TYX { + get { + return ResourceManager.GetString("TYX", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to WAIt for interrupt. + /// + internal static string WAI { + get { + return ResourceManager.GetString("WAI", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Reserved for future use, it performs no operation. + /// + internal static string WDM { + get { + return ResourceManager.GetString("WDM", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to EXchange low and high byte of the Accumulator. + /// + internal static string XBA { + get { + return ResourceManager.GetString("XBA", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to EXchange Carry and Emulation. + /// + internal static string XCE { + get { + return ResourceManager.GetString("XCE", resourceCulture); + } + } + } +} diff --git a/Resources/opcodes.resx b/Resources/opcodes.resx new file mode 100644 index 0000000..3e5f8d2 --- /dev/null +++ b/Resources/opcodes.resx @@ -0,0 +1,423 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ADd with Carry + + + ADd with Carry Long + + + Bitwise AND with accumulator + + + Bitwise AND with accumulator, Long + + + ASL shifts all bits left one position. 0 is shifted into bit 0 and the original bit 7 is shifted into the Carry + + + Branch if Carry Clear + + + Branch if Carry Set + + + Branch if EQual/Branch if zero + + + BIt Test + + + Branch if MInus value + + + Branch if Not Equal/Branch if not zero + + + Branch if PLus value + + + BRanch Always + + + Software BReaK + + + BRanch always Long + + + Branch if oVerflow Clear + + + Branch if oVerflow Set + + + CLear Carry flag + + + CLear Decimal flag + + + CLear Interrupt flag + + + CLear oVerflow flag + + + CoMPare accumulator with memory + + + CoMPare accumulator with memory, Long + + + COProcessor empowerment (interrupt) + + + ComPare X with memory + + + ComPare Y with memory + + + DECrement accumulator or memory + + + DEcrement X + + + Decrement Y + + + Exclusive OR accumulator with memory + + + Exclusive OR accumulator with memory, Long + + + INCrement accumulator or memory + + + INcrement X + + + INcrement Y + + + JuMp, Long + + + JuMP + + + JuMP, Long + + + Jump to Subroutine, Long + + + Jump to SubRoutine + + + LoaD Accumulator + + + LoaD Accumulator, Long + + + LoaD X register + + + LoaD Y register + + + LSR shifts all bits right one position. 0 is shifted into bit 7 and the original bit 0 is shifted into the Carry + + + Block MoVe Negative + + + Block MoVe Positive + + + No OPeration + + + Bitwise OR Accumulator with memory + + + Bitwise OR Accumulator with memory, Long + + + Push Effective Address + + + Push Effective Indirect address + + + Push program countEr Relative + + + PusH Accumulator + + + PusH data Bank register + + + PusH Direct page register + + + PusH program banK register + + + PusH Processor status flags + + + PusH X + + + PusH Y + + + Pull Accumulator + + + Pull data Bank register + + + Pull Direct page register + + + Pull Processor status flags + + + Pull X + + + Pull Y + + + REset Processor status flag + + + ROtate Left accumulator or memory + + + ROtate Right accumulator or memory + + + ReTurn from Interrupt + + + ReTurn from subroutine, Long + + + ReTurn from Subroutine; pulls the top two bytes off the stack (low byte first) and transfers program control to that address+1 + + + SuBtract with Carry + + + SuBtract with Carry Long + + + SEt Carry flag + + + SEt Decimal flag + + + SEt Interrupt flag + + + SEt Processor status flag + + + STore Accumulator to memory + + + STore Accumulator to memory, Long + + + SToP the clock + + + STore X to memory + + + STore Y to memory + + + STore Zero to memory + + + Transfer Accumulator to X + + + Transfer Accumulator to Y + + + Transfer aCcumulator to Direct page + + + Transfer aCcumulator to Stack page + + + Transfer Direct page to aCcumulator + + + Test and Reset Bit + + + Test and Set Bit + + + Transfer Stack pointer to aCcumulator + + + Transfer Stack pointer to X + + + Transfer X to Accumulator + + + Transfer X to Stack pointer + + + Transfer X to Y + + + Transfer Y to Accumulator + + + Transfer Y to X + + + WAIt for interrupt + + + Reserved for future use, it performs no operation + + + EXchange low and high byte of the Accumulator + + + EXchange Carry and Emulation + + \ No newline at end of file diff --git a/Test/HelloWorld.s b/Test/HelloWorld.s new file mode 100644 index 0000000..9027fd7 --- /dev/null +++ b/Test/HelloWorld.s @@ -0,0 +1,11 @@ +; Uses S-C Assembler variant. +* This is also a valid comment... + org $800 +main ldy #$00 +start_loop lda HelloWorld,y + beq end_loop + jsr $fded ; ROM routine, COUT, y is preserved + iny + bne start_loop +end_loop rts +HelloWorld ASC "HELLO WORLD!"00 diff --git a/VSLanguageServiceIcon.jpg b/VSLanguageServiceIcon.jpg new file mode 100644 index 0000000000000000000000000000000000000000..87a5bdbdff18b47f73a7640c7d86afcd8692cff1 GIT binary patch literal 21190 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 literal 0 HcmV?d00001 diff --git a/VSLanguageServicePreviewImage.jpg b/VSLanguageServicePreviewImage.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6cc9bc1d450ea643f1d0a67a8dace5de216412e9 GIT binary patch literal 38372 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 literal 0 HcmV?d00001 diff --git a/source.extension.vsixmanifest b/source.extension.vsixmanifest new file mode 100644 index 0000000..017a409 --- /dev/null +++ b/source.extension.vsixmanifest @@ -0,0 +1,36 @@ + + + + + + Merlin32 Language Service + Merlin32 classifier extension to the Visual Studio Editor. + http://www.brutaldeluxe.fr/products/crossdevtools/merlin/ + License.txt + https://github.com/OlivierGuinart/Merlin32Language + VSLanguageServiceIcon.jpg + VSLanguageServicePreviewImage.jpg + 6502, merlin32, assembly language, language service, Apple II + + + + + + + + + + + + + + \ No newline at end of file