⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 interp.java

📁 Hecl编程语言是一个高层次的脚本语言的Java实现。其用意是要小
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
            throw new HeclException("Variable " + varname + " does not exist");        }        return res;//#else	if(res == GLOBALREFTHING) {	    // ref to a global var	    Hashtable globalhash = getVarhash(0);	    res = (Thing)globalhash.get(varname);	    if(res == GLOBALREFTHING) {		// should not happen, but just in case...		System.err.println("Unexpected GLOBALREFTHING in globalhash");		res = null;	    }//#ifdef emptyglobals	    else if (res == null) {		// Return a fake empty value for a non-set global variable for		// the sake of modifying commands.		// !!!! THIS IS STRANGE !!!		System.err.println("FAKE EMPTY VALUE for global var");		res = new Thing("");		globalhash.put(varname,res);	    }//#endif	}        if (res == null) {            throw new HeclException("Variable " + varname + " does not exist");        }	//System.err.println("<<getvar, res="+res);        return res;//#endif    }    /**     * <code>setVar</code> sets a variable in the innermost variable stack     * frame to a value.     *     * @param varname a <code>Thing</code> value     * @param value a <code>Thing</code> value     */    public void setVar(Thing varname, Thing value) throws HeclException {        setVar(varname.toString(), value);    }    /**     * <code>setVar</code> sets a variable in the innermost variable stack     * frame to a value.     *     * @param varname a <code>String</code> value     * @param value a <code>Thing</code> value     */    public void setVar(String varname, Thing value) {        setVar(varname, value, -1);    }    /**     * <code>setVar</code> sets a variable to a value in the variable stack     * frame specified by <code>level</code>.     *     * @param varname a <code>String</code> value     * @param value a <code>Thing</code> value     * @param level an <code>int</code> value     */    public synchronized void setVar(String varname, Thing value, int level) {        Hashtable lookup = getVarhash(level);	// Bump the cache number so that SubstThing.get refetches the	// variable.        cacheversion++;	//if(value == GLOBALREFTHING) System.err.println("flag '"+varname+"' as global on level="+level);	//System.err.println("set local("+level+") var="+varname + ", val="+value.toString());//#ifdef old	if (lookup.containsKey(varname)) {	     Thing oldval = (Thing) lookup.get(varname);	     /* In order to make the 'global' command work, we check	      * and see if the previous 'inhabitant' of the hashtable	      * had its global flag set.  If that's the case, then we	      * set the variable both at the local level, and at the	      * global level.  */	     if (oldval.global && level != 0) {		 value.global = true;		 Hashtable globalhash = getVarhash(0);		 globalhash.put(varname, value);	     }	}	lookup.put(varname, value);//#else	if (value.isLiteral()) {	    try {		Thing copy = value.deepcopy();		value = copy;	    } catch (HeclException he) {		/* This isn't going to happen - we're dealing with a		 * literal from the parser. */		System.err.println("Interp.java: This can never happen!");	    }	}	// first take care of GLOBALREFTHING used to flag ref to global var	if(value == GLOBALREFTHING) {	    // do not clutter global table with GLOBALREFTHING	    Hashtable globalhash = getVarhash(0);	    if(lookup != globalhash) {		//System.err.println(" not on global level");		lookup.put(varname, value);//#ifdef emptyglobals		if(null == globalhash.get(varname)) {		    // Insert a new empty thing at top level for the sake of		    // modifying commands.		    //System.err.println(" inserting empty global value");		    globalhash.put(varname, new Thing(""));		}//#endif	    } else {		//System.err.println(" ignored, already in global scope");	    }	    return;	}		if(lookup.containsKey(varname)) {	    Thing oldval = (Thing)lookup.get(varname);	    if(oldval == GLOBALREFTHING) {		// level must be at != 0		//System.err.println(" forwarded to global value");		lookup = getVarhash(0);	    }	}	lookup.put(varname, value);//#endif    }    /**     * <code>unSetVar</code> unsets a variable in the current stack     * frame.     *     * @param varname a <code>Thing</code> value     */    public void unSetVar(Thing varname) throws HeclException {	unSetVar(varname.toString(),-1);    }    public synchronized void unSetVar(String varname) throws HeclException {	unSetVar(varname,-1);    }        public synchronized void unSetVar(String varname,int level) throws HeclException {        Hashtable lookup = getVarhash(level);	// Bump the cache number so that SubstThing.get refetches the	// variable.	Thing value = (Thing)lookup.get(varname);	if (value != null) {	    cacheversion++;	    lookup.remove(varname);	    if (value.global) {		Hashtable globalhash = getVarhash(0);		value = (Thing)globalhash.get(varname);		if (value != null) {		    globalhash.remove(varname);		}	    }	} else {            throw new HeclException("Variable " + varname + " does not exist");	}    }    	        /**     * <code>existsVar</code> returns <code>true</code> if the given     * variable exists in the current variable stack frame, <code>false</code>     * if it does not.     *     * @param varname a <code>Thing</code> value     * @return a <code>boolean</code> value     */    public boolean existsVar(Thing varname) throws HeclException {        return existsVar(varname.toString());    }    /**     * <code>existsVar</code> returns <code>true</code> if the given     * variable exists in the current variable stack frame, <code>false</code>     * if it does not.     *     * @param varname a <code>String</code> value     * @return a <code>boolean</code> value     */    public boolean existsVar(String varname) {        return existsVar(varname, -1);    }    /**     * <code>existsVar</code> returns <code>true</code> if the given     * variable exists in the variable stack frame given by <code>level</code>,     * <code>false</code> if it does not.     *     * @param varname a <code>String</code> value     * @param level an <code>int</code> value     * @return a <code>boolean</code> value     */    public synchronized boolean existsVar(String varname, int level) {        Hashtable lookup = getVarhash(level);        return lookup.containsKey(varname);    }    /**     * <code>addError</code> adds a Thing as an error message.     *     * @param err a <code>Thing</code> value     */    public void addError(Thing err) {        error.push(err);    }    /**     * <code>clearError</code> clears the error stack.     *     */    public void clearError() {        error = new Stack();    }    /**     * <code>checkArgCount</code> checks to see whether the command     * actually has the required number of arguments. The first element of the     * parameter array <code>argv</code> is not counted as argument!     *     * @param argv A <code>Thing[]</code> parameter array.     * @param minargs The minimal number of arguments or -1 if no check is required.     * @param maxargs The maximal number of arguments or -1 if no check is required.     * @exception HeclException if an error occurs     */    public static void checkArgCount(Thing[] argv,int minargs,int maxargs) 	throws HeclException {	int n = argv.length-1;		    // Ignore command name	if(minargs >= 0 && n < minargs) {	    throw new HeclException("Too few arguments, at least "				    + minargs + " arguments required.");	}	if(maxargs >= 0 && n > maxargs) {	    throw new HeclException("Bad argument count, max. "				    + maxargs				    +" arguments allowed.");	}    }    	        /**     * <code>nextTask</code> extracts first element from given vector.     * This function operates in a synchronized manner on the argument     * <code>v</code>.     *     * @param v A <code>Vector</code> of tasks.     * @param until A value to compare the result of     * <code>getGeneration</code> of the <code>HeclTask</code>. If     * <code>until</code> is less than 0 or <code>getGeneration</code>     * is less than <code>until</code> for the first element of     * <code>v</code>, the first task in the vector is returned, null     * otherwise.     */    protected synchronized HeclTask nextTask(Vector v,long until) {	HeclTask t = null;		if(v.size() > 0) {	    t = (HeclTask)v.elementAt(0);	    //System.err.println("now="+ts+", fire="+t.getGeneration());	    if(until < 0 || t.getGeneration() <= until) {		v.removeElementAt(0);	    } else {		t = null;	    }	}	return t;    }        /**     * Service at most one idle task of the idle task queue.     *     * @return a <code>boolean</code> indicatign that an idle task has been     * serviced (=true) or not (=false).     */    protected boolean serviceIdleTask() {	// The code below is trickier than it may look, for the following	// reasons:	//	// 1. New handlers can get added to the list while the current	//    one is being processed.  If new ones get added, we don't	//    want to process them during this pass through the list (want	//    to check for other work to do first).  This is implemented	//    using the generation number in the handler:  new handlers	//    will have a different generation than any of the ones currently	//    on the list.	// 2. The handler can call doOneEvent, so we have to remove	//    the handler from the list before calling it. Otherwise an	//    infinite loop could result.	// 3. cancelIdleCall can be called to remove an element from	//    the list while a handler is executing, so the list could	//    change structure during the call.	long oldgeneration;	synchronized(this) {	    if(idle.size()== 0) {		idlegeneration = 0;		return false;	    }	    oldgeneration = idlegeneration;	    ++idlegeneration;	}	HeclTask t = nextTask(idle,oldgeneration);	if(t != null)	    t.execute(this);	if(idle.size() > 0)	    maxblocktime = 0;	return true;    }        /**     * Service at most one idle task of the idle task queue.     *     * @param v A <code>Vector</code> of tasks to add the task to.     * @param task The <code>HeclTask</code> to add.     * @param pos The </code>int</code> position of <code>v</code> where to     * add <code>task</code> being in the range from 0 to     * <code>v.size()</code>.  -1 indicates to add <code>task</code> to the     * end of <code>v</code>.     *     * @return A <code>String</code> being the name of the inserted task.     */    private HeclTask addTask(Vector v,HeclTask task,int pos) {	synchronized (v) {	if(pos < 0)	    v.addElement(task);	else	    v.insertElementAt(task,pos);//	notify();	return task;	}    }        /**     * Cancel a task of the specified name in the specified vector.     * The functions performs nothing when no task of the specified name is     * an element of the vector.     *     * @param v A vector of <code>HeclTask</code>s.     * @param name A <code>String</code> specifying the name of the     * task to be removed from <code>v</code>.     */    private synchronized void cancelTask(Vector v,String name) {	int n = v.size();	for(int i = 0; i<n; ++i) {	    HeclTask t = (HeclTask)v.elementAt(i);	    if(name.equals(t.getName())) {		v.removeElementAt(i);		return;	    }	}    }    /**     * Execute a <code>task</code>.     *     * @return Always the boolean value <code>true</code> to indicate     * that a task has been serviced.     */    private boolean executeTask(HeclTask task) {	try {	    task.execute(this);	}	catch(Exception e) {	    // Nothing to do. It is expected that each task handles	    // its exceptions locally but we use this block is to ensure	    // that the queue continues to operate.	}	return true;    }    protected static class WaitToken {	public volatile boolean waiting = true;    }    static String readLine(InputStreamReader is) {	StringBuffer b = new StringBuffer();	int ch = -1;	try {	    while ((ch = is.read()) != -1) {		if(ch == '\r')		    continue;		if(ch == '\n')		    break;		b.append((char)ch);	    }	}	catch(IOException iox) {	}	if(b.length() > 0 || ch != -1)	    return b.toString();	return null;    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -