]> gitweb.factorcode.org Git - factor.git/commitdiff
more rearrangement
authorSlava Pestov <slava@factorcode.org>
Fri, 26 Nov 2004 02:53:27 +0000 (02:53 +0000)
committerSlava Pestov <slava@factorcode.org>
Fri, 26 Nov 2004 02:53:27 +0000 (02:53 +0000)
factor/DefaultVocabularyLookup.java [new file with mode: 0644]
factor/VocabularyLookup.java [new file with mode: 0644]
library/io/io-internals.factor [new file with mode: 0644]
library/io/network.factor [new file with mode: 0644]
library/io/stream-impl.factor [new file with mode: 0644]
library/tools/heap-stats.factor [new file with mode: 0644]
library/tools/profiler.factor [new file with mode: 0644]

diff --git a/factor/DefaultVocabularyLookup.java b/factor/DefaultVocabularyLookup.java
new file mode 100644 (file)
index 0000000..3821b54
--- /dev/null
@@ -0,0 +1,232 @@
+/* :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 factor.parser.*;
+import java.io.*;
+import java.util.*;
+
+public class DefaultVocabularyLookup implements VocabularyLookup
+{
+       public static final Cons DEFAULT_USE = new Cons("syntax",new Cons("scratchpad",null));
+       public static final String DEFAULT_IN = "scratchpad";
+
+       /**
+        * Maps vocabulary names to vocabularies.
+        */
+       private Map vocabularies;
+
+       //{{{ DefaultVocabularyLookup constructor
+       public DefaultVocabularyLookup()
+       {
+               vocabularies = new HashMap();
+
+               /* comments */
+               FactorWord lineComment = define("syntax","!");
+               lineComment.parsing = new LineComment(lineComment,false);
+               FactorWord stackComment = define("syntax","(");
+               stackComment.parsing = new StackComment(stackComment);
+               FactorWord docComment = define("syntax","#!");
+               docComment.parsing = new LineComment(docComment,true);
+
+               /* strings */
+               FactorWord str = define("syntax","\"");
+               str.parsing = new StringLiteral(str,true);
+               FactorWord ch = define("syntax","CHAR:");
+               ch.parsing = new CharLiteral(ch);
+
+               /* constants */
+               FactorWord t = define("syntax","t");
+               t.parsing = new T(t);
+               FactorWord f = define("syntax","f");
+               f.parsing = new F(f);
+               FactorWord complex = define("syntax","#{");
+               complex.parsing = new ComplexLiteral(complex,"}");
+
+               /* lists */
+               FactorWord bra = define("syntax","[");
+               bra.parsing = new Bra(bra);
+               FactorWord ket = define("syntax","]");
+               ket.parsing = new Ket(bra,ket);
+               FactorWord bar = define("syntax","|");
+               bar.parsing = new Bar(bar);
+
+               /* vectors */
+               FactorWord beginVector = define("syntax","{");
+               beginVector.parsing = new BeginVector(beginVector);
+               FactorWord endVector = define("syntax","}");
+               endVector.parsing = new EndVector(beginVector,endVector);
+
+               /* word defs */
+               FactorWord def = define("syntax",":");
+               def.parsing = new Def(def);
+               def.docComment = true;
+               FactorWord ine = define("syntax",";");
+               ine.parsing = new Ine(def,ine);
+               FactorWord symbol = define("syntax","SYMBOL:");
+               symbol.parsing = new Symbol(symbol);
+
+               /* reading numbers with another base */
+               FactorWord bin = define("syntax","BIN:");
+               bin.parsing = new Base(bin,2);
+               FactorWord oct = define("syntax","OCT:");
+               oct.parsing = new Base(oct,8);
+               FactorWord hex = define("syntax","HEX:");
+               hex.parsing = new Base(hex,16);
+
+               /* vocabulary parsing words */
+               FactorWord noParsing = define("syntax","POSTPONE:");
+               noParsing.parsing = new NoParsing(noParsing);
+               FactorWord defer = define("syntax","DEFER:");
+               defer.parsing = new Defer(defer);
+               FactorWord in = define("syntax","IN:");
+               in.parsing = new In(in);
+               FactorWord use = define("syntax","USE:");
+               use.parsing = new Use(use);
+
+               FactorWord pushWord = define("syntax","\\");
+               pushWord.parsing = new PushWord(pushWord);
+       } //}}}
+
+       //{{{ getVocabulary() method
+       public Map getVocabulary(String name)
+       {
+               return (Map)vocabularies.get(name);
+       } //}}}
+
+       //{{{ searchVocabulary() method
+       /**
+        * Search in the given vocabulary for the given word.
+        */
+       public FactorWord searchVocabulary(String vname, String name)
+       {
+               Map v = getVocabulary(vname);
+               if(v != null)
+                       return (FactorWord)v.get(name);
+               else
+                       return null;
+       } //}}}
+
+       //{{{ searchVocabulary() method
+       /**
+        * Search through the given vocabulary list for the given word.
+        */
+       public FactorWord searchVocabulary(Cons vocabulary, String name)
+       {
+               while(vocabulary != null)
+               {
+                       FactorWord word = searchVocabulary(
+                               (String)vocabulary.car,name);
+                       if(word != null)
+                               return word;
+
+                       vocabulary = vocabulary.next();
+               }
+
+               return null;
+       } //}}}
+
+       //{{{ define() method
+       /**
+        * Define a word in the given vocabulary if it doesn't exist already.
+        */
+       public FactorWord define(String vocabulary, String name)
+       {
+               Map v = getVocabulary(vocabulary);
+               if(v == null)
+               {
+                       v = new HashMap();
+                       vocabularies.put(vocabulary,v);
+               }
+               Object value = v.get(name);
+               if(value instanceof FactorWord)
+                       return (FactorWord)value;
+               else
+               {
+                       // save to same workspace as vocabulary,
+                       // or no workspace if vocabulary is builtins
+                       FactorWord word = new FactorWord(vocabulary,name);
+                       v.put(name,word);
+                       return word;
+               }
+       } //}}}
+
+       //{{{ getVocabularies() method
+       public Cons getVocabularies()
+       {
+               Cons vocabs = null;
+               Iterator iter = vocabularies.keySet().iterator();
+               while(iter.hasNext())
+                       vocabs = new Cons(iter.next(),vocabs);
+               return vocabs;
+       } //}}}
+
+       //{{{ getCompletions() method
+       public void getCompletions(String vocab, String word, Set completions,
+               boolean anywhere)
+       {
+               Map v = (Map)vocabularies.get(vocab);
+               if(v == null)
+                       return;
+
+               Iterator words = v.values().iterator();
+
+               while(words.hasNext())
+               {
+                       FactorWord w = (FactorWord)words.next();
+                       if(w != null && w.name != null)
+                       {
+                               if(!completions.contains(w))
+                               {
+                                       if(anywhere)
+                                       {
+                                               if(w.name.indexOf(word) != -1)
+                                                       completions.add(w);
+                                       }
+                                       else
+                                       {
+                                               if(w.name.startsWith(word))
+                                                       completions.add(w);
+                                       }
+                               }
+                       }
+               }
+       } //}}}
+
+       //{{{ parseObject() method
+       public Cons parseObject(String source) throws Exception
+       {
+               FactorReader parser = new FactorReader(
+                       "parseObject()",
+                       new BufferedReader(new StringReader(source)),
+                       true,this);
+               return parser.parse();
+       } //}}}
+}
diff --git a/factor/VocabularyLookup.java b/factor/VocabularyLookup.java
new file mode 100644 (file)
index 0000000..02849ac
--- /dev/null
@@ -0,0 +1,53 @@
+/* :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.util.Iterator;
+import java.util.Set;
+
+public interface VocabularyLookup
+{
+       public FactorWord define(String in, String word)
+               throws Exception;
+       public FactorWord searchVocabulary(Cons use, String word)
+               throws Exception;
+
+       /**
+        * @param vocab The vocabulary name
+        * @param word A substring of the word name to complete
+        * @param completions List to add completions to
+        * @param anywhere If true, word name will be matched anywhere, otherwise, just at
+        * the beginning of the name.
+        */
+       public void getCompletions(String vocab, String word, Set completions,
+               boolean anywhere) throws Exception;
+
+       public Cons getVocabularies() throws Exception;
+}
diff --git a/library/io/io-internals.factor b/library/io/io-internals.factor
new file mode 100644 (file)
index 0000000..4730283
--- /dev/null
@@ -0,0 +1,77 @@
+! :folding=none: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.
+
+IN: io-internals
+USE: combinators
+USE: continuations
+USE: kernel
+USE: namespaces
+USE: stack
+USE: strings
+USE: threads
+
+: stdin 0 getenv ;
+: stdout 1 getenv ;
+
+: blocking-flush ( port -- )
+    [ add-write-io-task (yield) ] callcc0 drop ;
+
+: wait-to-write ( len port -- )
+    tuck can-write? [ drop ] [ blocking-flush ] ifte ;
+
+: blocking-write ( str port -- )
+    over
+    dup string? [ str-length ] [ drop 1 ] ifte
+    over wait-to-write write-fd-8 ;
+
+: blocking-fill ( port -- )
+    [ add-read-line-io-task (yield) ] callcc0 drop ;
+
+: wait-to-read-line ( port -- )
+    dup can-read-line? [ drop ] [ blocking-fill ] ifte ;
+
+: blocking-read-line ( port -- line )
+    dup wait-to-read-line read-line-fd-8 dup [ sbuf>str ] when ;
+
+: fill-fd# ( count port -- )
+    [ add-read-count-io-task (yield) ] callcc0 2drop ;
+
+: wait-to-read# ( count port -- )
+    2dup can-read-count? [ 2drop ] [ fill-fd# ] ifte ;
+
+: blocking-read# ( count port -- str )
+    2dup wait-to-read# read-count-fd-8 dup [ sbuf>str ] when ;
+
+: wait-to-accept ( socket -- )
+    [ add-accept-io-task (yield) ] callcc0 drop ;
+
+: blocking-accept ( socket -- host port in out )
+    dup wait-to-accept accept-fd ;
+
+: blocking-copy ( in out -- )
+    [ add-copy-io-task (yield) ] callcc0
+    pending-io-error pending-io-error ;
diff --git a/library/io/network.factor b/library/io/network.factor
new file mode 100644 (file)
index 0000000..99bc281
--- /dev/null
@@ -0,0 +1,62 @@
+! :folding=indent: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.
+
+IN: streams
+USE: combinators
+USE: continuations
+USE: io-internals
+USE: errors
+USE: hashtables
+USE: kernel
+USE: logic
+USE: stack
+USE: stdio
+USE: strings
+USE: namespaces
+USE: unparser
+
+: <server> ( port -- stream )
+    #! Starts listening on localhost:port. Returns a stream that
+    #! you can close with fclose, and accept connections from
+    #! with accept. No other stream operations are supported.
+    server-socket <stream> [
+        "socket" set
+
+        ( -- )
+        [ "socket" get close-port ] "fclose" set
+    ] extend ;
+
+: <client-stream> ( host port in out -- stream )
+    <fd-stream> [ ":" swap unparse cat3 "client" set ] extend ;
+
+: <client> ( host port -- stream )
+    #! fflush yields until connection is established.
+    2dup client-socket <client-stream> dup fflush ;
+
+: accept ( server -- client )
+    #! Accept a connection from a server socket.
+    "socket" swap hash blocking-accept <client-stream> ;
diff --git a/library/io/stream-impl.factor b/library/io/stream-impl.factor
new file mode 100644 (file)
index 0000000..acca4d1
--- /dev/null
@@ -0,0 +1,99 @@
+! :folding=indent: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.
+
+IN: streams
+USE: combinators
+USE: continuations
+USE: io-internals
+USE: errors
+USE: hashtables
+USE: kernel
+USE: logic
+USE: stack
+USE: stdio
+USE: strings
+USE: namespaces
+
+: <fd-stream> ( in out -- stream )
+    #! Create a file descriptor stream object, wrapping a pair
+    #! of file descriptor handles for input and output.
+    <stream> [
+        "out" set
+        "in" set
+
+        ( str -- )
+        [ "out" get blocking-write ] "fwrite" set
+        
+        ( -- str )
+        [ "in" get dup [ blocking-read-line ] when ] "freadln" set
+        
+        ( count -- str )
+        [
+            "in" get dup [ blocking-read# ] [ nip ] ifte
+        ] "fread#" set
+        
+        ( -- )
+        [ "out" get [ blocking-flush ] when* ] "fflush" set
+        
+        ( -- )
+        [
+            "out" get [ dup blocking-flush close-port ] when*
+            "in" get [ close-port ] when*
+        ] "fclose" set
+    ] extend ;
+
+: <filecr> ( path -- stream )
+    t f open-file <fd-stream> ;
+
+: <filecw> ( path -- stream )
+    f t open-file <fd-stream> ;
+
+: <filebr> ( path -- stream )
+    <filecr> ;
+
+: <filebw> ( path -- stream )
+    <filecw> ;
+
+: init-stdio ( -- )
+    stdin stdout <fd-stream> <stdio-stream> "stdio" set ;
+
+: (fcopy) ( from to -- )
+    #! Copy the contents of the fd-stream 'from' to the
+    #! fd-stream 'to'. Use fcopy; this word does not close
+    #! streams.
+    "out" swap hash >r "in" swap hash r> blocking-copy ;
+
+: fcopy ( from to -- )
+    #! Copy the contents of the fd-stream 'from' to the
+    #! fd-stream 'to'.
+    [ 2dup (fcopy) ] [ -rot fclose fclose rethrow ] catch ;
+
+: resource-path ( -- path )
+    "resource-path" get [ "." ] unless* ;
+
+: <resource-stream> ( path -- stream )
+    resource-path swap cat2 <filecr> ;
diff --git a/library/tools/heap-stats.factor b/library/tools/heap-stats.factor
new file mode 100644 (file)
index 0000000..91e8a30
--- /dev/null
@@ -0,0 +1,52 @@
+! :folding=indent: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.
+
+IN: kernel
+USE: combinators
+USE: kernel
+USE: lists
+USE: math
+USE: namespaces
+USE: prettyprint
+USE: stack
+USE: stdio
+USE: words
+USE: vectors
+USE: unparser
+
+: heap-stat. ( type instances bytes -- )
+    dup 0 = [
+        3drop
+    ] [
+        rot type-name write ": " write
+        unparse write " bytes, " write
+        unparse write " instances" print
+    ] ifte ;
+
+: heap-stats. ( -- )
+    #! Print heap allocation breakdown.
+    0 heap-stats [ dupd uncons heap-stat. succ ] each drop ;
diff --git a/library/tools/profiler.factor b/library/tools/profiler.factor
new file mode 100644 (file)
index 0000000..d996448
--- /dev/null
@@ -0,0 +1,87 @@
+! :folding=indent: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.
+
+IN: profiler
+USE: combinators
+USE: kernel
+USE: lists
+USE: math
+USE: namespaces
+USE: prettyprint
+USE: stack
+USE: words
+USE: vectors
+
+! The variable "only-top" toggles between
+! culminative counts, and top of call stack counts.
+SYMBOL: only-top
+
+: reset-counts ( -- )
+    [ 0 over set-call-count 0 swap set-allot-count ] each-word ;
+
+: sort-counts ( alist -- alist )
+    [ swap cdr swap cdr > ] sort ;
+
+: call-count, ( word -- )
+    #! Add to constructing list if call count is non-zero.
+    dup call-count dup 0 = [ 2drop ] [ cons , ] ifte ;
+
+: counts. ( alist -- )
+    sort-counts [ . ] each ;
+
+: call-counts. ( -- )
+    #! Print word/call count pairs.
+    [ [ call-count, ] each-word ] make-list counts. ;
+
+: profile-depth ( -- n )
+    only-top get [ -1 ] [ callstack vector-length ] ifte ;
+
+: (call-profile) ( quot -- )
+    reset-counts
+    profile-depth call-profiling
+    call
+    f call-profiling ;
+
+: call-profile ( quot -- )
+    #! Execute a quotation with the CPU profiler enabled.
+    (call-profile) call-counts. ;
+
+: allot-count, ( word -- )
+    #! Add to constructing list if allot count is non-zero.
+    dup allot-count dup 0 = [ 2drop ] [ cons , ] ifte ;
+
+: allot-counts. ( -- alist )
+    #! Print word/allot count pairs.
+    [ [ allot-count, ] each-word ] make-list counts. ;
+
+: allot-profile ( quot -- )
+    #! Execute a quotation with the memory profiler enabled.
+    reset-counts
+    profile-depth allot-profiling
+    call
+    f allot-profiling
+    allot-counts. ;