start dataflow optimizer
parent
ec849514bb
commit
00195a2d2b
|
@ -1,35 +1,40 @@
|
|||
[error] AWT-EventQueue-0: java.lang.NullPointerException
|
||||
[error] AWT-EventQueue-0: at org.gjt.sp.jedit.Buffer.markTokens(Buffer.java:2109)
|
||||
[error] AWT-EventQueue-0: at factor.jedit.WordPreview.getWordAtCaret(WordPreview.java:95)
|
||||
[error] AWT-EventQueue-0: at factor.jedit.WordPreview.showPreview(WordPreview.java:137)
|
||||
[error] AWT-EventQueue-0: at factor.jedit.WordPreview.actionPerformed(WordPreview.java:79)
|
||||
[error] AWT-EventQueue-0: at javax.swing.Timer.fireActionPerformed(Timer.java:271)
|
||||
|
||||
|
||||
+ inference/interpreter:
|
||||
[error] AWT-EventQueue-0: java.lang.NullPointerException
|
||||
[error] AWT-EventQueue-0: at org.gjt.sp.jedit.Buffer.markTokens(Buffer.java:2109)
|
||||
[error] AWT-EventQueue-0: at factor.jedit.WordPreview.getWordAtCaret(WordPreview.java:95)
|
||||
[error] AWT-EventQueue-0: at factor.jedit.WordPreview.showPreview(WordPreview.java:137)
|
||||
[error] AWT-EventQueue-0: at factor.jedit.WordPreview.actionPerformed(WordPreview.java:79)
|
||||
[error] AWT-EventQueue-0: at javax.swing.Timer.fireActionPerformed(Timer.java:271)
|
||||
|
||||
+ inference/dataflow:
|
||||
|
||||
- combinator inference
|
||||
- type inference
|
||||
- some way to step over a word in the stepper
|
||||
- step: print NEXT word to execute, not word that JUST executed
|
||||
- handle odd base cases, with code after ifte
|
||||
- handle recursion with when, when* etc
|
||||
- lifting
|
||||
- stack ops and alien-call need special nodes
|
||||
|
||||
+ compiler/ffi:
|
||||
+ linearizer/generator:
|
||||
|
||||
- compiling when*
|
||||
- compiling each, etc.
|
||||
- peephole optimizer
|
||||
- linearize generic, 2generic
|
||||
- generate conditionals
|
||||
- generator needs to be aware of labels
|
||||
- getenv/setenv: if literal arg, compile as a load/store
|
||||
- inline words
|
||||
- compiler: drop literal peephole optimization
|
||||
|
||||
+ compiler frontend:
|
||||
|
||||
- assembler opcodes dispatch on operand types
|
||||
- save code in image
|
||||
- compile word twice; no more 'cannot compile' error!
|
||||
|
||||
+ ffi:
|
||||
|
||||
- is signed -vs- unsigned pointers an issue?
|
||||
- bitfields in C structs
|
||||
- SDL_Rect** type
|
||||
- struct membres that are not *
|
||||
- FFI float types
|
||||
- compile word twice; no more 'cannot compile' error!
|
||||
- perhaps /i should work with all numbers
|
||||
- assembler opcodes dispatch on operand types
|
||||
- lifting
|
||||
- save code in image
|
||||
|
||||
+ listener/plugin:
|
||||
|
||||
|
@ -57,6 +62,9 @@
|
|||
|
||||
+ misc:
|
||||
|
||||
- some way to step over a word in the stepper
|
||||
- step: print NEXT word to execute, not word that JUST executed
|
||||
- perhaps /i should work with all numbers
|
||||
- unit test weirdness: 2 lines appears at end
|
||||
- jedit ==> jedit-word, jedit takes a file name
|
||||
- command line parsing cleanup
|
||||
|
|
|
@ -385,6 +385,7 @@ public class FactorPlugin extends EditPlugin
|
|||
Buffer buffer = view.getBuffer();
|
||||
int lastUseOffset = 0;
|
||||
boolean leadingNewline = false;
|
||||
boolean seenUse = false;
|
||||
|
||||
for(int i = 0; i < buffer.getLineCount(); i++)
|
||||
{
|
||||
|
@ -393,13 +394,14 @@ public class FactorPlugin extends EditPlugin
|
|||
{
|
||||
lastUseOffset = buffer.getLineEndOffset(i) - 1;
|
||||
leadingNewline = true;
|
||||
seenUse = true;
|
||||
}
|
||||
else if(text.startsWith("!"))
|
||||
else if(text.startsWith("!") && !seenUse)
|
||||
{
|
||||
lastUseOffset = buffer.getLineEndOffset(i) - 1;
|
||||
leadingNewline = true;
|
||||
}
|
||||
else if(text.length() == 0)
|
||||
else if(text.length() == 0 && !seenUse)
|
||||
{
|
||||
if(i == 0)
|
||||
lastUseOffset = 0;
|
||||
|
|
|
@ -113,6 +113,7 @@ USE: stdio
|
|||
"/library/inference/branches.factor"
|
||||
"/library/inference/stack.factor"
|
||||
|
||||
"/library/compiler/optimizer.factor"
|
||||
"/library/compiler/linearizer.factor"
|
||||
"/library/compiler/assembler.factor"
|
||||
"/library/compiler/xt.factor"
|
||||
|
|
|
@ -27,12 +27,10 @@
|
|||
|
||||
IN: compiler
|
||||
USE: combinators
|
||||
USE: dataflow
|
||||
USE: inference
|
||||
USE: errors
|
||||
USE: generator
|
||||
USE: hashtables
|
||||
USE: kernel
|
||||
USE: linearizer
|
||||
USE: lists
|
||||
USE: logic
|
||||
USE: math
|
||||
|
|
|
@ -25,14 +25,12 @@
|
|||
! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
IN: generator
|
||||
IN: compiler
|
||||
USE: alien
|
||||
USE: combinators
|
||||
USE: compiler
|
||||
USE: dataflow
|
||||
USE: inference
|
||||
USE: errors
|
||||
USE: kernel
|
||||
USE: linearizer
|
||||
USE: lists
|
||||
USE: logic
|
||||
USE: math
|
||||
|
|
|
@ -25,12 +25,10 @@
|
|||
! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
IN: generator
|
||||
IN: compiler
|
||||
USE: combinators
|
||||
USE: compiler
|
||||
USE: dataflow
|
||||
USE: inference
|
||||
USE: errors
|
||||
USE: linearizer
|
||||
USE: lists
|
||||
USE: math
|
||||
USE: namespaces
|
||||
|
|
|
@ -25,12 +25,12 @@
|
|||
! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
IN: linearizer
|
||||
IN: compiler
|
||||
USE: lists
|
||||
USE: words
|
||||
USE: stack
|
||||
USE: namespaces
|
||||
USE: dataflow
|
||||
USE: inference
|
||||
USE: combinators
|
||||
|
||||
! Linear IR nodes. This is in addition to the symbols already
|
||||
|
@ -40,7 +40,6 @@ SYMBOL: #branch-t ( branch if top of stack is true )
|
|||
SYMBOL: #branch ( unconditional branch )
|
||||
SYMBOL: #label ( branch target )
|
||||
SYMBOL: #jump ( tail-call )
|
||||
SYMBOL: #return ( return to caller )
|
||||
|
||||
: linear, ( param op -- )
|
||||
swons , ;
|
||||
|
@ -49,12 +48,7 @@ SYMBOL: #return ( return to caller )
|
|||
#! Dataflow OPs have a linearizer word property. This
|
||||
#! quotation is executed to convert the node into linear
|
||||
#! form.
|
||||
[ node-param get node-op get ] bind
|
||||
dup "linearizer" word-property dup [
|
||||
nip call
|
||||
] [
|
||||
drop linear,
|
||||
] ifte ;
|
||||
"linearizer" [ drop linear, ] apply-dataflow ;
|
||||
|
||||
: (linearize) ( dataflow -- )
|
||||
[ >linear ] each ;
|
||||
|
@ -85,4 +79,4 @@ SYMBOL: #return ( return to caller )
|
|||
swap (linearize) ( true branch )
|
||||
label, ( branch target of false branch end ) ;
|
||||
|
||||
\ #ifte [ linearize-ifte ] "linearizer" set-word-property
|
||||
#ifte [ linearize-ifte ] "linearizer" set-word-property
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
! :folding=indent:collapseFolds=1:
|
||||
|
||||
! $Id$
|
||||
!
|
||||
! Copyright (C) 2004 Slava Pestov.
|
||||
!
|
||||
! Redistribution and use in source and binary forms, with or without
|
||||
! modification, are permitted provided that the following conditions are met:
|
||||
!
|
||||
! 1. Redistributions of source code must retain the above copyright notice,
|
||||
! this list of conditions and the following disclaimer.
|
||||
!
|
||||
! 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
! this list of conditions and the following disclaimer in the documentation
|
||||
! and/or other materials provided with the distribution.
|
||||
!
|
||||
! THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
! INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
! FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
! DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
! SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
! PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
! OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
! WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
IN: compiler
|
||||
USE: lists
|
||||
USE: stack
|
||||
USE: combinators
|
||||
USE: namespaces
|
||||
USE: kernel
|
||||
USE: inference
|
||||
USE: words
|
||||
USE: prettyprint
|
||||
USE: logic
|
||||
|
||||
! The optimizer transforms dataflow IR to dataflow IR. Currently
|
||||
! it simply removes literals that are eventually dropped, and
|
||||
! never arise as inputs to any other type of function. Such
|
||||
! 'dead' literals arise when combinators are inlined and
|
||||
! quotations are lifted to their call sites.
|
||||
|
||||
: scan-literal ( node -- )
|
||||
"scan-literal" [ 2drop ] apply-dataflow ;
|
||||
|
||||
: scan-literals ( dataflow -- list )
|
||||
[ [ scan-literal ] each ] make-list ;
|
||||
|
||||
: scan-branches ( branches -- )
|
||||
[ [ scan-literal ] each ] each ;
|
||||
|
||||
: mentions-literal? ( literal list -- )
|
||||
#! Does the given list of result objects refer to this
|
||||
#! literal?
|
||||
[ dup cons? [ car over = ] [ drop f ] ifte ] some? ;
|
||||
|
||||
: (can-kill?) ( literal node -- ? )
|
||||
#! Return false if the literal appears as input to this
|
||||
#! node, and this node is not a stack operation.
|
||||
[
|
||||
node-consume-d get mentions-literal? swap
|
||||
node-consume-r get mentions-literal? nip or not
|
||||
] bind ;
|
||||
|
||||
: can-kill? ( literal dataflow -- ? )
|
||||
[ dupd (can-kill?) ] all? nip ;
|
||||
|
||||
: kill-set ( dataflow -- list )
|
||||
#! Push a list of literals that may be killed in the IR.
|
||||
dup scan-literals [ over can-kill? ] subset nip ;
|
||||
|
||||
#push [ , ] "scan-literal" set-word-property
|
||||
#ifte [ scan-branches ] "scan-literal" set-word-property
|
||||
#generic [ scan-branches ] "scan-literal" set-word-property
|
||||
#2generic [ scan-branches ] "scan-literal" set-word-property
|
|
@ -27,12 +27,10 @@
|
|||
|
||||
IN: compiler
|
||||
USE: combinators
|
||||
USE: dataflow
|
||||
USE: inference
|
||||
USE: errors
|
||||
USE: generator
|
||||
USE: hashtables
|
||||
USE: kernel
|
||||
USE: linearizer
|
||||
USE: lists
|
||||
USE: logic
|
||||
USE: math
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
|
||||
IN: inference
|
||||
USE: combinators
|
||||
USE: dataflow
|
||||
USE: errors
|
||||
USE: interpreter
|
||||
USE: kernel
|
||||
|
@ -50,7 +49,7 @@ USE: hashtables
|
|||
[
|
||||
copy-interpreter
|
||||
dataflow-graph off
|
||||
(infer)
|
||||
infer-quot
|
||||
branch-effect
|
||||
] with-scope ;
|
||||
|
||||
|
|
|
@ -25,8 +25,7 @@
|
|||
! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
IN: dataflow
|
||||
USE: inference
|
||||
IN: inference
|
||||
USE: interpreter
|
||||
USE: lists
|
||||
USE: math
|
||||
|
@ -46,6 +45,8 @@ SYMBOL: #ifte
|
|||
SYMBOL: #generic
|
||||
SYMBOL: #2generic
|
||||
|
||||
SYMBOL: #return
|
||||
|
||||
SYMBOL: node-consume-d
|
||||
SYMBOL: node-produce-d
|
||||
SYMBOL: node-consume-r
|
||||
|
@ -60,10 +61,10 @@ SYMBOL: node-param
|
|||
<namespace> [
|
||||
node-op set
|
||||
node-param set
|
||||
{ } node-consume-d set
|
||||
{ } node-produce-d set
|
||||
{ } node-consume-r set
|
||||
{ } node-produce-r set
|
||||
[ ] node-consume-d set
|
||||
[ ] node-produce-d set
|
||||
[ ] node-consume-r set
|
||||
[ ] node-produce-r set
|
||||
] extend ;
|
||||
|
||||
: node-inputs ( d-count r-count -- )
|
||||
|
@ -93,3 +94,16 @@ SYMBOL: node-param
|
|||
#! Remove the top stack element and add a dataflow node
|
||||
#! noting this.
|
||||
\ drop #call dataflow, [ 1 0 node-inputs ] bind ;
|
||||
|
||||
: apply-dataflow ( dataflow name default -- )
|
||||
#! For the dataflow node, look up named word property,
|
||||
#! if its not defined, apply default quotation to
|
||||
#! ( param op ) otherwise apply property quotation to
|
||||
#! ( param ).
|
||||
>r >r [ node-param get node-op get ] bind dup r>
|
||||
word-property dup [
|
||||
( param op property )
|
||||
nip call r> drop
|
||||
] [
|
||||
drop r> call
|
||||
] ifte ;
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
|
||||
IN: inference
|
||||
USE: combinators
|
||||
USE: dataflow
|
||||
USE: errors
|
||||
USE: interpreter
|
||||
USE: kernel
|
||||
|
@ -116,7 +115,7 @@ DEFER: apply-word
|
|||
#! Apply the object's stack effect to the inferencer state.
|
||||
dup word? [ apply-word ] [ apply-literal ] ifte ;
|
||||
|
||||
: (infer) ( quot -- )
|
||||
: infer-quot ( quot -- )
|
||||
#! Recursive calls to this word are made for nested
|
||||
#! quotations.
|
||||
[ apply-object ] each ;
|
||||
|
@ -145,16 +144,26 @@ DEFER: apply-word
|
|||
2drop
|
||||
] ifte ;
|
||||
|
||||
: return-node ( -- )
|
||||
#! Add a #return node to the dataflow graph.
|
||||
f #return dataflow, [
|
||||
meta-d get vector>list node-consume-d set
|
||||
meta-r get vector-length 0 = [
|
||||
"Word leaves elements on return stack" throw
|
||||
] unless
|
||||
] bind ;
|
||||
|
||||
: (infer) ( quot -- )
|
||||
f init-inference infer-quot return-node ;
|
||||
|
||||
: infer ( quot -- [ in | out ] )
|
||||
#! Stack effect of a quotation.
|
||||
[ f init-inference (infer) effect ] with-scope ;
|
||||
[ (infer) effect ] with-scope ;
|
||||
|
||||
: try-infer ( quot -- effect/f )
|
||||
#! Push f if inference fails.
|
||||
[ infer ] [ [ drop f ] when ] catch ;
|
||||
|
||||
IN: dataflow
|
||||
|
||||
: dataflow ( quot -- dataflow )
|
||||
#! Data flow of a quotation.
|
||||
[ f init-inference (infer) get-dataflow ] with-scope ;
|
||||
[ (infer) get-dataflow ] with-scope ;
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
IN: inference
|
||||
USE: dataflow
|
||||
USE: interpreter
|
||||
USE: stack
|
||||
USE: words
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
|
||||
IN: inference
|
||||
USE: combinators
|
||||
USE: dataflow
|
||||
USE: errors
|
||||
USE: interpreter
|
||||
USE: kernel
|
||||
|
@ -73,7 +72,7 @@ USE: prettyprint
|
|||
: inline-compound ( word -- effect )
|
||||
#! Infer the stack effect of a compound word in the current
|
||||
#! inferencer instance.
|
||||
[ word-parameter (infer) effect ] with-recursive-state ;
|
||||
[ word-parameter infer-quot effect ] with-recursive-state ;
|
||||
|
||||
: (infer-compound) ( word -- effect )
|
||||
#! Infer a word's stack effect in a separate inferencer
|
||||
|
@ -152,7 +151,7 @@ USE: prettyprint
|
|||
\ drop #call dataflow, drop
|
||||
[
|
||||
dataflow-graph off
|
||||
pop-d uncons recursive-state set (infer)
|
||||
pop-d uncons recursive-state set infer-quot
|
||||
d-in get meta-d get get-dataflow
|
||||
] with-scope
|
||||
[ dataflow-graph cons@ ] each meta-d set d-in set ;
|
||||
|
|
|
@ -77,6 +77,3 @@ SYMBOL: list-buffer
|
|||
#! Append an object to the currently constructing list, only
|
||||
#! if the object does not already occur in the list.
|
||||
list-buffer unique@ ;
|
||||
|
||||
: count ( n -- [ 0 ... n-1 ] )
|
||||
[ [ , ] times* ] make-list ;
|
||||
|
|
|
@ -252,3 +252,13 @@ DEFER: tree-contains?
|
|||
|
||||
: vector>list ( vector -- list )
|
||||
stack>list reverse ;
|
||||
|
||||
: project ( n quot -- list )
|
||||
#! Execute the quotation n times, passing the loop counter
|
||||
#! the quotation as it ranges from 0..n-1. Collect results
|
||||
#! in a new list.
|
||||
[ ] rot [ -rot over >r >r call r> cons r> swap ] times*
|
||||
nip reverse ; inline
|
||||
|
||||
: count ( n -- [ 0 ... n-1 ] )
|
||||
[ ] project ;
|
||||
|
|
|
@ -7,11 +7,11 @@ USE: logic
|
|||
USE: combinators
|
||||
USE: hashtables
|
||||
USE: stack
|
||||
USE: dataflow
|
||||
USE: kernel
|
||||
USE: vectors
|
||||
USE: namespaces
|
||||
USE: prettyprint
|
||||
USE: words
|
||||
|
||||
: dataflow-contains-op? ( object list -- ? )
|
||||
#! Check if some dataflow node contains a given operation.
|
||||
|
@ -37,10 +37,10 @@ USE: prettyprint
|
|||
] unit-test
|
||||
|
||||
: dataflow-consume-d-len ( object -- n )
|
||||
[ node-consume-d get vector-length ] bind ;
|
||||
[ node-consume-d get length ] bind ;
|
||||
|
||||
: dataflow-produce-d-len ( object -- n )
|
||||
[ node-produce-d get vector-length ] bind ;
|
||||
[ node-produce-d get length ] bind ;
|
||||
|
||||
[ t ] [ [ drop ] dataflow car dataflow-consume-d-len 1 = ] unit-test
|
||||
|
||||
|
@ -51,7 +51,7 @@ USE: prettyprint
|
|||
|
||||
[ t ] [
|
||||
[ 2 [ swap ] [ nip "hi" ] ifte ] dataflow
|
||||
dataflow-ifte-node-consume-d vector-length 1 =
|
||||
dataflow-ifte-node-consume-d length 1 =
|
||||
] unit-test
|
||||
|
||||
[ t ] [
|
||||
|
@ -62,3 +62,23 @@ USE: prettyprint
|
|||
] some?
|
||||
] bind >boolean
|
||||
] unit-test
|
||||
|
||||
SYMBOL: #test
|
||||
|
||||
#test f "foobar" set-word-property
|
||||
|
||||
[ 6 ] [
|
||||
{{
|
||||
[ node-op | #test ]
|
||||
[ node-param | 5 ]
|
||||
}} "foobar" [ drop succ ] apply-dataflow
|
||||
] unit-test
|
||||
|
||||
#test [ sq ] "foobar" set-word-property
|
||||
|
||||
[ 25 ] [
|
||||
{{
|
||||
[ node-op | #test ]
|
||||
[ node-param | 5 ]
|
||||
}} "foobar" [ drop succ ] apply-dataflow
|
||||
] unit-test
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
IN: scratchpad
|
||||
USE: test
|
||||
USE: compiler
|
||||
USE: inference
|
||||
USE: words
|
||||
|
||||
: foo 1 2 3 ;
|
||||
|
||||
[ [ ] ] [ \ foo word-parameter dataflow kill-set ] unit-test
|
|
@ -113,6 +113,7 @@ USE: unparser
|
|||
"parsing-word"
|
||||
"inference"
|
||||
"dataflow"
|
||||
"optimizer"
|
||||
"interpreter"
|
||||
] [
|
||||
test
|
||||
|
|
|
@ -53,9 +53,9 @@ unit-test
|
|||
[ { 1 2 3 4 } { 5 6 7 8 } vector-zip ]
|
||||
unit-test
|
||||
|
||||
[ { } ] [ 0 { } vector-tail ] unit-test
|
||||
[ { } ] [ 2 { 1 2 } vector-tail ] unit-test
|
||||
[ { 3 4 } ] [ 2 { 1 2 3 4 } vector-tail ] unit-test
|
||||
[ 2 { } vector-tail ] unit-test-fails
|
||||
[ [ ] ] [ 0 { } vector-tail ] unit-test
|
||||
[ [ ] ] [ 2 { 1 2 } vector-tail ] unit-test
|
||||
[ [ 3 4 ] ] [ 2 { 1 2 3 4 } vector-tail ] unit-test
|
||||
[ 2 [ ] vector-tail ] unit-test-fails
|
||||
|
||||
[ { 3 } ] [ 1 { 1 2 3 } vector-tail* ] unit-test
|
||||
[ [ 3 ] ] [ 1 { 1 2 3 } vector-tail* ] unit-test
|
||||
|
|
|
@ -74,17 +74,6 @@ DEFER: vector-map
|
|||
#! Reached end?
|
||||
drop vector-length number= ;
|
||||
|
||||
: (vector=) ( n vec vec -- ? )
|
||||
3dup ?vector= [
|
||||
3drop t ( reached end without any unequal elts )
|
||||
] [
|
||||
3dup 2vector-nth = [
|
||||
>r >r succ r> r> (vector=)
|
||||
] [
|
||||
3drop f
|
||||
] ifte
|
||||
] ifte ;
|
||||
|
||||
: vector-length= ( vec vec -- ? )
|
||||
vector-length swap vector-length number= ;
|
||||
|
||||
|
@ -97,7 +86,7 @@ DEFER: vector-map
|
|||
] [
|
||||
over vector? [
|
||||
2dup vector-length= [
|
||||
0 -rot (vector=)
|
||||
swap vector>list swap vector>list =
|
||||
] [
|
||||
2drop f
|
||||
] ifte
|
||||
|
@ -114,14 +103,14 @@ DEFER: vector-map
|
|||
over ?vector-nth hashcode rot bitxor swap
|
||||
] times* drop ;
|
||||
|
||||
: vector-tail ( n vector -- vector )
|
||||
: vector-tail ( n vector -- list )
|
||||
#! Return a new vector, with all elements from the nth
|
||||
#! index upwards.
|
||||
2dup vector-length swap - [
|
||||
pick + over vector-nth
|
||||
] vector-project nip nip ;
|
||||
] project nip nip ;
|
||||
|
||||
: vector-tail* ( n vector -- vector )
|
||||
: vector-tail* ( n vector -- list )
|
||||
#! Unlike vector-tail, n is an index from the end of the
|
||||
#! vector. For example, if n=1, this returns a vector of
|
||||
#! one element.
|
||||
|
|
Loading…
Reference in New Issue