예제 #1
0
        public Expression Visit(ParserRec rec)
        {
            Expression input = rec.Input.Accept(this);
            Expression start = rec.Start.Accept(this);
            Expression step  = rec.Step.Accept(this);

            if (rec.Start.Type is ParserNumType)
            {
                return(new RecNumExpression(input as NumExpression, start as NumExpression, rec.NumVariableName, rec.AccVariableName,
                                            step as NumExpression));
            }
            if (rec.Start.Type is ParserLogicType)
            {
                return(new RecLogicExpression(input as NumExpression, start as LogicExpression, rec.NumVariableName, rec.AccVariableName,
                                              step as LogicExpression));
            }
            if (rec.Start.Type is ParserLambdaType)
            {
                return(new RecLambdaExpression(input as NumExpression, start as AbstractLambdaExpression, rec.NumVariableName, rec.AccVariableName,
                                               step as AbstractLambdaExpression));
            }
            if (rec.Start.Type is ParserProdType)
            {
                return(new RecPairExpression(input as NumExpression, start as AbstractPairExpression, rec.NumVariableName, rec.AccVariableName,
                                             step as AbstractPairExpression));
            }



            throw new ArgumentException("Unknown Rec type");
        }
예제 #2
0
        public ParserType Visit(ParserRec rec)
        {
            var inputType = rec.Input.Accept(this);

            if (!(inputType is ParserNumType))
            {
                throw new ArgumentException("The input to a Rec expression must be numeric. Type: " + inputType.ToString());
            }
            var startType = rec.Start.Accept(this);

            // In order to type check the step clone our current context, add two new variables, run
            // the type check, remove the bound variables, then join the new context with the old
            var newCtx = CloneContext();

            newCtx[rec.NumVariableName] = new ParserNumType();
            newCtx[rec.AccVariableName] = rec.AccType;
            var        visitor  = new TypeVisitor(newCtx);
            ParserType stepType = rec.Step.Accept(visitor);

            newCtx.Remove(rec.AccVariableName);
            newCtx.Remove(rec.NumVariableName);
            JoinContext(newCtx);

            if (!startType.Equivalent(stepType))
            {
                throw new ArgumentException(String.Format(
                                                "Start type and step type in Rec must be equivalent. Start Type: {0} Step Type: {1}",
                                                startType.ToString(), stepType.ToString()));
            }

            rec.Type = startType;
            return(startType);
        }