inference errors printed; type violations are flagged; plugin fixes

cvs
Slava Pestov 2005-02-23 04:07:47 +00:00
parent eb86c229e0
commit 6b9133bf30
20 changed files with 170 additions and 202 deletions

View File

@ -7,10 +7,8 @@
- type inference fails with some assembler words; - type inference fails with some assembler words;
displaced, register and other predicates need to inherit from list displaced, register and other predicates need to inherit from list
not cons, and need stronger branch partial eval not cons, and need stronger branch partial eval
- print warning on null class
- optimize away dispatch - optimize away dispatch
- code gc - code gc
- #jump-f #jump-f-label
- don't hardcode so many colors - don't hardcode so many colors
- ffi unicode strings: null char security hole - ffi unicode strings: null char security hole
- utf16 string boxing - utf16 string boxing
@ -19,6 +17,7 @@
+ compiler/ffi: + compiler/ffi:
- #jump-f #jump-f-label
- declarations - declarations
- value type structs - value type structs
- out parameters - out parameters

View File

@ -89,10 +89,10 @@ SYMBOL: center
] with-pixels ; compiled ] with-pixels ; compiled
: mandel ( -- ) : mandel ( -- )
640 480 0 SDL_HWSURFACE [ 1280 1024 0 SDL_HWSURFACE [
[ [
0.8 zoom-fact set 3.7 zoom-fact set
-0.65 center set -0.45 center set
100 nb-iter set 100 nb-iter set
init-mandel init-mandel
[ render ] time [ render ] time

View File

@ -193,7 +193,7 @@ public class DefaultVocabularyLookup implements VocabularyLookup
{ {
// save to same workspace as vocabulary, // save to same workspace as vocabulary,
// or no workspace if vocabulary is builtins // or no workspace if vocabulary is builtins
FactorWord word = new FactorWord(vocabulary,name); FactorWord word = new FactorWord(this,vocabulary,name);
v.put(name,word); v.put(name,word);
return word; return word;
} }

View File

@ -201,7 +201,7 @@ public class ExternalFactor extends DefaultVocabularyLookup
String name = (String)info.next().car; String name = (String)info.next().car;
FactorWord w = super.searchVocabulary(new Cons(vocabulary,null),name); FactorWord w = super.searchVocabulary(new Cons(vocabulary,null),name);
if(w == null) if(w == null)
w = new FactorWord(vocabulary,name); w = new FactorWord(this,vocabulary,name);
w.stackEffect = (String)info.next().next().car; w.stackEffect = (String)info.next().next().car;
return w; return w;
} //}}} } //}}}

View File

@ -67,4 +67,6 @@ public abstract class FactorArtifact
public abstract String getShortString(); public abstract String getShortString();
public abstract String getLongString(); public abstract String getLongString();
public void forget() {}
} }

View File

@ -46,7 +46,7 @@ public class FactorReader
/** /**
* Top level of parse tree. * Top level of parse tree.
*/ */
private FactorWord toplevel = new FactorWord(null,"#<EOF>"); private FactorWord toplevel = new FactorWord(null,null,"#<EOF>");
private boolean alwaysDocComments; private boolean alwaysDocComments;
private Cons use; private Cons use;

View File

@ -43,14 +43,18 @@ public class FactorWord extends FactorArtifact implements FactorExternalizable
*/ */
public FactorParsingDefinition parsing; public FactorParsingDefinition parsing;
private VocabularyLookup lookup;
/** /**
* For browsing, the parsing word that was used to define this word. * For browsing, the parsing word that was used to define this word.
*/ */
private FactorWord definer; private FactorWord definer;
//{{{ FactorWord constructor //{{{ FactorWord constructor
public FactorWord(String vocabulary, String name) public FactorWord(VocabularyLookup lookup,
String vocabulary, String name)
{ {
this.lookup = lookup;
this.vocabulary = vocabulary; this.vocabulary = vocabulary;
this.name = name; this.name = name;
} //}}} } //}}}
@ -65,7 +69,7 @@ public class FactorWord extends FactorArtifact implements FactorExternalizable
public FactorWord getDefiner() public FactorWord getDefiner()
{ {
if(definer == null) if(definer == null)
return new FactorWord(null,"DEFER:"); return new FactorWord(lookup,null,"DEFER:");
else else
return definer; return definer;
} //}}} } //}}}
@ -87,4 +91,15 @@ public class FactorWord extends FactorArtifact implements FactorExternalizable
{ {
return FactorWordRenderer.getWordHTMLString(this,false); return FactorWordRenderer.getWordHTMLString(this,false);
} //}}} } //}}}
//{{{ forget() method
public void forget()
{
/* Not allowed to forget parsing words, since that confuses our
parser */
if(parsing != null)
return;
lookup.forget(this);
} //}}}
} }

View File

@ -98,9 +98,9 @@ public class FactorSideKickParser extends SideKickParser
public SideKickParsedData parse(Buffer buffer, public SideKickParsedData parse(Buffer buffer,
DefaultErrorSource errorSource) DefaultErrorSource errorSource)
{ {
Object words = buffer.getProperty(ARTIFACTS_PROPERTY); Object artifacts = buffer.getProperty(ARTIFACTS_PROPERTY);
if(words instanceof Cons) if(artifacts instanceof Cons)
forgetWords((Cons)words); forgetArtifacts((Cons)artifacts);
FactorParsedData d = new FactorParsedData( FactorParsedData d = new FactorParsedData(
this,buffer.getPath()); this,buffer.getPath());
@ -157,17 +157,13 @@ public class FactorSideKickParser extends SideKickParser
return d; return d;
} //}}} } //}}}
//{{{ forgetWords() method //{{{ forgetArtifacts() method
private void forgetWords(Cons words) private void forgetArtifacts(Cons artifacts)
{ {
while(words != null) while(artifacts != null)
{ {
FactorWord word = (FactorWord)words.car; ((FactorArtifact)artifacts.car).forget();
// We're not allowed to forget parsing words. artifacts = artifacts.next();
if(word.parsing != null)
return;
FactorPlugin.getExternalInstance().forget(word);
words = words.next();
} }
} //}}} } //}}}

View File

@ -11,14 +11,21 @@ IN: lists USING: kernel ;
dup list? [ [ cons? ] all? ] [ drop f ] ifte ; dup list? [ [ cons? ] all? ] [ drop f ] ifte ;
: assoc* ( key alist -- [[ key value ]] ) : assoc* ( key alist -- [[ key value ]] )
#! Looks up the key in an alist. Push the key/value pair. #! Look up a key/value pair.
#! Most of the time you want to use assoc not assoc*.
[ car = ] some-with? dup [ car ] when ; [ car = ] some-with? dup [ car ] when ;
: assoc ( key alist -- value ) : assoc ( key alist -- value )
#! Looks up the key in an alist. #! Look up a value.
assoc* dup [ cdr ] when ; assoc* dup [ cdr ] when ;
: assq* ( key alist -- [[ key value ]] )
#! Looks up a key/value pair using identity comparison.
[ car eq? ] some-with? dup [ car ] when ;
: assq ( key alist -- value )
#! Looks up a key/value pair using identity comparison.
assq* dup [ cdr ] when ;
: remove-assoc ( key alist -- alist ) : remove-assoc ( key alist -- alist )
#! Remove all key/value pairs with this key. #! Remove all key/value pairs with this key.
[ car = not ] subset-with ; [ car = not ] subset-with ;

View File

@ -94,6 +94,7 @@ IN: alien : add-library 3drop ;
"/library/tools/profiler.factor" "/library/tools/profiler.factor"
"/library/tools/interpreter.factor" "/library/tools/interpreter.factor"
"/library/inference/conditions.factor"
"/library/inference/dataflow.factor" "/library/inference/dataflow.factor"
"/library/inference/inference.factor" "/library/inference/inference.factor"
"/library/inference/branches.factor" "/library/inference/branches.factor"

View File

@ -1,41 +1,8 @@
! :folding=indent:collapseFolds=1: ! Copyright (C) 2004, 2005 Slava Pestov.
! See http://factor.sf.net/license.txt for BSD license.
! $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: compiler IN: compiler
USE: assembler USING: assembler inference errors kernel lists math namespaces
USE: inference strings words vectors ;
USE: errors
USE: kernel
USE: lists
USE: math
USE: namespaces
USE: strings
USE: words
USE: vectors
! To support saving compiled code to disk, generator words ! To support saving compiled code to disk, generator words
! append relocation instructions to this vector. ! append relocation instructions to this vector.

View File

@ -1,41 +1,8 @@
! :folding=indent:collapseFolds=1: ! Copyright (C) 2004, 2005 Slava Pestov.
! See http://factor.sf.net/license.txt for BSD license.
! $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: compiler IN: compiler
USE: inference USING: inference kernel lists math namespaces words strings
USE: kernel errors prettyprint kernel-internals ;
USE: lists
USE: math
USE: namespaces
USE: words
USE: strings
USE: errors
USE: prettyprint
USE: kernel-internals
! The linear IR is close to assembly language. It also resembles ! The linear IR is close to assembly language. It also resembles
! Forth code in some sense. It exists so that pattern matching ! Forth code in some sense. It exists so that pattern matching
@ -49,6 +16,9 @@ SYMBOL: #push-indirect
SYMBOL: #replace-immediate SYMBOL: #replace-immediate
SYMBOL: #replace-indirect SYMBOL: #replace-indirect
SYMBOL: #jump-t ( branch if top of stack is true ) SYMBOL: #jump-t ( branch if top of stack is true )
SYMBOL: #jump-t-label ( branch if top of stack is true )
SYMBOL: #jump-f ( branch if top of stack is false )
SYMBOL: #jump-f-label ( branch if top of stack is false )
SYMBOL: #jump ( tail-call ) SYMBOL: #jump ( tail-call )
SYMBOL: #jump-label ( tail-call ) SYMBOL: #jump-label ( tail-call )
SYMBOL: #return-to ( push addr on C stack ) SYMBOL: #return-to ( push addr on C stack )
@ -133,7 +103,7 @@ SYMBOL: #end-dispatch
#! The parameter is a list of two lists, each one a dataflow #! The parameter is a list of two lists, each one a dataflow
#! IR. #! IR.
2unlist <label> [ 2unlist <label> [
#jump-t swons , #jump-t-label swons ,
(linearize) ( false branch ) (linearize) ( false branch )
<label> dup #jump-label swons , <label> dup #jump-label swons ,
] keep label, ( branch target of BRANCH-T ) ] keep label, ( branch target of BRANCH-T )

View File

@ -1,39 +1,8 @@
! :folding=indent:collapseFolds=1:
! $Id$
!
! Copyright (C) 2004, 2005 Slava Pestov. ! Copyright (C) 2004, 2005 Slava Pestov.
! ! See http://factor.sf.net/license.txt for BSD license.
! 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: compiler IN: compiler
USE: kernel USING: kernel lists namespaces words inference strings
USE: lists prettyprint ;
USE: namespaces
USE: words
USE: inference
USE: strings
USE: strings
USE: prettyprint
! The linear IR being simplified is stored in this variable. ! The linear IR being simplified is stored in this variable.
SYMBOL: simplifying SYMBOL: simplifying
@ -144,7 +113,7 @@ SYMBOL: simplifying
: double-jump ( linear op1 op2 -- linear ? ) : double-jump ( linear op1 op2 -- linear ? )
#! A jump to a jump is just a jump. If the next logical node #! A jump to a jump is just a jump. If the next logical node
#! is a jump of type op1, replace the jump at the car of the #! is a jump of type op1, replace the jump at the car of the
#! list with a just of type op2. #! list with a jump of type op2.
swap pick next-logical? [ swap pick next-logical? [
over next-logical car cdr cons swap cdr cons t over next-logical car cdr cons swap cdr cons t
] [ ] [

View File

@ -40,12 +40,34 @@ math memory namespaces words ;
compile-jump-label compile-jump-label
] "generator" set-word-property ] "generator" set-word-property
#jump-t [ : compile-jump-t ( word -- )
POP-DS POP-DS
! condition is now in EAX ! condition is now in EAX
EAX f address CMP EAX f address CMP
! jump w/ address added later ! jump w/ address added later
0 JNE fixup compiled-offset defer-xt 0 JNE fixup compiled-offset defer-xt ;
#jump-t-label [
compile-jump-t
] "generator" set-word-property
#jump-t [
dup compile-jump-t t rel-word
] "generator" set-word-property
: compile-jump-f ( word -- )
POP-DS
! condition is now in EAX
EAX f address CMP
! jump w/ address added later
0 JE fixup compiled-offset defer-xt ;
#jump-f-label [
compile-jump-f
] "generator" set-word-property
#jump-f [
dup compile-jump-f t rel-word
] "generator" set-word-property ] "generator" set-word-property
#return-to [ #return-to [

View File

@ -50,7 +50,7 @@ strings vectors words hashtables prettyprint ;
dup balanced? [ dup balanced? [
unzip unify-stacks >r unify-stacks r> unzip unify-stacks >r unify-stacks r>
] [ ] [
"Unbalanced branches" throw "Unbalanced branches" inference-error
] ifte ; ] ifte ;
: datastack-effect ( list -- ) : datastack-effect ( list -- )
@ -79,7 +79,7 @@ SYMBOL: cloned
: deep-clone ( obj -- obj ) : deep-clone ( obj -- obj )
#! Clone an object if it hasn't already been cloned in this #! Clone an object if it hasn't already been cloned in this
#! with-deep-clone scope. #! with-deep-clone scope.
dup cloned get assoc [ dup cloned get assq [
clone [ dup cloned [ acons ] change ] keep clone [ dup cloned [ acons ] change ] keep
] ?unless ; ] ?unless ;
@ -146,10 +146,10 @@ SYMBOL: cloned
#! parameter is a vector. #! parameter is a vector.
(infer-branches) dup unify-effects unify-dataflow ; (infer-branches) dup unify-effects unify-dataflow ;
: (with-block) ( label quot -- node ) : (with-block) ( [[ label quot ]] quot -- node )
#! Call a quotation in a new namespace, and transfer #! Call a quotation in a new namespace, and transfer
#! inference state from the outer scope. #! inference state from the outer scope.
swap >r [ swap car >r [
dataflow-graph off dataflow-graph off
call call
d-in get meta-d get meta-r get get-dataflow d-in get meta-d get meta-r get get-dataflow

View File

@ -0,0 +1,36 @@
! Copyright (C) 2004, 2005 Slava Pestov.
! See http://factor.sf.net/license.txt for BSD license.
IN: inference
USING: errors interpreter kernel lists namespaces prettyprint
stdio ;
DEFER: recursive-state
: inference-condition ( msg symbol -- )
[
, , recursive-state get , meta-d get , meta-r get ,
] make-list ;
: inference-error ( msg -- )
\ inference-error inference-condition throw ;
: inference-warning ( msg -- )
\ inference-warning inference-condition error. ;
: inference-condition. ( cond msg -- )
write
cdr unswons error.
"Recursive state:" print
car [.] ;
! "Meta data stack:" print
! unswons {.}
! "Meta return stack:" print
! car {.} ;
PREDICATE: cons inference-error car \ inference-error = ;
M: inference-error error. ( error -- )
"Inference error: " inference-condition. ;
PREDICATE: cons inference-warning car \ inference-warning = ;
M: inference-warning error. ( error -- )
"Inference warning: " inference-condition. ;

View File

@ -1,43 +1,8 @@
! :folding=indent:collapseFolds=1:
! $Id$
!
! Copyright (C) 2004, 2005 Slava Pestov. ! Copyright (C) 2004, 2005 Slava Pestov.
! ! See http://factor.sf.net/license.txt for BSD license.
! 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: inference IN: inference
USE: errors USING: generic interpreter kernel lists math namespaces strings
USE: interpreter unparser vectors words ;
USE: kernel
USE: lists
USE: math
USE: namespaces
USE: strings
USE: vectors
USE: words
USE: hashtables
USE: generic
USE: prettyprint
: max-recursion 0 ; : max-recursion 0 ;
@ -77,8 +42,20 @@ C: computed ( class -- value )
M: computed value= ( literal value -- ? ) M: computed value= ( literal value -- ? )
2drop f ; 2drop f ;
: failing-class-and
2dup class-and dup null = [
drop [
word-name , " and " , word-name ,
" do not intersect" ,
] make-string inference-error
] [
2nip
] ifte ;
M: computed value-class-and ( class value -- ) M: computed value-class-and ( class value -- )
[ value-class class-and ] keep set-value-class ; [
value-class failing-class-and
] keep set-value-class ;
TUPLE: literal value delegate ; TUPLE: literal value delegate ;
@ -98,6 +75,10 @@ M: literal value-class-and ( class value -- )
M: literal set-value-class ( class value -- ) M: literal set-value-class ( class value -- )
2drop ; 2drop ;
M: computed literal-value ( value -- )
"A literal value was expected where a computed value was"
" found: " rot unparse cat3 inference-error ;
: (ensure-types) ( typelist n stack -- ) : (ensure-types) ( typelist n stack -- )
pick [ pick [
3dup >r >r car r> r> vector-nth value-class-and 3dup >r >r car r> r> vector-nth value-class-and
@ -191,7 +172,7 @@ DEFER: apply-word
: check-return ( -- ) : check-return ( -- )
#! Raise an error if word leaves values on return stack. #! Raise an error if word leaves values on return stack.
meta-r get vector-length 0 = [ meta-r get vector-length 0 = [
"Word leaves elements on return stack" throw "Word leaves elements on return stack" inference-error
] unless ; ] unless ;
: values-node ( op -- ) : values-node ( op -- )

View File

@ -41,9 +41,9 @@ strings vectors words hashtables parser prettyprint ;
] ifte* ; ] ifte* ;
: no-effect ( word -- ) : no-effect ( word -- )
"Unknown stack effect: " swap word-name cat2 throw ; "Unknown stack effect: " swap word-name cat2 inference-error ;
: with-block ( word label quot -- node ) : with-block ( word [[ label quot ]] quot -- node )
#! Execute a quotation with the word on the stack, and add #! Execute a quotation with the word on the stack, and add
#! its dataflow contribution to a new block node in the IR. #! its dataflow contribution to a new block node in the IR.
over [ over [
@ -60,7 +60,9 @@ strings vectors words hashtables parser prettyprint ;
#! Infer the stack effect of a compound word in the current #! Infer the stack effect of a compound word in the current
#! inferencer instance. If the word in question is recursive #! inferencer instance. If the word in question is recursive
#! we infer its stack effect inside a new block. #! we infer its stack effect inside a new block.
gensym [ word-parameter infer-quot effect ] with-block ; gensym over word-parameter cons [
word-parameter infer-quot effect
] with-block ;
: infer-compound ( word -- ) : infer-compound ( word -- )
#! Infer a word's stack effect in a separate inferencer #! Infer a word's stack effect in a separate inferencer
@ -83,6 +85,10 @@ strings vectors words hashtables parser prettyprint ;
GENERIC: (apply-word) GENERIC: (apply-word)
M: object (apply-word) ( word -- )
#! A primitive with an unknown stack effect.
no-effect ;
M: compound (apply-word) ( word -- ) M: compound (apply-word) ( word -- )
#! Infer a compound word's stack effect. #! Infer a compound word's stack effect.
dup "no-effect" word-property [ dup "no-effect" word-property [
@ -110,9 +116,9 @@ M: symbol (apply-word) ( word -- )
rethrow rethrow
] catch ; ] catch ;
: base-case ( word label -- ) : base-case ( word [ label quot ] -- )
[ [
over inline-compound [ car over inline-compound [
drop drop
[ #call-label ] [ #call ] ?ifte [ #call-label ] [ #call ] ?ifte
node-op set node-op set
@ -121,9 +127,9 @@ M: symbol (apply-word) ( word -- )
] with-recursion ; ] with-recursion ;
: no-base-case ( word -- ) : no-base-case ( word -- )
word-name " does not have a base case." cat2 throw ; word-name " does not have a base case." cat2 inference-error ;
: recursive-word ( word label -- ) : recursive-word ( word [ label quot ] -- )
#! Handle a recursive call, by either applying a previously #! Handle a recursive call, by either applying a previously
#! inferred base case, or raising an error. If the recursive #! inferred base case, or raising an error. If the recursive
#! call is to a local block, emit a label call node. #! call is to a local block, emit a label call node.
@ -152,11 +158,10 @@ M: symbol (apply-word) ( word -- )
: infer-call ( -- ) : infer-call ( -- )
[ general-list ] ensure-d [ general-list ] ensure-d
dataflow-drop, dataflow-drop,
gensym dup [ pop-d gensym dup pick literal-value cons [
drop pop-d dup drop
value-recursion recursive-state set dup value-recursion recursive-state set
literal-value literal-value dup infer-quot
dup infer-quot
] with-block drop handle-terminator ; ] with-block drop handle-terminator ;
\ call [ infer-call ] "infer" set-word-property \ call [ infer-call ] "infer" set-word-property

View File

@ -1,14 +1,12 @@
IN: scratchpad IN: scratchpad
USE: kernel USING: generic kernel lists math memory words ;
USE: math
USE: memory
USE: generic
USE: lists
num-types [ num-types [
[ [
builtin-type instances [ builtin-type [
"predicate" word-property instances [
class drop class drop
] each ] each
] when*
] keep ] keep
] repeat ] repeat

View File

@ -47,7 +47,7 @@ C: quuux-tuple-2
100 200 <point> 100 200 <point>
! Use eval to sequence parsing explicitly ! Use eval to sequence parsing explicitly
"TUPLE: point y x ;" eval "TUPLE: point x y z ;" eval
point-x point-x
] unit-test ] unit-test