protected void ProcessExpression(Expression exp)
 {
     object value = EvalExpression(exp);
     WriteValue(value);
 }
 public void Add(Expression exp)
 {
     exps.Add(exp);
 }
        protected object EvalExpression(Expression exp)
        {
            _currentExpression = exp;

            if (exp is StringLiteral)
                return ((StringLiteral)exp).Content;
            else if (exp is Name)
            {
                object obj = _variables[((Name)exp).Id];
                return obj;
            }
            else if (exp is FieldAccess)
            {
                FieldAccess fa = (FieldAccess)exp;
                object obj = _variables[fa.Exp];
                string propertyName = fa.Field;
                return EvalProperty(obj, propertyName);
            }
            else if (exp is IntLiteral)
                return ((IntLiteral)exp).Value;
            else if (exp is FCall)
            {
                FCall fcall = (FCall)exp;
                if (!_functions.ContainsKey(fcall.Name))
                {
                    string msg = string.Format("Function {0} is not defined", fcall.Name);
                    WriteError(msg, exp.Line, exp.Col);
                    return null;
                }

                TemplateFunction func = _functions[fcall.Name];
                object[] values = new object[fcall.Args.Length];
                for (int i = 0; i < values.Length; i++)
                    values[i] = EvalExpression(fcall.Args[i]);

                return func(values);
            }
            else if (exp is StringExpression)
            {
                StringExpression stringExp = (StringExpression)exp;
                StringBuilder sb = new StringBuilder();
                foreach (Expression ex in stringExp.Expressions)
                    sb.Append(EvalExpression(ex));

                return sb.ToString();
            }

            return null;
        }