Esempio n. 1
0
        private IEnumerable <Parselet> LeftSquare(Token <R> token)
        {
            var tagToken = reader.ReadToken();

            switch (tagToken.ID)
            {
            default:
                compiler.SyntaxError(tagToken, "Expected function name, subroutine, regex or a script.");
                break;

            case R.Text:
                yield return(Parselet.GetParselet("FunctionText", tagToken, AddToOutput));

                break;

            case R.Regex:
                yield return(Parselet.GetParselet("FunctionRegex", tagToken, AddToOutput));

                break;

            case R.At:
                AddToOutput(compiler.ReadScript());
                break;

            case R.Dollar:
                yield return(Parselet.GetParselet("FunctionSubroutine", tagToken, AddToOutput));

                break;
            }
        }
Esempio n. 2
0
        private IEnumerable <Parselet> BlockWeight(Token <R> token)
        {
            Token <R> funcToken = null;
            var       actions   = new List <RantAction>();

            while (!reader.End)
            {
                funcToken = reader.ReadToken();

                if (funcToken.ID == R.RightParen)
                {
                    reader.SkipSpace();

                    if (!actions.Any())
                    {
                        compiler.SyntaxError(funcToken, "Expected weight value");
                    }

                    RantAction weightAction;
                    // probably a number
                    if (actions[0] is RAText)
                    {
                        if (actions.Count > 1)
                        {
                            if (!(actions[1] is RAText) || ((RAText)actions[1]).Text != "." || actions.Count != 3)
                            {
                                compiler.SyntaxError(actions[1].Range, "Invalid block weight value.");
                            }
                            weightAction = new RAText(actions[0].Range,
                                                      (actions[0] as RAText).Text +
                                                      (actions[1] as RAText).Text +
                                                      (actions[2] as RAText).Text);
                        }
                        else
                        {
                            weightAction = actions[0];
                        }
                    }
                    else
                    {
                        weightAction = new RASequence(actions, funcToken);
                    }

                    AddToOutput(weightAction);
                    yield break;
                }

                yield return(Parselet.GetParselet(funcToken, actions.Add));
            }

            // TODO: this token is "our" (the one that result is us being yielded) token. maybe have the 'fromToken' passed?
            compiler.SyntaxError(token, "Unterminated function: unexpected end of file");
        }
Esempio n. 3
0
        private IEnumerable <Parselet> LeftCurly(Token <R> token)
        {
            reader.SkipSpace();

            // LOOK AT ME. I'M THE COMPILER NOW
            Token <R> readToken = null;
            var       actions   = new List <RantAction>();
            var       sequences = new List <RantAction>();

            List <_ <int, double> >     constantWeights = null;
            List <_ <int, RantAction> > dynamicWeights  = null;

            while (!reader.End)
            {
                readToken = reader.ReadToken();

                // TODO: kinda stupid having this handle it's own whitespace when we have a parselet for whitespace
                if (readToken.ID == R.Whitespace)
                {
                    switch (reader.PeekType())
                    {
                    case R.RightCurly:
                    case R.Pipe:
                        continue;
                    }
                }
                else if (readToken.ID == R.LeftParen) // weight
                {
                    RantAction weightAction = null;

                    // i like this AddToOutput thing because it's just a delegate that takes in a RantAction.
                    // it can do anything with the RantAction, in this case it sets it to our weightAction
                    // :>
                    yield return(Parselet.GetParselet("BlockWeight", readToken, a => weightAction = a));

                    constantWeights = constantWeights ?? new List <_ <int, double> >();
                    dynamicWeights  = dynamicWeights ?? new List <_ <int, RantAction> >();

                    if (weightAction is RAText) // constant
                    {
                        var    strWeight = (weightAction as RAText).Text;
                        double d;

                        if (!Util.ParseDouble(strWeight, out d))
                        {
                            compiler.SyntaxError(weightAction.Range, $"Invalid weight value '{strWeight}'.");
                        }

                        constantWeights.Add(_.Create(sequences.Count, d));
                    }
                    else // dynamic
                    {
                        // TODO: there's some weird issue going on with doubles being seen as dynamic weights
                        dynamicWeights.Add(_.Create(sequences.Count, weightAction));
                    }

                    continue;
                }
                else if (readToken.ID == R.Pipe)
                {
                    // add action to block and continue
                    sequences.Add(actions.Count == 1 ? actions[0] : new RASequence(actions, readToken));
                    reader.SkipSpace();
                    actions.Clear();
                    continue;
                }
                else if (readToken.ID == R.RightCurly)
                {
                    // add action to block and return
                    sequences.Add(actions.Count == 1 ? actions[0] : new RASequence(actions, readToken));
                    AddToOutput(new RABlock(Stringe.Range(token, readToken), sequences, dynamicWeights, constantWeights));
                    yield break;
                }

                yield return(Parselet.GetParselet(readToken, actions.Add));
            }

            compiler.SyntaxError(token, "Unterminated block: unexpected end of file.");
        }