Esempio n. 1
0
    public static ProcessResult <Formula> ParseFormula(string formula)
    {
        var lexer = new Lexer(formula);

        var(success, tokens, errorMessage) = lexer.GetTokens();
        if (!success)
        {
            return(new ProcessResult <Formula>(errorMessage));
        }

        (success, errorMessage) = AreTokensValid(tokens);
        if (!success)
        {
            return(new ProcessResult <Formula>($"Parsing of formula ${formula} was aborted: {errorMessage}"));
        }
        TreeToken syntaxTree;

        (success, syntaxTree, errorMessage) = CreateSyntaxTree(tokens);
        if (!success)
        {
            return(new ProcessResult <Formula>(errorMessage));
        }

        // remaining steps:
        // convert any nested statements to inline clips - might involve some refactoring where parsing to commands and applying these can be done selectively and not as part of the fixed pipeline we have now

        Token[] commandTokens;
        (success, commandTokens, errorMessage) = ResolveAndFlattenSyntaxTree(syntaxTree);
        if (!success)
        {
            return(new ProcessResult <Formula>(errorMessage));
        }

        try
        {
            var allReferencedClips = commandTokens.Where(x => x.IsClipReference)
                                     .Select(x => ClipReference.FromString(x.Value)).ToList();

            var sourceClipReferences = commandTokens.TakeWhile(x => x.IsClipReference).Select(x => ClipReference.FromString(x.Value)).ToList();
            var commandTokensLists   = ExtractCommandTokensLists(commandTokens.Skip(sourceClipReferences.Count).ToArray());
            var commands             = commandTokensLists.Select(ParseTokensToCommand).ToList();

            var parsedFormula = new Formula(commands, sourceClipReferences, allReferencedClips, new Dictionary <ClipReference, ClipSlot>());
            return(new ProcessResult <Formula>(parsedFormula));
        }
        catch (ArgumentException ae)
        {
            return(new ProcessResult <Formula>($"ParseFormula threw exception: {ae.Message}"));
        }
    }
    public void TestEvaluationOfClipIsAbortedWhenContentsUnchanged()
    {
        var commandHandler = new CommandHandler();
        var result         = commandHandler.SetAndEvaluateClipData(new Clip(4, true)
        {
            ClipReference = ClipReference.FromString("A1"),
            Notes         = new SortedList <NoteEvent> {
                new NoteEvent(36, 0, .5m, 100),
                new NoteEvent(38, 1, .5m, 100),
                new NoteEvent(40, 2, .75m, 100)
            }
        });

        Assert.IsTrue(result.RanToCompletion);

        result = commandHandler.SetAndEvaluateClipData(new Clip(4, true)
        {
            ClipReference = ClipReference.FromString("A1"),
            Notes         = new SortedList <NoteEvent> {
                new NoteEvent(36, 0, .75m, 100),
                new NoteEvent(38, 1, .5m, 100),
                new NoteEvent(40, 2, .5m, 100)
            }
        });
        Assert.IsTrue(result.RanToCompletion);

        result = commandHandler.SetAndEvaluateClipData(new Clip(4, true)
        {
            ClipReference = ClipReference.FromString("A1"),
            Notes         = new SortedList <NoteEvent> {
                new NoteEvent(36, 0, .75m, 100),
                new NoteEvent(38, 1, .5m, 100),
                new NoteEvent(40, 2, .5m, 100)
            }
        });
        Assert.IsFalse(result.RanToCompletion);
        Assert.AreEqual($"Aborted evaluation of clip at A1 since it was unchanged.", result.Warnings.FirstOrDefault());
    }