From cf75abc247cdfcfd0eed37cae6a2ce572d4709b0 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 19 Nov 2004 22:28:23 +0000 Subject: [PATCH] communicates stack effect from socket --- factor/ExternalFactor.java | 6 +- factor/FactorCompoundDefinition.java | 10 - factor/FactorDocComment.java | 59 -- factor/FactorPrimitiveDefinition.java | 52 -- factor/FactorReader.java | 77 +- factor/FactorRuntimeException.java | 43 -- factor/FactorWord.java | 39 +- factor/FactorWordDefinition.java.new | 444 ----------- factor/PublicCloneable.java | 35 - factor/compiler/FactorCompiler.java.new | 983 ------------------------ factor/jedit/FactorAsset.java | 9 +- factor/jedit/FactorPlugin.props | 4 +- factor/jedit/FactorSideKickParser.java | 21 +- factor/jedit/FactorWordRenderer.java | 31 +- factor/jedit/WordPreview.java | 2 +- factor/parser/Ine.java | 7 +- factor/parser/LineComment.java | 2 +- factor/parser/StackComment.java | 2 +- factor/parser/Symbol.java | 3 +- 19 files changed, 89 insertions(+), 1740 deletions(-) delete mode 100644 factor/FactorDocComment.java delete mode 100644 factor/FactorPrimitiveDefinition.java delete mode 100644 factor/FactorRuntimeException.java delete mode 100644 factor/FactorWordDefinition.java.new delete mode 100644 factor/PublicCloneable.java delete mode 100644 factor/compiler/FactorCompiler.java.new diff --git a/factor/ExternalFactor.java b/factor/ExternalFactor.java index 6751fd4d8f..c6022061d0 100644 --- a/factor/ExternalFactor.java +++ b/factor/ExternalFactor.java @@ -135,7 +135,11 @@ public class ExternalFactor extends DefaultVocabularyLookup 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) { diff --git a/factor/FactorCompoundDefinition.java b/factor/FactorCompoundDefinition.java index 70a77e8f5c..8720258799 100644 --- a/factor/FactorCompoundDefinition.java +++ b/factor/FactorCompoundDefinition.java @@ -38,7 +38,6 @@ import java.util.*; public class FactorCompoundDefinition extends FactorWordDefinition { public Cons definition; - private Cons endOfDocs; //{{{ FactorCompoundDefinition constructor /** @@ -48,15 +47,6 @@ public class FactorCompoundDefinition extends FactorWordDefinition { 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 diff --git a/factor/FactorDocComment.java b/factor/FactorDocComment.java deleted file mode 100644 index 105a79a968..0000000000 --- a/factor/FactorDocComment.java +++ /dev/null @@ -1,59 +0,0 @@ -/* :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; - } -} diff --git a/factor/FactorPrimitiveDefinition.java b/factor/FactorPrimitiveDefinition.java deleted file mode 100644 index e134e81801..0000000000 --- a/factor/FactorPrimitiveDefinition.java +++ /dev/null @@ -1,52 +0,0 @@ -/* :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) - { - } //}}} -} diff --git a/factor/FactorReader.java b/factor/FactorReader.java index baa90bdc5d..1a80808292 100644 --- a/factor/FactorReader.java +++ b/factor/FactorReader.java @@ -269,6 +269,8 @@ public class FactorReader w.line = line; w.col = col; w.file = scanner.getFileName(); + w.stackEffect = null; + w.documentation = null; } return w; } @@ -313,8 +315,7 @@ public class FactorReader 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 */ @@ -341,24 +342,22 @@ public class FactorReader * 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 @@ -391,6 +390,18 @@ public class FactorReader 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. @@ -410,39 +421,24 @@ public class FactorReader 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 |"); @@ -459,6 +455,27 @@ public class FactorReader } } + 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) @@ -468,7 +485,7 @@ public class FactorReader scanner.error("Only one token allowed after |"); } - comma = true; + bar = true; } } //}}} } diff --git a/factor/FactorRuntimeException.java b/factor/FactorRuntimeException.java deleted file mode 100644 index 2c122a0888..0000000000 --- a/factor/FactorRuntimeException.java +++ /dev/null @@ -1,43 +0,0 @@ -/* :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); - } -} diff --git a/factor/FactorWord.java b/factor/FactorWord.java index 07ddbbf84b..f364f14769 100644 --- a/factor/FactorWord.java +++ b/factor/FactorWord.java @@ -36,21 +36,21 @@ import java.util.*; */ public class FactorWord implements FactorExternalizable { - private static int gensymCount = 0; - public String vocabulary; public String name; - - /** - * Interpreted/compiled word definition. - */ - public FactorWordDefinition def; + public String stackEffect; + public String documentation; /** * Parsing word definition. */ public FactorParsingDefinition parsing; + /** + * Stub for interpreter definitin. + */ + public FactorWordDefinition def; + /** * Should the parser keep doc comments? */ @@ -64,37 +64,12 @@ public class FactorWord implements FactorExternalizable 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() { diff --git a/factor/FactorWordDefinition.java.new b/factor/FactorWordDefinition.java.new deleted file mode 100644 index aa79ef70c6..0000000000 --- a/factor/FactorWordDefinition.java.new +++ /dev/null @@ -1,444 +0,0 @@ -/* :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; - } //}}} -} diff --git a/factor/PublicCloneable.java b/factor/PublicCloneable.java deleted file mode 100644 index 70e47031e0..0000000000 --- a/factor/PublicCloneable.java +++ /dev/null @@ -1,35 +0,0 @@ -/* :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(); -} diff --git a/factor/compiler/FactorCompiler.java.new b/factor/compiler/FactorCompiler.java.new deleted file mode 100644 index 5a06134f8d..0000000000 --- a/factor/compiler/FactorCompiler.java.new +++ /dev/null @@ -1,983 +0,0 @@ -/* :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; - } - } //}}} -} diff --git a/factor/jedit/FactorAsset.java b/factor/jedit/FactorAsset.java index 496e927fd2..934f1107c9 100644 --- a/factor/jedit/FactorAsset.java +++ b/factor/jedit/FactorAsset.java @@ -39,15 +39,12 @@ import sidekick.*; 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() @@ -62,6 +59,6 @@ public class FactorAsset extends Asset public String getLongString() { - return FactorWordRenderer.getWordHTMLString(word,def,false); + return FactorWordRenderer.getWordHTMLString(word,false); } } diff --git a/factor/jedit/FactorPlugin.props b/factor/jedit/FactorPlugin.props index 8f4a18e95c..ea6a3eda54 100644 --- a/factor/jedit/FactorPlugin.props +++ b/factor/jedit/FactorPlugin.props @@ -43,11 +43,11 @@ sidekick.parser.factor.label=Factor mode.factor.sidekick.parser=factor factor.completion.in=IN: {0}\ -factor.completion.plain=: {0} +factor.completion.colon=: {0} factor.completion.defer=DEFER: {0} factor.completion.parsing=PARSING: {0} -factor.completion.stack=: {0} {1} factor.completion.symbol=SYMBOL: {0} +factor.completion.stack={0} ({1}) # Dialog boxes factor.status.inserted-use=Inserted {0} diff --git a/factor/jedit/FactorSideKickParser.java b/factor/jedit/FactorSideKickParser.java index ca18a5a1c8..a4dc573faf 100644 --- a/factor/jedit/FactorSideKickParser.java +++ b/factor/jedit/FactorSideKickParser.java @@ -40,7 +40,6 @@ import sidekick.*; public class FactorSideKickParser extends SideKickParser { - private WordPreview wordPreview; private Map previewMap; /** @@ -55,22 +54,6 @@ public class FactorSideKickParser extends SideKickParser { 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 @@ -180,7 +163,6 @@ public class FactorSideKickParser extends SideKickParser parsed.car; FactorWord word = def.word; - worddefs.put(word,def); /* word lines are indexed from 1 */ int startLine = Math.min( @@ -197,8 +179,7 @@ public class FactorSideKickParser extends SideKickParser 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)); } diff --git a/factor/jedit/FactorWordRenderer.java b/factor/jedit/FactorWordRenderer.java index ae5372705b..af8a05d19c 100644 --- a/factor/jedit/FactorWordRenderer.java +++ b/factor/jedit/FactorWordRenderer.java @@ -37,13 +37,11 @@ import org.gjt.sp.jedit.*; 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"; @@ -63,11 +61,10 @@ public class FactorWordRenderer extends DefaultListCellRenderer d.car; if(comment.isStackComment()) { - prop = "factor.completion.stack"; stackEffect = comment.toString(); } } - } + } */ String in; if(showIn) @@ -80,13 +77,15 @@ public class FactorWordRenderer extends DefaultListCellRenderer else in = ""; - return "" + in + jEdit.getProperty(prop, - new Object[] { - MiscUtilities.charsToEntities(word.name), - stackEffect == null - ? null : - MiscUtilities.charsToEntities(stackEffect) - }); + String 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; @@ -114,9 +113,7 @@ public class FactorWordRenderer extends DefaultListCellRenderer return this; FactorWord word = (FactorWord)value; - setText(getWordHTMLString(word, - parser.getWordDefinition(word), - showIn)); + setText(getWordHTMLString(word,showIn)); return this; } //}}} diff --git a/factor/jedit/WordPreview.java b/factor/jedit/WordPreview.java index 0468832ae9..486e7cdcd0 100644 --- a/factor/jedit/WordPreview.java +++ b/factor/jedit/WordPreview.java @@ -125,7 +125,7 @@ public class WordPreview implements ActionListener, CaretListener { view.getStatus().setMessageAndClear( FactorWordRenderer.getWordHTMLString( - w,fdata.parser.getWordDefinition(w),true)); + w,true)); } } catch(IOException e) diff --git a/factor/parser/Ine.java b/factor/parser/Ine.java index 4e2a14288f..28dc939656 100644 --- a/factor/parser/Ine.java +++ b/factor/parser/Ine.java @@ -49,10 +49,13 @@ public class Ine extends FactorParsingDefinition 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); } } diff --git a/factor/parser/LineComment.java b/factor/parser/LineComment.java index 6412e166d1..edddc6c3dc 100644 --- a/factor/parser/LineComment.java +++ b/factor/parser/LineComment.java @@ -51,6 +51,6 @@ public class LineComment extends FactorParsingDefinition { String comment = reader.getScanner().readUntilEOL(); if(doc) - reader.append(new FactorDocComment(comment,false)); + reader.addDocComment(comment); } } diff --git a/factor/parser/StackComment.java b/factor/parser/StackComment.java index 13971c1f78..78d8a08ea9 100644 --- a/factor/parser/StackComment.java +++ b/factor/parser/StackComment.java @@ -47,6 +47,6 @@ public class StackComment extends FactorParsingDefinition throws Exception { String comment = reader.getScanner().readUntil( '(',')',false); - reader.append(new FactorDocComment(comment,true)); + reader.setStackComment(comment); } } diff --git a/factor/parser/Symbol.java b/factor/parser/Symbol.java index 824869f454..3e6198a1d8 100644 --- a/factor/parser/Symbol.java +++ b/factor/parser/Symbol.java @@ -46,6 +46,7 @@ public class Symbol extends FactorParsingDefinition throws Exception { FactorWord w = reader.nextWord(true); - reader.append(new FactorSymbolDefinition(w,w)); + w.def = new FactorSymbolDefinition(w,w); + reader.append(w.def); } }