src/main/java/com/bazaarvoice/jless/parser/Parser.java
boolean pushVariableReference(String name) {
        if (!isParserTranslationEnabled()) {
            return push(new SimpleNode(name));
        }

        // Walk down the stack, looking for a scope node that knows about a given variable
        for (Node node : getContext().getValueStack()) {
            if (!(node instanceof ScopeNode)) {
                continue;
            }

            // Ensure that the variable exists
            ScopeNode scope = (ScopeNode) node;
            if (!scope.isVariableDefined(name)) {
                continue;
            }

            return push(new VariableReferenceNode(name));
        }

        // Record error location
        throw new UndefinedVariableException(name);
    }
boolean pushVariableReference(String name) {
        if (!isParserTranslationEnabled()) {
            return push(new SimpleNode(name));
        }

        // Walk down the stack, looking for a scope node that knows about a given variable
        for (Node node : getContext().getValueStack()) {
            if (!(node instanceof ScopeNode)) {
                continue;
            }

            // Ensure that the variable exists
            ScopeNode scope = (ScopeNode) node;
            if (!scope.isVariableDefined(name)) {
                continue;
            }

            return push(new VariableReferenceNode(name));
        }

        // Record error location
        throw new UndefinedVariableException(name);
    }
Looks for a variable definition that matches the reference in the scope nodes on the stack.
If found, a reference node that can repeat this lookup later is placed on the stack, not the
current value itself. This is done because the value may change if the variable reference is
inside a mixin.