return null;
result = (Cons)result.car;
- return new FactorWord((String)result.car,(String)result.next().car);
+ w = new FactorWord(
+ (String)result.car,
+ (String)result.next().car);
+ w.stackEffect = (String)result.next().next().car;
+ return w;
}
catch(Exception e)
{
public class FactorCompoundDefinition extends FactorWordDefinition
{
public Cons definition;
- private Cons endOfDocs;
//{{{ FactorCompoundDefinition constructor
/**
{
super(word);
this.definition = definition;
- if(definition == null)
- endOfDocs = null;
- else
- {
- endOfDocs = definition;
- while(endOfDocs != null
- && endOfDocs.car instanceof FactorDocComment)
- endOfDocs = endOfDocs.next();
- }
} //}}}
//{{{ toList() method
+++ /dev/null
-/* :folding=explicit:collapseFolds=1: */
-
-/*
- * $Id$
- *
- * Copyright (C) 2004 Slava Pestov.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package factor;
-
-import java.io.IOException;
-
-public class FactorDocComment implements FactorExternalizable
-{
- private String msg;
- private boolean stack;
-
- public FactorDocComment(String msg, boolean stack)
- {
- if(stack)
- msg = msg.trim();
- this.msg = msg;
- this.stack = stack;
- }
-
- public String toString()
- {
- if(stack)
- return "( " + msg + " )\n";
- else
- return "#! " + msg + "\n";
- }
-
- public boolean isStackComment()
- {
- return stack;
- }
-}
+++ /dev/null
-/* :folding=explicit:collapseFolds=1: */
-
-/*
- * $Id$
- *
- * Copyright (C) 2003, 2004 Slava Pestov.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package factor;
-
-import java.util.Set;
-
-/**
- * All primitive words extend this.
- */
-public abstract class FactorPrimitiveDefinition extends FactorWordDefinition
-{
- //{{{ FactorPrimitiveDefinition constructor
- /**
- * A new definition.
- */
- public FactorPrimitiveDefinition(FactorWord word)
- {
- super(word);
- } //}}}
-
- //{{{ fromList() method
- public void fromList(Cons cons)
- {
- } //}}}
-}
w.line = line;
w.col = col;
w.file = scanner.getFileName();
+ w.stackEffect = null;
+ w.documentation = null;
}
return w;
}
return true;
else if(next instanceof String)
{
- FactorWord word = intern((String)next,
- !getCurrentState().warnUndefined);
+ FactorWord word = intern((String)next,false);
if(word == null)
{
/* We're ignoring errors */
* An exclusive state can only happen at the top level.
* For example, : ... ; definitions cannot be nested so they
* are exclusive.
- *
- * @param args Parsing words can use this to store arbitrary info
*/
- public void pushExclusiveState(FactorWord start, Object args)
+ public void pushExclusiveState(FactorWord start, FactorWord defining)
throws FactorParseException
{
if(getCurrentState().start != toplevel)
scanner.error(start + " cannot be nested");
- pushState(start,args);
+ pushState(start,defining);
} //}}}
//{{{ pushState() method
/**
* Push a parser state, for example reading of a list.
*/
- public void pushState(FactorWord start, Object args)
+ public void pushState(FactorWord start, FactorWord defining)
{
- states = new Cons(new ParseState(start,args),states);
+ states = new Cons(new ParseState(start,defining),states);
} //}}}
//{{{ popState() method
getCurrentState().append(obj);
} //}}}
+ //{{{ setStackComment() method
+ public void setStackComment(String comment)
+ {
+ getCurrentState().setStackComment(comment);
+ } //}}}
+
+ //{{{ addDocComment() method
+ public void addDocComment(String comment)
+ {
+ getCurrentState().addDocComment(comment);
+ } //}}}
+
//{{{ bar() method
/**
* Sets the current parser state's cdr to the given object.
public class ParseState
{
public FactorWord start;
- public Object arg;
+ public FactorWord defining;
public Cons first;
public Cons last;
- public boolean warnUndefined;
- private boolean comma;
+ private boolean bar;
private boolean docComment;
- ParseState(FactorWord start, Object arg)
+ ParseState(FactorWord start, FactorWord defining)
{
docComment = start.docComment;
- warnUndefined = true;
this.start = start;
- this.arg = arg;
+ this.defining = defining;
}
void append(Object obj) throws FactorParseException
{
- boolean docComment = (this.docComment || alwaysDocComments);
- // In a doc comment context, first object is always
- // a word, then followed by doc comments, then followed
- // by code.
- if(docComment && !(obj instanceof FactorDocComment)
- && first != null)
- {
- this.docComment = false;
- }
- else if(!docComment && obj instanceof FactorDocComment)
- {
- //scanner.error("Documentation comment not allowed here");
- return;
- }
+ docComment = false;
- if(comma)
+ if(bar)
{
if(last.cdr != null)
scanner.error("Only one token allowed after |");
}
}
+ void setStackComment(String comment)
+ {
+ if(defining != null && defining.stackEffect == null)
+ defining.stackEffect = comment;
+ }
+
+ void addDocComment(String comment)
+ {
+ if(defining != null && (docComment || alwaysDocComments))
+ {
+ if(defining.documentation == null)
+ defining.documentation = comment;
+ else
+ {
+ /* Its O(n^2). Big deal. */
+ defining.documentation = defining.documentation
+ .concat(comment);
+ }
+ }
+ }
+
void bar() throws FactorParseException
{
if(last.cdr != null)
scanner.error("Only one token allowed after |");
}
- comma = true;
+ bar = true;
}
} //}}}
}
+++ /dev/null
-/* :folding=explicit:collapseFolds=1: */
-
-/*
- * $Id$
- *
- * Copyright (C) 2003 Slava Pestov.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package factor;
-
-public class FactorRuntimeException extends FactorException
-{
- public FactorRuntimeException(String str)
- {
- super(str);
- }
-
- public FactorRuntimeException(String str, Throwable t)
- {
- super(str,t);
- }
-}
*/
public class FactorWord implements FactorExternalizable
{
- private static int gensymCount = 0;
-
public String vocabulary;
public String name;
+ public String stackEffect;
+ public String documentation;
/**
- * Interpreted/compiled word definition.
+ * Parsing word definition.
*/
- public FactorWordDefinition def;
+ public FactorParsingDefinition parsing;
/**
- * Parsing word definition.
+ * Stub for interpreter definitin.
*/
- public FactorParsingDefinition parsing;
+ public FactorWordDefinition def;
/**
* Should the parser keep doc comments?
public int col;
//{{{ FactorWord constructor
- /**
- * Do not use this constructor unless you're writing a packages
- * implementation or something. Use an FactorDictionary's
- * intern() method instead.
- */
- public FactorWord(String vocabulary, String name,
- FactorWordDefinition def)
- {
- this.vocabulary = vocabulary;
- this.name = name;
- this.def = def;
- } //}}}
-
- //{{{ FactorWord constructor
- /**
- * Do not use this constructor unless you're writing a packages
- * implementation or something. Use an FactorDictionary's
- * intern() method instead.
- */
public FactorWord(String vocabulary, String name)
{
this.vocabulary = vocabulary;
this.name = name;
} //}}}
- //{{{ define() method
- public void define(FactorWordDefinition def)
- {
- this.def = def;
- } //}}}
-
//{{{ toString() method
public String toString()
{
+++ /dev/null
-/* :folding=explicit:collapseFolds=1: */
-
-/*
- * $Id$
- *
- * Copyright (C) 2003, 2004 Slava Pestov.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package factor;
-
-import factor.db.*;
-import factor.compiler.*;
-import java.io.*;
-import java.util.*;
-import org.objectweb.asm.*;
-
-/**
- * A word definition.
- *
- * The pickled form is an unparsed list. The car of the list is the word,
- * the cdr is toList().
- */
-public abstract class FactorWordDefinition
- implements Constants, PersistentObject
-{
- public static final String ENCODING = "UTF8";
-
- private Workspace workspace;
- private long id;
-
- public FactorWord word;
-
- public boolean compileFailed;
-
- //{{{ FactorWordDefinition constructor
- /**
- * A new definition.
- */
- public FactorWordDefinition(FactorWord word, Workspace workspace)
- {
- this(workspace,workspace == null
- ? 0L : workspace.nextID());
- this.word = word;
- } //}}}
-
- //{{{ FactorWordDefinition constructor
- /**
- * A blank definition, about to be unpickled.
- */
- public FactorWordDefinition(Workspace workspace, long id)
- {
- this.workspace = workspace;
- this.id = id;
- } //}}}
-
- //{{{ FactorWordDefinition constructor
- /**
- * A definition that is not saved in the current workspace.
- */
- public FactorWordDefinition(FactorWord word)
- {
- this.word = word;
- } //}}}
-
- public abstract void eval(FactorInterpreter interp)
- throws Exception;
-
- //{{{ fromList() method
- public void fromList(Cons cons, FactorInterpreter interp)
- throws FactorRuntimeException, PersistenceException
- {
- throw new PersistenceException("Cannot unpickle " + this);
- } //}}}
-
- //{{{ toList() method
- public Cons toList(FactorInterpreter interp)
- {
- return new Cons(new FactorWord(null,getClass().getName()),null);
- } //}}}
-
- //{{{ getStackEffect() method
- public final StackEffect getStackEffect(FactorInterpreter interp)
- throws Exception
- {
- return getStackEffect(interp,new RecursiveState());
- } //}}}
-
- //{{{ getStackEffect() method
- public final StackEffect getStackEffect(FactorInterpreter interp,
- RecursiveState recursiveCheck)
- throws Exception
- {
- FactorCompiler compiler = new FactorCompiler(interp);
- recursiveCheck.add(word,new StackEffect(),null,null,null);
- compileCallTo(null,compiler,recursiveCheck);
- recursiveCheck.remove(word);
- return compiler.getStackEffect();
- } //}}}
-/*
- //{{{ getStackEffect() method
- public void getStackEffect(RecursiveState recursiveCheck,
- FactorCompiler compiler) throws Exception
- {
- compileCallTo(null,compiler,recursiveCheck);
- } //}}}
- */
- //{{{ compile() method
- FactorWordDefinition compile(FactorInterpreter interp,
- RecursiveState recursiveCheck) throws Exception
- {
- return this;
- } //}}}
-
- //{{{ getDefinition() method
- protected Cons getDefinition(FactorInterpreter interp)
- throws FactorCompilerException
- {
- Cons definition = toList(interp);
-
- while(definition != null
- && definition.car instanceof FactorDocComment)
- definition = definition.next();
-
- return definition;
- } //}}}
-
- //{{{ compileCallTo() method
- /**
- * Compile a call to this word. Returns maximum JVM stack use.
- */
- public void compileCallTo(CodeVisitor mw, FactorCompiler compiler,
- RecursiveState recursiveCheck) throws Exception
- {
- // normal word
- String defclass;
- String defmethod;
- StackEffect effect;
-
- FactorClassLoader loader;
-
- RecursiveForm rec = recursiveCheck.get(word);
- if(rec != null && rec.active)
- {
- if(compiler.interp.verboseCompile)
- System.err.println("Recursive call to " + rec);
- effect = StackEffect.decompose(rec.effect,rec.baseCase);
-
- // are we recursing back on a form inside the current
- // method?
- RecursiveForm last = recursiveCheck.last();
- if(mw != null
- && recursiveCheck.allTails(rec)
- && last.className.equals(rec.className)
- && last.method.equals(rec.method))
- {
- if(compiler.interp.verboseCompile)
- System.err.println(word + " is tail recursive");
- // GOTO instad of INVOKEVIRTUAL; ie a loop!
- compiler.normalizeStacks(mw);
- mw.visitJumpInsn(GOTO,rec.label);
- compiler.apply(effect);
- return;
- }
-
- /* recursive method call! */
- defclass = rec.className;
- defmethod = rec.method;
- loader = rec.loader;
-
- if(mw != null && !defclass.equals(compiler.className))
- compiler.loader.addDependency(defclass,loader);
- }
- else if(mw == null)
- {
- Cons definition = getDefinition(compiler.interp);
- compiler.getStackEffect(definition,recursiveCheck);
- return;
- }
- // not a recursive call but we're still not compiled
- // its a bug in the compiler.
- else if(this instanceof FactorCompoundDefinition)
- {
- throw new FactorCompilerException("You are an idiot!");
- }
- /* ordinary method call! */
- else
- {
- defclass = getClass().getName().replace('.','/');
- defmethod = "core";
- effect = getStackEffect(compiler.interp,
- new RecursiveState());
- ClassLoader l = getClass().getClassLoader();
- if(l instanceof FactorClassLoader)
- {
- loader = (FactorClassLoader)l;
- compiler.loader.addDependency(
- getClass().getName(),loader);
- }
- else
- loader = null;
- }
-
- if(mw == null)
- compiler.apply(effect);
- else
- {
- mw.visitVarInsn(ALOAD,0);
- compiler.generateArgs(mw,effect.inD,effect.inR,null);
- String signature = effect.getCorePrototype();
- mw.visitMethodInsn(INVOKESTATIC,defclass,defmethod,signature);
- compiler.generateReturn(mw,effect.outD,effect.outR);
- }
- } //}}}
-
- //{{{ compileNonRecursiveImmediate() method
- /**
- * Non-recursive immediate words are inlined.
- */
- protected void compileNonRecursiveImmediate(CodeVisitor mw,
- FactorCompiler compiler,
- RecursiveState recursiveCheck,
- StackEffect immediateEffect) throws Exception
- {
- Cons definition = toList(compiler.getInterpreter());
-
- Cons endOfDocs = definition;
- while(endOfDocs != null
- && endOfDocs.car instanceof FactorDocComment)
- endOfDocs = endOfDocs.next();
-
- compiler.compile(endOfDocs,mw,recursiveCheck);
- } //}}}
-
- //{{{ compileRecursiveImmediate() method
- /**
- * Recursive immediate words are compiled to an auxiliary method
- * inside the compiled class definition.
- *
- * This must be done so that recursion has something to jump to.
- */
- protected void compileRecursiveImmediate(CodeVisitor mw,
- FactorCompiler compiler,
- RecursiveState recursiveCheck,
- StackEffect immediateEffect) throws Exception
- {
- Cons definition = toList(compiler.getInterpreter());
-
- Cons endOfDocs = definition;
- while(endOfDocs != null
- && endOfDocs.car instanceof FactorDocComment)
- endOfDocs = endOfDocs.next();
-
- String method = compiler.auxiliary(word,
- endOfDocs,immediateEffect,recursiveCheck);
-
- mw.visitVarInsn(ALOAD,0);
-
- compiler.generateArgs(mw,immediateEffect.inD,
- immediateEffect.inR,null);
-
- String signature = immediateEffect.getCorePrototype();
-
- mw.visitMethodInsn(INVOKESTATIC,compiler.className,
- method,signature);
-
- compiler.generateReturn(mw,
- immediateEffect.outD,
- immediateEffect.outR);
- } //}}}
-
- //{{{ compileImmediate() method
- /**
- * Compile a call to this word. Returns maximum JVM stack use.
- */
- public void compileImmediate(CodeVisitor mw, FactorCompiler compiler,
- RecursiveState recursiveCheck) throws Exception
- {
- Cons definition = getDefinition(compiler.interp);
-
- if(mw == null)
- {
- compiler.compile(definition,null,recursiveCheck);
- return;
- }
-
- // determine stack effect of this instantiation, and if its
- // recursive.
-
- FactorArrayStack savedDatastack = (FactorArrayStack)
- compiler.datastack.clone();
- FactorCallStack savedCallstack = (FactorCallStack)
- compiler.callstack.clone();
- StackEffect savedEffect = compiler.getStackEffect();
-
- RecursiveState _recursiveCheck = (RecursiveState)
- recursiveCheck.clone();
- _recursiveCheck.last().effect = compiler.getStackEffect();
- compileImmediate(null,compiler,_recursiveCheck);
-
- boolean recursive = (_recursiveCheck.last().baseCase != null);
-
- StackEffect effect = compiler.getStackEffect();
-
- StackEffect immediateEffect = StackEffect.decompose(
- savedEffect,compiler.getStackEffect());
-
- // restore previous state.
-
- FactorArrayStack afterDatastack = (FactorArrayStack)
- compiler.datastack.clone();
- FactorCallStack afterCallstack = (FactorCallStack)
- compiler.callstack.clone();
-
- compiler.datastack = (FactorArrayStack)savedDatastack.clone();
- compiler.callstack = (FactorCallStack)savedCallstack.clone();
- compiler.effect = savedEffect;
-
- if(!recursive)
- {
- // not recursive; inline.
- compileNonRecursiveImmediate(mw,compiler,recursiveCheck,
- immediateEffect);
- }
- else
- {
- // recursive; must generate auxiliary method.
- compileRecursiveImmediate(mw,compiler,recursiveCheck,
- immediateEffect);
-
- mergeStacks(savedDatastack,afterDatastack,compiler.datastack);
- mergeStacks(savedCallstack,afterCallstack,compiler.callstack);
- }
- } //}}}
-
- //{{{ mergeStacks() method
- private void mergeStacks(FactorArrayStack s1, FactorArrayStack s2,
- FactorArrayStack into)
- {
- for(int i = 0; i < s2.top; i++)
- {
- if(s1.top <= i)
- break;
-
- if(FactorLib.objectsEqual(s1.stack[i],
- s2.stack[i]))
- {
- into.stack[i] = s1.stack[i];
- }
- }
- } //}}}
-
- //{{{ getWorkspace() method
- /**
- * Each persistent object is stored in one workspace only.
- */
- public Workspace getWorkspace()
- {
- return workspace;
- } //}}}
-
- //{{{ getID() method
- /**
- * Each persistent object has an associated ID.
- */
- public long getID()
- {
- return id;
- } //}}}
-
- //{{{ pickle() method
- /**
- * Each persistent object can turn itself into a byte array.
- */
- public byte[] pickle(FactorInterpreter interp)
- throws PersistenceException
- {
- try
- {
- ByteArrayOutputStream bytes = new ByteArrayOutputStream();
-
- Cons pickle = new Cons(word,toList(interp));
- bytes.write((FactorReader.getVocabularyDeclaration(pickle)
- + FactorReader.unparseDBObject(pickle))
- .getBytes(ENCODING));
-
- return bytes.toByteArray();
- }
- catch(Exception e)
- {
- // should not happen with byte array stream
- throw new PersistenceException("Unexpected error",e);
- }
- } //}}}
-
- //{{{ unpickle() method
- /**
- * Each persistent object can set its state to that in a byte array.
- */
- public void unpickle(byte[] bytes, int offset, FactorInterpreter interp)
- throws PersistenceException
- {
- try
- {
- String unparsed = new String(bytes,offset,
- bytes.length - offset,ENCODING);
- Cons pickle = (Cons)FactorReader.parseObject(unparsed,
- interp);
- word = (FactorWord)pickle.car;
- fromList(pickle.next(),interp);
- }
- catch(Exception e)
- {
- // should not happen with byte array stream
- throw new PersistenceException("Unexpected error",e);
- }
- } //}}}
-
- //{{{ toString() method
- public String toString()
- {
- return getClass().getName() + ": " + word;
- } //}}}
-}
+++ /dev/null
-/* :folding=explicit:collapseFolds=1: */
-
-/*
- * $Id$
- *
- * Copyright (C) 2003 Slava Pestov.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package factor;
-
-public interface PublicCloneable extends Cloneable
-{
- Object clone();
-}
+++ /dev/null
-/* :folding=explicit:collapseFolds=1: */
-
-/*
- * $Id$
- *
- * Copyright (C) 2004 Slava Pestov.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package factor.compiler;
-
-import factor.*;
-import java.lang.reflect.*;
-import java.util.*;
-import org.objectweb.asm.*;
-
-public class FactorCompiler implements Constants
-{
- public final FactorInterpreter interp;
-
- public final FactorWord word;
- public final String className;
- public final FactorClassLoader loader;
- public String method;
-
- private int base;
- private int allotD;
- private int allotR;
-
- public FactorArrayStack datastack;
- public FactorCallStack callstack;
-
- private int literalCount;
-
- private Map literals;
-
- public StackEffect effect;
-
- /**
- * getStackEffect() turns these into arrays and places them in the
- * returned object.
- */
- private Cons inDtypes, inRtypes;
-
- private Cons aux;
- private int auxCount;
-
- //{{{ FactorCompiler constructor
- /**
- * For balancing.
- */
- public FactorCompiler(FactorInterpreter interp)
- {
- this(interp,null,null,null);
- init(0,0,0,null);
- } //}}}
-
- //{{{ FactorCompiler constructor
- /**
- * For compiling.
- */
- public FactorCompiler(FactorInterpreter interp,
- FactorWord word, String className,
- FactorClassLoader loader)
- {
- this.interp = interp;
- this.word = word;
- this.className = className;
- this.loader = loader;
-
- literals = new HashMap();
-
- datastack = new FactorArrayStack();
- callstack = new FactorCallStack();
- } //}}}
-
- //{{{ getInterpreter() method
- public FactorInterpreter getInterpreter()
- {
- return interp;
- } //}}}
-
- //{{{ init() method
- public void init(int base, int allotD, int allotR, String method)
- {
- effect = new StackEffect();
-
- this.base = base;
-
- datastack.top = 0;
- callstack.top = 0;
-
- for(int i = 0; i < allotD; i++)
- {
- Result r = new Result(base + i,this,null,
- Object.class);
- datastack.push(r);
- inDtypes = new Cons(r,inDtypes);
- }
-
- for(int i = 0; i < allotR; i++)
- {
- Result r = new Result(base + allotD + i,this,null,
- Object.class);
- callstack.push(r);
- inRtypes = new Cons(r,inRtypes);
- }
-
- this.allotD = allotD;
- this.allotR = allotR;
- effect.inD = allotD;
- effect.inR = allotR;
-
- this.method = method;
- } //}}}
-
- //{{{ getAllotedEffect() method
- public StackEffect getAllotedEffect()
- {
- return new StackEffect(allotD,allotR,0,0);
- } //}}}
-
- //{{{ ensure() method
- public void ensure(FactorArrayStack stack, Class type)
- {
- if(stack.top == 0)
- {
- Result r = new Result(allocate(),this,null,type);
- if(stack == datastack)
- {
- inDtypes = new Cons(r,inDtypes);
- effect.inD++;
- }
- else if(stack == callstack)
- {
- inRtypes = new Cons(r,inRtypes);
- effect.inR++;
- }
- stack.push(r);
- }
- } //}}}
-
- //{{{ ensure() method
- /**
- * Ensure stack has at least 'count' elements.
- * Eg, if count is 4 and stack is A B,
- * stack will become RESULT RESULT A B.
- * Used when deducing stack effects.
- */
- public void ensure(FactorArrayStack stack, int count)
- {
- Class[] types = new Class[count];
- for(int i = 0; i < types.length; i++)
- types[i] = Object.class;
- ensure(stack,types);
- } //}}}
-
- //{{{ ensure() method
- /**
- * Ensure stack has at least 'count' elements.
- * Eg, if count is 4 and stack is A B,
- * stack will become RESULT RESULT A B.
- * Used when deducing stack effects.
- */
- public void ensure(FactorArrayStack stack, Class[] types)
- {
- int top = stack.top;
- if(top < types.length)
- {
- Cons typespec = null;
-
- if(stack == datastack)
- effect.inD += (types.length - top);
- else if(stack == callstack)
- effect.inR += (types.length - top);
-
- stack.ensurePush(types.length - top);
- System.arraycopy(stack.stack,0,stack.stack,
- types.length - top,top);
- for(int i = 0; i < types.length - top; i++)
- {
- int local = allocate();
- Result r = new Result(
- local,this,null,types[i]);
- stack.stack[i] = r;
- typespec = new Cons(r,typespec);
- }
- stack.top = types.length;
-
- if(stack == datastack)
- inDtypes = Cons.nappend(inDtypes,typespec);
- else if(stack == callstack)
- inRtypes = Cons.nappend(inRtypes,typespec);
- }
- } //}}}
-
- //{{{ consume() method
- public void consume(FactorArrayStack stack, int count)
- {
- ensure(stack,count);
- stack.top -= count;
- } //}}}
-
- //{{{ produce() method
- public void produce(FactorArrayStack stack, int count)
- {
- for(int i = 0; i < count; i++)
- {
- int local = allocate();
- stack.push(new Result(local,this,null,Object.class));
- }
- } //}}}
-
- //{{{ apply() method
- public void apply(StackEffect se)
- {
- consume(datastack,se.inD);
- produce(datastack,se.outD);
- consume(callstack,se.inR);
- produce(callstack,se.outR);
- } //}}}
-
- //{{{ getTypeSpec() method
- private Class[] getTypeSpec(Cons list)
- {
- if(list == null)
- return new Class[0];
-
- int length = list.length();
- Class[] typespec = new Class[length];
- int i = 0;
- while(list != null)
- {
- typespec[length - i - 1]
- = ((FlowObject)list.car).getType();
- i++;
- list = list.next();
- }
-
- return typespec;
- } //}}}
-
- //{{{ getStackEffect() method
- public StackEffect getStackEffect()
- {
- effect.inDtypes = getTypeSpec(inDtypes);
-
- effect.outD = datastack.top;
-
- effect.outDtypes = new Class[datastack.top];
- for(int i = 0; i < datastack.top; i++)
- {
- effect.outDtypes[i] = ((FlowObject)datastack.stack[i])
- .getType();
- }
-
- effect.inRtypes = getTypeSpec(inRtypes);
-
- effect.outR = callstack.top;
-
- effect.outRtypes = new Class[callstack.top];
- for(int i = 0; i < callstack.top; i++)
- {
- effect.outRtypes[i] = ((FlowObject)callstack.stack[i])
- .getType();
- }
-
- return (StackEffect)effect.clone();
- } //}}}
-
- //{{{ getStackEffect() method
- public void getStackEffect(Cons definition,
- RecursiveState recursiveCheck)
- throws Exception
- {
- while(definition != null)
- {
- Object obj = definition.car;
- if(obj instanceof FactorWord)
- getStackEffectOfWord((FactorWord)obj,recursiveCheck);
- else
- pushLiteral(obj,recursiveCheck);
-
- definition = definition.next();
- }
- } //}}}
-
- //{{{ getStackEffectOfWord() method
- private void getStackEffectOfWord(FactorWord word,
- RecursiveState recursiveCheck)
- throws Exception
- {
- RecursiveForm rec = recursiveCheck.get(word);
-
- try
- {
- boolean recursiveCall;
- if(rec == null)
- {
- recursiveCall = false;
- recursiveCheck.add(word,
- getStackEffect(),
- className,loader,
- "core");
- /* recursiveCheck.last().tail
- = (word.def instanceof FactorPrimitiveDefinition); */
- }
- else
- {
- recursiveCall = true;
- rec.active = true;
- }/*
- if(rec == null)
- recursiveCheck.add(word,getStackEffect(),null,null,null);
- else
- rec.active = true; */
-
- compileCallTo(word,null,recursiveCheck,false);
- }
- finally
- {
- if(rec == null)
- recursiveCheck.remove(word);
- else
- {
- rec.active = false;
- rec.tail = false;
- }
- }
- } //}}}
-
- //{{{ compileCore() method
- public void compileCore(Cons definition, ClassWriter cw,
- StackEffect effect, RecursiveState recursiveCheck)
- throws Exception
- {
- RecursiveForm last = recursiveCheck.last();
- last.method = "core";
- last.className = className;
- last.loader = loader;
-
- compileMethod(definition,cw,"core",effect,word,recursiveCheck,true);
- } //}}}
-
- //{{{ compileFieldInit() method
- private void compileFieldInit(CodeVisitor mw, Label start)
- {
- mw.visitFieldInsn(GETSTATIC,className,"initialized","Z");
- mw.visitJumpInsn(IFNE,start);
- mw.visitInsn(ICONST_1);
- mw.visitFieldInsn(PUTSTATIC,className,"initialized","Z");
- mw.visitVarInsn(ALOAD,0);
- mw.visitMethodInsn(INVOKESTATIC,className,"setFields",
- "(Lfactor/FactorInterpreter;)V");
- } //}}}
-
- //{{{ compileReturn() method
- /**
- * Once the word finishes executing, any return values need to be
- * passed up.
- */
- private void compileReturn(CodeVisitor mw, Label end,
- StackEffect effect) throws Exception
- {
- // special case where return value is passed on
- // JVM operand stack
-
- // note: in each branch, must visit end label before RETURN!
- if(effect.outD == 0 && effect.outR == 0)
- {
- mw.visitLabel(end);
- mw.visitInsn(RETURN);
- }
- else if(effect.outD == 1 && effect.outR == 0)
- {
- pop(datastack,mw,Object.class);
- mw.visitLabel(end);
- mw.visitInsn(ARETURN);
- }
- else
- {
- // store datastack in a local
- mw.visitVarInsn(ALOAD,0);
- mw.visitFieldInsn(GETFIELD,
- "factor/FactorInterpreter",
- "datastack",
- "Lfactor/FactorArrayStack;");
- int datastackLocal = allocate();
- mw.visitVarInsn(ASTORE,datastackLocal);
-
- for(int i = 0; i < datastack.top; i++)
- {
- mw.visitVarInsn(ALOAD,datastackLocal);
- ((FlowObject)datastack.stack[i])
- .pop(mw,Object.class);
- mw.visitMethodInsn(INVOKEVIRTUAL,
- "factor/FactorArrayStack",
- "push",
- "(Ljava/lang/Object;)V");
- }
-
- datastack.top = 0;
-
- // store callstack in a local
- mw.visitVarInsn(ALOAD,0);
- mw.visitFieldInsn(GETFIELD,
- "factor/FactorInterpreter",
- "callstack",
- "Lfactor/FactorCallStack;");
- int callstackLocal = allocate();
- mw.visitVarInsn(ASTORE,callstackLocal);
-
- for(int i = 0; i < callstack.top; i++)
- {
- mw.visitVarInsn(ALOAD,callstackLocal);
- ((FlowObject)callstack.stack[i])
- .pop(mw,Object.class);
- mw.visitMethodInsn(INVOKEVIRTUAL,
- "factor/FactorCallStack",
- "push",
- "(Ljava/lang/Object;)V");
- }
-
- callstack.top = 0;
-
- mw.visitLabel(end);
- mw.visitInsn(RETURN);
- }
- } //}}}
-
- //{{{ compileMethod() method
- /**
- * Compiles a method.
- */
- public void compileMethod(Cons definition, ClassWriter cw,
- String methodName, StackEffect effect, FactorWord word,
- RecursiveState recursiveCheck, boolean fieldInit)
- throws Exception
- {
- String signature = effect.getCorePrototype();
-
- CodeVisitor mw = cw.visitMethod(ACC_PUBLIC | ACC_STATIC,
- methodName,signature,null,null);
-
- Label start = recursiveCheck.get(word).label;
-
- if(fieldInit)
- compileFieldInit(mw,start);
-
- mw.visitLabel(start);
-
- compile(definition,mw,recursiveCheck);
-
- Label end = new Label();
-
- compileReturn(mw,end,effect);
-
- compileExceptionHandler(mw,start,end,word);
-
- mw.visitMaxs(0,0);
- } //}}}
-
- //{{{ compileExceptionHandler() method
- private void compileExceptionHandler(CodeVisitor mw,
- Label start, Label end, FactorWord word)
- {
- // otherwise no code can throw exception etc
- if(start.getOffset() != end.getOffset())
- {
- // Now compile exception handler.
-
- Label target = new Label();
- mw.visitLabel(target);
-
- mw.visitVarInsn(ASTORE,1);
- mw.visitVarInsn(ALOAD,0);
- mw.visitFieldInsn(GETSTATIC,className,literal(word),
- "Ljava/lang/Object;");
- mw.visitTypeInsn(CHECKCAST,"factor/FactorWord");
- mw.visitVarInsn(ALOAD,1);
-
- mw.visitMethodInsn(INVOKEVIRTUAL,"factor/FactorInterpreter",
- "compiledException",
- "(Lfactor/FactorWord;Ljava/lang/Throwable;)V");
-
- mw.visitVarInsn(ALOAD,1);
- mw.visitInsn(ATHROW);
-
- mw.visitTryCatchBlock(start,end,target,"java/lang/Throwable");
- }
- } //}}}
-
- //{{{ compile() method
- /**
- * Compiles a quotation.
- */
- public void compile(Cons definition, CodeVisitor mw,
- RecursiveState recursiveCheck) throws Exception
- {
- while(definition != null)
- {
- Object obj = definition.car;
- if(obj instanceof FactorWord)
- {
- compileWord((FactorWord)obj,mw,recursiveCheck,
- definition.cdr == null);
- }
- else
- pushLiteral(obj,recursiveCheck);
-
- definition = definition.next();
- }
- } //}}}
-
- //{{{ compileWord() method
- private void compileWord(FactorWord w, CodeVisitor mw,
- RecursiveState recursiveCheck,
- boolean tail) throws Exception
- {
- if(tail && interp.verboseCompile)
- System.err.println("Tail: " + recursiveCheck.last());
- recursiveCheck.last().tail = tail;
-
- RecursiveForm rec = recursiveCheck.get(w);
-
- try
- {
- boolean recursiveCall;
- if(rec == null)
- {
- recursiveCall = false;
- recursiveCheck.add(w,
- new StackEffect(),
- className,loader,
- "core");
- recursiveCheck.last().tail
- = (w.def instanceof FactorPrimitiveDefinition);
- }
- else
- {
- recursiveCall = true;
- rec.active = true;
- }
-
- compileCallTo(w,mw,recursiveCheck,recursiveCall);
- }
- finally
- {
- if(rec == null)
- recursiveCheck.remove(w);
- else
- {
- rec.active = false;
- rec.tail = false;
- }
- }
- } //}}}
-
- //{{{ compileCallTo() method
- private void compileCallTo(FactorWord w, CodeVisitor mw,
- RecursiveState recursiveCheck,
- boolean recursiveCall) throws Exception
- {
- if(w.def == null)
- throw new FactorUndefinedWordException(w);
-
- FactorWordDefinition d = w.def;
-
- if(!recursiveCall)
- {
- StackEffect effect = getStackEffectOrNull(d);
- if(w.inline)
- {
- d.compileImmediate(mw,this,recursiveCheck);
- return;
- }
- else if(d instanceof FactorCompoundDefinition
- && mw != null)
- {
- w.compile(interp,recursiveCheck);
- if(d == w.def)
- {
- throw new FactorCompilerException(word + " depends on " + w + " which cannot be compiled");
- }
- d = w.def;
- }
-
- w.compileRef = true;
- }
-
- d.compileCallTo(mw,this,recursiveCheck);
- } //}}}
-
- //{{{ push() method
- /**
- * Generates code for pushing the top of the JVM stack onto the
- * data stack. Also generates code for converting this value to
- * the given type.
- */
- public void push(FactorArrayStack stack, CodeVisitor mw, Class type)
- throws Exception
- {
- int local = allocate();
- Result r = new Result(local,this,null,type);
- stack.push(r);
- r.push(mw,type);
- } //}}}
-
- //{{{ pushLiteral() method
- public void pushLiteral(Object literal, RecursiveState recursiveCheck)
- {
- if(literal == null)
- datastack.push(new Null(this,recursiveCheck));
- else if(literal instanceof Cons)
- {
- datastack.push(new CompiledList((Cons)literal,this,
- recursiveCheck));
- }
- else if(literal instanceof String)
- {
- datastack.push(new ConstantPoolString((String)literal,
- this,recursiveCheck));
- }
- else
- {
- datastack.push(new Literal(literal,this,
- recursiveCheck));
- }
- } //}}}
-
- //{{{ pop() method
- /**
- * Generates code for popping the top of the data stack onto
- * the JVM stack. Also generates code for converting this value to
- * the given type.
- */
- public void pop(FactorArrayStack stack, CodeVisitor mw, Class type)
- throws Exception
- {
- FlowObject obj = (FlowObject)datastack.pop();
- obj.pop(mw,type);
- } //}}}
-
- //{{{ popLiteral() method
- /**
- * Pops a literal off the datastack or throws an exception.
- */
- public Object popLiteral() throws FactorException
- {
- FlowObject obj = (FlowObject)datastack.pop();
- return obj.getLiteral();
- } //}}}
-
- //{{{ allocate() method
- /**
- * Allocate a local variable.
- */
- public int allocate()
- {
- // inefficient!
- int i = base;
- for(;;)
- {
- if(allocate(i,datastack) && allocate(i,callstack))
- return i;
- else
- i++;
- }
- } //}}}
-
- //{{{ allocate() method
- /**
- * Return true if not in use, false if in use.
- */
- private boolean allocate(int local, FactorArrayStack stack)
- {
- for(int i = 0; i < stack.top; i++)
- {
- FlowObject obj = (FlowObject)stack.stack[i];
- if(obj.usingLocal(local))
- return false;
- }
- return true;
- } //}}}
-
- //{{{ literal() method
- public String literal(Object obj)
- {
- Integer i = (Integer)literals.get(obj);
- int literal;
- if(i == null)
- {
- literal = literalCount++;
- literals.put(obj,new Integer(literal));
- }
- else
- literal = i.intValue();
-
- return "literal_" + literal;
- } //}}}
-
- //{{{ auxiliary() method
- public String auxiliary(FactorWord word, Cons code, StackEffect effect,
- RecursiveState recursiveCheck) throws Exception
- {
- FactorArrayStack savedDatastack = (FactorArrayStack)
- datastack.clone();
- FactorCallStack savedCallstack = (FactorCallStack)
- callstack.clone();
-
- String method = "aux_" + FactorJava.getSanitizedName(word.name)
- + "_" + (auxCount++);
-
- recursiveCheck.last().method = method;
- aux = new Cons(new AuxiliaryQuotation(
- method,savedDatastack,savedCallstack,
- code,effect,word,this,recursiveCheck),aux);
-
- return method;
- } //}}}
-
- //{{{ generateAuxiliary() method
- public void generateAuxiliary(ClassWriter cw) throws Exception
- {
- while(aux != null)
- {
- AuxiliaryQuotation q = (AuxiliaryQuotation)aux.car;
- // order of these two important, in case
- // compilation of q adds more quotations to aux list
- aux = aux.next();
- q.compile(this,cw);
- }
- } //}}}
-
- //{{{ normalizeStacks() method
- public void normalizeStacks(CodeVisitor mw)
- throws Exception
- {
- int datastackTop = datastack.top;
- datastack.top = 0;
- int callstackTop = callstack.top;
- callstack.top = 0;
-
- localsToStack(callstack,callstackTop,mw);
- localsToStack(datastack,datastackTop,mw);
- stackToLocals(datastack,datastackTop,mw);
- stackToLocals(callstack,callstackTop,mw);
- } //}}}
-
- //{{{ localsToStack() method
- private void localsToStack(FactorArrayStack stack, int top,
- CodeVisitor mw)
- {
- for(int i = top - 1; i >= 0; i--)
- {
- FlowObject obj = (FlowObject)stack.stack[i];
- obj.pop(mw);
- }
- } //}}}
-
- //{{{ stackToLocals() method
- private void stackToLocals(FactorArrayStack stack, int top,
- CodeVisitor mw) throws Exception
- {
- for(int i = 0; i < top; i++)
- push(stack,mw,Object.class);
- } //}}}
-
- //{{{ generateArgs() method
- /**
- * Generate instructions for copying arguments from the allocated
- * local variables to the JVM stack, doing type conversion in the
- * process.
- */
- public void generateArgs(CodeVisitor mw, int inD, int inR, Class[] args)
- throws Exception
- {
- for(int i = 0; i < inD; i++)
- {
- FlowObject obj = (FlowObject)datastack.stack[
- datastack.top - inD + i];
- obj.pop(mw,args == null ? Object.class : args[i]);
- }
-
- datastack.top -= inD;
-
- for(int i = 0; i < inR; i++)
- {
- FlowObject obj = (FlowObject)callstack.stack[
- callstack.top - inR + i];
- obj.pop(mw,args == null ? Object.class : args[i]);
- }
-
- callstack.top -= inR;
- } //}}}
-
- //{{{ generateReturn() method
- public void generateReturn(CodeVisitor mw, int outD, int outR)
- throws Exception
- {
- if(outD == 0 && outR == 0)
- {
- // do nothing
- }
- else if(outD == 1 && outR == 0)
- {
- push(datastack,mw,Object.class);
- }
- else
- {
- // transfer from data stack to JVM locals
-
- // allocate the appropriate number of locals
-
- if(outD != 0)
- {
- produce(datastack,outD);
-
- // store the datastack instance somewhere
- mw.visitVarInsn(ALOAD,0);
- mw.visitFieldInsn(GETFIELD,
- "factor/FactorInterpreter",
- "datastack",
- "Lfactor/FactorArrayStack;");
- int datastackLocal = allocate();
- mw.visitVarInsn(ASTORE,datastackLocal);
-
- // put all elements from the real datastack
- // into locals
- for(int i = 0; i < outD; i++)
- {
- mw.visitVarInsn(ALOAD,datastackLocal);
- mw.visitMethodInsn(INVOKEVIRTUAL,
- "factor/FactorArrayStack",
- "pop",
- "()Ljava/lang/Object;");
-
- Result destination = (Result)
- datastack.stack[
- datastack.top - i - 1];
-
- destination.push(mw,Object.class);
- }
- }
-
- if(outR != 0)
- {
- produce(callstack,outR);
-
- mw.visitVarInsn(ALOAD,0);
- mw.visitFieldInsn(GETFIELD,
- "factor/FactorInterpreter",
- "callstack",
- "Lfactor/FactorCallStack;");
- int callstackLocal = allocate();
- mw.visitVarInsn(ASTORE,callstackLocal);
-
- // put all elements from the real callstack
- // into locals
- for(int i = 0; i < outR; i++)
- {
- mw.visitVarInsn(ALOAD,callstackLocal);
- mw.visitMethodInsn(INVOKEVIRTUAL,
- "factor/FactorCallStack",
- "pop",
- "()Ljava/lang/Object;");
-
- Result destination = (Result)
- callstack.stack[
- callstack.top - i - 1];
-
- destination.push(mw,Object.class);
- }
- }
- }
- } //}}}
-
- //{{{ generateFields() method
- public void generateFields(ClassWriter cw)
- throws Exception
- {
- for(int i = 0; i < literalCount; i++)
- {
- cw.visitField(ACC_PRIVATE | ACC_STATIC,"literal_" + i,
- "Ljava/lang/Object;",null,null);
- }
-
- CodeVisitor mw = cw.visitMethod(ACC_PRIVATE | ACC_STATIC,
- "setFields","(Lfactor/FactorInterpreter;)V",null,null);
-
- Iterator entries = literals.entrySet().iterator();
- while(entries.hasNext())
- {
- Map.Entry entry = (Map.Entry)entries.next();
- Object literal = entry.getKey();
- int index = ((Integer)entry.getValue()).intValue();
-
- generateParse(mw,literal,0);
- mw.visitFieldInsn(PUTSTATIC,
- className,
- "literal_" + index,
- "Ljava/lang/Object;");
- }
-
- mw.visitInsn(RETURN);
-
- mw.visitMaxs(0,0);
- } //}}}
-
- //{{{ generateParse() method
- public void generateParse(CodeVisitor mw, Object obj, int interpLocal)
- {
- mw.visitLdcInsn(FactorReader.getVocabularyDeclaration(obj)
- + FactorReader.unparseObject(obj));
- mw.visitVarInsn(ALOAD,interpLocal);
- mw.visitMethodInsn(INVOKESTATIC,
- "factor/FactorReader",
- "parseObject",
- "(Ljava/lang/String;Lfactor/FactorInterpreter;)"
- + "Ljava/lang/Object;");
- } //}}}
-
- //{{{ getStackEffectOrNull() method
- public StackEffect getStackEffectOrNull(FactorWordDefinition def)
- {
- try
- {
- return def.getStackEffect(interp,
- new RecursiveState());
- }
- catch(Exception e)
- {
- //System.err.println("WARNING: " + e);
- //System.err.println(def);
- return null;
- }
- } //}}}
-
- //{{{ getStackEffectOrNull() method
- public StackEffect getStackEffectOrNull(FlowObject obj,
- RecursiveState recursiveCheck,
- boolean decompose)
- {
- try
- {
- obj.getStackEffect(recursiveCheck);
- StackEffect effect = getStackEffect();
- if(decompose)
- {
- effect = StackEffect.decompose(
- recursiveCheck.last().effect,
- effect);
- }
- return effect;
- }
- catch(Exception e)
- {
- //System.err.println("WARNING: " + e);
- //System.err.println(obj);
- return null;
- }
- } //}}}
-}
public class FactorAsset extends Asset
{
private FactorWord word;
- private FactorWordDefinition def;
- public FactorAsset(FactorWord word, FactorWordDefinition def,
- Position start)
+ public FactorAsset(FactorWord word, Position start)
{
super(word.name);
- this.start = start;
this.word = word;
- this.def = def;
+ this.start = start;
}
public Icon getIcon()
public String getLongString()
{
- return FactorWordRenderer.getWordHTMLString(word,def,false);
+ return FactorWordRenderer.getWordHTMLString(word,false);
}
}
mode.factor.sidekick.parser=factor
factor.completion.in=<font color="#a0a0a0">IN: {0}</font>\
-factor.completion.plain=: <b>{0}</b>
+factor.completion.colon=: <b>{0}</b>
factor.completion.defer=DEFER: <b>{0}</b>
factor.completion.parsing=PARSING: <b>{0}</b>
-factor.completion.stack=: <b>{0}</b> {1}
factor.completion.symbol=SYMBOL: <b>{0}</b>
+factor.completion.stack={0} ({1})
# Dialog boxes
factor.status.inserted-use=Inserted {0}
public class FactorSideKickParser extends SideKickParser
{
- private WordPreview wordPreview;
private Map previewMap;
/**
{
super("factor");
previewMap = new HashMap();
- worddefs = new HashMap();
- } //}}}
-
- //{{{ getWordDefinition() method
- /**
- * Check for a word definition from a parsed source file. If one is
- * found, return it, otherwise return interpreter's definition.
- */
- public FactorWordDefinition getWordDefinition(FactorWord word)
- {
- FactorWordDefinition def = (FactorWordDefinition)
- worddefs.get(word);
- if(def != null)
- return def;
- else
- return word.def;
} //}}}
//{{{ activate() method
parsed.car;
FactorWord word = def.word;
- worddefs.put(word,def);
/* word lines are indexed from 1 */
int startLine = Math.min(
if(last != null)
last.end = buffer.createPosition(start - 1);
- last = new FactorAsset(word,def,
- buffer.createPosition(start));
+ last = new FactorAsset(word,buffer.createPosition(start));
d.root.add(new DefaultMutableTreeNode(last));
}
public class FactorWordRenderer extends DefaultListCellRenderer
{
//{{{ getWordHTMLString() method
- public static String getWordHTMLString(FactorWord word,
- FactorWordDefinition def, boolean showIn)
+ public static String getWordHTMLString(FactorWord word, boolean showIn)
{
- String prop = "factor.completion.plain";
- String stackEffect = null;
+ String prop = "factor.completion.colon";
- if(def == null)
+ /* if(def == null)
{
if(word.parsing != null)
prop = "factor.completion.parsing";
d.car;
if(comment.isStackComment())
{
- prop = "factor.completion.stack";
stackEffect = comment.toString();
}
}
- }
+ } */
String in;
if(showIn)
else
in = "";
- return "<html>" + in + jEdit.getProperty(prop,
- new Object[] {
- MiscUtilities.charsToEntities(word.name),
- stackEffect == null
- ? null :
- MiscUtilities.charsToEntities(stackEffect)
- });
+ String html = "<html>" + in + jEdit.getProperty(prop,
+ new Object[] { MiscUtilities.charsToEntities(word.name) });
+ if(word.stackEffect != null)
+ {
+ html += jEdit.getProperty("factor.completion.stack",
+ new String[] { html, word.stackEffect });
+ }
+
+ return html;
} //}}}
private FactorSideKickParser parser;
return this;
FactorWord word = (FactorWord)value;
- setText(getWordHTMLString(word,
- parser.getWordDefinition(word),
- showIn));
+ setText(getWordHTMLString(word,showIn));
return this;
} //}}}
{
view.getStatus().setMessageAndClear(
FactorWordRenderer.getWordHTMLString(
- w,fdata.parser.getWordDefinition(w),true));
+ w,true));
}
}
catch(IOException e)
throws Exception
{
FactorReader.ParseState state = reader.popState(start,word);
- FactorWord w = (FactorWord)state.arg;
+ FactorWord w = state.defining;
+ /* Only ever null with restartable scanner;
+ error already logged, so give up */
if(w == null)
return;
- reader.append(new FactorCompoundDefinition(w,state.first));
+ w.def = new FactorCompoundDefinition(w,state.first);
+ reader.append(w.def);
}
}
{
String comment = reader.getScanner().readUntilEOL();
if(doc)
- reader.append(new FactorDocComment(comment,false));
+ reader.addDocComment(comment);
}
}
throws Exception
{
String comment = reader.getScanner().readUntil( '(',')',false);
- reader.append(new FactorDocComment(comment,true));
+ reader.setStackComment(comment);
}
}
throws Exception
{
FactorWord w = reader.nextWord(true);
- reader.append(new FactorSymbolDefinition(w,w));
+ w.def = new FactorSymbolDefinition(w,w);
+ reader.append(w.def);
}
}