inlining method body if type of object passed to generic is known

cvs
Slava Pestov 2005-02-25 01:52:17 +00:00
parent e376755fda
commit 4f3457efb6
28 changed files with 215 additions and 151 deletions

View File

@ -7,7 +7,6 @@
- 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
- optimize away dispatch
- code gc - code gc
- 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
@ -15,6 +14,7 @@
- more accurate types for various words - more accurate types for various words
- declarations - declarations
- write read: write should flush - write read: write should flush
- optimize away arithmetic dispatch
+ compiler/ffi: + compiler/ffi:

View File

@ -21,9 +21,18 @@ IN: kernel
#! restore a and b after the quotation returns. #! restore a and b after the quotation returns.
over >r pick >r call r> r> ; inline over >r pick >r call r> r> ; inline
: apply ( code input -- code output ) : while ( quot generator -- )
#! Apply code to input. #! Keep applying the quotation to the value produced by
swap dup >r call r> swap ; inline #! calling the generator until the generator returns f.
2dup >r >r swap >r call dup [
r> call r> r> while
] [
r> 2drop r> r> 2drop
] ifte ; inline
: apply ( code input -- code )
#! A utility word for recursive combinators.
swap dup slip ; inline
: ifte* ( cond true false -- ) : ifte* ( cond true false -- )
#! If the condition is not f, execute the 'true' quotation, #! If the condition is not f, execute the 'true' quotation,

View File

@ -11,19 +11,19 @@ BUILTIN: cons 2 [ 0 "car" f ] [ 1 "cdr" f ] ;
: swons ( cdr car -- [[ car cdr ]] ) : swons ( cdr car -- [[ car cdr ]] )
#! Push a new cons cell. If the cdr is f or a proper list, #! Push a new cons cell. If the cdr is f or a proper list,
#! has the effect of prepending the car to the cdr. #! has the effect of prepending the car to the cdr.
swap cons ; inline swap cons ;
: uncons ( [[ car cdr ]] -- car cdr ) : uncons ( [[ car cdr ]] -- car cdr )
#! Push both the head and tail of a list. #! Push both the head and tail of a list.
dup car swap cdr ; inline dup car swap cdr ;
: unit ( a -- [ a ] ) : unit ( a -- [ a ] )
#! Construct a proper list of one element. #! Construct a proper list of one element.
f cons ; inline f cons ;
: unswons ( [[ car cdr ]] -- cdr car ) : unswons ( [[ car cdr ]] -- cdr car )
#! Push both the head and tail of a list. #! Push both the head and tail of a list.
dup cdr swap car ; inline dup cdr swap car ;
: 2car ( cons cons -- car car ) : 2car ( cons cons -- car car )
swap car swap car ; swap car swap car ;

View File

