public override object VisitAssignmentExpr([NotNull] ChessVCParser.AssignmentExprContext context)
        {
            string s       = context.GetText();
            var    rhsNode = context.assignmentExpr();

            if (rhsNode != null)
            {
                object lhs = Visit(context.conditionalExpr());
                if (lhs == null || !(lhs is Reference))
                {
                    throw new Exception("Attempt to assign to object without l-value");
                }
                object rhs        = deref(Visit(rhsNode));
                Type   assignType = ((Reference)lhs).EffectiveType;
                if (rhs.GetType() != assignType && !rhs.GetType().IsSubclassOf(assignType))
                {
                    //	First check - if we're assigning a string to a ChoiceVariable, we
                    //	will automatically assign it to it's Value member. This makes cleaner
                    //	code as we don't need to put ".Value" all over the place.
                    if (assignType == typeof(ChoiceVariable) && rhs is string)
                    {
                        return(((ChoiceVariable)(((Reference)lhs).GetValue())).Value = (string)rhs);
                    }

                    //	We can't directly assign = however, we may be able to construct a new object
                    //	if the type to be assigned contains a constructor with a single argument
                    //	of the type supplied on the right-hand-side.
                    var constructors = assignType.GetConstructors();
                    foreach (ConstructorInfo ci in constructors)
                    {
                        var parameters = ci.GetParameters();
                        if (parameters.Length == 1)
                        {
                            if (rhs.GetType() == parameters[0].ParameterType ||
                                parameters[0].ParameterType.IsSubclassOf(assignType))
                            {
                                //	types compatible - we can perform constructon
                                ((Reference)lhs).SetValue(ci.Invoke(new object[] { rhs }));
                                return(lhs);
                            }
                        }
                    }
                    throw new Exception("Incompatable types for assignment");
                }
                ((Reference)lhs).SetValue(rhs);
                return(lhs);
            }
            return(base.VisitAssignmentExpr(context));
        }
Example #2
0
 /// <summary>
 /// Visit a parse tree produced by <see cref="ChessVCParser.assignmentExpr"/>.
 /// <para>
 /// The default implementation returns the result of calling <see cref="AbstractParseTreeVisitor{Result}.VisitChildren(IRuleNode)"/>
 /// on <paramref name="context"/>.
 /// </para>
 /// </summary>
 /// <param name="context">The parse tree.</param>
 /// <return>The visitor result.</return>
 public virtual Result VisitAssignmentExpr([NotNull] ChessVCParser.AssignmentExprContext context)
 {
     return(VisitChildren(context));
 }
Example #3
0
 /// <summary>
 /// Exit a parse tree produced by <see cref="ChessVCParser.assignmentExpr"/>.
 /// <para>The default implementation does nothing.</para>
 /// </summary>
 /// <param name="context">The parse tree.</param>
 public virtual void ExitAssignmentExpr([NotNull] ChessVCParser.AssignmentExprContext context)
 {
 }