All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.python.compiler.ScopeInfo Maven / Gradle / Ivy

Go to download

Jython is an implementation of the high-level, dynamic, object-oriented language Python written in 100% Pure Java, and seamlessly integrated with the Java platform. It thus allows you to run Python on any Java platform.

There is a newer version: 2.7.4
Show newest version
// (C) Copyright 2001 Samuele Pedroni

package org.python.compiler;

import java.util.*;
import org.python.parser.SimpleNode;

public class ScopeInfo extends Object implements ScopeConstants {

    public SimpleNode scope_node;
    public String scope_name;
    public int level;
    public int func_level;
    public int list_comprehension_count;

    public void dump() { // for debugging
        if (org.python.core.Options.verbose < org.python.core.Py.DEBUG)
            return;
        for(int i=0; i nop
        this.up = up;
        this.distance = distance;
        boolean func = kind == FUNCSCOPE;
        Vector purecells = new Vector();
        cell = 0;
        boolean some_inner_free = inner_free.size() > 0;

        for (Enumeration e = inner_free.keys(); e.hasMoreElements(); ) {
            String name = (String)e.nextElement();
            SymInfo info = (SymInfo)tbl.get(name);
            if (info == null) {
                tbl.put(name,new SymInfo(FREE));
                continue;
            }
            int flags = info.flags;
            if (func) {
                // not func global and bound ?
                if ((flags&NGLOBAL) == 0 && (flags&BOUND) != 0) {
                    info.flags |= CELL;
                    if ((info.flags&PARAM) != 0)
                        jy_paramcells.addElement(name);
                    cellvars.addElement(name);
                    info.env_index = cell++;
                    if ((flags&PARAM) == 0) purecells.addElement(name);
                    continue;
                }
            } else {
                info.flags |= FREE;
            }
        }
        boolean some_free = false;

        boolean nested = up.kind != TOPSCOPE;
        for (Enumeration e = tbl.keys(); e.hasMoreElements(); ) {
            String name = (String)e.nextElement();
            SymInfo info = (SymInfo)tbl.get(name);
            int flags = info.flags;
            if (nested && (flags&FREE) != 0) up.inner_free.put(name,PRESENT);
            if ((flags&(GLOBAL|PARAM|CELL)) == 0) {
                if ((flags&BOUND) != 0) { // ?? only func
                    // System.err.println("local: "+name);
                    names.addElement(name);
                    info.locals_index = local++;
                    continue;
                }
                info.flags |= FREE;
                some_free = true;
                if (nested) up.inner_free.put(name,PRESENT);
            }
        }
        if ((jy_npurecell = purecells.size()) > 0) {
            int sz = purecells.size();
            for (int i = 0; i < sz; i++) {
                names.addElement(purecells.elementAt(i));
            }
        }
        if ((unqual_exec || from_import_star)) {
            if(some_inner_free) dynastuff_trouble(true, ctxt);
            else if(func_level > 1 && some_free)
                dynastuff_trouble(false, ctxt);
        }

    }

    private void dynastuff_trouble(boolean inner_free,
                                   CompilationContext ctxt) throws Exception {
        String illegal;
        if (unqual_exec && from_import_star)
            illegal = "function '"+scope_name+
                      "' uses import * and bare exec, which are illegal";
        else if (unqual_exec)
            illegal = "unqualified exec is not allowed in function '"+
                      scope_name+"'";
        else
            illegal = "import * is not allowed in function '"+scope_name+"'";
        String why;
        if (inner_free)
            why = " because it contains a function with free variables";
        else
            why = " because it contains free variables";
        ctxt.error(illegal + why, true, scope_node);
    }

    public Vector freevars = new Vector();

    /**
     * setup the closure on this scope using the scope passed into cook as up as
     * the containing scope
     */
    public void setup_closure() {
        setup_closure(up);
    }
    
    /**
     * setup the closure on this scope using the passed in scope. This is used
     * by jythonc to setup its closures.
     */
    public void setup_closure(ScopeInfo up){
        int free = cell; // env = cell...,free...
        Hashtable up_tbl = up.tbl;
        boolean nested = up.kind != TOPSCOPE;
        for (Enumeration e = tbl.keys(); e.hasMoreElements(); ) {
            String name = (String)e.nextElement();
            SymInfo info = (SymInfo)tbl.get(name);
            int flags = info.flags;
            if ((flags&FREE) != 0) {
                SymInfo up_info = (SymInfo)up_tbl.get(name);
                // ?? differs from CPython -- what is the intended behaviour?
                if (up_info != null) {
                    int up_flags = up_info.flags;
                    if ((up_flags&(CELL|FREE)) != 0) {
                        info.env_index = free++;
                        freevars.addElement(name);
                        continue;
                    }
                    // ! func global affect nested scopes
                    if (nested && (up_flags&NGLOBAL) != 0) {
                        info.flags = NGLOBAL|BOUND;
                        continue;
                    }
                }
                info.flags &= ~FREE;
            }
        }

    }

    public String toString() {
        return "ScopeInfo[" + scope_name + " " + kind + "]@" +
                System.identityHashCode(this);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy