private static string MatchEval(Match m, object data, bool htmlEncode)
        {
            var parser = new SimpleParser(m.Groups[1].Value)
                {
                    GlobalType = data.GetType(),
                    StaticTypes = new[] { typeof(Path) },
                };
            var valueExecutor = parser.Read<TemplateParser.ValueBuilder, TemplateParser.INode>();
            var type = valueExecutor.Compile(parser.GlobalType);
            var value = valueExecutor.Execute(data);
            var result = value.ToString();
            if (htmlEncode)
                result = HttpUtility.HtmlEncode(result);

            return result;
        }
        private static string MatchEval(Match m, object data, bool htmlEncode)
        {
            var parser = new SimpleParser(m.Groups[1].Value)
            {
                GlobalType = data.GetType()
            };
            var valueExecutor = parser.Read <TemplateParser.ValueBuilder, TemplateParser.INode>();
            var type          = valueExecutor.Compile(parser.GlobalType);
            var value         = valueExecutor.Execute(data);
            var result        = value.ToString();

            if (htmlEncode)
            {
                result = HttpUtility.HtmlEncode(result);
            }

            return(result);
        }
Example #3
0
            /// <summary>
            /// Reads the code trying to extract the AST from it.
            /// </summary>
            /// <param name="parser">The parser object used to read the code.</param>
            /// <param name="prevData">Previously parsed result. This is used to chain results together.</param>
            /// <returns>Returns an object that results from parsing the code.</returns>
            public override object Read(SimpleParser parser, object prevData)
            {
                var prevExecutor = (INode)prevData;

                parser.SkipSpaces();

                if (prevExecutor == null)
                {
                    var name = this.ReadName(parser);

                    // this is a direct method call in the root
                    var call = ReadMethodCall(parser, null, name);
                    if (call != null)
                        return call;

                    // this is a global property
                    if (!string.IsNullOrWhiteSpace(name))
                        return new PropertyGet { Name = name, Element = null };

                    // this is an array construct
                    if (parser.ReadChar('{'))
                    {
                        var values = parser.ReadList<ValueBuilder, INode>(ReadListSeparator);
                        if (values.Count > 0)
                        {
                            parser.SkipSpaces();
                            if (!parser.ReadChar('}'))
                                return new Exception("Unterminated array construct.");

                            return new ArrayConstruct { Values = values };
                        }
                    }

                    // this is a precedence operator
                    if (parser.ReadChar('('))
                    {
                        var value = parser.Read<ValueBuilder, INode>();
                        if (value == null)
                            return new Exception("Syntax error.");

                        parser.SkipSpaces();
                        if (!parser.ReadChar(')'))
                            return new Exception("Unterminated precedence construct.");

                        return value;
                    }

                    // this is a number literal
                    var number = parser.ReadWhileCharOrEof(char.IsNumber);
                    if (number.Length > 0)
                        return new NumberLiteral { Data = number };

                    // this is a string literal
                    if (parser.ReadChar('"'))
                    {
                        var strBuilder = new StringBuilder();
                        while (true)
                        {
                            strBuilder.Append(parser.ReadWhileCharOrEof(ch => ch != '\\' && ch != '"'));

                            if (parser.Eof)
                                return new InvalidOperationException("String literal not terminated.");

                            if (parser.ReadChar('\\'))
                            {
                                if (parser.ReadChar('0')) strBuilder.Append('\0');
                                else if (parser.ReadChar('n')) strBuilder.Append('\n');
                                else if (parser.ReadChar('r')) strBuilder.Append('\r');
                                else if (parser.ReadChar('\\')) strBuilder.Append('\\');
                                else if (parser.ReadChar('"')) strBuilder.Append('"');
                                else
                                    return new InvalidOperationException("Escape sequence not recognized.");
                            }

                            if (parser.ReadChar('"'))
                                break;
                        }

                        return new StringLiteral { Data = strBuilder.ToString() };
                    }
                }
                else
                {
                    if (parser.ReadChar('.'))
                    {
                        var name = this.ReadName(parser);

                        // this is a direct method call in the previous element
                        var call = ReadMethodCall(parser, prevExecutor, name);
                        if (call != null)
                            return call;

                        if (!string.IsNullOrWhiteSpace(name))
                            return new PropertyGet { Name = name, Element = prevExecutor };
                    }

                    // indexer property
                    if (parser.ReadChar('['))
                    {
                        var indexValues = parser.ReadList<ValueBuilder, INode>(ReadListSeparator);

                        if (indexValues.Count == 0)
                            return new Exception("Index is missing.");

                        parser.SkipSpaces();
                        if (!parser.ReadChar(']'))
                            return new Exception("Unterminated indexer.");

                        return new IndexerGet { Element = prevExecutor, Indexes = indexValues };
                    }

                    // this only happens when calling a delegate
                    // direct method calls never fall here
                    if (parser.ReadChar('('))
                    {
                        var paramValues = parser.ReadList<ValueBuilder, INode>(ReadListSeparator);

                        parser.SkipSpaces();
                        if (parser.ReadChar(')'))
                            return new Call { Element = prevExecutor, Name = "Invoke", Parameters = paramValues };
                    }

                    if (parser.ReadChar('?'))
                    {
                        var trueValue = parser.Read<ValueBuilder, INode>();
                        parser.SkipSpaces();
                        if (!parser.ReadChar(':'))
                            throw new Exception("Missing ':' for ternary operator a?b:c.");
                        parser.SkipSpaces();
                        var falseValue = parser.Read<ValueBuilder, INode>();

                        return new TernaryInlineIf { Condition = prevExecutor, TrueValue = trueValue, FalseValue = falseValue };
                    }

                    var binOp = parser.ReadAnyStringAlternative("==", "!=", ">", "<", ">=", "<=", "&&", "||");
                    if (binOp != null)
                    {
                        var valueB = parser.Read<ValueBuilder, INode>();

                        return new BinaryBoolOps { ValueA = prevExecutor, ValueB = valueB, Operator = binOp };
                    }
                }

                return null;
            }