@ -1,12 +1,16 @@
! Copyright (C) 2004, 2005 Slava Pestov. ! Copyright (C) 2004, 2005 Slava Pestov.
! See http://factor.sf.net/license.txt for BSD license. ! See http://factor.sf.net/license.txt for BSD license.
IN: kernel DEFER: callcc1 IN: kernel DEFER: callcc1
IN: errors USING: kernel-internals lists namespaces ; IN: streams DEFER: line-number
IN: parser DEFER: file
IN: errors USING: kernel-internals lists namespaces streams ;
TUPLE: undefined-method object generic ;
: undefined-method ( object generic -- ) : undefined-method ( object generic -- )
#! This word is redefined in tools/debugger.factor with a #! We 2dup here to leave both values on the stack, for
#! more useful definition once unparse is available. #! post-mortem inspection.
"No suitable method" throw ; 2dup <undefined-method> throw ;
! This is a very lightweight exception handling system. ! This is a very lightweight exception handling system.
@ -22,8 +26,8 @@ IN: errors USING: kernel-internals lists namespaces ;
namespace [ namespace [
"col" get "col" get
"line" get "line" get
"line-number" get line-number get
"file" get file get
global [ global [
"error-file" set "error-file" set
"error-line-number" set "error-line-number" set

View File

@ -92,11 +92,17 @@ namespaces parser strings words vectors math math-internals ;
: single-combination ( obj vtable -- ) : single-combination ( obj vtable -- )
>r dup type r> dispatch ; inline >r dup type r> dispatch ; inline
PREDICATE: compound generic ( word -- ? )
"combination" word-property [ single-combination ] = ;
: arithmetic-combination ( n n vtable -- ) : arithmetic-combination ( n n vtable -- )
#! Note that the numbers remain on the stack, possibly after #! Note that the numbers remain on the stack, possibly after
#! being coerced to a maximal type. #! being coerced to a maximal type.
>r arithmetic-type r> dispatch ; inline >r arithmetic-type r> dispatch ; inline
PREDICATE: compound 2generic ( word -- ? )
"combination" word-property [ arithmetic-combination ] = ;
! Maps lists of builtin type numbers to class objects. ! Maps lists of builtin type numbers to class objects.
SYMBOL: classes SYMBOL: classes

View File

@ -44,7 +44,7 @@ IN: hashtables
dup hash-size 1 - swap set-hash-size ; dup hash-size 1 - swap set-hash-size ;
: bucket-count ( hash -- n ) : bucket-count ( hash -- n )
hash-array array-capacity ; inline hash-array array-capacity ;
: (hashcode) ( key table -- index ) : (hashcode) ( key table -- index )
#! Compute the index of the bucket for a key. #! Compute the index of the bucket for a key.

View File

@ -150,6 +150,23 @@ SYMBOL: cloned
r> swap #label dataflow, [ node-label set ] extend >r r> swap #label dataflow, [ node-label set ] extend >r
meta-r set meta-d set d-in set r> ; meta-r set meta-d set d-in set r> ;
: with-block ( word [[ label quot ]] quot -- node )
#! Execute a quotation with the word on the stack, and add
#! its dataflow contribution to a new block node in the IR.
over [
>r
dupd cons
recursive-state cons@
r> call
] (with-block) ;
: infer-quot-value ( value -- )
gensym dup pick literal-value cons [
drop
dup value-recursion recursive-state set
literal-value dup infer-quot
] with-block drop handle-terminator ;
: boolean-value? ( value -- ? ) : boolean-value? ( value -- ? )
#! Return if the value's boolean valuation is known. #! Return if the value's boolean valuation is known.
value-class value-class
@ -170,10 +187,7 @@ SYMBOL: cloned
#! If the branch taken is statically known, just infer #! If the branch taken is statically known, just infer
#! along that branch. #! along that branch.
dataflow-drop, pop-d boolean-value [ drop ] [ nip ] ifte dataflow-drop, pop-d boolean-value [ drop ] [ nip ] ifte
gensym [ infer-quot-value ;
dup value-recursion recursive-state set
literal-value infer-quot
] (with-block) drop ;
: dynamic-ifte ( true false -- ) : dynamic-ifte ( true false -- )
#! If branch taken is computed, infer along both paths and #! If branch taken is computed, infer along both paths and
@ -207,16 +221,32 @@ SYMBOL: cloned
0 recursive-state get <literal> 0 recursive-state get <literal>
[ set-value-literal-ties ] keep ; [ set-value-literal-ties ] keep ;
: static-dispatch? ( -- )
peek-d literal? branches-can-fail? not and ;
USE: kernel-internals USE: kernel-internals
: infer-dispatch ( -- )
#! Infer effects for all branches, unify. : static-dispatch ( vtable -- )
[ object vector ] ensure-d >r dataflow-drop, pop-d literal-value r>
dataflow-drop, pop-d vtable>list dup literal-value swap value-recursion
>r vector-nth r> <literal> infer-quot-value ;
: dynamic-dispatch ( vtable -- )
>r 1 meta-d get vector-tail* \ dispatch r> >r 1 meta-d get vector-tail* \ dispatch r>
vtable>list
pop-d <dispatch-index> pop-d <dispatch-index>
over length [ <literal-tie> ] project-with over length [ <literal-tie> ] project-with
zip infer-branches ; zip infer-branches ;
: infer-dispatch ( -- )
#! Infer effects for all branches, unify.
[ object vector ] ensure-d
dataflow-drop, pop-d static-dispatch? [
static-dispatch
] [
dynamic-dispatch
] ifte ;
\ dispatch [ infer-dispatch ] "infer" set-word-property \ dispatch [ infer-dispatch ] "infer" set-word-property
\ dispatch [ [ fixnum vector ] [ ] ] \ dispatch [ [ fixnum vector ] [ ] ]
"infer-effect" set-word-property "infer-effect" set-word-property

View File

@ -27,7 +27,11 @@ M: inference-error error. ( error -- )
"Inference error: " inference-condition. ; "Inference error: " inference-condition. ;
: inference-warning ( msg -- ) : inference-warning ( msg -- )
\ inference-warning inference-condition error. ; "inference-warnings" get [
\ inference-warning inference-condition error.
] [
drop
] ifte ;
PREDICATE: cons inference-warning car \ inference-warning = ; PREDICATE: cons inference-warning car \ inference-warning = ;
M: inference-warning error. ( error -- ) M: inference-warning error. ( error -- )

View File

@ -121,9 +121,6 @@ M: computed literal-value ( value -- )
#! After inference is finished, collect information. #! After inference is finished, collect information.
uncons vector-length >r vector-length r> cons ; uncons vector-length >r vector-length r> cons ;
: effect ( -- [[ d-in meta-d ]] )
d-in get meta-d get cons ;
: init-inference ( recursive-state -- ) : init-inference ( recursive-state -- )
init-interpreter init-interpreter
0 <vector> d-in set 0 <vector> d-in set
@ -131,7 +128,7 @@ M: computed literal-value ( value -- )
dataflow-graph off dataflow-graph off
0 inferring-base-case set ; 0 inferring-base-case set ;
DEFER: apply-word GENERIC: apply-object
: apply-literal ( obj -- ) : apply-literal ( obj -- )
#! Literals are annotated with the current recursive #! Literals are annotated with the current recursive
@ -139,14 +136,20 @@ DEFER: apply-word
dup recursive-state get <literal> push-d dup recursive-state get <literal> push-d
#push dataflow, [ 1 0 node-outputs ] bind ; #push dataflow, [ 1 0 node-outputs ] bind ;
: apply-object ( obj -- ) M: object apply-object apply-literal ;
#! Apply the object's stack effect to the inferencer state.
dup word? [ apply-word ] [ apply-literal ] ifte ;
: active? ( -- ? ) : active? ( -- ? )
#! Is this branch not terminated? #! Is this branch not terminated?
d-in get meta-d get and ; d-in get meta-d get and ;
: check-active ( -- )
active? [
"Provable runtime error" inference-error
] unless ;
: effect ( -- [[ d-in meta-d ]] )
d-in get meta-d get cons ;
: terminate ( -- ) : terminate ( -- )
#! Ignore this branch's stack effect. #! Ignore this branch's stack effect.
meta-d off meta-r off d-in off ; meta-d off meta-r off d-in off ;
@ -184,6 +187,7 @@ DEFER: apply-word
: (infer) ( quot -- ) : (infer) ( quot -- )
f init-inference f init-inference
infer-quot infer-quot
check-active
#return values-node check-return ; #return values-node check-return ;
: infer ( quot -- [[ in out ]] ) : infer ( quot -- [[ in out ]] )

View File

@ -17,6 +17,7 @@ lists math namespaces strings vectors words stdio prettyprint ;
\ slot [ [ object ] [ object ] ] (consume/produce) ; \ slot [ [ object ] [ object ] ] (consume/produce) ;
: computed-slot ( -- ) : computed-slot ( -- )
"Computed slot access is slower" inference-warning
\ slot dup "infer-effect" word-property consume/produce ; \ slot dup "infer-effect" word-property consume/produce ;
\ slot [ \ slot [
@ -29,8 +30,11 @@ lists math namespaces strings vectors words stdio prettyprint ;
[ tuck builtin-type <class-tie> cons ] project-with [ tuck builtin-type <class-tie> cons ] project-with
[ cdr class-tie-class ] subset ; [ cdr class-tie-class ] subset ;
\ type [ : literal-type ( -- )
[ object ] ensure-d dataflow-drop, pop-d value-class builtin-supertypes car
apply-literal ;
: computed-type ( -- )
\ type #call dataflow, [ \ type #call dataflow, [
peek-d type-value-map >r peek-d type-value-map >r
1 0 node-inputs 1 0 node-inputs
@ -38,5 +42,9 @@ lists math namespaces strings vectors words stdio prettyprint ;
[ fixnum ] produce-d [ fixnum ] produce-d
r> peek-d set-value-literal-ties r> peek-d set-value-literal-ties
1 0 node-outputs 1 0 node-outputs
] bind ] bind ;
\ type [
[ object ] ensure-d
literal-type? [ literal-type ] [ computed-type ] ifte
] "infer" set-word-property ] "infer" set-word-property

View File

@ -29,30 +29,9 @@ strings vectors words hashtables parser prettyprint ;
#! produces a number of values. #! produces a number of values.
#call swap (consume/produce) ; #call swap (consume/produce) ;
: apply-effect ( word [ in-types out-types ] -- )
#! If a word does not have special inference behavior, we
#! either execute the word in the meta interpreter (if it is
#! side-effect-free and all parameters are literal), or
#! simply apply its stack effect to the meta-interpreter.
over "infer" word-property [
swap car ensure-d call drop
] [
consume/produce
] ifte* ;
: no-effect ( word -- ) : no-effect ( word -- )
"Unknown stack effect: " swap word-name cat2 inference-error ; "Unknown stack effect: " swap word-name cat2 inference-error ;
: with-block ( word [[ label quot ]] quot -- node )
#! Execute a quotation with the word on the stack, and add
#! its dataflow contribution to a new block node in the IR.
over [
>r
dupd cons
recursive-state cons@
r> call
] (with-block) ;
: recursive? ( word -- ? ) : recursive? ( word -- ? )
dup word-parameter tree-contains? ; dup word-parameter tree-contains? ;
@ -93,20 +72,54 @@ 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 [
no-effect no-effect
] [
dup "inline" word-property [
inline-compound 2drop
] [ ] [
infer-compound infer-compound
] ifte
] ifte ; ] ifte ;
M: promise (apply-word) ( word -- )
"promise" word-property unit ensure-d ;
M: symbol (apply-word) ( word -- ) M: symbol (apply-word) ( word -- )
apply-literal ; apply-literal ;
GENERIC: apply-word
: apply-default ( word -- )
dup "infer-effect" word-property [
over "infer" word-property [
swap car ensure-d call drop
] [
consume/produce
] ifte*
] [
(apply-word)
] ifte* ;
M: word apply-word ( word -- )
apply-default ;
M: compound apply-word ( word -- )
dup "inline" word-property [
inline-compound 2drop
] [
apply-default
] ifte ;
: literal-type? ( -- ? )
peek-d value-class builtin-supertypes
dup length 1 = >r [ tuple ] = not r> and ;
: dynamic-dispatch-warning ( word -- )
"Dynamic dispatch for " swap word-name cat2
inference-warning ;
M: generic apply-word ( word -- )
#! If the type of the value at the top of the stack is
#! known, inline the method body.
[ object ] ensure-d
literal-type? branches-can-fail? not and [
inline-compound 2drop
] [
dup dynamic-dispatch-warning apply-default
] ifte ;
: with-recursion ( quot -- ) : with-recursion ( quot -- )
[ [
inferring-base-case inc inferring-base-case inc
@ -143,32 +156,24 @@ M: symbol (apply-word) ( word -- )
] ifte ] ifte
] ifte ; ] ifte ;
: apply-word ( word -- ) M: word apply-object ( word -- )
#! Apply the word's stack effect to the inferencer state. #! Apply the word's stack effect to the inferencer state.
dup recursive-state get assoc [ dup recursive-state get assoc [
recursive-word recursive-word
] [ ] [
dup "infer-effect" word-property [ apply-word
apply-effect
] [
(apply-word)
] ifte*
] ifte* ; ] ifte* ;
: infer-call ( -- ) : infer-call ( -- )
[ general-list ] ensure-d [ general-list ] ensure-d
dataflow-drop, dataflow-drop, pop-d infer-quot-value ;
pop-d gensym dup pick literal-value cons [
drop
dup value-recursion recursive-state set
literal-value dup infer-quot
] with-block drop handle-terminator ;
\ call [ infer-call ] "infer" set-word-property \ call [ infer-call ] "infer" set-word-property
! These hacks will go away soon ! These hacks will go away soon
\ * [ [ number number ] [ number ] ] "infer-effect" set-word-property \ * [ [ number number ] [ number ] ] "infer-effect" set-word-property
\ - [ [ number number ] [ number ] ] "infer-effect" set-word-property \ - [ [ number number ] [ number ] ] "infer-effect" set-word-property
\ + [ [ number number ] [ number ] ] "infer-effect" set-word-property
\ = [ [ object object ] [ object ] ] "infer-effect" set-word-property \ = [ [ object object ] [ object ] ] "infer-effect" set-word-property
\ undefined-method t "terminator" set-word-property \ undefined-method t "terminator" set-word-property

View File

@ -3,7 +3,7 @@
IN: stdio IN: stdio
DEFER: stdio DEFER: stdio
IN: streams IN: streams
USING: errors kernel namespaces strings generic lists ; USING: errors generic kernel lists math namespaces strings ;
GENERIC: stream-flush ( stream -- ) GENERIC: stream-flush ( stream -- )
GENERIC: stream-auto-flush ( stream -- ) GENERIC: stream-auto-flush ( stream -- )
@ -53,3 +53,19 @@ C: wrapper-stream ( stream -- stream )
>r <namespace> [ stdio set ] extend r> >r <namespace> [ stdio set ] extend r>
set-wrapper-stream-scope set-wrapper-stream-scope
] keep ; ] keep ;
SYMBOL: line-number
SYMBOL: parser-stream
: next-line ( -- str )
parser-stream get stream-readln
line-number [ 1 + ] change ;
: read-lines ( stream quot -- )
#! Apply a quotation to each line as its read. Close the
#! stream.
swap [
parser-stream set 0 line-number set [ next-line ] while
] [
parser-stream get stream-close rethrow
] catch ;

View File

@ -9,7 +9,7 @@ USING: generic kernel kernel-internals math ;
: (rect>) ( xr xi -- x ) : (rect>) ( xr xi -- x )
#! Does not perform a check that the arguments are reals. #! Does not perform a check that the arguments are reals.
#! Do not use in your own code. #! Do not use in your own code.
dup 0 number= [ drop ] [ <complex> ] ifte ; inline dup 0 number= [ drop ] [ <complex> ] ifte ;
IN: math IN: math
@ -28,7 +28,7 @@ M: number = ( n n -- ? ) number= ;
"Complex number must have real components" throw drop "Complex number must have real components" throw drop
] ifte ; ] ifte ;
: >rect ( x -- xr xi ) dup real swap imaginary ; inline : >rect ( x -- xr xi ) dup real swap imaginary ;
: conjugate ( z -- z* ) : conjugate ( z -- z* )
>rect neg rect> ; >rect neg rect> ;
@ -65,8 +65,8 @@ IN: math-internals
M: complex number= ( x y -- ? ) M: complex number= ( x y -- ? )
2>rect number= [ number= ] [ 2drop f ] ifte ; 2>rect number= [ number= ] [ 2drop f ] ifte ;
: *re ( x y -- xr*yr xi*ri ) 2>rect * >r * r> ; inline : *re ( x y -- xr*yr xi*ri ) 2>rect * >r * r> ;
: *im ( x y -- xi*yr xr*yi ) 2>rect >r * swap r> * ; inline : *im ( x y -- xi*yr xr*yi ) 2>rect >r * swap r> * ;
M: complex + 2>rect + >r + r> (rect>) ; M: complex + 2>rect + >r + r> (rect>) ;
M: complex - 2>rect - >r - r> (rect>) ; M: complex - 2>rect - >r - r> (rect>) ;
@ -74,7 +74,7 @@ M: complex * ( x y -- x*y ) 2dup *re - -rot *im + (rect>) ;
: complex/ ( x y -- r i m ) : complex/ ( x y -- r i m )
#! r = xr*yr+xi*yi, i = xi*yr-xr*yi, m = yr*yr+yi*yi #! r = xr*yr+xi*yi, i = xi*yr-xr*yi, m = yr*yr+yi*yi
dup absq >r 2dup *re + -rot *im - r> ; inline dup absq >r 2dup *re + -rot *im - r> ;
M: complex / ( x y -- x/y ) complex/ tuck / >r / r> (rect>) ; M: complex / ( x y -- x/y ) complex/ tuck / >r / r> (rect>) ;
M: complex /f ( x y -- x/y ) complex/ tuck /f >r /f r> (rect>) ; M: complex /f ( x y -- x/y ) complex/ tuck /f >r /f r> (rect>) ;

