Hi,

I'm trying to extend the code sample from Ayende described on
http://ayende.com/Blog/archive/2007/12/11/A-rule-engine-in-less-than-70-lines-of-code.aspx.
When you use a statement in the when clause I want to check first if
the properties used in the conditions are not null.

See code sample:

public abstract class Rule
    {
        public delegate bool Condition();

        public delegate void Action();

        public delegate object Value();

        protected OrderedDictionary conditionsAndActions = new
OrderedDictionary();
        protected System.Collections.Generic.List<Value> constraints =
new System.Collections.Generic.List<Value>();

        public object User{ get; set;}
        public object Car{ get; set;}

        [Meta]
        public static Expression when(Expression expression,
Expression action)
        {
            System.Collections.Generic.List<MemberReferenceExpression>
conditions = new
System.Collections.Generic.List<MemberReferenceExpression>();

            ParseNotNullConstraints(expression,conditions);

            var totalExpression = new BlockExpression();

            foreach (var constraint in conditions)
            {
                var notnullcondition = new BlockExpression();
                notnullcondition.Body.Add(new ReturnStatement
(constraint));
                totalExpression.Body.Add(new MethodInvocationExpression
(new ReferenceExpression("NotNull"),notnullcondition));
            }

            var condition = new BlockExpression();
            condition.Body.Add(new ReturnStatement(expression));

            var whenexpression  = new MethodInvocationExpression(
                new ReferenceExpression("When"), condition, action
                );

            totalExpression.Body.Add(whenexpression);

            return totalExpression;
        }

        private static void ParseNotNullConstraints(Expression
expression, System.Collections.Generic.List<MemberReferenceExpression>
conditions)
        {
            if(expression is BinaryExpression)
            {
                var bexpr = (BinaryExpression) expression;
                ParseNotNullConstraints(bexpr.Left,conditions);
                ParseNotNullConstraints(bexpr.Right,conditions);
            }
            if(expression is UnaryExpression)
            {
                var uexp = (UnaryExpression) expression;
                ParseNotNullConstraints(uexp.Operand,conditions);
            }
            if(expression is MemberReferenceExpression)
            {
                var type = expression.GetType();

                conditions.Add((MemberReferenceExpression)expression);

                Console.WriteLine(expression.ToString());
            }

        }

        protected void When(Condition condition, Action action)
        {
            conditionsAndActions[condition] = action;
        }

        protected void NotNull(Value checkObject)
        {
             constraints.Add(checkObject);
        }

        protected void allow()
        {
            Console.WriteLine("Accepted");
        }

        protected void deny()
        {
            Console.WriteLine("Deny");
        }

        public abstract void Prepare();

        public void Execute()
        {
            foreach (DictionaryEntry entry in conditionsAndActions)
            {
                Condition condition = (Condition) entry.Key;
                if(condition())
                {
                    Action action = (Action) entry.Value;
                    action();
                    break;
                }
            }
        }

        public void CheckConstraints()
        {
            foreach (var value in constraints)
            {
                if(value()==null)
                {
                    Console.WriteLine("something is null");
                }
            }
        }
    }

When I try to use the DSL I get a Boo.Lang.Compiler.CompilerError
exception with the following message:
BCE0034: Boo.Lang.Compiler.CompilerError: Expressions in statements
must only be executed for their side-effects.\r\nD:\\testScript.boo

Can't I use a BlockExpression to invoke multiple method calls? Is
there an other way for doing this?

Thanks in advance,

Bavo

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Rhino Tools Dev" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/rhino-tools-dev?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to