commit d821e25fdb0e97e3405595cf2e0f7d3f94ac5b1d Author: Olivier Guinart Date: Fri Dec 30 16:46:52 2016 -0800 First commit 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 0000000..5966779 Binary files /dev/null and b/Merlin32LanguageService.gif differ 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 0000000..87a5bdb Binary files /dev/null and b/VSLanguageServiceIcon.jpg differ diff --git a/VSLanguageServicePreviewImage.jpg b/VSLanguageServicePreviewImage.jpg new file mode 100644 index 0000000..6cc9bc1 Binary files /dev/null and b/VSLanguageServicePreviewImage.jpg differ 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