예제 #1
0
        public ParserType Visit(ParserBinder binder)
        {
            // idea: copy our current context, add the new bound variable, visit, remove bound variable
            //   then merge back into our current context
            var newCtx = CloneContext();

            newCtx[binder.VariableName] = binder.VariableType;
            var        visitor = new TypeVisitor(newCtx);
            ParserType subExpr = binder.Expr.Accept(visitor);

            newCtx.Remove(binder.VariableName);
            JoinContext(newCtx);

            if (subExpr.Typ != ParserTypeEnum.Logic || !(subExpr is ParserLogicType))
            {
                throw new ArgumentException("Bound subexpression must be a logical expression. Type: " + subExpr.ToString());
            }

            var logicalExpr = subExpr as ParserLogicType;

            switch (binder.OpType)
            {
            case ParserBinderType.Exists:
                if ((binder.VariableType.Flags & ParserTypeFlags.Overt) == 0)
                {
                    throw new ArgumentException("Exists can only bind overt variables");
                }
                ParserType logicType = new ParserLogicType();
                binder.Type = logicType;
                return(logicType);

            case ParserBinderType.Lambda:
                ParserType newType = new ParserLambdaType(binder.VariableType);
                binder.Type = newType;
                return(newType);

            case ParserBinderType.The:
                if (binder.VariableType is ParserNumType)
                {
                    ParserType numType = new ParserNumType();
                    binder.Type = numType;
                    return(numType);
                }
                else
                {
                    throw new ArgumentException("'The' binder can only bind Nat types");
                }

            default:
                throw new ArgumentException("Unknown Binder");
            }
        }
예제 #2
0
        public Expression Visit(ParserBinder binder)
        {
            Expression subExpr = binder.Expr.Accept(this);

            switch (binder.OpType)
            {
            case ParserBinderType.Exists:
                return(new NumExists(binder.VariableName, subExpr as LogicExpression));

            case ParserBinderType.Lambda:
                return(new LambdaExpression(binder.VariableName, subExpr as LogicExpression));

            case ParserBinderType.The:
                return(new NumThe(binder.VariableName, subExpr as LogicExpression));

            default:
                break;
            }

            throw new ArgumentException("Unknown binder");
        }