Esempio n. 1
0
        /// <exception cref="ParseException">Token '{0}' not expected in object declaration</exception>
        private Tailcall ParseItemsInDictionary(ObjectNode context, Continuation onComplete = null, bool justOneItem = false, string prefix = null)
        {
            switch (NextAfter(justOneItem ? WhiteSpaceOrComments : WhiteSpaceCommentsOrSemicolons, onComplete != null))
            {
            case TokenType.Identifier:
                if (Data == "@alias")
                {
                    ParseAlias(context);
                    return(ParseItemsInDictionary(context, onComplete, prefix: prefix));
                }
                break;

            case TokenType.Pound:
                // metadata entry
                ParseMetadataItem(context);
                return(ParseItemsInDictionary(context, onComplete, prefix: prefix));

            case TokenType.OpenParenthesis:
                //var iValue = ParseMatrixForEach(context, Semicolon, new ObjectIterator(context, new SourceLocation(Token, Filename)){Prefix = prefix ?? (context.IndexValue-1).ToString()});
                // iValue is the ObjectIterator.

                var n = new ExpansionPropertyNode();
                context.Properties[Guid.NewGuid().ToString()] = n;     // unique node for the item
                n.ObjectIterator = ParseMatrixForEach(context, Semicolon, new ObjectIterator(context, new SourceLocation(Token, Filename))
                {
                    Prefix = prefix ?? (context.CurrentIndex).ToString()
                }) as ObjectIterator;

                return(justOneItem ? (onComplete ?? Continue)() : ParseItemsInDictionary(context, onComplete, prefix: prefix));

            case TokenType.CloseBrace:
                return((onComplete ?? Continue)());

            case TokenType.Eof:
                // we should only get here if we discovered the EOF outside of anything.
                return(onComplete);
            }

            Rewind();

            var selector = ParseSelector(MemberTerminator);

            if (selector.Name.StartsWith("."))
            {
                selector = new Selector((prefix ?? string.Empty) + context.NextIndexValue + selector.Name, selector.Parameter, selector.SourceLocation);
            }

            switch (Type)
            {
            case TokenType.Dot:
            case TokenType.Identifier: {
                // if we're pointing to an identifier or a dot, we're about to take whatever is next, and include it in a dictionary as a way of syntatic sugar.
                return(ParseItemsInDictionary(context.Children[selector], () => ParseItemsInDictionary(context, onComplete, prefix: prefix), true));
            }

            case TokenType.OpenBrace: {
                if (justOneItem)
                {
                    return(ParseItemsInDictionary(context.Children[selector], (onComplete ?? Continue)));
                }
                return(ParseItemsInDictionary(context.Children[selector], () => ParseItemsInDictionary(context, onComplete, prefix: prefix)));
            }

            case TokenType.Colon: {
                var p = context.Properties[selector];
                p.SetCollection(ParseRValue(context, SemicolonCommaOrCloseBrace, p));
                return(justOneItem ? (onComplete ?? Continue)() : ParseItemsInDictionary(context, onComplete, prefix: prefix));
            }

            case TokenType.PlusEquals: {
                var p = context.Properties[selector];
                p.AddToCollection(ParseRValue(context, Semicolon, p));
                return(justOneItem ? (onComplete ?? Continue)() : ParseItemsInDictionary(context, onComplete, prefix: prefix));
            }

            // same as the part in ParseItemAsDictionary()
            case TokenType.EmbeddedInstruction:
                var n = context.Children[selector];
                n.SetNodeValue(new Instruction(n, Token.Data, new SourceLocation(Token, Filename)));
                if (NextAfter(WhiteSpaceOrComments) == TokenType.Semicolon)
                {
                    return(justOneItem ? (onComplete ?? Continue)() : ParseItemsInDictionary(context, onComplete, prefix: prefix));
                }

                throw Fail(ErrorCode.TokenNotExpected, "Token '{0}' not expected after Instruction. Looking for ';'");

            // same as the part in ParseItemAsDictionary()
            case TokenType.ColonEquals:
                // expecting one of:
                //      - an object declaration { }
                //      - an instruction
                //      - an RValue to be used as the value source for an object.
                switch (NextAfter(WhiteSpaceOrComments))
                {
                case TokenType.OpenBrace:
                    if (justOneItem)
                    {
                        return(ParseItemsInDictionary(context.Children[selector], (onComplete ?? Continue)));
                    }
                    return(ParseItemsInDictionary(context.Children[selector], () => ParseItemsInDictionary(context, onComplete, prefix: prefix)));

                case TokenType.EmbeddedInstruction:
                    var no = context.Children[selector];
                    no.SetNodeValue(new Instruction(no, Token.Data, new SourceLocation(Token, Filename)));
                    if (NextAfter(WhiteSpaceOrComments) == TokenType.Semicolon)
                    {
                        return(justOneItem ? (onComplete ?? Continue)() : ParseItemsInDictionary(context, onComplete, prefix: prefix));
                    }

                    throw Fail(ErrorCode.TokenNotExpected, "Token '{0}' not expected after Instruction. Looking for ';'");
                }
                // hmm. didn't seem to be one of the first two types. Try to grab it as an RValue then.
                Rewind();
                context.SetNodeValue(ParseRValue(context, Semicolon, context));

                return(justOneItem ? (onComplete ?? Continue)() : ParseItemsInDictionary(context, onComplete, prefix: prefix));

            case TokenType.Equal: {
                var p = context.Properties[selector];
                p.SetValue(ParseRValue(context, SemicolonCommaOrCloseBrace, p));
                return(justOneItem ? (onComplete ?? Continue)() : ParseItemsInDictionary(context, onComplete, prefix: prefix));
            }
            }
            throw Fail(ErrorCode.TokenNotExpected, "Token '{0}' not expected in object declaration");
        }
Esempio n. 2
0
 internal ObjectNode(ObjectNode parent, Selector selector) : this()
 {
     Parent   = parent;
     Selector = selector;
 }