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