Expression Parse_OpRegex()
        {
            Expression expr = Parse_FunctionCall();

            for (;;)
            {
                TokenType op = m_Tokenizer.PeekNextToken().type;
                if (op != TokenType.OpRegexMatch && op != TokenType.OpRegexNotMatch)
                {
                    break;
                }

                m_Tokenizer.ConsumeNextToken();

                Token      token      = m_Tokenizer.PeekNextToken();
                Expression regex_expr = Parse_FunctionCall();
                Value      const_val  = regex_expr.EliminateConstSubExpressions();
                if (const_val == null)
                {
                    throw new ParserException(m_Tokenizer.Text, token.pos, "Expected a constant expression that evaluates into a regex string. This expression isn't constant.");
                }
                if (!(const_val is StringValue))
                {
                    throw new ParserException(m_Tokenizer.Text, token.pos, "Expected a constant expression that evaluates into a regex string. This expression evaluates to a bool constant.");
                }

                Regex regex;
                try
                {
                    regex = new Regex(const_val.ToString(), RegexOptions.IgnoreCase);
                }
                catch (System.Exception ex)
                {
                    throw new ParserException(m_Tokenizer.Text, token.pos, "Invalid regex! " + ex.Message);
                }

                expr = new OpRegexMatch(expr, regex_expr, regex, op == TokenType.OpRegexNotMatch);
            }
            return(expr);
        }
        Expression Parse_OpRegex()
        {
            Expression expr = Parse_FunctionCall();

            for (;;)
            {
                TokenType op = m_Tokenizer.PeekNextToken().type;
                if (op != TokenType.OpRegexMatch && op != TokenType.OpRegexNotMatch)
                    break;

                m_Tokenizer.ConsumeNextToken();

                Token token = m_Tokenizer.PeekNextToken();
                Expression regex_expr = Parse_FunctionCall();
                Value const_val = regex_expr.EliminateConstSubExpressions();
                if (const_val == null)
                    throw new ParserException(m_Tokenizer.Text, token.pos, "Expected a constant expression that evaluates into a regex string. This expression isn't constant.");
                if (!(const_val is StringValue))
                    throw new ParserException(m_Tokenizer.Text, token.pos, "Expected a constant expression that evaluates into a regex string. This expression evaluates to a bool constant.");

                Regex regex;
                try
                {
                    regex = new Regex(const_val.ToString(), RegexOptions.IgnoreCase);
                }
                catch (System.Exception ex)
                {
                    throw new ParserException(m_Tokenizer.Text, token.pos, "Invalid regex! " + ex.Message);
                }

                expr = new OpRegexMatch(expr, regex_expr, regex, op == TokenType.OpRegexNotMatch);
            }
            return expr;
        }