inlining method body if type of object passed to generic is known
parent
e376755fda
commit
4f3457efb6
|
@ -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:
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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 ;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 -- )
|
||||||
|
|
|
@ -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 ]] )
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 ;
|
||||||
|
|
|
@ -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>) ;
|
||||||
|
|
|
@ -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 ;
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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 )
|
||||||
|
|
|
@ -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 ;
|
||||||
|
|
|
@ -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 ;
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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 ;
|
||||||
|
|
|
@ -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 [
|
||||||
|
|
|
@ -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 -- )
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue