Пример #1
0
 // IGenerator
 public void OutputOrgDirective(int offset, int address)
 {
     // 64tass separates the "compile offset", which determines where the output fits
     // into the generated binary, and "program counter", which determines the code
     // the assembler generates.  Since we need to explicitly specify every byte in
     // the output file, the compile offset isn't very useful.  We want to set it once
     // before the first line of code, then leave it alone.
     //
     // Any subsequent ORG changes are made to the program counter, and take the form
     // of a pair of ops (.logical <addr> to open, .here to end).  Omitting the .here
     // causes an error.
     if (offset == 0)
     {
         // Set the "compile offset" to the initial address.
         OutputLine("*", "=", SourceFormatter.FormatHexValue(Project.AddrMap.Get(0), 4),
                    string.Empty);
     }
     else
     {
         if (mNeedHereOp)
         {
             OutputLine(string.Empty, SourceFormatter.FormatPseudoOp(HERE_PSEUDO_OP),
                        string.Empty, string.Empty);
         }
         OutputLine(string.Empty, SourceFormatter.FormatPseudoOp(sDataOpNames.OrgDirective),
                    SourceFormatter.FormatHexValue(address, 4), string.Empty);
         mNeedHereOp = true;
     }
 }
Пример #2
0
        // IGenerator
        public void OutputOrgDirective(int offset, int address)
        {
            // If there's only one address range, just set the "real" PC.  If there's more
            // than one we can run out of space if the source file has a chunk in high memory
            // followed by a chunk in low memory, because the "real" PC determines when the
            // 64KB bank is overrun.
            if (offset == 0)
            {
                // first one
                if (Project.AddrMap.Count == 1)
                {
                    OutputLine("*", "=", SourceFormatter.FormatHexValue(address, 4), string.Empty);
                    return;
                }
                else
                {
                    // set the real PC to address zero to ensure we get a full 64KB
                    OutputLine("*", "=", SourceFormatter.FormatHexValue(0, 4), string.Empty);
                }
            }

            if (mInPseudoPcBlock)
            {
                // close previous block
                OutputLine(string.Empty, CLOSE_PSEUDOPC, string.Empty, string.Empty);
            }
            OutputLine(string.Empty, sDataOpNames.OrgDirective,
                       SourceFormatter.FormatHexValue(address, 4) + " {", string.Empty);
            mInPseudoPcBlock = true;
        }
Пример #3
0
        // IGenerator
        public void OutputOrgDirective(int offset, int address)
        {
            // Linear search for offset.  List should be small, so this should be quick.
            int index = 0;

            foreach (AddressMap.AddressMapEntry ame in Project.AddrMap)
            {
                if (ame.Offset == offset)
                {
                    break;
                }
                index++;
            }

            mLineBuilder.Clear();
            TextUtil.AppendPaddedString(mLineBuilder, ";", 0);
            // using +1 to make it look like the comment ';' shifted it over
            TextUtil.AppendPaddedString(mLineBuilder, SourceFormatter.FormatPseudoOp(".segment"),
                                        mColumnWidths[0] + 1);
            TextUtil.AppendPaddedString(mLineBuilder, string.Format("\"SEG{0:D3}\"", index),
                                        mColumnWidths[0] + mColumnWidths[1] + 1);
            OutputLine(mLineBuilder.ToString());

            OutputLine(string.Empty, SourceFormatter.FormatPseudoOp(sDataOpNames.OrgDirective),
                       SourceFormatter.FormatHexValue(address, 4), string.Empty);
        }
Пример #4
0
        /// <summary>
        /// Outputs formatted data in an unformatted way, because the code generator couldn't
        /// figure out how to do something better.
        /// </summary>
        private void OutputNoJoy(int offset, int length, string labelStr, string commentStr)
        {
            byte[] data = Project.FileData;
            Debug.Assert(length > 0);
            Debug.Assert(offset >= 0 && offset < data.Length);

            bool singleValue = true;
            byte val         = data[offset];

            for (int i = 1; i < length; i++)
            {
                if (data[offset + i] != val)
                {
                    singleValue = false;
                    break;
                }
            }

            if (singleValue && length > 1)
            {
                string opcodeStr  = SourceFormatter.FormatPseudoOp(sDataOpNames.Fill);
                string operandStr = length + "," + SourceFormatter.FormatHexValue(val, 2);
                OutputLine(labelStr, opcodeStr, operandStr, commentStr);
            }
            else
            {
                OutputDenseHex(offset, length, labelStr, commentStr);
            }
        }
Пример #5
0
        private static string InjectSourceCodeAtLevel(int level, string sourceCode)
        {
            SourceFormatter formatter = new SourceFormatter();

            formatter.AppendCodeBlock(level, sourceCode);
            return(formatter.ReturnSource());
        }
        public static string GenerateContractEventHandlerMethod(CsField sourceField, CsEvent targetEvent, NamespaceManager manager = null)
        {
            if (sourceField == null)
            {
                return(null);
            }
            if (!sourceField.IsLoaded)
            {
                return(null);
            }
            if (targetEvent == null)
            {
                return(null);
            }
            if (!targetEvent.IsLoaded)
            {
                return(null);
            }

            SourceFormatter formatter = new SourceFormatter();

            formatter.AppendCodeLine(0, "/// <summary>");
            formatter.AppendCodeLine(0, $"/// Handles the raised event {targetEvent.Name}");
            formatter.AppendCodeLine(0, "/// </summary>");
            formatter.AppendCodeLine(0, $"protected void {GenerateContractEventHandlerMethodName(sourceField,targetEvent)}{targetEvent.EventHandlerDelegate.Parameters.CSharpFormatParametersSignature(manager,false)}");
            formatter.AppendCodeLine(0, "{");
            formatter.AppendCodeLine(0);
            formatter.AppendCodeLine(1, "//TODO: Add Event handler logic");
            formatter.AppendCodeLine(0);
            formatter.AppendCodeLine(0, "}");
            formatter.AppendCodeLine(0);

            return(formatter.ReturnSource());
        }
Пример #7
0
        // IGenerator
        public void OutputAsmConfig()
        {
            CpuDef cpuDef = Project.CpuDef;
            string cpuStr;

            if (cpuDef.Type == CpuDef.CpuType.Cpu65816)
            {
                cpuStr = "65816";
            }
            else if (cpuDef.Type == CpuDef.CpuType.Cpu65C02)
            {
                cpuStr = "65c02";
            }
            else if (cpuDef.Type == CpuDef.CpuType.CpuW65C02)
            {
                cpuStr = "w65c02";
            }
            else if (cpuDef.Type == CpuDef.CpuType.Cpu6502 && cpuDef.HasUndocumented)
            {
                cpuStr = "6510";
            }
            else
            {
                cpuStr = "6502";
            }

            OutputLine(string.Empty, SourceFormatter.FormatPseudoOp("!cpu"), cpuStr, string.Empty);
        }
        /// <summary>
        /// Updates the directives in the page file to use razor syntax.
        /// </summary>
        /// <param name="fileName">The file being processed.</param>
        /// <param name="sourceData">The source data to be updated.</param>
        /// <returns>The updated content.</returns>
        private async Task <String> SetRazorPageDirectives(string fileName, Dictionary <string, string> sourceData)
        {
            //String result = String.Empty;
            SourceFormatter result = new SourceFormatter();

            try
            {
                var    pageData = sourceData["HeaderData"];
                Regex  regex    = new Regex(@"(?<=\bMasterPageFile="")[^""]*");
                Match  match    = regex.Match(pageData);
                string layout   = match.Value;
                layout = layout.Replace(".", ""); //remove the old-style Site.Master layout to read SiteMaster

                result.AppendCode($"@page \"/{fileName}\" ");
                if (layout.Length > 0)
                {
                    //Making sure the ~ gets removed from directives
                    result.AppendCodeLine(0, $"@layout { layout.Replace("~/", "")}");
                }
                //result += $"@inherits {fileName}Base\r\n\r\n {sourceData["alteredSource"]}";

                result.AppendCodeLine(0);
                result.AppendCodeLine(0);
                result.AppendCodeLine(0, $"{sourceData["alteredSource"]}");
            }
            catch (Exception unhandledError)
            {
                await _statusTracking.UpdateCurrentStatusAsync(MigrationStepEnum.AspxPages, MessageTypeEnum.Error,
                                                               $"The following unhandled error occured while setting the razor page directives in the file {fileName}. '{unhandledError.Message}'");
            }

            return(result.ReturnSource());
        }
Пример #9
0
        public static string GeneratePartialClass(CsClass source, NamespaceManager manager = null)
        {
            if (source == null)
            {
                return(null);
            }
            if (!source.IsLoaded)
            {
                return(null);
            }
            SourceFormatter formatter = new SourceFormatter();

            StringBuilder classBuilder = new StringBuilder($"{source.Security.CSharpFormatKeyword()} partial {Keywords.Class} {source.Name}");

            if (source.IsGeneric)
            {
                classBuilder.Append(source.GenericParameters.CSharpFormatGenericParametersSignature(manager));
            }

            formatter.AppendCodeLine(0);
            formatter.AppendCodeLine(0, $"namespace {source.Namespace}");
            formatter.AppendCodeLine(0, "{");
            formatter.AppendCodeLine(0);
            formatter.AppendCodeLine(1, classBuilder.ToString());
            formatter.AppendCodeLine(1, "{");
            formatter.AppendCodeLine(1);
            formatter.AppendCodeLine(1, "}");
            formatter.AppendCodeLine(0);
            formatter.AppendCodeLine(0, "}");
            return(formatter.ReturnSource());
        }
Пример #10
0
        public void TestBasicTransformation()
        {
            SourceCode           source         = new SourceCode("abc123");
            SourceTransformation transformation = new SourceTransformation(new SourceContext(0, 3), n => "a");
            string transformed = SourceFormatter.Format(source, transformation);

            Assert.AreEqual(transformed, "aaa123");
        }
Пример #11
0
        public void TestNestedTransformation()
        {
            SourceCode           source          = new SourceCode("1111111");
            SourceTransformation transformation1 = new SourceTransformation(new SourceContext(2, 3), n => "2");
            SourceTransformation transformation2 = new SourceTransformation(new SourceContext(3, 1), n => "3");
            string transformed = SourceFormatter.Format(source, transformation1, transformation2);

            Assert.AreEqual(transformed, "1123211");
        }
Пример #12
0
        public void TestUnrollingWithHigherIndexThanZero()
        {
            SourceCode           source          = new SourceCode("abc123");
            SourceTransformation transformation1 = new SourceTransformation(new SourceContext(2, 3), n => "2");
            SourceTransformation transformation2 = new SourceTransformation(new SourceContext(3, 1), n => "3");
            var unrolled = SourceFormatter.UnrollNested(new[] { transformation1, transformation2 }).ToArray();

            Assert.IsNotNull(unrolled);
            Assert.AreEqual(unrolled.Length, 3);
            Assert.AreEqual(unrolled[0].Context, new SourceContext(2, 1));
            Assert.AreEqual(unrolled[1].Context, new SourceContext(3, 1));
            Assert.AreEqual(unrolled[2].Context, new SourceContext(4, 1));
        }
Пример #13
0
 // IGenerator
 public void OutputLocalVariableTable(int offset, List <DefSymbol> newDefs,
                                      LocalVariableTable allDefs)
 {
     foreach (DefSymbol defSym in newDefs)
     {
         string valueStr = PseudoOp.FormatNumericOperand(SourceFormatter,
                                                         Project.SymbolTable, null, defSym.DataDescriptor, defSym.Value, 1,
                                                         PseudoOp.FormatNumericOpFlags.OmitLabelPrefixSuffix);
         OutputLine(SourceFormatter.FormatVariableLabel(defSym.Label),
                    SourceFormatter.FormatPseudoOp(sDataOpNames.VarDirective),
                    valueStr, SourceFormatter.FormatEolComment(defSym.Comment));
     }
 }
Пример #14
0
        public void TestUnrolling()
        {
            SourceCode           source               = new SourceCode("abc123");
            SourceTransformation transformation       = new SourceTransformation(new SourceContext(0, 4), n => "a");
            SourceTransformation transformationNested = new SourceTransformation(new SourceContext(1, 1), n => "b");
            var unrolled = SourceFormatter.UnrollNested(new[] { transformation, transformationNested }).ToArray();

            Assert.IsNotNull(unrolled);
            Assert.AreEqual(unrolled.Length, 4);
            Assert.AreEqual(unrolled[0].Context, new SourceContext(0, 1));
            Assert.AreEqual(unrolled[1].Context, new SourceContext(1, 1));
            Assert.AreEqual(unrolled[2].Context, new SourceContext(2, 1));
            Assert.AreEqual(unrolled[3].Context, new SourceContext(3, 1));
        }
Пример #15
0
 // IGenerator
 public void OutputLocalVariableTable(int offset, List <DefSymbol> newDefs,
                                      LocalVariableTable allDefs)
 {
     foreach (DefSymbol defSym in newDefs)
     {
         // Use an operand length of 1 so values are shown as concisely as possible.
         string valueStr = PseudoOp.FormatNumericOperand(SourceFormatter,
                                                         Project.SymbolTable, null, defSym.DataDescriptor, defSym.Value, 1,
                                                         PseudoOp.FormatNumericOpFlags.None);
         OutputLine(SourceFormatter.FormatVariableLabel(defSym.Label),
                    SourceFormatter.FormatPseudoOp(sDataOpNames.VarDirective),
                    valueStr, SourceFormatter.FormatEolComment(defSym.Comment));
     }
 }
Пример #16
0
        // IGenerator
        public void OutputRegWidthDirective(int offset, int prevM, int prevX, int newM, int newX)
        {
            // prevM/prevX may be ambiguous for offset 0, but otherwise everything
            // should be either 0 or 1.
            Debug.Assert(newM == 0 || newM == 1);
            Debug.Assert(newX == 0 || newX == 1);

            if (offset == 0 && newM == 1 && newX == 1)
            {
                // Assembler defaults to short regs, so we can skip this.
                return;
            }
            OutputLine(string.Empty, SourceFormatter.FormatPseudoOp(REG_WIDTH_DIRECTIVE),
                       "%" + newM + newX, string.Empty);
        }
Пример #17
0
 // IGenerator
 public void FlushArDirectives()
 {
     // Output pending directives.  There will always be something to do here unless
     // we were in "relative" mode.
     Debug.Assert(mNextAddress >= 0 || mIsInRelative);
     if (mNextAddress >= 0)
     {
         OutputLine(string.Empty,
                    SourceFormatter.FormatPseudoOp(sDataOpNames.ArStartDirective),
                    SourceFormatter.FormatHexValue(mNextAddress, 4),
                    string.Empty);
     }
     mNextAddress  = -1;
     mIsInRelative = false;
 }
Пример #18
0
 // IGenerator
 public void OutputRegWidthDirective(int offset, int prevM, int prevX, int newM, int newX)
 {
     if (prevM != newM)
     {
         string mop = (newM == 0) ? ".al" : ".as";
         OutputLine(string.Empty, SourceFormatter.FormatPseudoOp(mop),
                    string.Empty, string.Empty);
     }
     if (prevX != newX)
     {
         string xop = (newX == 0) ? ".xl" : ".xs";
         OutputLine(string.Empty, SourceFormatter.FormatPseudoOp(xop),
                    string.Empty, string.Empty);
     }
 }
Пример #19
0
        // IGenerator
        public void OutputLocalVariableTable(int offset, List <DefSymbol> newDefs,
                                             LocalVariableTable allDefs)
        {
            OutputLine(string.Empty, "!zone", "Z" + offset.ToString("x6"), string.Empty);
            for (int i = 0; i < allDefs.Count; i++)
            {
                DefSymbol defSym = allDefs[i];

                string valueStr = PseudoOp.FormatNumericOperand(SourceFormatter,
                                                                Project.SymbolTable, null, defSym.DataDescriptor, defSym.Value, 1,
                                                                PseudoOp.FormatNumericOpFlags.None);
                OutputEquDirective(SourceFormatter.FormatVariableLabel(defSym.Label),
                                   valueStr, defSym.Comment);
            }
        }
        public static string GenerateRaiseContractEvent(CsEvent targetEvent, NamespaceManager manager = null)
        {
            if (targetEvent == null)
            {
                return(null);
            }
            if (!targetEvent.IsLoaded)
            {
                return(null);
            }

            SourceFormatter formatter = new SourceFormatter();


            string eventParameters = targetEvent.RaiseMethod.Parameters.CSharpFormatParametersSignature(manager);


            int parameterCount = 0;

            StringBuilder parameterBuilder = new StringBuilder();

            foreach (var raiseMethodParameter in targetEvent.RaiseMethod.Parameters)
            {
                parameterCount++;

                if (parameterCount > 1)
                {
                    parameterBuilder.Append($", {raiseMethodParameter.Name}");
                    continue;
                }

                parameterBuilder.Append(raiseMethodParameter.Name);
            }

            formatter.AppendCodeLine(0, "/// <summary>");
            formatter.AppendCodeLine(0, $"/// Raises the event {targetEvent.Name}");
            formatter.AppendCodeLine(0, "/// </summary>");
            formatter.AppendCodeLine(0, $"protected void On{targetEvent.Name}{targetEvent.RaiseMethod.Parameters.CSharpFormatParametersSignature(manager,false)}");
            formatter.AppendCodeLine(0, "{");
            formatter.AppendCodeLine(0);
            formatter.AppendCodeLine(1, $"var raiseHandler = _{targetEvent.Name.ConvertToCamelCase()};");
            formatter.AppendCodeLine(1, $"raiseHandler?.Invoke({parameterBuilder});");
            formatter.AppendCodeLine(0);
            formatter.AppendCodeLine(0, "}");
            formatter.AppendCodeLine(0);

            return(formatter.ReturnSource());
        }
Пример #21
0
        // IGenerator
        public void OutputAsmConfig()
        {
            CpuDef cpuDef = Project.CpuDef;
            string cpuStr;

            if (cpuDef.Type == CpuDef.CpuType.Cpu65816)
            {
                cpuStr = "65816";
            }
            else if (cpuDef.Type == CpuDef.CpuType.Cpu65C02)
            {
                cpuStr = "65c02";
            }
            else if (cpuDef.Type == CpuDef.CpuType.CpuW65C02)
            {
                cpuStr = "w65c02";
            }
            else if (cpuDef.Type == CpuDef.CpuType.Cpu6502 && cpuDef.HasUndocumented)
            {
                cpuStr = "6502i";
            }
            else
            {
                cpuStr = "6502";
            }

            OutputLine(string.Empty, SourceFormatter.FormatPseudoOp(".cpu"),
                       '\"' + cpuStr + '\"', string.Empty);

            // C64 PETSCII and C64 screen codes are built in.  Define ASCII if we also
            // need that.
            mCurrentEncoding = CharEncoding.Encoding.C64Petscii;

            CheckAsciiFormats(out bool hasAscii, out bool hasHighAscii);
            if (hasHighAscii)
            {
                OutputLine(string.Empty, ".enc", '"' + HIGH_ASCII_ENC_NAME + '"', string.Empty);
                OutputLine(string.Empty, ".cdef", "$20,$7e,$a0", string.Empty);
                mCurrentEncoding = CharEncoding.Encoding.HighAscii;
            }
            if (hasAscii)
            {
                OutputLine(string.Empty, ".enc", '"' + ASCII_ENC_NAME + '"', string.Empty);
                OutputLine(string.Empty, ".cdef", "$20,$7e,$20", string.Empty);
                mCurrentEncoding = CharEncoding.Encoding.Ascii;
            }
        }
        /// <summary>
        /// Generates a method that releases to a target interface contract for the target field.
        /// </summary>
        /// <param name="sourceField">The field for which events to subscribe to.</param>
        /// <param name="contract">The contract to subscribe to.</param>
        /// <returns>Full source code for the subscribe method.</returns>
        public static string GenerateContractReleaseMethod(CsField sourceField, CsInterface contract)
        {
            if (sourceField == null)
            {
                return(null);
            }
            if (!sourceField.IsLoaded)
            {
                return(null);
            }
            if (contract == null)
            {
                return(null);
            }
            if (!contract.IsLoaded)
            {
                return(null);
            }

            SourceFormatter formatter = new SourceFormatter();

            formatter.AppendCodeLine(0, "/// <summary>");
            formatter.AppendCodeLine(0, $"/// Releases the events from the interface contract of {contract.Namespace}.{contract.Name} for the field {sourceField.Name}");
            formatter.AppendCodeLine(0, "/// </summary>");
            formatter.AppendCodeLine(0, $"private void {GenerateContractReleaseMethodName(sourceField)}()");
            formatter.AppendCodeLine(0, "{");
            formatter.AppendCodeLine(0);
            formatter.AppendCodeLine(1, $"if({sourceField.Name} == null) return;");
            formatter.AppendCodeLine(0);
            foreach (var contractEvent in contract.Events)
            {
                if (!contractEvent.IsLoaded)
                {
                    continue;
                }
                formatter.AppendCodeLine(1, $"{sourceField.Name}.{contractEvent.Name} -= {sourceField.Name.ConvertToProperCase(new []{'_'})}_{contractEvent.Name}_EventHandler;");
            }
            formatter.AppendCodeLine(0);
            formatter.AppendCodeLine(0, "}");
            formatter.AppendCodeLine(0);

            return(formatter.ReturnSource());
        }
Пример #23
0
        // IGenerator
        public void OutputLocalVariableTable(int offset, List <DefSymbol> newDefs,
                                             LocalVariableTable allDefs)
        {
            // We can do better here, but it requires knowing whether anything in "newDefs"
            // overwrote a previous entry.  If everything is new, we don't need to start
            // a new zone, and can just output newDefs.  (We don't need to start a new zone
            // on a "clear previous".)
            OutputLine(string.Empty, "!zone", "Z" + offset.ToString("x6"), string.Empty);
            for (int i = 0; i < allDefs.Count; i++)
            {
                DefSymbol defSym = allDefs[i];

                string valueStr = PseudoOp.FormatNumericOperand(SourceFormatter,
                                                                Project.SymbolTable, null, defSym.DataDescriptor, defSym.Value, 1,
                                                                PseudoOp.FormatNumericOpFlags.OmitLabelPrefixSuffix);
                OutputEquDirective(SourceFormatter.FormatVariableLabel(defSym.Label),
                                   valueStr, defSym.Comment);
            }
        }
Пример #24
0
        // IGenerator
        public void GenerateShortSequence(int offset, int length, out string opcode,
                                          out string operand)
        {
            Debug.Assert(length >= 1 && length <= 4);

            // Use a comma-separated list of individual hex bytes.
            opcode = sDataOpNames.DefineData1;

            StringBuilder sb = new StringBuilder(length * 4);

            for (int i = 0; i < length; i++)
            {
                if (i != 0)
                {
                    sb.Append(',');
                }
                sb.Append(SourceFormatter.FormatHexValue(Project.FileData[offset + i], 2));
            }
            operand = sb.ToString();
        }
Пример #25
0
 // IGenerator
 public void OutputOrgDirective(int offset, int address)
 {
     // For the first one, set the "real" PC.  For all subsequent directives, set the
     // "pseudo" PC.
     if (offset == 0)
     {
         OutputLine("*", "=", SourceFormatter.FormatHexValue(address, 4), string.Empty);
     }
     else
     {
         if (mInPseudoPcBlock)
         {
             // close previous block
             OutputLine(string.Empty, CLOSE_PSEUDOPC, string.Empty, string.Empty);
         }
         OutputLine(string.Empty, sDataOpNames.OrgDirective,
                    SourceFormatter.FormatHexValue(address, 4) + " {", string.Empty);
         mInPseudoPcBlock = true;
     }
 }
        /// <summary>
        /// Extension method that will add a using statement to target source code. If the using statement already exists it will simply return the existing source.
        /// </summary>
        /// <param name="source">The source code to update.</param>
        /// <param name="nameSpace">The namespace to be added to the using statement.</param>
        /// <param name="alias">Optional parameter to set if you want an alias assigned to the namespace.</param>
        /// <returns>The updated source code or the original source code if no changes were necessary.</returns>
        public static async Task <CsSource> AddUsingStatementAsync(this CsSource source, string nameSpace, string alias = null)
        {
            // ReSharper disable once ExpressionIsAlwaysNull
            if (source == null)
            {
                return(source);
            }

            if (string.IsNullOrEmpty(nameSpace))
            {
                return(source);
            }

            if (source.HasUsingStatement(nameSpace, alias))
            {
                return(source);
            }

            SourceFormatter usingFormatter = new SourceFormatter();

            usingFormatter.AppendCodeLine(0, alias == null ? $"using {nameSpace};" : $"using {alias} = {nameSpace};");

            string usingStatement = usingFormatter.ReturnSource();

            CsSource result = null;

            if (source.NamespaceReferences.Any())
            {
                var lastUsingStatement = source.NamespaceReferences.Last();

                result = await lastUsingStatement.AddAfterAsync(usingStatement);
            }
            else
            {
                result = await source.AddToBeginningAsync(usingStatement);
            }

            return(result);
        }
Пример #27
0
 // IGenerator
 public void OutputEquDirective(string name, string valueStr, string comment)
 {
     OutputLine(name, SourceFormatter.FormatPseudoOp(sDataOpNames.EquDirective),
                valueStr, SourceFormatter.FormatEolComment(comment));
 }
Пример #28
0
        // IGenerator
        public void OutputDataOp(int offset)
        {
            Formatter formatter = SourceFormatter;

            byte[]   data = Project.FileData;
            Anattrib attr = Project.GetAnattrib(offset);

            string labelStr = string.Empty;

            if (attr.Symbol != null)
            {
                labelStr = mLocalizer.ConvLabel(attr.Symbol.Label);
            }

            string commentStr = SourceFormatter.FormatEolComment(Project.Comments[offset]);
            string opcodeStr, operandStr;

            FormatDescriptor dfd = attr.DataDescriptor;

            Debug.Assert(dfd != null);
            int length = dfd.Length;

            Debug.Assert(length > 0);

            bool multiLine = false;

            switch (dfd.FormatType)
            {
            case FormatDescriptor.Type.Default:
                if (length != 1)
                {
                    Debug.Assert(false);
                    length = 1;
                }
                opcodeStr = sDataOpNames.DefineData1;
                int operand = RawData.GetWord(data, offset, length, false);
                operandStr = formatter.FormatHexValue(operand, length * 2);
                break;

            case FormatDescriptor.Type.NumericLE:
                opcodeStr = sDataOpNames.GetDefineData(length);
                operand   = RawData.GetWord(data, offset, length, false);
                UpdateCharacterEncoding(dfd);
                operandStr = PseudoOp.FormatNumericOperand(formatter, Project.SymbolTable,
                                                           mLocalizer.LabelMap, dfd, operand, length,
                                                           PseudoOp.FormatNumericOpFlags.OmitLabelPrefixSuffix);
                break;

            case FormatDescriptor.Type.NumericBE:
                opcodeStr = sDataOpNames.GetDefineBigData(length);
                if ((string.IsNullOrEmpty(opcodeStr)))
                {
                    // Nothing defined, output as comma-separated single-byte values.
                    GenerateShortSequence(offset, length, out opcodeStr, out operandStr);
                }
                else
                {
                    UpdateCharacterEncoding(dfd);
                    operand    = RawData.GetWord(data, offset, length, true);
                    operandStr = PseudoOp.FormatNumericOperand(formatter, Project.SymbolTable,
                                                               mLocalizer.LabelMap, dfd, operand, length,
                                                               PseudoOp.FormatNumericOpFlags.OmitLabelPrefixSuffix);
                }
                break;

            case FormatDescriptor.Type.Fill:
                opcodeStr  = sDataOpNames.Fill;
                operandStr = length + "," + formatter.FormatHexValue(data[offset], 2);
                break;

            case FormatDescriptor.Type.Dense:
                multiLine = true;
                opcodeStr = operandStr = null;
                OutputDenseHex(offset, length, labelStr, commentStr);
                break;

            case FormatDescriptor.Type.Junk:
                int fillVal = Helper.CheckRangeHoldsSingleValue(data, offset, length);
                if (fillVal >= 0 && GenCommon.CheckJunkAlign(offset, dfd, Project.AddrMap))
                {
                    // .align <expression>[, <fill>]
                    opcodeStr = sDataOpNames.Align;
                    int alignVal = 1 << FormatDescriptor.AlignmentToPower(dfd.FormatSubType);
                    operandStr = alignVal.ToString() +
                                 "," + formatter.FormatHexValue(fillVal, 2);
                }
                else if (fillVal >= 0)
                {
                    // treat same as Fill
                    opcodeStr  = sDataOpNames.Fill;
                    operandStr = length + "," + formatter.FormatHexValue(fillVal, 2);
                }
                else
                {
                    // treat same as Dense
                    multiLine = true;
                    opcodeStr = operandStr = null;
                    OutputDenseHex(offset, length, labelStr, commentStr);
                }
                break;

            case FormatDescriptor.Type.StringGeneric:
            case FormatDescriptor.Type.StringReverse:
            case FormatDescriptor.Type.StringNullTerm:
            case FormatDescriptor.Type.StringL8:
            case FormatDescriptor.Type.StringL16:
            case FormatDescriptor.Type.StringDci:
                multiLine = true;
                opcodeStr = operandStr = null;
                OutputString(offset, labelStr, commentStr);
                break;

            default:
                opcodeStr  = "???";
                operandStr = "***";
                break;
            }

            if (!multiLine)
            {
                opcodeStr = formatter.FormatPseudoOp(opcodeStr);
                OutputLine(labelStr, opcodeStr, operandStr, commentStr);
            }
        }
Пример #29
0
        private async Task <CsSource> UpdateSubscriptionAsync(CsField subscriptionField, CsClass sourceClass, VsCSharpSource source)
        {
            SourceFormatter formatter        = new SourceFormatter();
            string          injectSourceCode = null;

            var contract = subscriptionField.DataType.GetInterfaceModel();

            if (contract == null)
            {
                return(null);
            }

            CsSource sourceCode = source.SourceCode;

            try
            {
                CsClass currentClass = sourceClass;

                var events = contract.Events;

                var subscribePath = ContractHelper.GetSubscribeFilePath(currentClass);


                if (!subscribePath.hasFile)
                {
                    var manager = sourceCode.LoadNamespaceManager(sourceClass.Namespace);

                    var parent = await source.GetParentAsync();

                    if (parent == null)
                    {
                        throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                    }

                    VsDocument generatedDocument  = null;
                    string     partialClassSource = CSharpSourceGenerationCommon.GeneratePartialClass(currentClass, manager);
                    if (parent.ModelType == VisualStudioModelType.ProjectFolder)
                    {
                        var parentFolder = parent as VsProjectFolder;

                        if (parentFolder == null)
                        {
                            throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                        }

                        generatedDocument = await parentFolder.AddDocumentAsync(Path.GetFileName(subscribePath.filePath),
                                                                                partialClassSource);
                    }
                    else
                    {
                        var parentProject = parent as VsProject;

                        if (parentProject == null)
                        {
                            throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                        }

                        generatedDocument = await parentProject.AddDocumentAsync(subscribePath.filePath,
                                                                                 partialClassSource);
                    }
                    sourceCode = await generatedDocument.GetCSharpSourceModelAsync();

                    sourceCode = await sourceCode.AddMissingNamespaces(contract.Events, currentClass.Namespace);

                    currentClass = sourceCode.GetModel(currentClass.LookupPath) as CsClass;

                    if (currentClass == null)
                    {
                        throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                    }
                }
                else
                {
                    var parent = await source.GetParentAsync();

                    VsCSharpSource sourceDocument = null;
                    if (parent.ModelType == VisualStudioModelType.ProjectFolder)
                    {
                        var parentFolder = parent as VsProjectFolder;

                        if (parentFolder == null)
                        {
                            throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                        }

                        var children = await parentFolder.GetChildrenAsync(false, true);

                        sourceDocument = children.Where(c => c.ModelType == VisualStudioModelType.CSharpSource)
                                         .Cast <VsCSharpSource>()
                                         .FirstOrDefault(s => s.SourceCode.SourceDocument == subscribePath.filePath);
                    }
                    else
                    {
                        var parentProject = parent as VsProject;

                        if (parentProject == null)
                        {
                            throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                        }

                        var children = await parentProject.GetChildrenAsync(false, true);

                        sourceDocument = children.Where(c => c.ModelType == VisualStudioModelType.CSharpSource)
                                         .Cast <VsCSharpSource>()
                                         .FirstOrDefault(s => s.SourceCode.SourceDocument == subscribePath.filePath);;
                    }

                    if (sourceDocument == null)
                    {
                        throw new CodeFactoryException("Could load the contract document.");
                    }

                    sourceCode = sourceDocument.SourceCode;

                    sourceCode = await sourceCode.AddMissingNamespaces(contract.Events, currentClass.Namespace);

                    currentClass = sourceCode.GetModel(currentClass.LookupPath) as CsClass;
                    if (currentClass == null)
                    {
                        throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                    }
                }

                var namespaceManager = sourceCode.LoadNamespaceManager(currentClass.Namespace);

                foreach (var contractEvent in contract.Events)
                {
                    var eventHandlerName =
                        CSharpSourceGenerationWPF.GenerateContractEventHandlerMethodName(subscriptionField, contractEvent);

                    if (eventHandlerName == null)
                    {
                        throw new CodeFactoryException($"Could not create the source code for a contract event handler.");
                    }

                    if (currentClass.Methods.Any(m => m.Name == eventHandlerName))
                    {
                        continue;
                    }

                    var eventHandlerSource = CSharpSourceGenerationWPF.GenerateContractEventHandlerMethod(subscriptionField, contractEvent,
                                                                                                          namespaceManager);

                    if (eventHandlerSource == null)
                    {
                        throw new CodeFactoryException($"Could not create the source code for the event handler {eventHandlerName}");
                    }

                    sourceCode = await currentClass.AddToEndAsync(subscribePath.filePath, InjectSourceCodeAtLevel(2, eventHandlerSource));

                    currentClass = sourceCode.GetModel(currentClass.LookupPath) as CsClass;
                    if (currentClass == null)
                    {
                        throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                    }
                }

                var subscriptionName   = CSharpSourceGenerationWPF.GenerateContractSubscriptionMethodName(subscriptionField);
                var subscriptionMethod = currentClass.Methods.FirstOrDefault(m => m.Name == subscriptionName);

                if (subscriptionMethod != null)
                {
                    sourceCode = await subscriptionMethod.DeleteAsync();

                    currentClass = sourceCode.GetModel(currentClass.LookupPath) as CsClass;
                    if (currentClass == null)
                    {
                        throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                    }
                }

                var subscriptionSource = CSharpSourceGenerationWPF.GenerateContractSubscriptionMethod(subscriptionField, contract);

                if (subscriptionSource == null)
                {
                    throw new CodeFactoryException("Cannot generate the subscription contract source code.");
                }

                sourceCode = await currentClass.AddToEndAsync(subscribePath.filePath, InjectSourceCodeAtLevel(2, subscriptionSource));

                currentClass = sourceCode.GetModel(currentClass.LookupPath) as CsClass;
                if (currentClass == null)
                {
                    throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                }

                var releaseName   = CSharpSourceGenerationWPF.GenerateContractReleaseMethodName(subscriptionField);
                var releaseMethod = currentClass.Methods.FirstOrDefault(m => m.Name == releaseName);

                if (releaseMethod != null)
                {
                    sourceCode = await releaseMethod.DeleteAsync();

                    currentClass = sourceCode.GetModel(currentClass.LookupPath) as CsClass;
                    if (currentClass == null)
                    {
                        throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                    }
                }

                var releaseSource = CSharpSourceGenerationWPF.GenerateContractReleaseMethod(subscriptionField, contract);

                if (releaseSource == null)
                {
                    throw new CodeFactoryException("Cannot generate the release contract source code.");
                }

                sourceCode = await currentClass.AddToEndAsync(subscribePath.filePath, InjectSourceCodeAtLevel(2, releaseSource));
            }
            catch (CodeFactoryException)
            {
                throw;
            }
            catch (Exception unhandledException)
            {
                throw new CodeFactoryException("The following unhandledException occured", unhandledException);
            }

            return(sourceCode);
        }
