/// <summary>
        /// Transforms each unit reference of the given <paramref name="unitReferenceSet"/> into a full qualified
        /// unit name.
        /// </summary>
        /// <param name="unitReferenceSet">Collection of unit references</param>
        /// <returns>Collection of full qualified unit names</returns>
        /// <exception cref="BuddyCompilerException">If a unit name could not be found</exception>
        private string[] ToQualifiedUnitNames(string[] unitReferenceSet)
        {
            if (unitReferenceSet == null)
            {
                return(new string[0]);
            }
            if (unitReferenceSet.Length == 0)
            {
                return(new string[0]);
            }

            IImportPathProvider importPathProvider = ImportPathProvider;

            string[] qualifiedUnitNames = new string[unitReferenceSet.Length];
            for (int i = -1; ++i != unitReferenceSet.Length;)
            {
                string   unitReference = unitReferenceSet[i].Replace('_', ' ');
                UnitName unitName      = importPathProvider.GetUnitName(unitReference);
                if (unitName == null)
                {
                    throw new BuddyCompilerException($"There is no unit registered for the given reference '{unitReference}'");
                }
                string qualifiedUnitName = unitName.ToQualifiedString();
                qualifiedUnitNames[i] = qualifiedUnitName;
            }

            return(qualifiedUnitNames);
        }
Beispiel #2
0
 /// <inheritdoc />
 public string GetPath(UnitName unitName)
 {
     if (unitName.ToQualifiedString() == "v.s.w.t1")
     {
         return(iFileSet[0].FullName);
     }
     return(iFileSet[1].FullName);
 }