View File

@ -13,7 +13,7 @@ USING: errors generic kernel math ;
drop drop
] [ ] [
(fraction>) (fraction>)
] ifte ; inline ] ifte ;
: division-by-zero ( x y -- ) : division-by-zero ( x y -- )
"Division by zero" throw drop ; "Division by zero" throw drop ;

View File

@ -40,10 +40,10 @@ GENERIC: bitnot ( n -- n )
#! by swapping them. #! by swapping them.
2dup > [ swap ] when >r dupd max r> min = ; 2dup > [ swap ] when >r dupd max r> min = ;
: sq dup * ; inline : sq dup * ;
: neg 0 swap - ; inline : neg 0 swap - ;
: recip 1 swap / ; inline : recip 1 swap / ;
: rem ( x y -- x%y ) : rem ( x y -- x%y )
#! Like modulus, but always gives a positive result. #! Like modulus, but always gives a positive result.

View File

@ -30,7 +30,7 @@ strings vectors ;
: namespace ( -- namespace ) : namespace ( -- namespace )
#! Push the current namespace. #! Push the current namespace.
namestack car ; inline namestack car ;
: >n ( namespace -- n:namespace ) : >n ( namespace -- n:namespace )
#! Push a namespace on the namespace stack. #! Push a namespace on the namespace stack.

View File

@ -19,7 +19,7 @@ IN: strings USING: kernel lists math namespaces strings ;
#! push a new string constructed from return values. #! push a new string constructed from return values.
#! The quotation must have stack effect ( X -- X ). #! The quotation must have stack effect ( X -- X ).
over str-length <sbuf> rot [ over str-length <sbuf> rot [
swap >r apply r> tuck sbuf-append swap >r apply swap r> tuck sbuf-append
] str-each nip sbuf>str ; inline ] str-each nip sbuf>str ; inline
: split-next ( index string split -- next ) : split-next ( index string split -- next )

View File

@ -36,29 +36,7 @@ USE: streams
USE: strings USE: strings
! Stream parsing uses a number of variables: ! Stream parsing uses a number of variables:
! file SYMBOL: file
! line-number
! parse-stream
: next-line ( -- str )
"parse-stream" get stream-readln
"line-number" [ 1 + ] change ;
: (read-lines) ( quot -- )
next-line dup [
swap dup >r call r> (read-lines)
] [
2drop
] ifte ;
: read-lines ( stream quot -- )
#! Apply a quotation to each line as its read. Close the
#! stream.
swap [
"parse-stream" set 0 "line-number" set (read-lines)
] [
"parse-stream" get stream-close rethrow
] catch ;
: file-vocabs ( -- ) : file-vocabs ( -- )
"file-in" get "in" set "file-in" get "in" set
@ -66,10 +44,10 @@ USE: strings
: (parse-stream) ( name stream -- quot ) : (parse-stream) ( name stream -- quot )
#! Uses the current namespace for temporary variables. #! Uses the current namespace for temporary variables.
>r "file" set f ( initial parse tree ) r> >r file set f ( initial parse tree ) r>
[ (parse) ] read-lines reverse [ (parse) ] read-lines reverse
"file" off file off
"line-number" off ; line-number off ;
: parse-stream ( name stream -- quot ) : parse-stream ( name stream -- quot )
[ file-vocabs (parse-stream) ] with-scope ; [ file-vocabs (parse-stream) ] with-scope ;

View File

@ -1,7 +1,7 @@
! Copyright (C) 2005 Slava Pestov. ! Copyright (C) 2005 Slava Pestov.
! See http://factor.sf.net/license.txt for BSD license. ! See http://factor.sf.net/license.txt for BSD license.
IN: parser IN: parser
USING: errors kernel lists math namespaces strings words USING: errors kernel lists math namespaces streams strings words
unparser ; unparser ;
! The parser uses a number of variables: ! The parser uses a number of variables:
@ -109,9 +109,9 @@ global [ string-mode off ] bind
: save-location ( word -- ) : save-location ( word -- )
#! Remember where this word was defined. #! Remember where this word was defined.
dup set-word dup set-word
dup "line-number" get "line" set-word-property dup line-number get "line" set-word-property
dup "col" get "col" set-word-property dup "col" get "col" set-word-property
"file" get "file" set-word-property ; file get "file" set-word-property ;
: create-in "in" get create ; : create-in "in" get create ;

View File

@ -107,13 +107,19 @@ M: compound see ( word -- )
prettyprint-; prettyprint-;
terpri ; terpri ;
M: generic see ( word -- ) : see-generic ( word definer -- )
dup prettyprint-IN: >r dup prettyprint-IN:
0 swap 0 swap
dup "definer" word-property prettyprint-word " " write r> prettyprint-word " " write
dup prettyprint-word terpri dup prettyprint-word terpri
dup methods [ over >r uncons see-method r> ] each 2drop ; dup methods [ over >r uncons see-method r> ] each 2drop ;
M: generic see ( word -- )
\ GENERIC: see-generic ;
M: 2generic see ( word -- )
\ 2GENERIC: see-generic ;
M: primitive see ( word -- ) M: primitive see ( word -- )
dup prettyprint-IN: dup prettyprint-IN:
"PRIMITIVE: " write dup prettyprint-word stack-effect. "PRIMITIVE: " write dup prettyprint-word stack-effect.

View File

@ -16,7 +16,7 @@ USE: math-internals
[ 9227465 ] [ 34 fixnum-fib ] unit-test [ 9227465 ] [ 34 fixnum-fib ] unit-test
: fib ( n -- nth fibonacci number ) : fib ( n -- nth fibonacci number )
dup 1 <= [ drop 1 ] [ 1 - dup fib swap 1 - fib + ] ifte ; dup 1 <= [ drop 1 ] [ dup 1 - fib swap 2 - fib + ] ifte ;
compiled compiled
[ 9227465 ] [ 34 fib ] unit-test [ 9227465 ] [ 34 fib ] unit-test

View File

@ -219,6 +219,14 @@ SYMBOL: sym-test
[ [ [ object ] [ general-t ] ] ] [ [ dup [ drop t ] unless ] infer ] unit-test [ [ [ object ] [ general-t ] ] ] [ [ dup [ drop t ] unless ] infer ] unit-test
[ [ [ cons ] [ cons ] ] ] [ [ uncons cons ] infer ] unit-test [ [ [ cons ] [ cons ] ] ] [ [ uncons cons ] infer ] unit-test
[ [ [ general-list ] [ object ] ] ] [ [ dup [ car ] when ] infer ] unit-test [ [ [ general-list ] [ object ] ] ] [ [ dup [ car ] when ] infer ] unit-test
[ [ 5 car ] infer ] unit-test-fails
GENERIC: potential-hang
M: fixnum potential-hang dup [ potential-hang ] when ;
[ ] [ [ 5 potential-hang ] infer drop ] unit-test
! [ [ [ number ] [ number ] ] ] [ [ dup + ] infer ] unit-test ! [ [ [ number ] [ number ] ] ] [ [ dup + ] infer ] unit-test
! [ [ [ number number number ] [ number ] ] ] [ [ digit+ ] infer ] unit-test ! [ [ [ number number number ] [ number ] ] ] [ [ digit+ ] infer ] unit-test
! [ [ [ number ] [ real real ] ] ] [ [ >rect ] infer ] unit-test ! [ [ [ number ] [ real real ] ] ] [ [ >rect ] infer ] unit-test

View File

@ -141,15 +141,13 @@ M: object error. ( error -- )
[ dup save-error rethrow ] 5 setenv ( kernel calls on error ) [ dup save-error rethrow ] 5 setenv ( kernel calls on error )
kernel-error 12 setenv ; kernel-error 12 setenv ;
: undefined-method ( object generic -- ) M: undefined-method error. ( error -- )
#! We 2dup here to leave both values on the stack, for [
#! post-mortem inspection.
2dup [
"The generic word " , "The generic word " ,
unparse , dup undefined-method-generic unparse ,
" does not have a suitable method for " , " does not have a suitable method for " ,
unparse , undefined-method-object unparse ,
] make-string throw ; ] make-string print ;
! So that stage 2 boot gives a useful error message if something ! So that stage 2 boot gives a useful error message if something
! fails after this file is loaded. ! fails after this file is loaded.

View File

@ -21,17 +21,11 @@ namespaces prettyprint stdio unparser vectors words ;
! Some words for iterating through the heap. ! Some words for iterating through the heap.
: (each-object) ( quot -- )
next-object dup [
swap dup slip (each-object)
] [
2drop
] ifte ;
: each-object ( quot -- ) : each-object ( quot -- )
#! Applies the quotation to each object in the image. #! Applies the quotation to each object in the image.
[ [
begin-scan (each-object) begin-scan
[ next-object ] while
] [ ] [
end-scan rethrow end-scan rethrow
] catch ; ] catch ;

View File

@ -13,9 +13,15 @@ M: compound word-uses? ( of in -- ? )
] [ ] [
word-parameter tree-contains? word-parameter tree-contains?
] ifte ; ] ifte ;
M: generic word-uses? ( of in -- ? )
: generic-uses? ( of in -- ? )
"methods" word-property hash>alist tree-contains? ; "methods" word-property hash>alist tree-contains? ;
M: generic word-uses? ( of in -- ? )
generic-uses? ;
M: 2generic word-uses? ( of in -- ? )
generic-uses? ;
: usages-in-vocab ( of vocab -- usages ) : usages-in-vocab ( of vocab -- usages )
#! Push a list of all usages of a word in a vocabulary. #! Push a list of all usages of a word in a vocabulary.
words [ words [

View File

@ -27,7 +27,7 @@ IN: kernel-internals
: grow-capacity ( len vec -- ) : grow-capacity ( len vec -- )
#! If the vector cannot accomodate len elements, resize it #! If the vector cannot accomodate len elements, resize it
#! to exactly len. #! to exactly len.
[ vector-array grow-array ] keep set-vector-array ; inline [ vector-array grow-array ] keep set-vector-array ;
: ensure-capacity ( n vec -- ) : ensure-capacity ( n vec -- )
#! If n is beyond the vector's length, increase the length, #! If n is beyond the vector's length, increase the length,
@ -41,7 +41,7 @@ IN: kernel-internals
(set-vector-length) (set-vector-length)
] [ ] [
2drop 2drop
] ifte ; inline ] ifte ;
: copy-array ( to from n -- ) : copy-array ( to from n -- )
[ 3dup swap array-nth pick rot set-array-nth ] repeat 2drop ; [ 3dup swap array-nth pick rot set-array-nth ] repeat 2drop ;
@ -95,7 +95,7 @@ IN: vectors
#! vector with the results. The code must have stack effect #! vector with the results. The code must have stack effect
#! ( obj -- obj ). #! ( obj -- obj ).
over vector-length <vector> rot [ over vector-length <vector> rot [
swap >r apply r> tuck vector-push swap >r apply swap r> tuck vector-push
] vector-each nip ; inline ] vector-each nip ; inline
: vector-nappend ( v1 v2 -- ) : vector-nappend ( v1 v2 -- )

View File

@ -43,15 +43,6 @@ PREDICATE: word primitive ( obj -- ? ) word-primitive 2 > ;
PREDICATE: word symbol ( obj -- ? ) word-primitive 2 = ; PREDICATE: word symbol ( obj -- ? ) word-primitive 2 = ;
PREDICATE: word undefined ( obj -- ? ) word-primitive 0 = ; PREDICATE: word undefined ( obj -- ? ) word-primitive 0 = ;
! These should really be somewhere in library/generic/, but
! during bootstrap, we cannot execute parsing words after they
! are defined by code loaded into the target image.
PREDICATE: compound generic ( word -- ? )
"combination" word-property ;
PREDICATE: compound promise ( obj -- ? )
"promise" word-property ;
: define ( word primitive parameter -- ) : define ( word primitive parameter -- )
pick set-word-parameter pick set-word-parameter
over set-word-primitive over set-word-primitive

View File

@ -126,9 +126,6 @@ void primitive_gc(void)
gc_in_progress = true; gc_in_progress = true;
fprintf(stderr,"GC\n");
fflush(stderr);
flip_zones(); flip_zones();
scan = active.base; scan = active.base;
collect_roots(); collect_roots();