compiling mutually recursive words
parent
2c2d33d6e9
commit
564a8ad46c
|
|
@ -1,6 +1,8 @@
|
||||||
FFI:
|
FFI:
|
||||||
- is signed -vs- unsigned pointers an issue?
|
- is signed -vs- unsigned pointers an issue?
|
||||||
|
|
||||||
|
- symbols are not primitives
|
||||||
|
|
||||||
[error] SideKick$BufferChangeHandler: We have cplusplus.xml (/home/slava/jEdit/modes/) but got event for DefaultInputHandler.java (/home/slava/jEdit/org/gjt/sp/jedit/gui/)
|
[error] SideKick$BufferChangeHandler: We have cplusplus.xml (/home/slava/jEdit/modes/) but got event for DefaultInputHandler.java (/home/slava/jEdit/org/gjt/sp/jedit/gui/)
|
||||||
[error] SideKick$BufferChangeHandler: We have cplusplus.xml (/home/slava/jEdit/modes/) but got event for DefaultInputHandler.java (/home/slava/jEdit/org/gjt/sp/jedit/gui/)
|
[error] SideKick$BufferChangeHandler: We have cplusplus.xml (/home/slava/jEdit/modes/) but got event for DefaultInputHandler.java (/home/slava/jEdit/org/gjt/sp/jedit/gui/)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
SOME NOTES ON FACTOR'S FFI
|
||||||
|
|
||||||
|
The FFI is quite a neat design and I think it is better than JNI and
|
||||||
|
similar approaches. Also, it offers better performance than libffi et
|
||||||
|
al. Of course, both of those technologies are great and Factor FFI has
|
||||||
|
its drawbacks -- namely, its not portable.
|
||||||
|
|
||||||
|
All FFI words are in the "alien" vocabulary.
|
||||||
|
|
||||||
|
The basic principle is generating machine stubs from C function
|
||||||
|
prototypes. The main entry point is the 'alien-call' word, which is
|
||||||
|
defined as simply throwing an error. However, it is given special
|
||||||
|
compilation behavior. This means it can only be used in compiled words.
|
||||||
|
|
||||||
|
Here is an example from sdl-video.factor:
|
||||||
|
|
||||||
|
: SDL_LockSurface ( surface -- )
|
||||||
|
"int" "sdl" "SDL_LockSurface" [ "surface*" ] alien-call ; compiled
|
||||||
|
|
||||||
|
The parameters are:
|
||||||
|
|
||||||
|
"int" - return type. later it will be surface*
|
||||||
|
"sdl" - library
|
||||||
|
"SDL_LockSurface" - function
|
||||||
|
[ "surface*" ] - parameters
|
||||||
|
|
||||||
|
Note the word ends with 'compiled'. This is a hack and won't be needed
|
||||||
|
later.
|
||||||
|
|
||||||
|
Parameters and return values are C type names. C types include the
|
||||||
|
following:
|
||||||
|
|
||||||
|
- char - 1 byte signed
|
||||||
|
- short - 2 bytes signed
|
||||||
|
- int - 4 bytes signed
|
||||||
|
- void* - word-size width field, can only be used as a parameter
|
||||||
|
|
||||||
|
Structs can be defined in this fashion:
|
||||||
|
|
||||||
|
BEGIN-STRUCT: point
|
||||||
|
FIELD: int x
|
||||||
|
FIELD: int y
|
||||||
|
END-STRUCT
|
||||||
|
|
||||||
|
And then referred to in parameter type specifiers as "point*". Struct
|
||||||
|
return values are not yet supported.
|
||||||
|
|
||||||
|
Enumerations can be defined; they simply become words that push
|
||||||
|
integers:
|
||||||
|
|
||||||
|
BEGIN-ENUM: 0
|
||||||
|
ENUM: int xuzzy
|
||||||
|
ENUM: int bax
|
||||||
|
END-ENUM
|
||||||
|
|
||||||
|
The parameter to BEGIN-ENUM specifies the starting index.
|
||||||
|
|
@ -36,14 +36,14 @@ USE: stack
|
||||||
|
|
||||||
: UNBOX ( name -- )
|
: UNBOX ( name -- )
|
||||||
#! Move top of datastack to C stack.
|
#! Move top of datastack to C stack.
|
||||||
dlsym-self CALL drop
|
dlsym-self CALL JUMP-FIXUP
|
||||||
EAX PUSH-R ;
|
EAX PUSH-R ;
|
||||||
|
|
||||||
: BOX ( name -- )
|
: BOX ( name -- )
|
||||||
#! Move EAX to datastack.
|
#! Move EAX to datastack.
|
||||||
24 ESP R-I
|
24 ESP R-I
|
||||||
EAX PUSH-R
|
EAX PUSH-R
|
||||||
dlsym-self CALL drop
|
dlsym-self CALL JUMP-FIXUP
|
||||||
28 ESP R+I ;
|
28 ESP R+I ;
|
||||||
|
|
||||||
: PARAMETERS ( params -- count )
|
: PARAMETERS ( params -- count )
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ USE: stack
|
||||||
USE: words
|
USE: words
|
||||||
|
|
||||||
: BEGIN-ENUM:
|
: BEGIN-ENUM:
|
||||||
#! C-style enumartions. Their use is not encouraged unless
|
#! C-style enumerations. Their use is not encouraged unless
|
||||||
#! it is for C library interfaces. Used like this:
|
#! it is for C library interfaces. Used like this:
|
||||||
#!
|
#!
|
||||||
#! BEGIN-ENUM 0
|
#! BEGIN-ENUM 0
|
||||||
|
|
@ -69,11 +69,11 @@ USE: words
|
||||||
|
|
||||||
: compile-alien-call
|
: compile-alien-call
|
||||||
pop-literal reverse PARAMETERS >r
|
pop-literal reverse PARAMETERS >r
|
||||||
pop-literal pop-literal alien-function CALL drop
|
pop-literal pop-literal alien-function CALL JUMP-FIXUP
|
||||||
r> CLEANUP
|
r> CLEANUP
|
||||||
pop-literal RETURNS ;
|
pop-literal RETURNS ;
|
||||||
|
|
||||||
global [ <namespace> "libraries" set ] bind
|
global [ <namespace> "libraries" set ] bind
|
||||||
|
|
||||||
[ alien-call compile-alien-call ]
|
[ alien-call compile-alien-call ]
|
||||||
unswons "compiling" swap set-word-property
|
unswons "compiling" set-word-property
|
||||||
|
|
|
||||||
|
|
@ -147,23 +147,23 @@ USE: combinators
|
||||||
compile-cell
|
compile-cell
|
||||||
] ifte ;
|
] ifte ;
|
||||||
|
|
||||||
: fixup ( addr where -- )
|
: JUMP-FIXUP ( addr where -- )
|
||||||
#! Encode a relative offset to addr from where at where.
|
#! Encode a relative offset to addr from where at where.
|
||||||
#! Add 4 because addr is relative to *after* insn.
|
#! Add 4 because addr is relative to *after* insn.
|
||||||
dup >r 4 + - r> set-compiled-cell ;
|
dup >r 4 + - r> set-compiled-cell ;
|
||||||
|
|
||||||
: (JUMP) ( xt -- fixup )
|
: (JUMP) ( xt -- fixup )
|
||||||
#! addr is relative to *after* insn
|
#! addr is relative to *after* insn
|
||||||
compiled-offset dup >r 4 + - compile-cell r> ;
|
compiled-offset 0 compile-cell ;
|
||||||
|
|
||||||
: JUMP ( xt -- fixup )
|
: JUMP ( -- fixup )
|
||||||
#! Push address of branch for fixup
|
#! Push address of branch for fixup
|
||||||
HEX: e9 compile-byte (JUMP) ;
|
HEX: e9 compile-byte (JUMP) ;
|
||||||
|
|
||||||
: CALL ( xt -- fixup )
|
: CALL ( -- fixup )
|
||||||
HEX: e8 compile-byte (JUMP) ;
|
HEX: e8 compile-byte (JUMP) ;
|
||||||
|
|
||||||
: JE ( xt -- fixup )
|
: JE ( -- fixup )
|
||||||
HEX: 0f compile-byte HEX: 84 compile-byte (JUMP) ;
|
HEX: 0f compile-byte HEX: 84 compile-byte (JUMP) ;
|
||||||
|
|
||||||
: RET ( -- )
|
: RET ( -- )
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
IN: compiler
|
IN: compiler
|
||||||
USE: combinators
|
USE: combinators
|
||||||
USE: errors
|
USE: errors
|
||||||
|
USE: hashtables
|
||||||
USE: kernel
|
USE: kernel
|
||||||
USE: lists
|
USE: lists
|
||||||
USE: logic
|
USE: logic
|
||||||
|
|
@ -40,8 +41,69 @@ USE: unparser
|
||||||
USE: vectors
|
USE: vectors
|
||||||
USE: words
|
USE: words
|
||||||
|
|
||||||
|
! We use a hashtable "compiled-xts" that maps words to
|
||||||
|
! xt's that are currently being compiled. The commit-xt's word
|
||||||
|
! sets the xt of each word in the hashtable to the value in the
|
||||||
|
! hastable.
|
||||||
|
!
|
||||||
|
! This has the advantage that we can compile a word before the
|
||||||
|
! words it depends on and perform a fixup later; among other
|
||||||
|
! things this enables mutually recursive words.
|
||||||
|
|
||||||
|
SYMBOL: compiled-xts
|
||||||
|
|
||||||
|
: save-xt ( word -- )
|
||||||
|
cell compile-aligned
|
||||||
|
compiled-offset swap compiled-xts acons@ ;
|
||||||
|
|
||||||
|
: commit-xts ( -- )
|
||||||
|
compiled-xts get [ unswons set-word-xt ] each
|
||||||
|
compiled-xts off ;
|
||||||
|
|
||||||
|
: compiled-xt ( word -- xt )
|
||||||
|
dup compiled-xts get assoc dup [
|
||||||
|
nip
|
||||||
|
] [
|
||||||
|
drop word-xt
|
||||||
|
] ifte ;
|
||||||
|
|
||||||
|
! "fixup-xts" is a list of [ where | word ] pairs; the xt of
|
||||||
|
! word when its done compiling will be written to the offset.
|
||||||
|
|
||||||
|
SYMBOL: deferred-xts
|
||||||
|
|
||||||
|
: defer-xt ( word where -- )
|
||||||
|
#! After word is compiled, put a call to it at offset.
|
||||||
|
deferred-xts acons@ ;
|
||||||
|
|
||||||
|
: fixup-deferred-xt ( where word -- )
|
||||||
|
compiled-xt swap JUMP-FIXUP ;
|
||||||
|
|
||||||
|
: fixup-deferred-xts ( -- )
|
||||||
|
deferred-xts get [ uncons fixup-deferred-xt ] each
|
||||||
|
deferred-xts off ;
|
||||||
|
|
||||||
|
! Words being compiled are consed onto this list. When a word
|
||||||
|
! is encountered that has not been previously compiled, it is
|
||||||
|
! consed onto this list. Compilation stops when the list is
|
||||||
|
! empty.
|
||||||
|
|
||||||
|
SYMBOL: compile-words
|
||||||
|
|
||||||
|
: postpone-word ( word -- )
|
||||||
|
t over "compiled" set-word-property
|
||||||
|
compile-words cons@ ;
|
||||||
|
|
||||||
|
! During compilation, these two variables store pending
|
||||||
|
! literals. Literals are either consumed at compile-time by
|
||||||
|
! words with special compilation behavior, or otherwise they are
|
||||||
|
! compiled into code that pushes them.
|
||||||
|
|
||||||
|
SYMBOL: compile-datastack
|
||||||
|
SYMBOL: compile-callstack
|
||||||
|
|
||||||
: pop-literal ( -- obj )
|
: pop-literal ( -- obj )
|
||||||
"compile-datastack" get vector-pop ;
|
compile-datastack get vector-pop ;
|
||||||
|
|
||||||
: immediate? ( obj -- ? )
|
: immediate? ( obj -- ? )
|
||||||
#! fixnums and f have a pointerless representation, and
|
#! fixnums and f have a pointerless representation, and
|
||||||
|
|
@ -57,7 +119,7 @@ USE: words
|
||||||
] ifte ;
|
] ifte ;
|
||||||
|
|
||||||
: commit-literals ( -- )
|
: commit-literals ( -- )
|
||||||
"compile-datastack" get
|
compile-datastack get
|
||||||
dup vector-empty? [
|
dup vector-empty? [
|
||||||
drop
|
drop
|
||||||
] [
|
] [
|
||||||
|
|
@ -65,46 +127,43 @@ USE: words
|
||||||
0 swap set-vector-length
|
0 swap set-vector-length
|
||||||
] ifte ;
|
] ifte ;
|
||||||
|
|
||||||
: postpone ( obj -- )
|
: postpone-literal ( obj -- )
|
||||||
#! Literals are not compiled immediately, so that words like
|
#! Literals are not compiled immediately, so that words like
|
||||||
#! ifte with special compilation behavior can work.
|
#! ifte with special compilation behavior can work.
|
||||||
"compile-datastack" get vector-push ;
|
compile-datastack get vector-push ;
|
||||||
|
|
||||||
: tail? ( -- ? )
|
: tail? ( -- ? )
|
||||||
"compile-callstack" get vector-empty? ;
|
compile-callstack get vector-empty? ;
|
||||||
|
|
||||||
: compiled-xt ( word -- xt )
|
: compiled? ( word -- ? )
|
||||||
"compiled-xt" over word-property dup [
|
#! This is a hack.
|
||||||
nip
|
dup "compiled" word-property swap primitive? or ;
|
||||||
] [
|
|
||||||
drop word-xt
|
|
||||||
] ifte ;
|
|
||||||
|
|
||||||
: compile-simple-word ( word -- )
|
: compile-simple-word ( word -- )
|
||||||
#! Compile a JMP at the end (tail call optimization)
|
#! Compile a JMP at the end (tail call optimization)
|
||||||
commit-literals compiled-xt
|
dup compiled? [ dup postpone-word ] unless
|
||||||
tail? [ JUMP ] [ CALL ] ifte drop ;
|
commit-literals tail? [ JUMP ] [ CALL ] ifte defer-xt ;
|
||||||
|
|
||||||
: compile-word ( word -- )
|
: compile-word ( word -- )
|
||||||
#! If a word has a compiling property, then it has special
|
#! If a word has a compiling property, then it has special
|
||||||
#! compilation behavior.
|
#! compilation behavior.
|
||||||
"compiling" over word-property dup [
|
dup "compiling" word-property dup [
|
||||||
nip call
|
nip call
|
||||||
] [
|
] [
|
||||||
drop compile-simple-word
|
drop compile-simple-word
|
||||||
] ifte ;
|
] ifte ;
|
||||||
|
|
||||||
: begin-compiling-quot ( quot -- )
|
: begin-compiling-quot ( quot -- )
|
||||||
"compile-callstack" get vector-push ;
|
compile-callstack get vector-push ;
|
||||||
|
|
||||||
: end-compiling-quot ( -- )
|
: end-compiling-quot ( -- )
|
||||||
"compile-callstack" get vector-pop drop ;
|
compile-callstack get vector-pop drop ;
|
||||||
|
|
||||||
: compiling ( quot -- )
|
: compiling ( quot -- )
|
||||||
#! Called on each iteration of compile-loop, with the
|
#! Called on each iteration of compile-loop, with the
|
||||||
#! remaining quotation.
|
#! remaining quotation.
|
||||||
[
|
[
|
||||||
"compile-callstack" get
|
compile-callstack get
|
||||||
dup vector-length pred
|
dup vector-length pred
|
||||||
swap set-vector-nth
|
swap set-vector-nth
|
||||||
] [
|
] [
|
||||||
|
|
@ -112,7 +171,7 @@ USE: words
|
||||||
] ifte* ;
|
] ifte* ;
|
||||||
|
|
||||||
: compile-atom ( obj -- )
|
: compile-atom ( obj -- )
|
||||||
dup word? [ compile-word ] [ postpone ] ifte ;
|
dup word? [ compile-word ] [ postpone-literal ] ifte ;
|
||||||
|
|
||||||
: compile-loop ( quot -- )
|
: compile-loop ( quot -- )
|
||||||
[
|
[
|
||||||
|
|
@ -126,23 +185,23 @@ USE: words
|
||||||
|
|
||||||
: with-compiler ( quot -- )
|
: with-compiler ( quot -- )
|
||||||
[
|
[
|
||||||
10 <vector> "compile-datastack" set
|
10 <vector> compile-datastack set
|
||||||
10 <vector> "compile-callstack" set
|
10 <vector> compile-callstack set
|
||||||
call
|
call
|
||||||
|
fixup-deferred-xts
|
||||||
|
commit-xts
|
||||||
] with-scope ;
|
] with-scope ;
|
||||||
|
|
||||||
: begin-compiling ( word -- )
|
: (compile) ( word -- )
|
||||||
cell compile-aligned
|
#! Should be called inside the with-compiler scope.
|
||||||
compiled-offset "compiled-xt" rot set-word-property ;
|
intern dup save-xt word-parameter compile-quot RET ;
|
||||||
|
|
||||||
: end-compiling ( word -- xt )
|
: compile-postponed ( -- )
|
||||||
"compiled-xt" over word-property over set-word-xt
|
compile-words get [
|
||||||
f "compiled-xt" rot set-word-property ;
|
uncons compile-words set (compile) compile-postponed
|
||||||
|
] when* ;
|
||||||
|
|
||||||
: compile ( word -- )
|
: compile ( word -- )
|
||||||
intern dup
|
[ postpone-word compile-postponed ] with-compiler ;
|
||||||
begin-compiling
|
|
||||||
dup word-parameter [ compile-quot RET ] with-compiler
|
|
||||||
end-compiling ;
|
|
||||||
|
|
||||||
: compiled word compile ; parsing
|
: compiled word compile ; parsing
|
||||||
|
|
|
||||||
|
|
@ -38,16 +38,17 @@ USE: lists
|
||||||
POP-DS
|
POP-DS
|
||||||
! ptr to condition is now in EAX
|
! ptr to condition is now in EAX
|
||||||
f address EAX CMP-I-[R]
|
f address EAX CMP-I-[R]
|
||||||
compiled-offset JE ;
|
! jump w/ address added later
|
||||||
|
JE ;
|
||||||
|
|
||||||
: branch-target ( fixup -- )
|
: branch-target ( fixup -- )
|
||||||
cell compile-aligned compiled-offset swap fixup ;
|
cell compile-aligned compiled-offset swap JUMP-FIXUP ;
|
||||||
|
|
||||||
: compile-else ( fixup -- fixup )
|
: compile-else ( fixup -- fixup )
|
||||||
#! Push addr where we write the branch target address,
|
#! Push addr where we write the branch target address,
|
||||||
#! and fixup branch target address from compile-f-test.
|
#! and fixup branch target address from compile-f-test.
|
||||||
#! Push f for the fixup if we're tail position.
|
#! Push f for the fixup if we're tail position.
|
||||||
tail? [ RET f ] [ 0 JUMP ] ifte swap branch-target ;
|
tail? [ RET f ] [ JUMP ] ifte swap branch-target ;
|
||||||
|
|
||||||
: compile-end-if ( fixup -- )
|
: compile-end-if ( fixup -- )
|
||||||
tail? [ drop RET ] [ branch-target ] ifte ;
|
tail? [ drop RET ] [ branch-target ] ifte ;
|
||||||
|
|
@ -63,5 +64,5 @@ USE: lists
|
||||||
[
|
[
|
||||||
[ ifte compile-ifte ]
|
[ ifte compile-ifte ]
|
||||||
] [
|
] [
|
||||||
unswons "compiling" swap set-word-property
|
unswons "compiling" set-word-property
|
||||||
] each
|
] each
|
||||||
|
|
|
||||||
|
|
@ -190,7 +190,7 @@ DEFER: unparse-float
|
||||||
IN: image
|
IN: image
|
||||||
|
|
||||||
: primitives, ( -- )
|
: primitives, ( -- )
|
||||||
1 [
|
2 [
|
||||||
execute
|
execute
|
||||||
call
|
call
|
||||||
ifte
|
ifte
|
||||||
|
|
|
||||||
|
|
@ -63,8 +63,8 @@ USE: words
|
||||||
|
|
||||||
: word-line/file ( word -- line dir file )
|
: word-line/file ( word -- line dir file )
|
||||||
#! Note that line numbers here start from 1
|
#! Note that line numbers here start from 1
|
||||||
"line" over word-property swap
|
dup "line" word-property swap "file" word-property
|
||||||
"file" swap word-property word-file ;
|
word-file ;
|
||||||
|
|
||||||
: jedit ( word -- )
|
: jedit ( word -- )
|
||||||
intern dup [
|
intern dup [
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,15 @@ USE: stack
|
||||||
#! Prepend x to the list stored in var.
|
#! Prepend x to the list stored in var.
|
||||||
tuck get cons put ;
|
tuck get cons put ;
|
||||||
|
|
||||||
|
: acons@ ( value key var -- )
|
||||||
|
#! Prepend [ key | value ] to the alist stored in var.
|
||||||
|
[ get acons ] keep set ;
|
||||||
|
|
||||||
|
: uncons@ ( var -- car )
|
||||||
|
#! Push the car of the list in var, and set the var to the
|
||||||
|
#! cdr.
|
||||||
|
dup get uncons rot set ;
|
||||||
|
|
||||||
: remove@ ( obj var -- )
|
: remove@ ( obj var -- )
|
||||||
#! Remove all occurrences of the object from the list
|
#! Remove all occurrences of the object from the list
|
||||||
#! stored in the variable.
|
#! stored in the variable.
|
||||||
|
|
|
||||||
|
|
@ -374,7 +374,11 @@ DEFER: tree-contains?
|
||||||
: cdr= swap cdr swap cdr = ;
|
: cdr= swap cdr swap cdr = ;
|
||||||
|
|
||||||
: cons= ( obj cons -- ? )
|
: cons= ( obj cons -- ? )
|
||||||
over cons? [ 2dup car= >r cdr= r> and ] [ 2drop f ] ifte ;
|
2dup eq? [
|
||||||
|
2drop t
|
||||||
|
] [
|
||||||
|
over cons? [ 2dup car= >r cdr= r> and ] [ 2drop f ] ifte
|
||||||
|
] ifte ;
|
||||||
|
|
||||||
: cons-hashcode ( cons count -- hash )
|
: cons-hashcode ( cons count -- hash )
|
||||||
dup 0 = [
|
dup 0 = [
|
||||||
|
|
|
||||||
|
|
@ -26,14 +26,16 @@
|
||||||
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
IN: init
|
IN: init
|
||||||
|
USE: combinators
|
||||||
|
USE: errors
|
||||||
USE: kernel
|
USE: kernel
|
||||||
USE: lists
|
USE: lists
|
||||||
USE: parser
|
USE: parser
|
||||||
USE: stack
|
USE: stack
|
||||||
|
USE: strings
|
||||||
USE: stdio
|
USE: stdio
|
||||||
|
|
||||||
"Cold boot in progress..." print
|
"Cold boot in progress..." print
|
||||||
|
|
||||||
[
|
[
|
||||||
"/library/platform/native/kernel.factor"
|
"/library/platform/native/kernel.factor"
|
||||||
"/library/platform/native/stack.factor"
|
"/library/platform/native/stack.factor"
|
||||||
|
|
|
||||||
|
|
@ -68,13 +68,13 @@ USE: unparser
|
||||||
! Colon defs
|
! Colon defs
|
||||||
: CREATE ( -- word )
|
: CREATE ( -- word )
|
||||||
scan "in" get create dup set-word
|
scan "in" get create dup set-word
|
||||||
f "documentation" pick set-word-property
|
f over "documentation" set-word-property
|
||||||
f "stack-effect" pick set-word-property ;
|
f over "stack-effect" set-word-property ;
|
||||||
|
|
||||||
: remember-where ( word -- )
|
: remember-where ( word -- )
|
||||||
"line-number" get "line" pick set-word-property
|
"line-number" get over "line" set-word-property
|
||||||
"col" get "col" pick set-word-property
|
"col" get over "col" set-word-property
|
||||||
"file" get "file" pick set-word-property
|
"file" get over "file" set-word-property
|
||||||
drop ;
|
drop ;
|
||||||
|
|
||||||
: :
|
: :
|
||||||
|
|
@ -91,6 +91,9 @@ USE: unparser
|
||||||
nreverse
|
nreverse
|
||||||
;-hook ; parsing
|
;-hook ; parsing
|
||||||
|
|
||||||
|
! Symbols
|
||||||
|
: SYMBOL: CREATE define-symbol ; parsing
|
||||||
|
|
||||||
! Vocabularies
|
! Vocabularies
|
||||||
: DEFER: CREATE drop ; parsing
|
: DEFER: CREATE drop ; parsing
|
||||||
: USE: scan "use" cons@ ; parsing
|
: USE: scan "use" cons@ ; parsing
|
||||||
|
|
@ -157,7 +160,7 @@ USE: unparser
|
||||||
|
|
||||||
: parsed-stack-effect ( parsed str -- parsed )
|
: parsed-stack-effect ( parsed str -- parsed )
|
||||||
over doc-comment-here? [
|
over doc-comment-here? [
|
||||||
"stack-effect" word set-word-property
|
word "stack-effect" set-word-property
|
||||||
] [
|
] [
|
||||||
drop
|
drop
|
||||||
] ifte ;
|
] ifte ;
|
||||||
|
|
@ -168,11 +171,11 @@ USE: unparser
|
||||||
|
|
||||||
: documentation+ ( str word -- )
|
: documentation+ ( str word -- )
|
||||||
[
|
[
|
||||||
"documentation" swap word-property [
|
"documentation" word-property [
|
||||||
swap "\n" swap cat3
|
swap "\n" swap cat3
|
||||||
] when*
|
] when*
|
||||||
] keep
|
] keep
|
||||||
"documentation" swap set-word-property ;
|
"documentation" set-word-property ;
|
||||||
|
|
||||||
: parsed-documentation ( parsed str -- parsed )
|
: parsed-documentation ( parsed str -- parsed )
|
||||||
over doc-comment-here? [
|
over doc-comment-here? [
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ USE: unparser
|
||||||
|
|
||||||
: parsing? ( word -- ? )
|
: parsing? ( word -- ? )
|
||||||
dup word? [
|
dup word? [
|
||||||
"parsing" swap word-property
|
"parsing" word-property
|
||||||
] [
|
] [
|
||||||
drop f
|
drop f
|
||||||
] ifte ;
|
] ifte ;
|
||||||
|
|
@ -59,7 +59,7 @@ USE: unparser
|
||||||
#! Mark the most recently defined word to execute at parse
|
#! Mark the most recently defined word to execute at parse
|
||||||
#! time, rather than run time. The word can use 'scan' to
|
#! time, rather than run time. The word can use 'scan' to
|
||||||
#! read ahead in the input stream.
|
#! read ahead in the input stream.
|
||||||
t "parsing" word set-word-property ;
|
t word "parsing" set-word-property ;
|
||||||
|
|
||||||
: end? ( -- ? )
|
: end? ( -- ? )
|
||||||
"col" get "line" get str-length >= ;
|
"col" get "line" get str-length >= ;
|
||||||
|
|
@ -185,4 +185,4 @@ USE: unparser
|
||||||
! Once this file has loaded, we can use 'parsing' normally.
|
! Once this file has loaded, we can use 'parsing' normally.
|
||||||
! This hack is needed because in Java Factor, 'parsing' is
|
! This hack is needed because in Java Factor, 'parsing' is
|
||||||
! not parsing, but in CFactor, it is.
|
! not parsing, but in CFactor, it is.
|
||||||
t "parsing" "parsing" [ "parser" ] search set-word-property
|
t "parsing" [ "parser" ] search "parsing" set-word-property
|
||||||
|
|
|
||||||
|
|
@ -236,5 +236,5 @@ USE: words
|
||||||
[ set-alien-1 | " n alien off -- " ]
|
[ set-alien-1 | " n alien off -- " ]
|
||||||
[ heap-stats | " -- instances bytes " ]
|
[ heap-stats | " -- instances bytes " ]
|
||||||
] [
|
] [
|
||||||
unswons "stack-effect" swap set-word-property
|
unswons "stack-effect" set-word-property
|
||||||
] each
|
] each
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,9 @@ USE: stack
|
||||||
#! Check if two vectors are equal. Two vectors are
|
#! Check if two vectors are equal. Two vectors are
|
||||||
#! considered equal if they have the same length and contain
|
#! considered equal if they have the same length and contain
|
||||||
#! equal elements.
|
#! equal elements.
|
||||||
|
2dup eq? [
|
||||||
|
2drop t
|
||||||
|
] [
|
||||||
over vector? [
|
over vector? [
|
||||||
2dup vector-length= [
|
2dup vector-length= [
|
||||||
0 -rot (vector=)
|
0 -rot (vector=)
|
||||||
|
|
@ -65,6 +68,7 @@ USE: stack
|
||||||
] ifte
|
] ifte
|
||||||
] [
|
] [
|
||||||
2drop f
|
2drop f
|
||||||
|
] ifte
|
||||||
] ifte ;
|
] ifte ;
|
||||||
|
|
||||||
: ?vector-nth ( n vec -- obj/f )
|
: ?vector-nth ( n vec -- obj/f )
|
||||||
|
|
|
||||||
|
|
@ -33,11 +33,11 @@ USE: logic
|
||||||
USE: namespaces
|
USE: namespaces
|
||||||
USE: stack
|
USE: stack
|
||||||
|
|
||||||
: word-property ( pname word -- pvalue )
|
: word-property ( word pname -- pvalue )
|
||||||
word-plist assoc ;
|
swap word-plist assoc ;
|
||||||
|
|
||||||
: set-word-property ( pvalue pname word -- )
|
: set-word-property ( pvalue word pname -- )
|
||||||
dup >r word-plist set-assoc r> set-word-plist ;
|
swap [ word-plist set-assoc ] keep set-word-plist ;
|
||||||
|
|
||||||
: defined? ( obj -- ? )
|
: defined? ( obj -- ? )
|
||||||
dup word? [ word-primitive 0 = not ] [ drop f ] ifte ;
|
dup word? [ word-primitive 0 = not ] [ drop f ] ifte ;
|
||||||
|
|
@ -48,6 +48,9 @@ USE: stack
|
||||||
: primitive? ( obj -- ? )
|
: primitive? ( obj -- ? )
|
||||||
dup word? [ word-primitive 1 = not ] [ drop f ] ifte ;
|
dup word? [ word-primitive 1 = not ] [ drop f ] ifte ;
|
||||||
|
|
||||||
|
: symbol? ( obj -- ? )
|
||||||
|
dup word? [ word-primitive 2 = ] [ drop f ] ifte ;
|
||||||
|
|
||||||
! Various features not supported by native Factor.
|
! Various features not supported by native Factor.
|
||||||
: comment? drop f ;
|
: comment? drop f ;
|
||||||
|
|
||||||
|
|
@ -61,8 +64,12 @@ USE: stack
|
||||||
over set-word-parameter
|
over set-word-parameter
|
||||||
1 swap set-word-primitive ;
|
1 swap set-word-primitive ;
|
||||||
|
|
||||||
|
: define-symbol ( word -- )
|
||||||
|
dup dup set-word-parameter
|
||||||
|
2 swap set-word-primitive ;
|
||||||
|
|
||||||
: stack-effect ( word -- str )
|
: stack-effect ( word -- str )
|
||||||
"stack-effect" swap word-property ;
|
"stack-effect" word-property ;
|
||||||
|
|
||||||
: documentation ( word -- str )
|
: documentation ( word -- str )
|
||||||
"documentation" swap word-property ;
|
"documentation" word-property ;
|
||||||
|
|
|
||||||
|
|
@ -199,9 +199,8 @@ DEFER: prettyprint*
|
||||||
tab-size - ;
|
tab-size - ;
|
||||||
|
|
||||||
: prettyprint-plist ( word -- )
|
: prettyprint-plist ( word -- )
|
||||||
"parsing" over word-property [ " parsing" write ] when
|
dup "parsing" word-property [ " parsing" write ] when
|
||||||
"inline" over word-property [ " inline" write ] when
|
"inline" word-property [ " inline" write ] when ;
|
||||||
drop ;
|
|
||||||
|
|
||||||
: . ( obj -- )
|
: . ( obj -- )
|
||||||
[
|
[
|
||||||
|
|
|
||||||
|
|
@ -40,11 +40,6 @@ USE: words
|
||||||
|
|
||||||
[ t ] [ ] [ word-parameter-test ] test-word
|
[ t ] [ ] [ word-parameter-test ] test-word
|
||||||
|
|
||||||
: words-test ( -- ? )
|
|
||||||
t vocabs [ words [ word? and ] each ] each ;
|
|
||||||
|
|
||||||
[ t ] [ ] [ words-test ] test-word
|
|
||||||
|
|
||||||
! At one time we had a bug in FactorShuffleDefinition.toList()
|
! At one time we had a bug in FactorShuffleDefinition.toList()
|
||||||
~<< test-shuffle-1 A r:B -- A r:B >>~
|
~<< test-shuffle-1 A r:B -- A r:B >>~
|
||||||
|
|
||||||
|
|
@ -95,15 +90,6 @@ test-word
|
||||||
|
|
||||||
[ [ 1 1 0 0 ] ] [ [ system-property ] ] [ balance>list ] test-word
|
[ [ 1 1 0 0 ] ] [ [ system-property ] ] [ balance>list ] test-word
|
||||||
|
|
||||||
: test-last ( -- )
|
|
||||||
nop ;
|
|
||||||
word >str "last-word-test" set
|
|
||||||
|
|
||||||
[ "test-last" ] [ ] [ "last-word-test" get ] test-word
|
|
||||||
[ f ] [ 5 ] [ compound? ] test-word
|
|
||||||
[ f ] [ 5 ] [ compiled? ] test-word
|
|
||||||
[ f ] [ 5 ] [ shuffle? ] test-word
|
|
||||||
|
|
||||||
! Make sure callstack only clones callframes, and not
|
! Make sure callstack only clones callframes, and not
|
||||||
! everything on the callstack.
|
! everything on the callstack.
|
||||||
[ ] [ ] [ f unit dup dup set-cdr >r callstack r> 2drop ] test-word
|
[ ] [ ] [ f unit dup dup set-cdr >r callstack r> 2drop ] test-word
|
||||||
|
|
|
||||||
|
|
@ -8,3 +8,10 @@ USE: test
|
||||||
[ [ 1 ] ] [ 1 f ] [ "x" set "x" cons@ "x" get ] test-word
|
[ [ 1 ] ] [ 1 f ] [ "x" set "x" cons@ "x" get ] test-word
|
||||||
[ [ 1 | 2 ] ] [ 1 2 ] [ "x" set "x" cons@ "x" get ] test-word
|
[ [ 1 | 2 ] ] [ 1 2 ] [ "x" set "x" cons@ "x" get ] test-word
|
||||||
[ [ 1 2 ] ] [ 1 [ 2 ] ] [ "x" set "x" cons@ "x" get ] test-word
|
[ [ 1 2 ] ] [ 1 [ 2 ] ] [ "x" set "x" cons@ "x" get ] test-word
|
||||||
|
|
||||||
|
[ [ [ 2 | 3 ] [ 1 | 2 ] ] ] [
|
||||||
|
"x" off 2 1 "x" acons@ 3 2 "x" acons@ "x" get
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[ [ 2 | 3 ] ] [ "x" uncons@ ] unit-test
|
||||||
|
[ [ 1 | 2 ] ] [ "x" uncons@ ] unit-test
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,23 @@ IN: scratchpad
|
||||||
USE: math
|
USE: math
|
||||||
USE: test
|
USE: test
|
||||||
USE: words
|
USE: words
|
||||||
|
USE: namespaces
|
||||||
|
USE: logic
|
||||||
|
USE: lists
|
||||||
|
|
||||||
[ 4 ] [
|
[ 4 ] [
|
||||||
"poo" "scratchpad" create [ 2 2 + ] define-compound
|
"poo" "scratchpad" create [ 2 2 + ] define-compound
|
||||||
"poo" [ "scratchpad" ] search execute
|
"poo" [ "scratchpad" ] search execute
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
|
: words-test ( -- ? )
|
||||||
|
t vocabs [ words [ word? and ] each ] each ;
|
||||||
|
|
||||||
|
[ t ] [ ] [ words-test ] test-word
|
||||||
|
|
||||||
|
|
||||||
|
: test-last ( -- ) ;
|
||||||
|
word word-name "last-word-test" set
|
||||||
|
|
||||||
|
[ "test-last" ] [ ] [ "last-word-test" get ] test-word
|
||||||
|
[ f ] [ 5 ] [ compound? ] test-word
|
||||||
|
|
|
||||||
|
|
@ -7,23 +7,29 @@ USE: kernel
|
||||||
USE: combinators
|
USE: combinators
|
||||||
USE: words
|
USE: words
|
||||||
|
|
||||||
|
"Hi." USE: stdio print
|
||||||
|
|
||||||
: no-op ; compiled
|
: no-op ; compiled
|
||||||
|
|
||||||
[ ] [ no-op ] unit-test
|
[ ] [ no-op ] unit-test
|
||||||
|
|
||||||
: literals 3 5 ; compiled
|
: literals 3 5 ; compiled
|
||||||
|
|
||||||
|
: tail-call fixnum+ ; compiled
|
||||||
|
|
||||||
|
[ 4 ] [ 1 3 tail-call ] unit-test
|
||||||
|
|
||||||
[ 3 5 ] [ literals ] unit-test
|
[ 3 5 ] [ literals ] unit-test
|
||||||
|
|
||||||
: literals&tail-call 3 5 + ; compiled
|
: literals&tail-call 3 5 fixnum+ ; compiled
|
||||||
|
|
||||||
[ 8 ] [ literals&tail-call ] unit-test
|
[ 8 ] [ literals&tail-call ] unit-test
|
||||||
|
|
||||||
: two-calls dup * ; compiled
|
: two-calls dup fixnum* ; compiled
|
||||||
|
|
||||||
[ 25 ] [ 5 two-calls ] unit-test
|
[ 25 ] [ 5 two-calls ] unit-test
|
||||||
|
|
||||||
: mix-test 3 5 + 6 * ; compiled
|
: mix-test 3 5 fixnum+ 6 fixnum* ; compiled
|
||||||
|
|
||||||
[ 48 ] [ mix-test ] unit-test
|
[ 48 ] [ mix-test ] unit-test
|
||||||
|
|
||||||
|
|
@ -50,7 +56,7 @@ garbage-collection
|
||||||
|
|
||||||
[ 2 ] [ dummy-ifte-4 ] unit-test
|
[ 2 ] [ dummy-ifte-4 ] unit-test
|
||||||
|
|
||||||
: dummy-ifte-5 0 dup 1 <= [ drop 1 ] [ ] ifte ; compiled
|
: dummy-ifte-5 0 dup 1 fixnum<= [ drop 1 ] [ ] ifte ; compiled
|
||||||
|
|
||||||
[ 1 ] [ dummy-ifte-5 ] unit-test
|
[ 1 ] [ dummy-ifte-5 ] unit-test
|
||||||
|
|
||||||
|
|
@ -58,7 +64,7 @@ garbage-collection
|
||||||
dup 1 <= [
|
dup 1 <= [
|
||||||
drop 1
|
drop 1
|
||||||
] [
|
] [
|
||||||
1 - dup swap 1 - +
|
1 fixnum- dup swap 1 fixnum- fixnum+
|
||||||
] ifte ;
|
] ifte ;
|
||||||
|
|
||||||
[ 17 ] [ 10 dummy-ifte-6 ] unit-test
|
[ 17 ] [ 10 dummy-ifte-6 ] unit-test
|
||||||
|
|
@ -80,3 +86,10 @@ garbage-collection
|
||||||
t [ ] [ ] ifte 5 ; compiled
|
t [ ] [ ] ifte 5 ; compiled
|
||||||
|
|
||||||
[ 5 ] [ after-ifte-test ] unit-test
|
[ 5 ] [ after-ifte-test ] unit-test
|
||||||
|
|
||||||
|
DEFER: countdown-b
|
||||||
|
|
||||||
|
: countdown-a ( n -- ) dup 0 eq? [ drop ] [ pred countdown-b ] ifte ;
|
||||||
|
: countdown-b ( n -- ) dup 0 eq? [ drop ] [ pred countdown-a ] ifte ; compiled
|
||||||
|
|
||||||
|
[ ] [ 10 countdown-b ] unit-test
|
||||||
|
|
|
||||||
|
|
@ -34,16 +34,16 @@ USE: namespaces
|
||||||
USE: stack
|
USE: stack
|
||||||
|
|
||||||
: word-name ( word -- name )
|
: word-name ( word -- name )
|
||||||
"name" swap word-property ;
|
"name" word-property ;
|
||||||
|
|
||||||
: set-word-name ( word name -- )
|
: set-word-name ( word name -- )
|
||||||
"name" swap set-word-property ;
|
"name" set-word-property ;
|
||||||
|
|
||||||
: word-vocabulary ( word -- vocab )
|
: word-vocabulary ( word -- vocab )
|
||||||
"vocabulary" swap word-property ;
|
"vocabulary" word-property ;
|
||||||
|
|
||||||
: set-word-vocabulary ( word vocab -- )
|
: set-word-vocabulary ( word vocab -- )
|
||||||
"vocabulary" swap set-word-property ;
|
"vocabulary" set-word-property ;
|
||||||
|
|
||||||
: each-word ( quot -- )
|
: each-word ( quot -- )
|
||||||
#! Apply a quotation to each word in the image.
|
#! Apply a quotation to each word in the image.
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
XT primitives[] = {
|
XT primitives[] = {
|
||||||
undefined,
|
undefined,
|
||||||
docol,
|
docol,
|
||||||
|
dosym,
|
||||||
primitive_execute,
|
primitive_execute,
|
||||||
primitive_call,
|
primitive_call,
|
||||||
primitive_ifte,
|
primitive_ifte,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
extern XT primitives[];
|
extern XT primitives[];
|
||||||
#define PRIMITIVE_COUNT 193
|
#define PRIMITIVE_COUNT 194
|
||||||
|
|
||||||
CELL primitive_to_xt(CELL primitive);
|
CELL primitive_to_xt(CELL primitive);
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,12 @@ void docol(void)
|
||||||
call(executing->parameter);
|
call(executing->parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* pushes word parameter */
|
||||||
|
void dosym(void)
|
||||||
|
{
|
||||||
|
dpush(executing->parameter);
|
||||||
|
}
|
||||||
|
|
||||||
void primitive_execute(void)
|
void primitive_execute(void)
|
||||||
{
|
{
|
||||||
executing = untag_word(dpop());
|
executing = untag_word(dpop());
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,7 @@ void clear_environment(void);
|
||||||
void run(void);
|
void run(void);
|
||||||
void undefined(void);
|
void undefined(void);
|
||||||
void docol(void);
|
void docol(void);
|
||||||
|
void dosym(void);
|
||||||
void primitive_execute(void);
|
void primitive_execute(void);
|
||||||
void primitive_call(void);
|
void primitive_call(void);
|
||||||
void primitive_ifte(void);
|
void primitive_ifte(void);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue