001    package railo.runtime.functions.dynamicEvaluation;
002    
003    import railo.runtime.PageContext;
004    import railo.runtime.PageContextImpl;
005    import railo.runtime.exp.PageException;
006    import railo.runtime.ext.function.Function;
007    import railo.runtime.interpreter.CFMLExpressionInterpreter;
008    import railo.runtime.op.Caster;
009    import railo.runtime.type.Scope;
010    import railo.runtime.type.scope.Argument;
011    import railo.runtime.type.scope.CallerImpl;
012    import railo.runtime.type.scope.UndefinedImpl;
013    import railo.runtime.type.scope.Variables;
014    
015    /**
016     * Implements the Cold Fusion Function evaluate
017     */
018    public final class Evaluate implements Function {
019            
020    
021            public static Object call(PageContext pc , Object[] objs) throws PageException {
022                    return call(pc, objs, false);
023            }
024            public static Object call(PageContext pc , Object[] objs, boolean preciseMath) throws PageException {
025                    // define a ohter enviroment for the function
026                    if(objs.length>1 && objs[objs.length-1] instanceof Scope){
027                            
028                            // Variables Scope
029                            Variables var=null;
030                            if(objs[objs.length-1] instanceof Variables){
031                                    var=(Variables) objs[objs.length-1];
032                            }
033                            else if(objs[objs.length-1] instanceof CallerImpl){
034                                    var=((CallerImpl) objs[objs.length-1]).getVariablesScope();
035                            }
036                            if(var!=null){
037                                    Variables current=pc.variablesScope();
038                                    pc.setVariablesScope(var);
039                            try{
040                                    return _call(pc, objs,objs.length-1,preciseMath);
041                            }
042                            finally{
043                                    pc.setVariablesScope(current);
044                            }
045                            }
046                            
047                            // Undefined Scope
048                            else if(objs[objs.length-1] instanceof UndefinedImpl) {
049                                    PageContextImpl pci=(PageContextImpl) pc;
050                                    UndefinedImpl undefined=(UndefinedImpl) objs[objs.length-1];
051                                    
052                                    boolean check=undefined.getCheckArguments();
053                                    Variables orgVar=pc.variablesScope();
054                                    Argument orgArgs=pc.argumentsScope();
055                            Scope orgLocal=pc.localScope();
056                                    
057                                    pci.setVariablesScope(undefined.variablesScope());
058                                    if(check)pci.setFunctionScopes(undefined.localScope(), undefined.argumentsScope());
059                            try{
060                                    return _call(pc, objs,objs.length-1,preciseMath);
061                            }
062                            finally{
063                                    pc.setVariablesScope(orgVar);
064                                    if(check)pci.setFunctionScopes(orgLocal,orgArgs);
065                            }
066                                    
067                            }
068                    }
069                    return _call(pc,objs,objs.length,preciseMath);
070            }
071    
072            private static Object _call(PageContext pc , Object[] objs,int len, boolean preciseMath) throws PageException {
073                    Object rst=null;
074                    for(int i=0;i<len;i++) {
075                            if(objs[i] instanceof Number) rst= objs[i];
076                            else rst= new CFMLExpressionInterpreter().interpret(pc,Caster.toString(objs[i]), preciseMath);
077                    }
078                    return rst;
079            }
080    }