]> gitweb.factorcode.org Git - factor.git/commitdiff
various inference fixes; cond compiles now
authorSlava Pestov <slava@factorcode.org>
Tue, 30 Aug 2005 22:12:21 +0000 (22:12 +0000)
committerSlava Pestov <slava@factorcode.org>
Tue, 30 Aug 2005 22:12:21 +0000 (22:12 +0000)
12 files changed:
TODO.FACTOR.txt
library/collections/sequences-epilogue.factor
library/errors.factor
library/generic/math-combination.factor
library/inference/branches.factor
library/inference/inference.factor
library/inference/known-words.factor
library/inference/words.factor
library/syntax/parse-numbers.factor
library/test/compiler/ifte.factor
library/test/inference.factor
library/tools/jedit.factor

index cd64d841d074f196f19d6b118e34c0a18c74678f..54c76e0fac251817293c48fae95047b5d4d4ed1c 100644 (file)
@@ -1,6 +1,7 @@
 - reader syntax for arrays, byte arrays, displaced aliens\r
 - out of memory error when printing global namespace\r
 - removing unneeded #label\r
+- pprint trailing space regression\r
 \r
 + ui:\r
 \r
index e4008c9005fc47a30237cde45d9cc3f41b628067..b1c8bfe7318123b431f07af6ae80aa2aba516a0c 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2005 Slava Pestov.
 ! See http://factor.sf.net/license.txt for BSD license.
 IN: sequences
-USING: generic kernel kernel-internals lists math strings
+USING: errors generic kernel kernel-internals lists math strings
 vectors words ;
 
 ! Combinators
@@ -234,12 +234,14 @@ IN: kernel
     #! Push the number of elements on the datastack.
     datastack length ;
 
+: no-cond "cond fall-through" throw ; inline
+
 : cond ( conditions -- )
     #! Conditions is a sequence of quotation pairs.
     #! { { [ X ] [ Y ] } { [ Z ] [ T ] } }
     #! => X [ Y ] [ Z [ T ] [ ] ifte ] ifte
     #! The last condition should be a catch-all 't'.
-    [ first call ] find nip second call ;
+    [ first call ] find nip [ second call ] [ no-cond ] ifte ;
 
 : with-datastack ( stack word -- stack )
     datastack >r >r set-datastack r> execute
index 787a2c5b3be6f6f8c5e169bc62159f1de4ede784..142d43191633885759dc4b6d29bf071bc1f7c98c 100644 (file)
@@ -9,7 +9,7 @@ IN: errors
 
 TUPLE: no-method object generic ;
 
-: no-method ( object generic -- ) <no-method> throw ;
+: no-method ( object generic -- ) <no-method> throw ; inline
 
 : catchstack ( -- cs ) 6 getenv ;
 : set-catchstack ( cs -- ) 6 setenv ;
index c447b785abe90c5ea25dd6cb49501d217f77b2b0..8c3d7410af6963b1d32d8b0cae8bc515c52f231d 100644 (file)
@@ -31,7 +31,7 @@ math namespaces sequences words ;
 TUPLE: no-math-method left right generic ;
 
 : no-math-method ( left right generic -- )
-    3dup <no-math-method> throw ;
+    3dup <no-math-method> throw ; inline
 
 : applicable-method ( generic class -- quot )
     over "methods" word-prop hash [ ] [
index 532e7b55695d41ddc4ac0d3a02584510fe9fb6f3..ca443c326dcdf726245a697a1f521217e2bbdb14 100644 (file)
@@ -74,10 +74,14 @@ namespaces parser prettyprint sequences strings vectors words ;
     #! meta-d, meta-r, d-in. They are set to f if
     #! terminate was called.
     [
-        copy-inference
-        dup value-recursion recursive-state set
-        literal-value dup infer-quot handle-terminator
-        active? [ #values node, ] when
+        [
+            base-case-continuation set
+            copy-inference
+            dup value-recursion recursive-state set
+            dup literal-value infer-quot
+            active? [ #values node, ] when
+            f
+        ] callcc1 [ terminate ] when drop
     ] make-hash ;
 
 : (infer-branches) ( branchlist -- list )
index a138a5b3e0c96e9e227d80220a2a03b4da9776a9..f5d7740481293eb0f0c85a1a0df46cced26e6ee1 100644 (file)
@@ -7,11 +7,15 @@ namespaces parser prettyprint sequences strings vectors words ;
 ! This variable takes a boolean value.
 SYMBOL: inferring-base-case
 
+! Called when a recursive call during base case inference is
+! found. Either tries to infer another branch, or gives up.
+SYMBOL: base-case-continuation
+
 TUPLE: inference-error message rstate data-stack call-stack ;
 
 : inference-error ( msg -- )
     recursive-state get meta-d get meta-r get
-    <inference-error> throw ;
+    <inference-error> throw ; inline
 
 M: inference-error error. ( error -- )
     "! Inference error:" print
@@ -22,10 +26,9 @@ M: inference-error error. ( error -- )
 M: value literal-value ( value -- )
     {
         "A literal value was expected where a computed value was found.\n"
-        "This means that an attempt was made to compile a word that\n"
-        "applies 'call' or 'execute' to a value that is not known\n"
-        "at compile time. The value might become known if the word\n"
-        "is marked 'inline'. See the handbook for details."
+        "This means the word you are inferring applies 'call' or 'execute'\n"
+        "to a value that is not known at compile time.\n"
+        "See the handbook for details."
     } concat inference-error ;
 
 ! Word properties that affect inference:
@@ -63,6 +66,13 @@ SYMBOL: d-in
     d-in get length object <repeated> >list
     meta-d get length object <repeated> >list 2list ;
 
+: no-base-case ( word -- )
+    {
+        "The base case of a recursive word could not be inferred.\n"
+        "This means the word calls itself in every control flow path.\n"
+        "See the handbook for details."
+    } concat inference-error ;
+
 : init-inference ( recursive-state -- )
     init-interpreter
     { } clone d-in set
@@ -89,25 +99,14 @@ M: wrapper apply-object wrapped apply-literal ;
     #! Ignore this branch's stack effect.
     meta-d off meta-r off d-in off ;
 
-: terminator? ( obj -- ? )
-    #! Does it throw an error?
-    dup word? [ "terminator" word-prop ] [ drop f ] ifte ;
-
-: handle-terminator ( quot -- )
-    #! If the quotation throws an error, do not count its stack
-    #! effect.
-    [ terminator? ] contains? [ terminate ] when ;
-
 : infer-quot ( quot -- )
     #! Recursive calls to this word are made for nested
     #! quotations.
     [ active? [ apply-object t ] [ drop f ] ifte ] all? drop ;
 
 : infer-quot-value ( rstate quot -- )
-    recursive-state get >r
-    swap recursive-state set
-    dup infer-quot handle-terminator
-    r> recursive-state set ;
+    recursive-state get >r swap recursive-state set
+    infer-quot r> recursive-state set ;
 
 : check-return ( -- )
     #! Raise an error if word leaves values on return stack.
@@ -120,6 +119,7 @@ M: wrapper apply-object wrapped apply-literal ;
 : with-infer ( quot -- )
     [
         inferring-base-case off
+        [ no-base-case ] base-case-continuation set
         f init-inference
         call
         check-return
index da53231ff5bf55375f1d5b501b0b0c29d20b344b..e57cbcaaea5acb9e905fe95129b5ab0d9df15c46 100644 (file)
@@ -4,25 +4,42 @@ io-internals kernel kernel-internals lists math math-internals
 memory parser sequences strings vectors words prettyprint ;
 
 ! Primitive combinators
+\ call [ [ general-list ] [ ] ] "infer-effect" set-word-prop
+
 \ call [
     pop-literal infer-quot-value
 ] "infer" set-word-prop
 
+\ execute [ [ word ] [ ] ] "infer-effect" set-word-prop
+
 \ execute [
     pop-literal unit infer-quot-value
 ] "infer" set-word-prop
 
+\ ifte [ [ object general-list general-list ] [ ] ] "infer-effect" set-word-prop
+
 \ ifte [
     2 #drop node, pop-d pop-d swap 2vector
     #ifte pop-d drop infer-branches
 ] "infer" set-word-prop
 
+\ cond [ [ object ] [ ] ] "infer-effect" set-word-prop
+
+\ cond [
+    pop-literal [ 2unseq cons ] map
+    [ no-cond ] swap alist>quot infer-quot-value
+] "infer" set-word-prop
+
+\ dispatch [ [ fixnum vector ] [ ] ] "infer-effect" set-word-prop
+
 \ dispatch [
     pop-literal nip [ <literal> ] map
     #dispatch pop-d drop infer-branches
 ] "infer" set-word-prop
 
 ! Stack manipulation
+\ >r [ [ object ] [ ] ] "infer-effect" set-word-prop
+
 \ >r [
     \ >r #call
     1 0 pick node-inputs
@@ -31,6 +48,8 @@ memory parser sequences strings vectors words prettyprint ;
     node,
 ] "infer" set-word-prop
 
+\ r> [ [ ] [ object ] ] "infer-effect" set-word-prop
+
 \ r> [
     \ r> #call
     0 1 pick node-inputs
@@ -40,57 +59,25 @@ memory parser sequences strings vectors words prettyprint ;
 ] "infer" set-word-prop
 
 \ drop [ 1 #drop node, pop-d drop ] "infer" set-word-prop
+\ drop [ [ object ] [ ] ] "infer-effect" set-word-prop
+
 \ dup  [ \ dup  infer-shuffle ] "infer" set-word-prop
+\ dup [ [ object ] [ object object ] ] "infer-effect" set-word-prop
+
 \ swap [ \ swap infer-shuffle ] "infer" set-word-prop
+\ swap [ [ object object ] [ object object ] ] "infer-effect" set-word-prop
+
 \ over [ \ over infer-shuffle ] "infer" set-word-prop
+\ over [ [ object object ] [ object object object ] ] "infer-effect" set-word-prop
+
 \ pick [ \ pick infer-shuffle ] "infer" set-word-prop
+\ pick [ [ object object object ] [ object object object object ] ] "infer-effect" set-word-prop
 
-! These hacks will go away soon
-\ delegate [ [ object ] [ object ] ] "infer-effect" set-word-prop
-\ no-method t "terminator" set-word-prop
-\ no-method [ [ object word ] [ ] ] "infer-effect" set-word-prop
-\ <no-method> [ [ object object ] [ tuple ] ] "infer-effect" set-word-prop
-\ set-no-method-generic [ [ object tuple ] [ ] ] "infer-effect" set-word-prop
-\ set-no-method-object [ [ object tuple ] [ ] ] "infer-effect" set-word-prop
-\ no-math-method t "terminator" set-word-prop
-\ not-a-number t "terminator" set-word-prop
-\ inference-error t "terminator" set-word-prop
-\ throw t "terminator" set-word-prop
-\ = [ [ object object ] [ boolean ] ] "infer-effect" set-word-prop
-\ hash-contained? [ [ object object ] [ boolean ] ] "infer-effect" set-word-prop
-\ gcd [ [ integer integer ] [ integer integer ] ] "infer-effect" set-word-prop
-\ car [ [ general-list ] [ object ] ] "infer-effect" set-word-prop
-\ cdr [ [ general-list ] [ object ] ] "infer-effect" set-word-prop
-\ < [ [ real real ] [ boolean ] ] "infer-effect" set-word-prop
-\ <= [ [ real real ] [ boolean ] ] "infer-effect" set-word-prop
-\ > [ [ real real ] [ boolean ] ] "infer-effect" set-word-prop
-\ >= [ [ real real ] [ boolean ] ] "infer-effect" set-word-prop
-\ number= [ [ object object ] [ boolean ] ] "infer-effect" set-word-prop
-\ + [ [ number number ] [ number ] ] "infer-effect" set-word-prop
-\ - [ [ number number ] [ number ] ] "infer-effect" set-word-prop
-\ * [ [ number number ] [ number ] ] "infer-effect" set-word-prop
-\ / [ [ number number ] [ number ] ] "infer-effect" set-word-prop
-\ /i [ [ number number ] [ number ] ] "infer-effect" set-word-prop
-\ /f [ [ number number ] [ number ] ] "infer-effect" set-word-prop
-\ mod [ [ integer integer ] [ integer ] ] "infer-effect" set-word-prop
-\ /mod [ [ integer integer ] [ integer integer ] ] "infer-effect" set-word-prop
-\ bitand [ [ integer integer ] [ integer ] ] "infer-effect" set-word-prop
-\ bitor [ [ integer integer ] [ integer ] ] "infer-effect" set-word-prop
-\ bitxor [ [ integer integer ] [ integer ] ] "infer-effect" set-word-prop
-\ shift [ [ integer integer ] [ integer ] ] "infer-effect" set-word-prop
-\ bitnot [ [ integer ] [ integer ] ] "infer-effect" set-word-prop
-\ real [ [ number ] [ real ] ] "infer-effect" set-word-prop
-\ imaginary [ [ number ] [ real ] ] "infer-effect" set-word-prop
+! Non-standard control flow
+\ throw [ [ object ] [ ] ] "infer-effect" set-word-prop
+\ throw [ terminate ] "infer" set-word-prop
 
 ! Stack effects for all primitives
-\ execute [ [ word ] [ ] ] "infer-effect" set-word-prop
-
-\ call [ [ general-list ] [ ] ] "infer-effect" set-word-prop
-
-\ ifte [ [ object general-list general-list ] [ ] ] "infer-effect" set-word-prop
-
-\ dispatch [ [ fixnum vector ] [ ] ] "infer-effect" set-word-prop
-
 \ cons [ [ object object ] [ cons ] ] "infer-effect" set-word-prop
 \ cons t "foldable" set-word-prop
 \ cons t "flushable" set-word-prop
@@ -371,13 +358,6 @@ memory parser sequences strings vectors words prettyprint ;
 
 \ update-xt [ [ word ] [ ] ] "infer-effect" set-word-prop
 \ compiled? [ [ word ] [ boolean ] ] "infer-effect" set-word-prop
-\ drop [ [ object ] [ ] ] "infer-effect" set-word-prop
-\ dup [ [ object ] [ object object ] ] "infer-effect" set-word-prop
-\ swap [ [ object object ] [ object object ] ] "infer-effect" set-word-prop
-\ over [ [ object object ] [ object object object ] ] "infer-effect" set-word-prop
-\ pick [ [ object object object ] [ object object object object ] ] "infer-effect" set-word-prop
-\ >r [ [ object ] [ ] ] "infer-effect" set-word-prop
-\ r> [ [ ] [ object ] ] "infer-effect" set-word-prop
 
 \ eq? [ [ object object ] [ boolean ] ] "infer-effect" set-word-prop
 \ eq? t "flushable" set-word-prop
@@ -395,6 +375,7 @@ memory parser sequences strings vectors words prettyprint ;
 \ os-env [ [ string ] [ object ] ] "infer-effect" set-word-prop
 \ millis [ [ ] [ integer ] ] "infer-effect" set-word-prop
 \ (random-int) [ [ ] [ integer ] ] "infer-effect" set-word-prop
+
 \ type [ [ object ] [ fixnum ] ] "infer-effect" set-word-prop
 \ type t "flushable" set-word-prop
 \ type t "foldable" set-word-prop
@@ -484,7 +465,6 @@ memory parser sequences strings vectors words prettyprint ;
 \ alien-c-string t "flushable" set-word-prop
 
 \ set-alien-c-string [ [ string c-ptr integer ] [ ] ] "infer-effect" set-word-prop
-\ throw [ [ object ] [ ] ] "infer-effect" set-word-prop
 \ string>memory [ [ string integer ] [ ] ] "infer-effect" set-word-prop
 \ memory>string [ [ integer integer ] [ string ] ] "infer-effect" set-word-prop
 \ alien-address [ [ alien ] [ integer ] ] "infer-effect" set-word-prop
index 8182918f2905714e26335cbf41e08200276b8ae3..daa1ff052c4873de8cb664cc0688b42d4eec46ed 100644 (file)
@@ -112,7 +112,7 @@ M: symbol apply-object ( word -- )
             nip consume/produce
         ] [
             inferring-base-case get [
-                2drop terminate
+                t base-case-continuation get call
             ] [
                 car base-case
             ] ifte
index 87d0ef3123e6d9b2eabef968460eb901026c8b39..91d19cf68b79e2ed3ee5523be854b1054c8011fc 100644 (file)
@@ -5,7 +5,7 @@ USING: errors generic kernel math namespaces sequences strings ;
 
 ! Number parsing
 
-: not-a-number "Not a number" throw ;
+: not-a-number "Not a number" throw ; inline
 
 GENERIC: digit> ( ch -- n )
 M: digit  digit> CHAR: 0 - ;
index 06914b6f3874c713d3ff802ae461874838841903..59624a1513f9ffdd56f0ae510c65fae836f9b818 100644 (file)
@@ -1,4 +1,5 @@
 IN: temporary
+USING: alien strings ;
 USE: compiler
 USE: test
 USE: math
@@ -94,3 +95,32 @@ DEFER: countdown-b
 
 [ 3 ] [ f dummy-unless-3 ] unit-test
 [ 4 ] [ 4 dummy-unless-3 ] unit-test
+
+[ "even" ] [
+    [
+        2 {
+            { [ dup 2 mod 0 = ] [ drop "even" ] }
+            { [ dup 2 mod 1 = ] [ drop "odd" ] }
+        } cond
+    ] compile-1
+] unit-test
+
+[ "odd" ] [
+    [
+        3 {
+            { [ dup 2 mod 0 = ] [ drop "even" ] }
+            { [ dup 2 mod 1 = ] [ drop "odd" ] }
+        } cond
+    ] compile-1
+] unit-test
+
+[ "neither" ] [
+    [
+        3 {
+            { [ dup string? ] [ drop "string" ] }
+            { [ dup float? ] [ drop "float" ] }
+            { [ dup alien? ] [ drop "alien" ] }
+            { [ t ] [ drop "neither" ] }
+        } cond
+    ] compile-1
+] unit-test
index ae2928cdc3a021256b6c424912e8138b4fc55607..1573a6ea01428879c345036d9f36d7cac2941a82 100644 (file)
@@ -155,9 +155,11 @@ DEFER: agent
 [ [ [ ] [ object object ] ] ]
 [ [ [ drop ] 0 agent ] infer ] unit-test
 
-! : no-base-case dup [ no-base-case ] [ no-base-case ] ifte ;
-! 
-! [ [ no-base-case ] infer simple-effect ] unit-test-fails
+: no-base-case-1 dup [ no-base-case-1 ] [ no-base-case-1 ] ifte ;
+[ [ no-base-case-1 ] infer ] unit-test-fails
+
+: no-base-case-2 no-base-case-2 ;
+[ [ no-base-case-2 ] infer ] unit-test-fails
 
 [ { 2 1 } ] [ [ 2vector ] infer simple-effect ] unit-test
 [ { 3 1 } ] [ [ 3vector ] infer simple-effect ] unit-test
index ead715d2d4de0d47009ecaaf9c2b30fe501b184d..033d95b297cd7ed3f0fdc4e45a3702c5d978e4c1 100644 (file)
@@ -76,12 +76,11 @@ sequences strings unparser vectors words ;
     #! required word info.
     dup [
         [
-            "vocabulary"
-            "name"
-            "stack-effect"
-        ] [
-            dupd word-prop
-        ] map >r definer r> cons
+            dup definer ,
+            dup word-vocabulary ,
+            dup word-name ,
+            "stack-effect" word-prop ,
+        ] [ ] make
     ] when ;
 
 : completions ( str pred -- list | pred: str word -- ? )