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

📄 interp.java

📁 Hecl编程语言是一个高层次的脚本语言的Java实现。其用意是要小
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* Copyright 2004-2007 David N. Welton, DedaSys LLC Licensed 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.hecl;import java.io.InputStream;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.EOFException;import java.io.InputStreamReader;import java.io.IOException;import java.io.PrintStream;import java.util.Enumeration;import java.util.Hashtable;import java.util.Stack;import java.util.Vector;//#if j2seimport java.util.LinkedList;import java.util.List;import jline.ArgumentCompletor;import jline.ConsoleReader;import jline.NullCompletor;import jline.SimpleCompletor;//#endif/** * <code>Interp</code> is the Hecl interpreter, the class responsible for * knowing what variables and commands are available. * * @author <a href="mailto:davidw@dedasys.com">David N. Welton </a> * @version 1.0 */public class Interp extends Thread/*implements Runnable*/ {    /**     * Package name prefix of the module classes.     */    public static final String MODULE_CLASS_PACKAGE = "org.hecl";    /**     * Flags for the event loop.     */    public static final int DONT_WAIT = 1;    public static final int IDLE_EVENTS = 2;    public static final int TIMER_EVENTS = 4;    public static final int ALL_EVENTS = ~DONT_WAIT;    /**     * Some string constants used to generate names for internal events.     */    public static final String ASYNCPREFIX = "async";    public static final String IDLEPREFIX = "idle";    public static final String TIMERPREFIX = "timer";    /**     * The prompt for the <code>readEvalPrint</code> loop.     */    public final String PROMPT = "hecl> ";    /**     * The prompt for continued lines in the <code>readEvalPrint</code> loop.     */    public final String PROMPT2 = "hecl+ ";    /**     * A <code>Thing</code> to indicate  global reference.     */    static final Thing GLOBALREFTHING = new Thing("");    public long cacheversion = 0;    /**     * The <code>commands</code> <code>Hashtable</code> provides the     * mapping from the strings containing command names to the code     * implementing the commands.     *     * We save some space by making this public and removing the     * accessors.     *     */    protected Hashtable commands = new Hashtable();    /**     * The <code>auxdata</code> <code>Hashtable</code> is a place to     * store extra information about the state of the program.     *     */    protected Hashtable auxdata = new Hashtable();    protected Stack stack = new Stack();    protected Stack error = new Stack();    protected Vector timers = new Vector();    protected Vector asyncs = new Vector();    protected Vector idle = new Vector();    protected Hashtable waittokens = new Hashtable();    protected long idlegeneration = 0;    protected boolean running = true;    protected long maxblocktime = 0;	    // block time in milliseconds    protected Vector ci = new Vector();    protected Hashtable classcmdcache = new Hashtable();        /**     * Creates a new <code>Interp</code> instance, initializing command and     * variable hashtables, a stack, and an error stack.     *     * @exception HeclException if an error occurs     */    public Interp() throws HeclException {        // Set up stack frame for globals.        stack.push(new Hashtable());        initInterp();	start();    }//#ifdef j2se    protected String[] hashKeysToArray(Hashtable h) {	return hashKeysToArray(h, "");    }    protected String[] hashKeysToArray(Hashtable h, String prefix) {	Vector<String> cmds = new Vector<String>();	for (Enumeration e = h.keys(); e.hasMoreElements();) {	    cmds.add(prefix + (String)e.nextElement());	}	String[] scmds = new String[cmds.size()];	cmds.copyInto(scmds);	return scmds;    }//#endif    /**     * The <code>commandLine</code> method implements a     * Read/Eval/Print Loop.     *     * @param in Input stream to read input from.     * @param out Output stream to print results to.     * @param err Output stream for error messages.     *     * This function never returns.     */    public void readEvalPrint(InputStream in, PrintStream out, PrintStream err) {	String prompt = PROMPT;	StringBuffer sb = new StringBuffer();//#if j2se        List completors = null;	ConsoleReader reader = null;	int oldsz = 0;	int newsz = 0;//#else	InputStreamReader reader = new InputStreamReader(in);//#endif	while(true) {	    byte outbytes[] = null;	    String line = null;//#if j2se	    Hashtable vars = getVarhash(-1);	    newsz = commands.size() + vars.size();	    /* If the number of commands or variables has increased,	     * reindex them in the command line completor.  Currently,	     * it uses commands for the first completion, and variable	     * names (with leading $) for subsequent completions. */	    if (newsz > oldsz) {		completors = new LinkedList();		completors.add(		    new SimpleCompletor(hashKeysToArray(commands)));		completors.add(		    new SimpleCompletor(hashKeysToArray(vars, "$")));		completors.add(new NullCompletor());		try {		    reader = new ConsoleReader();		    reader.addCompletor(new ArgumentCompletor(completors));		} catch (IOException e) {		    System.err.println(e);		    return;		}		oldsz = newsz;	    }	    try {		line = reader.readLine(prompt);	    } catch (IOException e) {		err.println(e);		break;	    }//#else	    out.print(prompt);	    out.flush();	    line = readLine(reader);//#endif	    if(line == null)		break;	    if(sb.length() > 0)		sb.append('\n');	    sb.append(line);	    try {		if(sb.length() <= 0)		    continue;		Thing res = evalAsyncAndWait(new Thing(sb.toString()));		if (res != null) {		    String s = res.toString();		    if(s.length() > 0) {			// It seems that DataOutputStream.println(String)			// is broken and returns OutOfmemory when the			// string is to long, so we convert the string			// into bytes and write out the pure bytes			// directly.			outbytes = s.getBytes();		    }		}		sb.delete(0,sb.length());		prompt = PROMPT;	    }	    catch(HeclException he) {		if (he.code.equals("PARSE_ERROR")) {		    // Change prompt and get more input		    prompt = PROMPT2;		} else {		    sb.delete(0,sb.length());		    he.printStackTrace();		    outbytes = he.getMessage().getBytes();		    prompt = PROMPT;		}	    }	    if(outbytes != null) {		// result output		try {		    out.write(outbytes);		    out.println();		}		catch(IOException ioex) {		    err.println(ioex.getMessage());		    break;		}		outbytes = null;	    }	}    }    /**     * Add a new class command to an <code>Interp</code>.     *     * @param clazz The Java class the command should operate on.     * @param cmd The command to add. When this paramter is <code>null</code>,     * an existing command is removed.     */    public void addClassCmd(Class clazz,ClassCommand cmd) {	// clear cache first, even when deleting a cmd	this.classcmdcache.clear();		int l = this.ci.size();	for(int i=0; i<l; ++i) {	    ClassCommandInfo info = (ClassCommandInfo)this.ci.elementAt(i);	    if(info.forClass() == clazz) {		//identical, replace		if(cmd == null) {		    ci.removeElementAt(i);		} else {		    info.setCommand(cmd);		}		return;	    }	}	if(cmd != null)	    this.ci.addElement(new ClassCommandInfo(clazz,cmd));    }    /**     * Remove a command for a specific class from an <code>Interp</code>.     *     * @param clazz The class to remove the command for.     */    public void removeClassCmd(Class clazz) { addClassCmd(clazz,null);}	             /**     * Add a new class command to an <code>Interp</code>.     *<br>     * The current implementation does not support any subclassing and selects     * the first class command <code>clazz</code> is assignable to.     *     * @param clazz The Java class to look up the class command for.     * @return A <code>ClassCommandInfo</code> decsribing the class command,     * or <code>null</null> if no command was found.     */    ClassCommandInfo findClassCmd(Class clazz) {	ClassCommandInfo found = (ClassCommandInfo)this.classcmdcache.get(clazz);	if(found == null) {	    // No entry in cache, so we loop over all class commands and try	    // to detect the most specific one.	    int l = this.ci.size();	    for(int i=0; i<l; ++i) {		ClassCommandInfo info = (ClassCommandInfo)this.ci.elementAt(i);		Class cl2 = info.forClass();		if(cl2.isAssignableFrom(clazz)) {		    //System.err.println("clazz="+clazz+" assignable to cl="+cl2);		    if(found == null)			found = info;		    else {			// check if this is more specialized than the one we			// already have.			if(found.forClass().isAssignableFrom(cl2)) {			    //System.err.println("superclass="+found.forClass()+" for cl="+cl2);			    found = info;			}			// else keep existing one		    }		}	    }	    // Add what we found to the cache, so we do not need to look it up	    // next time.	    if(found != null)		this.classcmdcache.put(clazz,found);	}	return found;    }            /**     * Add a new command to an <code>Interp</code>.     *     * @param name the name of the command to add.     * @param c the command to add.     */    public synchronized String addCommand(String name,Command c) {	commands.put(name,c);	return name;    }    /**     * Remove a command from an <code>Interp</code>.     *     * @param name the name of the command to add.     */    public synchronized void removeCommand(String name) {	commands.remove(name);    }    /**     * Attach auxiliary data to an <code>Interp</code>.     */    public synchronized void setAuxData(String key,Object value) {	auxdata.put(key, value);    }    /**     * Retrieve auxiliary data from an <code>Interp</code>.     *     * @return a <code>Object</code> value or <code>null</code> when no     * auxiliary data under the given key is attached to the interpreter.     */    public synchronized Object getAuxData(String key) {	return auxdata.get(key);    }    /**     * Remove auxiliary data from an <code>Interp</code>.     */    public synchronized void removeAuxData(String key) {	auxdata.remove(key);    }    /**     * The <code>eval</code> method evaluates some Hecl code passed to     * it.     *     * @return a <code>Thing</code> value - the result of the     * evaluation.     * @exception HeclException if an error occurs.     */    public synchronized Thing eval(Thing in) throws HeclException {	//System.err.println("-->eval: "+in.toString());	return CodeThing.get(this, in).run(this);    }    public HeclTask evalIdle(Thing idleThing) {	return addTask(idle,new HeclTask(idleThing,idlegeneration,IDLEPREFIX),-1);    }    public HeclTask evalAsync(Thing asyncThing) {	return addTask(asyncs, new HeclTask(asyncThing,0,ASYNCPREFIX),-1);

⌨️ 快捷键说明

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