Beispiel #3
0
 public string ToQualifiedString(UnitName unitName)
 {
     return(unitName.ToQualifiedString());
 }
        /// <summary>
        /// Compiles the given <paramref name="buddyText"/> into a TDIL file as string.
        /// </summary>
        /// <param name="buddyText">Buddy language text to compile</param>
        /// <returns>Compiled buddy text</returns>
        /// <exception cref="ArgumentNullException">If the given <paramref name="buddyText"/> is NULL or empty</exception>
        /// <exception cref="BuddyCompilerException">If something went wrong during the compilation process</exception>
        public virtual string Compile(string buddyText)
        {
            if (string.IsNullOrEmpty(buddyText))
            {
                throw new ArgumentNullException(nameof(buddyText));
            }

            StopwatchLog   compilerStopwatch = StopwatchLog.StartNew(LogCompilerPerformance);
            TdilFileWriter tdilFileWriter    = new TdilFileWriter("0.1.2");

            try {
                // TODO Remove workaround add 'Vorbedingung'
                if (!buddyText.Contains("Vorbedingung: -") && buddyText.Contains("Anwendung: "))
                {
                    int insertPoint = buddyText.IndexOf("Schritte:");
                    buddyText = buddyText.Insert(insertPoint, "Vorbedingung: -\r\n\r\n");
                }

                // TODO Remove workaround add final linefeeds
                if (!buddyText.EndsWith("\r\n"))
                {
                    buddyText += "\r\n";
                }

                // Process text
                StopwatchLog  textProcessorStopwatch = StopwatchLog.StartNew(LogBuddyTextProcessorPerformance);
                BuddyTextInfo buddyTextInfo          = _buddyTextProcessor.ProcessText(buddyText);
                textProcessorStopwatch.Dispose(buddyTextInfo);

                // In the case of an short form, create standard names
                if (buddyTextInfo.IsShortForm)
                {
                    buddyTextInfo.ApplicationText = "untitled";
                    buddyTextInfo.UseCaseText     = "untitled";
                    buddyTextInfo.ScenarioText    = "untitled";
                }

                // TODO Check if this is a workaround and remove it
                if (string.IsNullOrEmpty(buddyTextInfo.VersionText))
                {
                    buddyTextInfo.VersionText = "*";
                }

                // Little verification
                ushort expectedNoOfSteps = CalculateNoOfSteps(buddyText);
                if (expectedNoOfSteps != buddyTextInfo.Steps.Length)
                {
                    ThrowUncompilableDirectiveException(buddyText, expectedNoOfSteps, buddyTextInfo.Steps.Length);
                }

                string[] buddyTextSteps = buddyTextInfo.Steps;

                // Normalize directives
                string[] normalizedBuddyTextSteps;
                using (StopwatchLog.StartNew(LogNormalizingPerformance)) {
                    normalizedBuddyTextSteps = NormalizeSteps(buddyTextSteps, buddyTextInfo.Parameters);
                }

                // Create unit name
                UnitName unitName          = new UnitName(buddyTextInfo.ApplicationText, buddyTextInfo.VersionText, buddyTextInfo.UseCaseText, buddyTextInfo.ScenarioText);
                string   qualifiedUnitName = unitName.ToQualifiedString();

                using (CompilingContext compilingContext = new CompilingContext()) {
                    // Compile directives
                    string[] directiveSet = new string[1000];
                    int      pr           = 0;
                    using (StopwatchLog.StartNew(LogInstructionTranslationPerformance)) {
                        for (int i = -1; ++i != normalizedBuddyTextSteps.Length;)
                        {
                            string actionLine = normalizedBuddyTextSteps[i];
                            string directive  = _instructionTranslator.ToDirective(actionLine);
                            directiveSet[pr++] = directive;
                        }
                        Array.Resize(ref directiveSet, pr);
                    }

                    // Add alias references
                    string[] aliasReferenceSet = compilingContext.AliasReferenceSet;
                    tdilFileWriter.AddAlias(aliasReferenceSet);

                    // Add unit references
                    string[] unitReferenceSet   = compilingContext.UnitReferenceSet;
                    string[] qualifiedUnitNames = ToQualifiedUnitNames(unitReferenceSet);
                    tdilFileWriter.AddImport(qualifiedUnitNames);

                    // Write unit
                    using (StopwatchLog.StartNew(LogTdilUnitWritingPerformance)) {
                        using (TdilUnitWriter tdilUnitWriter = tdilFileWriter.CreateUnit(qualifiedUnitName)) {
                            string executeSectionName           = unitName.GetEncodedScenarioName();
                            BuddyTextParameter[] unitParameters = buddyTextInfo.Parameters;
                            string[]             parameterNames = new string[unitParameters.Length];
                            for (int l = -1; ++l != parameterNames.Length;)
                            {
                                parameterNames[l] = unitParameters[l].Name;
                            }

                            // Write main section
                            using (TdilSectionWriter tdilSectionWriter = tdilUnitWriter.CreateSection("Main")) {
                                // Declare parameters
                                for (int i = -1; ++i != unitParameters.Length;)
                                {
                                    BuddyTextParameter unitParameter = unitParameters[i];
                                    tdilSectionWriter.AppendLine("{0} = {1}", unitParameter.Name, unitParameter.DefaultValue);
                                }

                                // Add start statement
                                tdilSectionWriter.AppendLine("start(,, \"{{{0}}}\")", buddyTextInfo.ApplicationText);

                                // Add argument invocation line if there are some
                                string argInvLine = null;
                                if (parameterNames.Length != 0)
                                {
                                    string argSetLine = string.Join(", ", parameterNames);
                                    argInvLine = $"({argSetLine})";
                                }

                                tdilSectionWriter.AppendLine("gosub {0}:{1}", executeSectionName, argInvLine);

                                // Add close statement
                                tdilSectionWriter.AppendLine("close(_Application,, Default)");
                                tdilSectionWriter.AppendLine("kill(_Application,, 3000)");

                                tdilSectionWriter.AppendLine("close(\"AcroRd32\",, Default)");
                                tdilSectionWriter.AppendLine("kill(\"AcroRd32\",, 3000)");
                            }

                            // Write execute section
                            using (TdilSectionWriter tdilSectionWriter = tdilUnitWriter.CreateSection(executeSectionName, parameterNames)) {
                                for (int l = -1; ++l != directiveSet.Length;)
                                {
                                    tdilSectionWriter.AppendLine(directiveSet[l]);
                                }
                            }
                        }
                    }
                }
            } catch (BuddyCompilerException) {
                throw;
            } catch (Exception ex) {
                throw new BuddyCompilerException("Error on compiling buddy language unit.", ex);
            }

            string tdilFileContent = tdilFileWriter.WriteToString();

            compilerStopwatch.Dispose();

            return(tdilFileContent);
        }