You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by fm...@apache.org on 2014/11/28 11:18:09 UTC

svn commit: r1642281 [7/14] - in /sling/trunk/contrib/scripting/sightly: ./ engine/ engine/src/main/antlr4/org/apache/sling/parser/expr/generated/ engine/src/main/antlr4/org/apache/sling/scripting/ engine/src/main/antlr4/org/apache/sling/scripting/sigh...

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/UnusedVariableRemoval.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/UnusedVariableRemoval.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/UnusedVariableRemoval.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/UnusedVariableRemoval.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+
+package org.apache.sling.scripting.sightly.impl.compiler.optimization;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+import org.apache.sling.scripting.sightly.impl.compiler.ris.Command;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.CommandStream;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.VariableBinding;
+import org.apache.sling.scripting.sightly.impl.compiler.util.stream.EmitterVisitor;
+import org.apache.sling.scripting.sightly.impl.compiler.util.stream.PushStream;
+import org.apache.sling.scripting.sightly.impl.compiler.util.stream.Streams;
+import org.apache.sling.scripting.sightly.impl.compiler.visitor.TrackingVisitor;
+
+/**
+ * This optimization removes variables which are bound but
+ * never used in the command stream
+ */
+public final class UnusedVariableRemoval extends TrackingVisitor<UnusedVariableRemoval.VariableActivity> implements EmitterVisitor {
+
+    public static final StreamTransformer TRANSFORMER = new StreamTransformer() {
+        @Override
+        public CommandStream transform(CommandStream inStream) {
+            return Streams.map(inStream, new UnusedVariableRemoval());
+        }
+    };
+
+    private final PushStream outputStream = new PushStream();
+    private final Stack<List<Command>> storedCommandsStack = new Stack<List<Command>>();
+
+    private UnusedVariableRemoval() {
+    }
+
+    @Override
+    public PushStream getOutputStream() {
+        return outputStream;
+    }
+
+    @Override
+    public void visit(VariableBinding.Start variableBindingStart) {
+        //push a new buffer where we will store the following commands
+        //these commands will be emitted only if this variable will be used in
+        //it's scope
+        storedCommandsStack.push(new ArrayList<Command>());
+        //start tracking the variable
+        tracker.pushVariable(variableBindingStart.getVariableName(), new VariableActivity(variableBindingStart));
+    }
+
+    @Override
+    public void visit(VariableBinding.End variableBindingEnd) {
+        // Get the activity of the exiting variable
+        VariableActivity variableActivity = tracker.peek().getValue();
+        tracker.popVariable();
+        boolean emitBindingEnd = true;
+        if (variableActivity != null) {
+            //this was a tracked variable. Popping all the commands
+            //which were delayed for this variable
+            List<Command> commands = storedCommandsStack.pop();
+            //if the variable binding is emitted than this binding
+            //end must be emitted as well
+            emitBindingEnd = variableActivity.isUsed();
+            if (variableActivity.isUsed()) {
+                VariableBinding.Start variableBindingStart = variableActivity.getCommand();
+                //variable was used. we can let it pass through
+                emit(variableBindingStart);
+                //register the usage of all the variables that appear in the bound expression
+                registerUsage(variableBindingStart);
+            }
+            //emit all the delayed commands
+            for (Command command : commands) {
+                emit(command);
+            }
+        }
+        if (emitBindingEnd) {
+            emit(variableBindingEnd);
+        }
+    }
+
+    @Override
+    protected VariableActivity assignDefault(Command command) {
+        return null;
+    }
+
+    @Override
+    protected void onCommand(Command command) {
+        registerUsage(command);
+        emit(command);
+    }
+
+    /**
+     * Emit the current command. If the command is delayed by
+     * a variable tracking process, than add it to the top command list
+     * @param command a stream command
+     */
+    private void emit(Command command) {
+        if (storedCommandsStack.isEmpty()) {
+            outputStream.emit(command);
+        } else {
+            List<Command> list = storedCommandsStack.peek();
+            list.add(command);
+        }
+    }
+
+    /**
+     * Extract all the variables in this command and mark them
+     * as used
+     * @param command - a stream command
+     */
+    private void registerUsage(Command command) {
+        List<String> usedVariables = CommandVariableUsage.extractVariables(command);
+        for (String usedVariable : usedVariables) {
+            VariableActivity activity = tracker.get(usedVariable);
+            if (activity != null) {
+                activity.markUsed();
+            }
+        }
+    }
+
+    /**
+     * Track the activity of a variable binding
+     */
+    static class VariableActivity {
+        private boolean used;
+        private VariableBinding.Start command;
+
+        VariableActivity(VariableBinding.Start command) {
+            this.command = command;
+        }
+
+        public void markUsed() {
+            used = true;
+        }
+
+        public boolean isUsed() {
+            return used;
+        }
+
+        public VariableBinding.Start getCommand() {
+            return command;
+        }
+    }
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/UnusedVariableRemoval.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/VariableFinder.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/VariableFinder.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/VariableFinder.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/VariableFinder.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.sling.scripting.sightly.impl.compiler.optimization;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.sling.scripting.sightly.impl.compiler.expression.ExpressionNode;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.ArrayLiteral;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.BinaryOperation;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.BooleanConstant;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.Identifier;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.MapLiteral;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.NullLiteral;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.NumericConstant;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.PropertyAccess;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.RuntimeCall;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.StringConstant;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.TernaryOperator;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.UnaryOperation;
+import org.apache.sling.scripting.sightly.impl.compiler.util.expression.SideEffectVisitor;
+
+/**
+ * SideEffectVisitor which extracts all the variables from an expression
+ */
+public class VariableFinder extends SideEffectVisitor {
+
+    private final Set<String> variables;
+
+    public VariableFinder(Set<String> variables) {
+        this.variables = variables;
+    }
+
+    private void traverse(ExpressionNode node) {
+        if (node != null) {
+            node.accept(this);
+        }
+    }
+
+    public static Set<String> findVariables(ExpressionNode node) {
+        HashSet<String> result = new HashSet<String>();
+        VariableFinder finder = new VariableFinder(result);
+        finder.traverse(node);
+        return result;
+    }
+
+    @Override
+    public void visit(PropertyAccess propertyAccess) {
+        traverse(propertyAccess.getTarget());
+        traverse(propertyAccess.getProperty());
+    }
+
+    @Override
+    public void visit(Identifier identifier) {
+        variables.add(identifier.getName());
+    }
+
+    @Override
+    public void visit(StringConstant text) {
+    }
+
+    @Override
+    public void visit(BinaryOperation binaryOperation) {
+        traverse(binaryOperation.getLeftOperand());
+        traverse(binaryOperation.getRightOperand());
+    }
+
+    @Override
+    public void visit(BooleanConstant booleanConstant) {
+    }
+
+    @Override
+    public void visit(NumericConstant numericConstant) {
+    }
+
+    @Override
+    public void visit(UnaryOperation unaryOperation) {
+        traverse(unaryOperation.getTarget());
+    }
+
+    @Override
+    public void visit(TernaryOperator ternaryOperator) {
+        traverse(ternaryOperator.getCondition());
+        traverse(ternaryOperator.getThenBranch());
+        traverse(ternaryOperator.getElseBranch());
+    }
+
+    @Override
+    public void visit(RuntimeCall runtimeCall) {
+        for (ExpressionNode node : runtimeCall.getArguments()) {
+            traverse(node);
+        }
+    }
+
+    @Override
+    public void visit(MapLiteral mapLiteral) {
+        for (ExpressionNode value : mapLiteral.getMap().values()) {
+            traverse(value);
+        }
+    }
+
+    @Override
+    public void visit(ArrayLiteral arrayLiteral) {
+        for (ExpressionNode item : arrayLiteral.getItems()) {
+            traverse(item);
+        }
+    }
+
+    @Override
+    public void visit(NullLiteral nullLiteral) {
+    }
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/VariableFinder.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/reduce/ConstantFolding.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/reduce/ConstantFolding.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/reduce/ConstantFolding.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/reduce/ConstantFolding.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+
+package org.apache.sling.scripting.sightly.impl.compiler.optimization.reduce;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.sling.scripting.sightly.impl.compiler.expression.ExpressionNode;
+import org.apache.sling.scripting.sightly.impl.compiler.optimization.StreamTransformer;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.Command;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.CommandStream;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.VariableBinding;
+import org.apache.sling.scripting.sightly.impl.compiler.util.stream.EmitterVisitor;
+import org.apache.sling.scripting.sightly.impl.compiler.util.stream.PushStream;
+import org.apache.sling.scripting.sightly.impl.compiler.util.stream.Streams;
+import org.apache.sling.scripting.sightly.impl.compiler.visitor.TrackingVisitor;
+import org.apache.sling.scripting.sightly.render.RenderContext;
+
+/**
+ * Optimization which evaluates constant expressions during compilation-time
+ */
+public final class ConstantFolding extends TrackingVisitor<EvalResult> implements EmitterVisitor {
+
+    private final RenderContext renderContext;
+    private final PushStream outStream = new PushStream();
+
+    private ConstantFolding(RenderContext renderContext) {
+        this.renderContext = renderContext;
+    }
+
+    public static StreamTransformer transformer(final RenderContext renderContext) {
+        return new StreamTransformer() {
+            @Override
+            public CommandStream transform(CommandStream inStream) {
+                return Streams.map(inStream, new ConstantFolding(renderContext));
+            }
+        };
+    }
+
+    @Override
+    public void visit(VariableBinding.Start variableBindingStart) {
+        String variable = variableBindingStart.getVariableName();
+        ExpressionNode node = variableBindingStart.getExpression();
+        EvalResult result = ExpressionReducer.reduce(node, tracker, renderContext);
+        result = avoidFoldingDataStructures(result);
+        tracker.pushVariable(variable, result);
+        outStream.emit(new VariableBinding.Start(variable, result.getNode()));
+    }
+
+    private EvalResult avoidFoldingDataStructures(EvalResult evalResult) {
+        //this prevents us from replacing variables that are bound to maps & collections
+        //in expressions since that would mean we rebuild the same constant data structures
+        //each time
+        if (evalResult.isConstant() && isDataStructure(evalResult.getValue())) {
+            return EvalResult.nonConstant(evalResult.getNode());
+        }
+        return evalResult;
+    }
+
+    private boolean isDataStructure(Object obj) {
+        return (obj instanceof Collection) || (obj instanceof Map);
+    }
+
+    @Override
+    protected EvalResult assignDefault(Command command) {
+        return null;
+    }
+
+    @Override
+    protected void onCommand(Command command) {
+        outStream.emit(command);
+    }
+
+    @Override
+    public PushStream getOutputStream() {
+        return outStream;
+    }
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/reduce/ConstantFolding.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/reduce/EvalResult.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/reduce/EvalResult.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/reduce/EvalResult.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/reduce/EvalResult.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+
+package org.apache.sling.scripting.sightly.impl.compiler.optimization.reduce;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.sling.scripting.sightly.impl.compiler.CompilerException;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.ExpressionNode;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.ArrayLiteral;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.BooleanConstant;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.MapLiteral;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.NullLiteral;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.NumericConstant;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.StringConstant;
+
+/**
+ * Data structure used in expression reducing
+ */
+public final class EvalResult {
+    private final ExpressionNode node;
+    private final Object value;
+
+    public static EvalResult constant(Object obj) {
+        return new EvalResult(null, obj);
+    }
+
+    public static EvalResult nonConstant(ExpressionNode node) {
+        return new EvalResult(node, null);
+    }
+
+    private EvalResult(ExpressionNode node, Object value) {
+        this.node = node;
+        this.value = value;
+    }
+
+    public boolean isConstant() {
+        return node == null;
+    }
+
+    public Object getValue() {
+        if (!isConstant()) {
+            throw new CompilerException(new UnsupportedOperationException("Cannot get constant value from non-constant result"));
+        }
+        return value;
+    }
+
+    public ExpressionNode getNode() {
+        return (isConstant()) ? asLiteral(getValue()) : node;
+    }
+
+    private static ExpressionNode asLiteral(Object value) {
+        if (value instanceof Boolean) {
+            return new BooleanConstant((Boolean) value);
+        }
+        if (value instanceof String) {
+            return new StringConstant((String) value);
+        }
+        if (value instanceof Number) {
+            return new NumericConstant((Number) value);
+        }
+        if (value instanceof Map) {
+            //noinspection unchecked
+            return asMapLiteral((Map<String, Object>) value);
+        }
+        if (value instanceof List) {
+            //noinspection unchecked
+            return asArrayLiteral((List<Object>) value);
+        }
+        if (value == null) {
+            return NullLiteral.INSTANCE;
+        }
+        throw new CompilerException(new UnsupportedOperationException("Cannot transform to literal: " + value));
+    }
+
+    private static MapLiteral asMapLiteral(Map<String, Object> map) {
+        HashMap<String, ExpressionNode> literal = new HashMap<String, ExpressionNode>();
+        for (Map.Entry<String, Object> entry : map.entrySet()) {
+            literal.put(entry.getKey(), asLiteral(entry.getValue()));
+        }
+        return new MapLiteral(literal);
+    }
+
+    private static ArrayLiteral asArrayLiteral(List<Object> list) {
+        ArrayList<ExpressionNode> literal = new ArrayList<ExpressionNode>();
+        for (Object obj : list) {
+            literal.add(asLiteral(obj));
+        }
+        return new ArrayLiteral(literal);
+    }
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/reduce/EvalResult.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/reduce/ExpressionReducer.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/reduce/ExpressionReducer.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/reduce/ExpressionReducer.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/reduce/ExpressionReducer.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,212 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+
+package org.apache.sling.scripting.sightly.impl.compiler.optimization.reduce;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.sling.scripting.sightly.impl.compiler.CompilerException;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.ExpressionNode;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.NodeVisitor;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.ArrayLiteral;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.BinaryOperation;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.BooleanConstant;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.Identifier;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.MapLiteral;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.NullLiteral;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.NumericConstant;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.PropertyAccess;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.RuntimeCall;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.StringConstant;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.TernaryOperator;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.UnaryOperation;
+import org.apache.sling.scripting.sightly.impl.compiler.util.VariableTracker;
+import org.apache.sling.scripting.sightly.render.RenderContext;
+
+/**
+ * Try to evaluate constant parts in expressions
+ */
+public class ExpressionReducer implements NodeVisitor<EvalResult> {
+
+    private final RenderContext renderContext;
+    private final VariableTracker<EvalResult> tracker;
+
+    public static EvalResult reduce(ExpressionNode node, VariableTracker<EvalResult> tracker, RenderContext renderContext) {
+        ExpressionReducer reducer = new ExpressionReducer(renderContext, tracker);
+        return reducer.eval(node);
+    }
+
+    public ExpressionReducer(RenderContext renderContext, VariableTracker<EvalResult> tracker) {
+        this.renderContext = renderContext;
+        this.tracker = tracker;
+    }
+
+    private EvalResult eval(ExpressionNode node) {
+        try {
+            return node.accept(this);
+        } catch (CompilerException e) {
+            throw e;
+        } catch (Exception e) {
+            //evaluating constant expressions may lead to errors (like division by zero)
+            //in this case we leave the node as-is.
+            return EvalResult.nonConstant(node);
+        }
+    }
+
+    @Override
+    public EvalResult evaluate(PropertyAccess propertyAccess) {
+        EvalResult target = eval(propertyAccess.getTarget());
+        EvalResult property = eval(propertyAccess.getProperty());
+        if (!target.isConstant() || !property.isConstant()) {
+            return EvalResult.nonConstant(new PropertyAccess(
+                    target.getNode(),
+                    property.getNode()));
+        }
+
+        return EvalResult.constant(renderContext.resolveProperty(
+                target.getValue(), property.getValue()));
+    }
+
+    @Override
+    public EvalResult evaluate(Identifier identifier) {
+        EvalResult result = tracker.get(identifier.getName());
+        if (result != null && result.isConstant()) {
+            return EvalResult.constant(result.getValue());
+        }
+        return EvalResult.nonConstant(identifier);
+    }
+
+    @Override
+    public EvalResult evaluate(StringConstant text) {
+        return EvalResult.constant(text.getText());
+    }
+
+    @Override
+    public EvalResult evaluate(BinaryOperation binaryOperation) {
+        EvalResult left = eval(binaryOperation.getLeftOperand());
+        EvalResult right = eval(binaryOperation.getRightOperand());
+        if (!(left.isConstant() && right.isConstant())) {
+            return EvalResult.nonConstant(new BinaryOperation(
+                    binaryOperation.getOperator(),
+                    left.getNode(),
+                    right.getNode()));
+        }
+        return EvalResult.constant(binaryOperation.getOperator().eval(renderContext, left.getValue(), right.getValue()));
+    }
+
+    @Override
+    public EvalResult evaluate(BooleanConstant booleanConstant) {
+        return EvalResult.constant(booleanConstant.getValue());
+    }
+
+    @Override
+    public EvalResult evaluate(NumericConstant numericConstant) {
+        return EvalResult.constant(numericConstant.getValue());
+    }
+
+    @Override
+    public EvalResult evaluate(UnaryOperation unaryOperation) {
+        EvalResult target = eval(unaryOperation.getTarget());
+        if (!target.isConstant()) {
+            return EvalResult.nonConstant(new UnaryOperation(
+                    unaryOperation.getOperator(), target.getNode()));
+        }
+        return EvalResult.constant(unaryOperation.getOperator().eval(renderContext, target.getValue()));
+    }
+
+    @Override
+    public EvalResult evaluate(TernaryOperator ternaryOperator) {
+        EvalResult condition = eval(ternaryOperator.getCondition());
+        if (!condition.isConstant()) {
+            return EvalResult.nonConstant(new TernaryOperator(
+                    condition.getNode(),
+                    ternaryOperator.getThenBranch(),
+                    ternaryOperator.getElseBranch()));
+        }
+        return (renderContext.toBoolean(condition.getValue()))
+                ? eval(ternaryOperator.getThenBranch())
+                : eval(ternaryOperator.getElseBranch());
+    }
+
+    @Override
+    public EvalResult evaluate(RuntimeCall runtimeCall) {
+        List<ExpressionNode> nodes = new ArrayList<ExpressionNode>();
+        for (ExpressionNode node : runtimeCall.getArguments()) {
+            EvalResult result = eval(node);
+            nodes.add(result.getNode());
+        }
+        return EvalResult.nonConstant(new RuntimeCall(runtimeCall.getFunctionName(), nodes));
+    }
+
+    @Override
+    public EvalResult evaluate(MapLiteral mapLiteral) {
+        HashMap<String, EvalResult> results = new HashMap<String, EvalResult>();
+        boolean isConstant = true;
+        for (Map.Entry<String, ExpressionNode> entry : mapLiteral.getMap().entrySet()) {
+            EvalResult result = eval(entry.getValue());
+            results.put(entry.getKey(), result);
+            isConstant = isConstant && result.isConstant();
+        }
+        if (isConstant) {
+            HashMap<String, Object> map = new HashMap<String, Object>();
+            for (Map.Entry<String, EvalResult> entry : results.entrySet()) {
+                map.put(entry.getKey(), entry.getValue().getValue());
+            }
+            return EvalResult.constant(map);
+        } else {
+            HashMap<String, ExpressionNode> literal = new HashMap<String, ExpressionNode>();
+            for (Map.Entry<String, EvalResult> entry : results.entrySet()) {
+                literal.put(entry.getKey(), entry.getValue().getNode());
+            }
+            return EvalResult.nonConstant(new MapLiteral(literal));
+        }
+    }
+
+    @Override
+    public EvalResult evaluate(ArrayLiteral arrayLiteral) {
+        ArrayList<EvalResult> results = new ArrayList<EvalResult>();
+        boolean isConstant = true;
+        for (ExpressionNode node : arrayLiteral.getItems()) {
+            EvalResult result = eval(node);
+            results.add(result);
+            isConstant = isConstant && result.isConstant();
+        }
+        if (isConstant) {
+            ArrayList<Object> list = new ArrayList<Object>();
+            for (EvalResult result : results) {
+                list.add(result.getValue());
+            }
+            return EvalResult.constant(list);
+        } else {
+            ArrayList<ExpressionNode> literal = new ArrayList<ExpressionNode>();
+            for (EvalResult result : results) {
+                literal.add(result.getNode());
+            }
+            return EvalResult.nonConstant(new ArrayLiteral(literal));
+        }
+    }
+
+    @Override
+    public EvalResult evaluate(NullLiteral nullLiteral) {
+        return EvalResult.constant(null);
+    }
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/reduce/ExpressionReducer.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/Command.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/Command.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/Command.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/Command.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.sling.scripting.sightly.impl.compiler.ris;
+
+/**
+ * A text rendering command
+ */
+public interface Command {
+
+    /**
+     * Accept a visitor
+     * @param visitor - the visitor that will process this command
+     */
+    void accept(CommandVisitor visitor);
+
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/Command.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/CommandHandler.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/CommandHandler.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/CommandHandler.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/CommandHandler.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.sling.scripting.sightly.impl.compiler.ris;
+
+/**
+ * Handles commands from streams
+ */
+public interface CommandHandler {
+
+    /**
+     * Handle the incoming command
+     * @param command - the received command
+     */
+    void onEmit(Command command);
+
+    /**
+     * Called when an error occurs.
+     * @param errorMessage - the message of the error
+     */
+    void onError(String errorMessage);
+
+    /**
+     * Called when the stream has finished. The contract is that after this call, no other
+     * commands or errors will be emitted.
+     */
+    void onDone();
+
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/CommandHandler.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/CommandStream.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/CommandStream.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/CommandStream.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/CommandStream.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.sling.scripting.sightly.impl.compiler.ris;
+
+/**
+ * A push-stream of commands
+ */
+public interface CommandStream {
+
+    /**
+     * Add a listening handler
+     * @param handler - a command handler
+     */
+    void addHandler(CommandHandler handler);
+
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/CommandStream.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/CommandVisitor.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/CommandVisitor.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/CommandVisitor.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/CommandVisitor.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.sling.scripting.sightly.impl.compiler.ris;
+
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Conditional;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Loop;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.OutText;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.OutVariable;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Procedure;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.VariableBinding;
+
+/**
+ * Processor of rendering commands
+ */
+public interface CommandVisitor {
+
+    void visit(Conditional.Start conditionalStart);
+
+    void visit(Conditional.End conditionalEnd);
+
+    void visit(VariableBinding.Start variableBindingStart);
+
+    void visit(VariableBinding.End variableBindingEnd);
+
+    void visit(VariableBinding.Global globalAssignment);
+
+    void visit(OutVariable outVariable);
+
+    void visit(OutText outText);
+
+    void visit(Loop.Start loopStart);
+
+    void visit(Loop.End loopEnd);
+
+    void visit(Procedure.Start startProcedure);
+
+    void visit(Procedure.End endProcedure);
+
+    void visit(Procedure.Call procedureCall);
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/CommandVisitor.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/Conditional.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/Conditional.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/Conditional.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/Conditional.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.sling.scripting.sightly.impl.compiler.ris.command;
+
+import org.apache.sling.scripting.sightly.impl.compiler.ris.Command;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.CommandVisitor;
+
+/**
+ * Imposes a condition on the next rendering commands
+ */
+public class Conditional {
+
+    public static class Start implements Command {
+        private String variable;
+        private boolean expectedTruthValue;
+
+        public Start(String variable, boolean expectedTruthValue) {
+            this.variable = variable;
+            this.expectedTruthValue = expectedTruthValue;
+        }
+
+        @Override
+        public void accept(CommandVisitor visitor) {
+            visitor.visit(this);
+        }
+
+        public String getVariable() {
+            return variable;
+        }
+
+        public boolean getExpectedTruthValue() {
+            return expectedTruthValue;
+        }
+
+        @Override
+        public String toString() {
+            return "Conditional.Start{" +
+                    "variable='" + variable + '\'' +
+                    ", expectedTruthValue=" + expectedTruthValue +
+                    '}';
+        }
+    }
+
+    public static final End END = new End();
+
+    public static final class End implements Command {
+
+        private End() {
+        }
+
+        @Override
+        public void accept(CommandVisitor visitor) {
+            visitor.visit(this);
+        }
+
+        @Override
+        public String toString() {
+            return "Conditional.End{}";
+        }
+    }
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/Conditional.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/Loop.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/Loop.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/Loop.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/Loop.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.sling.scripting.sightly.impl.compiler.ris.command;
+
+import org.apache.sling.scripting.sightly.impl.compiler.ris.Command;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.CommandVisitor;
+
+/**
+ * Render a sequence of commands repeatedly. Must have a corresponding end loop later
+ * in the stream
+ */
+public class Loop {
+
+    public static class Start implements Command {
+
+        private String listVariable;
+        private String itemVariable;
+        private String indexVariable;
+
+        public Start(String listVariable, String itemVariable, String indexVariable) {
+            this.listVariable = listVariable;
+            this.itemVariable = itemVariable;
+            this.indexVariable = indexVariable;
+        }
+
+        public String getListVariable() {
+            return listVariable;
+        }
+
+        public String getItemVariable() {
+            return itemVariable;
+        }
+
+        public String getIndexVariable() {
+            return indexVariable;
+        }
+
+        @Override
+        public void accept(CommandVisitor visitor) {
+            visitor.visit(this);
+        }
+
+        @Override
+        public String toString() {
+            return "Loop.Start{" +
+                    "listVariable='" + listVariable + '\'' +
+                    ", itemVariable='" + itemVariable + '\'' +
+                    ", indexVariable='" + indexVariable + '\'' +
+                    '}';
+        }
+    }
+
+    public static final End END = new End();
+
+    public static final class End implements Command {
+        private End() {
+        }
+
+        @Override
+        public void accept(CommandVisitor visitor) {
+            visitor.visit(this);
+        }
+
+        @Override
+        public String toString() {
+            return "Loop.End{}";
+        }
+    }
+
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/Loop.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/OutText.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/OutText.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/OutText.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/OutText.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.sling.scripting.sightly.impl.compiler.ris.command;
+
+import org.apache.sling.scripting.sightly.impl.compiler.ris.Command;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.CommandVisitor;
+
+/**
+ * Render a text fragment
+ */
+public class OutText implements Command {
+
+    private String text;
+
+    public OutText(String text) {
+        this.text = text;
+    }
+
+    @Override
+    public void accept(CommandVisitor visitor) {
+        visitor.visit(this);
+    }
+
+    public String getText() {
+        return text;
+    }
+
+    @Override
+    public String toString() {
+        return "OutText{" +
+                "text='" + text + '\'' +
+                '}';
+    }
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/OutText.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/OutVariable.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/OutVariable.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/OutVariable.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/OutVariable.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.sling.scripting.sightly.impl.compiler.ris.command;
+
+import org.apache.sling.scripting.sightly.impl.compiler.ris.Command;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.CommandVisitor;
+
+/**
+ * Render the content of a variable
+ */
+public class OutVariable implements Command {
+
+    private final String variableName;
+
+    public OutVariable(String variableName) {
+        this.variableName = variableName;
+    }
+
+    @Override
+    public void accept(CommandVisitor visitor) {
+        visitor.visit(this);
+    }
+
+    public String getVariableName() {
+        return variableName;
+    }
+
+    @Override
+    public String toString() {
+        return "OutVariable{" +
+                "variableName='" + variableName + '\'' +
+                '}';
+    }
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/OutVariable.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/Patterns.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/Patterns.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/Patterns.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/Patterns.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.sling.scripting.sightly.impl.compiler.ris.command;
+
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.BooleanConstant;
+import org.apache.sling.scripting.sightly.impl.compiler.util.stream.PushStream;
+
+/**
+ * Usual command patterns
+ */
+public class Patterns {
+
+    private static final String ALWAYS_FALSE_VAR = "always_false";
+
+    /**
+     * Inserts a sequence of commands that will ignore the rest of the stream until
+     * the end stream sequence is inserted
+     * @param stream - the stream
+     */
+    public static void beginStreamIgnore(PushStream stream) {
+        stream.emit(new VariableBinding.Start(ALWAYS_FALSE_VAR, BooleanConstant.FALSE));
+        stream.emit(new Conditional.Start(ALWAYS_FALSE_VAR, true));
+    }
+
+    /**
+     * Inserts a sequence of commands that cancels stream ignore
+     * @param stream - the input stream
+     */
+    public static void endStreamIgnore(PushStream stream) {
+        stream.emit(Conditional.END);
+        stream.emit(VariableBinding.END);
+    }
+
+
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/Patterns.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/Procedure.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/Procedure.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/Procedure.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/Procedure.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.sling.scripting.sightly.impl.compiler.ris.command;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.sling.scripting.sightly.impl.compiler.ris.Command;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.CommandVisitor;
+
+/**
+ * Commands that delimitate a procedure
+ */
+public class Procedure {
+
+    public static class Start implements Command {
+
+        private String name;
+        private Set<String> parameters;
+
+        public Start(String name, Set<String> parameters) {
+            this.name = name;
+            this.parameters = new HashSet<String>(parameters);
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public Set<String> getParameters() {
+            return Collections.unmodifiableSet(parameters);
+        }
+
+        @Override
+        public void accept(CommandVisitor visitor) {
+            visitor.visit(this);
+        }
+    }
+
+    public static final End END = new End();
+
+    public static final class End implements Command {
+
+        private End() {
+        }
+
+        @Override
+        public void accept(CommandVisitor visitor) {
+            visitor.visit(this);
+        }
+    }
+
+    public static class Call implements Command {
+
+        private final String templateVariable;
+        private final String argumentsVariable;
+
+        public Call(String templateVariable, String argumentsVariable) {
+            this.templateVariable = templateVariable;
+            this.argumentsVariable = argumentsVariable;
+        }
+
+        public String getTemplateVariable() {
+            return templateVariable;
+        }
+
+        public String getArgumentsVariable() {
+            return argumentsVariable;
+        }
+
+        @Override
+        public void accept(CommandVisitor visitor) {
+            visitor.visit(this);
+        }
+    }
+
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/Procedure.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/VariableBinding.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/VariableBinding.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/VariableBinding.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/VariableBinding.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.sling.scripting.sightly.impl.compiler.ris.command;
+
+import org.apache.sling.scripting.sightly.impl.compiler.expression.ExpressionNode;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.CommandVisitor;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.Command;
+
+/**
+ * Marks the binding of a variable. Must have a corresponding binding end later in the stream
+ */
+public class VariableBinding {
+
+    public static class Start implements Command {
+        private String variableName;
+        private ExpressionNode expression;
+
+        public Start(String variableName, ExpressionNode expression) {
+            this.variableName = variableName;
+            this.expression = expression;
+        }
+
+        public String getVariableName() {
+            return variableName;
+        }
+
+        public ExpressionNode getExpression() {
+            return expression;
+        }
+
+        @Override
+        public void accept(CommandVisitor visitor) {
+            visitor.visit(this);
+        }
+
+        @Override
+        public String toString() {
+            return "VariableBinding.Start{" +
+                    "variableName='" + variableName + '\'' +
+                    ", expression=" + expression +
+                    '}';
+        }
+    }
+
+    public static final End END = new End();
+
+    public static final class End implements Command {
+
+        private End() {
+        }
+
+        @Override
+        public void accept(CommandVisitor visitor) {
+            visitor.visit(this);
+        }
+
+        @Override
+        public String toString() {
+            return "VariableBinding.End{}";
+        }
+    }
+
+    public static final class Global implements Command {
+
+        private final String variableName;
+        private final ExpressionNode expressionNode;
+
+        public Global(String variableName, ExpressionNode expressionNode) {
+            this.variableName = variableName;
+            this.expressionNode = expressionNode;
+        }
+
+        public String getVariableName() {
+            return variableName;
+        }
+
+        public ExpressionNode getExpression() {
+            return expressionNode;
+        }
+
+
+        @Override
+        public void accept(CommandVisitor visitor) {
+            visitor.visit(this);
+        }
+    }
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ris/command/VariableBinding.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/GlobalShadowCheckBackend.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/GlobalShadowCheckBackend.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/GlobalShadowCheckBackend.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/GlobalShadowCheckBackend.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+
+package org.apache.sling.scripting.sightly.impl.compiler.util;
+
+import java.util.Set;
+
+import org.apache.sling.scripting.sightly.impl.compiler.CompilerBackend;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.CommandStream;
+import org.apache.sling.scripting.sightly.impl.compiler.util.stream.VisitorHandler;
+
+/**
+ * Wrapping backend that checks for global bindings shadowing
+ */
+public class GlobalShadowCheckBackend implements CompilerBackend {
+
+    private final CompilerBackend baseBackend;
+    private final Set<String> globals;
+
+    public GlobalShadowCheckBackend(CompilerBackend baseBackend, Set<String> globals) {
+        this.baseBackend = baseBackend;
+        this.globals = globals;
+    }
+
+    @Override
+    public void handle(CommandStream stream) {
+        stream.addHandler(new VisitorHandler(new GlobalShadowChecker(globals)));
+        baseBackend.handle(stream);
+    }
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/GlobalShadowCheckBackend.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/GlobalShadowChecker.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/GlobalShadowChecker.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/GlobalShadowChecker.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/GlobalShadowChecker.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+
+package org.apache.sling.scripting.sightly.impl.compiler.util;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.sling.scripting.sightly.impl.compiler.ris.CommandVisitor;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Conditional;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Loop;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.OutText;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.OutVariable;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Procedure;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.VariableBinding;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Checks whether variable declarations shadow global bindings
+ */
+public class GlobalShadowChecker implements CommandVisitor {
+
+    private static final Logger log = LoggerFactory.getLogger(GlobalShadowChecker.class);
+    private final Map<String, String> globals;
+
+    public GlobalShadowChecker(Set<String> globals) {
+        this.globals = new HashMap<String, String>();
+        for (String global : globals) {
+            this.globals.put(global.toLowerCase(), global);
+        }
+    }
+
+    @Override
+    public void visit(Conditional.Start conditionalStart) {
+    }
+
+    @Override
+    public void visit(Conditional.End conditionalEnd) {
+    }
+
+    @Override
+    public void visit(VariableBinding.Start variableBindingStart) {
+        checkVariable(variableBindingStart.getVariableName());
+    }
+
+    @Override
+    public void visit(VariableBinding.End variableBindingEnd) {
+
+    }
+
+    @Override
+    public void visit(VariableBinding.Global globalAssignment) {
+        checkVariable(globalAssignment.getVariableName());
+    }
+
+    @Override
+    public void visit(OutVariable outVariable) {
+
+    }
+
+    @Override
+    public void visit(OutText outText) {
+
+    }
+
+    @Override
+    public void visit(Loop.Start loopStart) {
+        checkVariable(loopStart.getItemVariable());
+        checkVariable(loopStart.getIndexVariable());
+    }
+
+    @Override
+    public void visit(Loop.End loopEnd) {
+    }
+
+    @Override
+    public void visit(Procedure.Start startProcedure) {
+        checkVariable(startProcedure.getName());
+    }
+
+    @Override
+    public void visit(Procedure.End endProcedure) {
+    }
+
+    @Override
+    public void visit(Procedure.Call procedureCall) {
+    }
+
+    private void checkVariable(String variableName) {
+        variableName = variableName.toLowerCase();
+        if (globals.containsKey(variableName)) {
+            String originalName = globals.get(variableName);
+            log.warn("Global variable '{}' is being overridden in template", originalName);
+        }
+    }
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/GlobalShadowChecker.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/SymbolGenerator.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/SymbolGenerator.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/SymbolGenerator.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/SymbolGenerator.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.sling.scripting.sightly.impl.compiler.util;
+
+public class SymbolGenerator {
+
+    public static final String DEFAULT_VAR_PREFIX = "var_";
+
+    private int counter = 0;
+    private final String prefix;
+
+    public SymbolGenerator() {
+        this(DEFAULT_VAR_PREFIX);
+    }
+
+    public SymbolGenerator(String prefix) {
+        this.prefix = prefix;
+    }
+
+    public String next(String hint) {
+        String middle = (hint != null) ? hint.replaceAll("\\-", "_") : "";
+        return prefix + middle + counter++;
+    }
+
+    public String next() {
+        return next(null);
+    }
+
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/SymbolGenerator.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/VariableTracker.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/VariableTracker.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/VariableTracker.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/VariableTracker.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.sling.scripting.sightly.impl.compiler.util;
+
+import java.util.AbstractMap;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+
+/**
+ * Track information related to Sightly variables
+ */
+public class VariableTracker<T> {
+
+    private final Map<String, Stack<T>> variableData = new HashMap<String, Stack<T>>();
+    private final Stack<String> declarationStack = new Stack<String>();
+
+    public boolean isDeclared(String name) {
+        name = name.toLowerCase();
+        Stack<T> dataStack = variableData.get(name);
+        return dataStack != null;
+    }
+
+    /**
+     * Push a variable. Use this at a variable declaration
+     * @param name - the name of the variable
+     * @param data - data associated with the variable
+     */
+    public void pushVariable(String name, T data) {
+        name = name.toLowerCase();
+        Stack<T> dataStack = variableData.get(name);
+        if (dataStack == null) {
+            dataStack = new Stack<T>();
+            variableData.put(name, dataStack);
+        }
+        dataStack.push(data);
+        declarationStack.push(name);
+    }
+
+    /**
+     * Pop a variable. Use this when a variable goes out of scope
+     * @return - the name of the popped variable
+     * @throws java.util.NoSuchElementException - if there are no declared variables in the scope
+     */
+    public String popVariable() {
+        String variable = declarationStack.pop();
+        Stack<T> dataStack = variableData.get(variable);
+        assert dataStack != null;
+        dataStack.pop();
+        if (dataStack.isEmpty()) {
+            variableData.remove(variable);
+        }
+        return variable;
+    }
+
+    /**
+     * Peek at the top of the declaration stack
+     * @return - the most recently declared variable and it's associated data
+     * @throws java.util.NoSuchElementException - if there are no variables in scope
+     */
+    public Map.Entry<String, T> peek() {
+        String variable = declarationStack.peek();
+        Stack<T> dataStack = variableData.get(variable);
+        assert dataStack != null;
+        T data = dataStack.peek();
+        return new AbstractMap.SimpleImmutableEntry<String, T>(variable, data);
+    }
+
+    public boolean isEmpty() {
+        return declarationStack.isEmpty();
+    }
+
+    /**
+     * Get the data associated with the given variable
+     * @param name - the name of the variable
+     * @return the associated data or null if that variable is not in scope
+     */
+    public T get(String name) {
+        name = name.toLowerCase();
+        Stack<T> dataStack = variableData.get(name);
+        if (dataStack == null) {
+            return null;
+        }
+        assert !dataStack.isEmpty();
+        return dataStack.peek();
+    }
+
+    /**
+     * Check whether a variable was declared and is visible in the current scope
+     * @param name - the name of the variable
+     * @return - the visibility of the variable in the current scope
+     */
+    public boolean isInScope(String name) {
+        name = name.toLowerCase();
+        return variableData.get(name) != null;
+    }
+
+    /**
+     * Get an immutable view of all the data items associated with the specified
+     * variable.
+     * @param name - the name of the variable
+     * @return - a list of all the data associated with this variable name. If the
+     * variable is not declared in the current scope then that list will be empty. Otherwise
+     * it will contain all the data associated for the current scope starting with the data
+     * associated at the topmost scope and ending with the most recently associated data
+     */
+    public List<T> getAll(String name) {
+        name = name.toLowerCase();
+        Stack<T> dataStack = variableData.get(name);
+        if (dataStack == null) {
+            return Collections.emptyList();
+        }
+        return Collections.unmodifiableList(dataStack);
+    }
+
+    /**
+     * Get how many times a variable was declared in the current scope
+     * @param name - the name of the variable
+     * @return - the number of declarations for a variable in the current scope
+     */
+    public int getOccurrenceCount(String name) {
+        name = name.toLowerCase();
+        Stack<T> dataStack = variableData.get(name);
+        if (dataStack == null) {
+            return 0;
+        }
+        return dataStack.size();
+    }
+
+}

Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/VariableTracker.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/expression/HomogenousNodeVisitor.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/expression/HomogenousNodeVisitor.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/expression/HomogenousNodeVisitor.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/expression/HomogenousNodeVisitor.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+
+package org.apache.sling.scripting.sightly.impl.compiler.util.expression;
+
+import org.apache.sling.scripting.sightly.impl.compiler.expression.ExpressionNode;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.NodeVisitor;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.ArrayLiteral;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.BinaryOperation;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.BooleanConstant;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.Identifier;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.MapLiteral;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.NullLiteral;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.NumericConstant;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.PropertyAccess;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.RuntimeCall;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.StringConstant;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.TernaryOperator;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.UnaryOperation;
+
+/**
+ * Apply the same evaluation for all expression nodes
+ */
+public abstract class HomogenousNodeVisitor<T> implements NodeVisitor<T> {
+
+    protected abstract T evaluateDefault(ExpressionNode node);
+
+    @Override
+    public T evaluate(PropertyAccess propertyAccess) {
+        return evaluateDefault(propertyAccess);
+    }
+
+    @Override
+    public T evaluate(Identifier identifier) {
+        return evaluateDefault(identifier);
+    }
+
+    @Override
+    public T evaluate(StringConstant text) {
+        return evaluateDefault(text);
+    }
+
+    @Override
+    public T evaluate(BinaryOperation binaryOperation) {
+        return evaluateDefault(binaryOperation);
+    }
+
+    @Override
+    public T evaluate(BooleanConstant booleanConstant) {
+        return evaluateDefault(booleanConstant);
+    }
+
+    @Override
+    public T evaluate(NumericConstant numericConstant) {
+        return evaluateDefault(numericConstant);
+    }
+
+    @Override
+    public T evaluate(UnaryOperation unaryOperation) {
+        return evaluateDefault(unaryOperation);
+    }
+
+    @Override
+    public T evaluate(TernaryOperator ternaryOperator) {
+        return evaluateDefault(ternaryOperator);
+    }
+
+    @Override
+    public T evaluate(RuntimeCall runtimeCall) {
+        return evaluateDefault(runtimeCall);
+    }
+
+    @Override
+    public T evaluate(MapLiteral mapLiteral) {
+        return evaluateDefault(mapLiteral);
+    }
+
+    @Override
+    public T evaluate(ArrayLiteral arrayLiteral) {
+        return evaluateDefault(arrayLiteral);
+    }
+
+    @Override
+    public T evaluate(NullLiteral nullLiteral) {
+        return evaluateDefault(nullLiteral);
+    }
+}