Пример #30
0
        // IGenerator
        public void OutputArDirective(CommonUtil.AddressMap.AddressChange change)
        {
            // This is similar in operation to the AsmTass64 implementation.  See comments there.
            Debug.Assert(mPcDepth >= 0);
            int nextAddress = change.Address;

            if (nextAddress == Address.NON_ADDR)
            {
                // Start non-addressable regions at zero to ensure they don't overflow bank.
                nextAddress = 0;
            }
            if (change.IsStart)
            {
                if (change.Region.HasValidPreLabel)
                {
                    string labelStr = mLocalizer.ConvLabel(change.Region.PreLabel);
                    OutputLine(labelStr, string.Empty, string.Empty, string.Empty);
                }
                if (mPcDepth == 0 && mFirstIsOpen)
                {
                    mPcDepth++;

                    // Set the "real" PC for the first address change.  If we're in "loadable"
                    // mode, just set "*=".  If we're in "streaming" mode, we set "*=" to zero
                    // and then use a pseudo-PC.
                    if (mOutputMode == OutputMode.Loadable)
                    {
                        OutputLine("*", "=", SourceFormatter.FormatHexValue(nextAddress, 4),
                                   string.Empty);
                        return;
                    }
                    else
                    {
                        // set the real PC to address zero to ensure we get a full 64KB
                        OutputLine("*", "=", SourceFormatter.FormatHexValue(0, 4), string.Empty);
                    }
                }
                AddressMap.AddressRegion region = change.Region;
                string addrStr;
                if (region.HasValidIsRelative)
                {
                    int    diff = nextAddress - region.PreLabelAddress;
                    string pfxStr;
                    if (diff >= 0)
                    {
                        pfxStr = "*+";
                    }
                    else
                    {
                        pfxStr = "*-";
                        diff   = -diff;
                    }
                    addrStr = pfxStr + SourceFormatter.FormatHexValue(diff, 4);
                }
                else
                {
                    addrStr = SourceFormatter.FormatHexValue(nextAddress, 4);
                }
                OutputLine(string.Empty,
                           SourceFormatter.FormatPseudoOp(sDataOpNames.ArStartDirective),
                           addrStr + " {",
                           string.Empty);
                mPcDepth++;
            }
            else
            {
                mPcDepth--;
                if (mPcDepth > 0 || !mFirstIsOpen)
                {
                    // close previous block
                    OutputLine(string.Empty,
                               SourceFormatter.FormatPseudoOp(sDataOpNames.ArEndDirective),
                               string.Empty, string.Empty);
                    //";" + SourceFormatter.FormatPseudoOp(sDataOpNames.ArStartDirective));
                }
                else
                {
                    // mark initial "*=" region as closed, but don't output anything
                    mFirstIsOpen = false;
                }
            }
        }