diff --git a/actions.xml b/actions.xml index ee174c35d5..6745783f60 100644 --- a/actions.xml +++ b/actions.xml @@ -82,4 +82,10 @@ FactorPlugin.extractWord(view); + + + InferBufferProcessor.createInferUnitTests(view,buffer, + FactorPlugin.getExternalInstance()); + + diff --git a/factor/jedit/FactorBufferProcessor.java b/factor/jedit/FactorBufferProcessor.java index a7ea200653..9c85a9f82e 100644 --- a/factor/jedit/FactorBufferProcessor.java +++ b/factor/jedit/FactorBufferProcessor.java @@ -38,22 +38,15 @@ import org.gjt.sp.jedit.Buffer; * A class used to compile all words in a file, or infer stack effects of all * words in a file, etc. */ -public class FactorBufferProcessor +public abstract class FactorBufferProcessor { - private String code; private LinkedHashMap results; //{{{ FactorBufferProcessor constructor - /** - * @param buffer The buffer - * @param code The snippet of code to apply to each word. The snippet - * should print a string. - */ - public FactorBufferProcessor(Buffer buffer, String code, ExternalFactor factor) - throws IOException + public FactorBufferProcessor(Buffer buffer, ExternalFactor factor) + throws Exception { results = new LinkedHashMap(); - this.code = code; Cons words = (Cons)buffer.getProperty( FactorSideKickParser.WORDS_PROPERTY); @@ -61,33 +54,26 @@ public class FactorBufferProcessor while(words != null) { FactorWord word = (FactorWord)words.car; - - StringBuffer expression = new StringBuffer(); - expression.append(FactorPlugin.factorWord(word)); - expression.append(" "); - expression.append(code); - - results.put(word,factor.eval(expression.toString())); - + String expr = processWord(word); + System.err.println(expr); + results.put(word,factor.eval(expr)); words = words.next(); } } //}}} + /** + * @return Code to process the word. + */ + public abstract String processWord(FactorWord word); + //{{{ insertResults() method public void insertResults(Buffer buffer, int offset) + throws Exception { StringBuffer result = new StringBuffer(); - Iterator iter = results.entrySet().iterator(); + Iterator iter = results.values().iterator(); while(iter.hasNext()) - { - Map.Entry entry = (Map.Entry)iter.next(); - result.append("[ "); - result.append(((String)entry.getValue()).trim()); - result.append(" ] [ \\ "); - result.append(FactorReader.unparseObject(entry.getKey())); - result.append(code); - result.append(" ] unit-test\n"); - } - buffer.insert(offset,result.toString()); + result.append(iter.next()); + buffer.insert(offset,result.toString().trim()); } //}}} } diff --git a/factor/jedit/FactorPlugin.props b/factor/jedit/FactorPlugin.props index 85dba2b6b0..ed79bed93b 100644 --- a/factor/jedit/FactorPlugin.props +++ b/factor/jedit/FactorPlugin.props @@ -29,6 +29,8 @@ plugin.factor.jedit.FactorPlugin.menu=factor-listener \ - \ factor-extract-word \ - \ + factor-infer-effects \ + - \ factor-restart factor-listener.label=Listener @@ -41,6 +43,7 @@ factor-edit.label=Edit word at caret factor-edit-dialog.label=Edit word... factor-usages.label=Word usages at caret factor-extract-word.label=Extract word... +factor-infer-effects.label=Infer word stack effects... factor-restart.label=Restart Factor # SideKick stuff diff --git a/factor/jedit/InferBufferProcessor.java b/factor/jedit/InferBufferProcessor.java new file mode 100644 index 0000000000..cfc266fcec --- /dev/null +++ b/factor/jedit/InferBufferProcessor.java @@ -0,0 +1,87 @@ +/* :folding=explicit:collapseFolds=1: */ + +/* + * $Id$ + * + * Copyright (C) 2005 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.jedit; + +import factor.*; +import java.io.IOException; +import java.util.*; +import org.gjt.sp.jedit.io.VFSManager; +import org.gjt.sp.jedit.*; +import org.gjt.sp.util.*; + +/** + * A class used to compile all words in a file, or infer stack effects of all + * words in a file, etc. + */ +public class InferBufferProcessor extends FactorBufferProcessor +{ + //{{{ createInferUnitTests() method + public static void createInferUnitTests(View view, + final Buffer buffer, + final ExternalFactor factor) + { + final Buffer newBuffer = jEdit.newFile(view); + VFSManager.runInAWTThread(new Runnable() + { + public void run() + { + newBuffer.setMode("factor"); + try + { + new InferBufferProcessor(buffer,factor) + .insertResults(newBuffer,0); + } + catch(Exception e) + { + Log.log(Log.ERROR,this,e); + } + } + }); + } //}}} + + //{{{ InferBufferProcessor constructor + public InferBufferProcessor(Buffer buffer, ExternalFactor factor) + throws Exception + { + super(buffer,factor); + } //}}} + + //{{{ processWord() method + /** + * @return Code to process the word. + */ + public String processWord(FactorWord word) + { + StringBuffer expression = new StringBuffer(); + expression.append(FactorPlugin.factorWord(word)); + expression.append(" unit infer>test print"); + return expression.toString(); + } //}}} +} diff --git a/library/bootstrap/boot-stage2.factor b/library/bootstrap/boot-stage2.factor index 0eb5df43ff..c9b75a48b3 100644 --- a/library/bootstrap/boot-stage2.factor +++ b/library/bootstrap/boot-stage2.factor @@ -118,6 +118,7 @@ USE: namespaces "/library/inference/words.factor" "/library/inference/stack.factor" "/library/inference/types.factor" + "/library/inference/test.factor" "/library/compiler/assembler.factor" "/library/compiler/xt.factor" diff --git a/library/inference/inference.factor b/library/inference/inference.factor index 4d66760ebe..2ee4c4c9b8 100644 --- a/library/inference/inference.factor +++ b/library/inference/inference.factor @@ -188,10 +188,6 @@ DEFER: apply-word #! Stack effect of a quotation. [ (infer) effect ] with-scope ; -: try-infer ( quot -- effect/f ) - #! Push f if inference fails. - [ infer ] [ [ drop f ] when ] catch ; - : dataflow ( quot -- dataflow ) #! Data flow of a quotation. [ (infer) get-dataflow ] with-scope ; diff --git a/library/inference/test.factor b/library/inference/test.factor new file mode 100644 index 0000000000..9cbd8166d3 --- /dev/null +++ b/library/inference/test.factor @@ -0,0 +1,53 @@ +! :folding=indent:collapseFolds=1: + +! $Id$ +! +! Copyright (C) 2005 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. + +IN: test +USE: errors +USE: inference +USE: kernel +USE: lists +USE: prettyprint +USE: stdio +USE: strings +USE: unparser + +: try-infer ( quot -- effect error ) + [ infer f ] [ [ >r drop f r> ] when* ] catch ; + +: infer-fail ( quot error -- ) + "! " , dup string? [ unparse ] unless , "\n" , + [ [ infer ] cons . \ unit-test-fails . ] with-string , ; + +: infer-pass ( quot effect -- ) + [ unit . [ infer ] cons . \ unit-test . ] with-string , ; + +: infer>test ( quot -- str ) + #! Make a string representing a unit test for the stack + #! effect of a word. + [ + dup try-infer [ infer-fail ] [ infer-pass ] ?ifte + ] make-string ; diff --git a/library/test/test.factor b/library/test/test.factor index 54496d8c70..6aa91411a8 100644 --- a/library/test/test.factor +++ b/library/test/test.factor @@ -1,7 +1,5 @@ ! Factor test suite. -! Some of these words should be moved to the standard library. - IN: test USE: errors USE: kernel