]> gitweb.factorcode.org Git - factor.git/commitdiff
compiling mutually recursive words
authorSlava Pestov <slava@factorcode.org>
Tue, 28 Sep 2004 04:24:36 +0000 (04:24 +0000)
committerSlava Pestov <slava@factorcode.org>
Tue, 28 Sep 2004 04:24:36 +0000 (04:24 +0000)
27 files changed:
TODO.FACTOR.txt
doc/alien.txt [new file with mode: 0644]
library/compiler/alien-macros.factor
library/compiler/alien.factor
library/compiler/assembly-x86.factor
library/compiler/compiler.factor
library/compiler/words.factor
library/cross-compiler.factor
library/jedit/jedit.factor
library/list-namespaces.factor
library/lists.factor
library/platform/native/boot-stage2.factor
library/platform/native/parse-syntax.factor
library/platform/native/parser.factor
library/platform/native/primitives.factor
library/platform/native/vectors.factor
library/platform/native/words.factor
library/prettyprint.factor
library/test/jvm-compiler/miscellaneous.factor
library/test/lists/namespaces.factor
library/test/words.factor
library/test/x86-compiler/compiler.factor
library/words.factor
native/primitives.c
native/primitives.h
native/run.c
native/run.h

index 4e0b1a6c5517db0bdebf24f406046dff47579cef..c016dff5d2d02235e536eb1d908b0098808db962 100644 (file)
@@ -1,6 +1,8 @@
 FFI:\r
 - is signed -vs- unsigned pointers an issue?\r
 \r
+- symbols are not primitives\r
+\r
 [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/)\r
 [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/)\r
 \r
diff --git a/doc/alien.txt b/doc/alien.txt
new file mode 100644 (file)
index 0000000..0e6d6b7
--- /dev/null
@@ -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.
index 329f1e9ea13156cd09f68c570debcf66953c4953..b9bc5984e6a753f23e1d644ba76c63b95ebb702e 100644 (file)
@@ -36,14 +36,14 @@ USE: stack
 
 : UNBOX ( name -- )
     #! Move top of datastack to C stack.
-    dlsym-self CALL drop
+    dlsym-self CALL JUMP-FIXUP
     EAX PUSH-R ;
 
 : BOX ( name -- )
     #! Move EAX to datastack.
     24 ESP R-I
     EAX PUSH-R
-    dlsym-self CALL drop
+    dlsym-self CALL JUMP-FIXUP
     28 ESP R+I ;
 
 : PARAMETERS ( params -- count )
index 21d015dc18eb47dbdc16b0b9182e763346f5fe65..776367fc1cc69f3dcff2522692fdd1a1f7750bb5 100644 (file)
@@ -36,7 +36,7 @@ USE: stack
 USE: words
 
 : 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:
     #!
     #! BEGIN-ENUM 0
@@ -69,11 +69,11 @@ USE: words
 
 : compile-alien-call
     pop-literal reverse PARAMETERS >r
-    pop-literal pop-literal alien-function CALL drop
+    pop-literal pop-literal alien-function CALL JUMP-FIXUP
     r> CLEANUP
     pop-literal RETURNS ;
 
 global [ <namespace> "libraries" set ] bind
 
 [ alien-call compile-alien-call ]
-unswons "compiling" swap set-word-property
+unswons "compiling" set-word-property
index 0b71d35977508b748b892b518cafa11aa667d2a6..08b4eaa0670fdbbc4f35fcc515402c19db21cef0 100644 (file)
@@ -147,24 +147,24 @@ USE: combinators
         compile-cell
     ] ifte ;
 
-: fixup ( addr where -- )
+: JUMP-FIXUP ( addr where -- )
     #! Encode a relative offset to addr from where at where.
     #! Add 4 because addr is relative to *after* insn.
     dup >r 4 + - r> set-compiled-cell ;
 
 : (JUMP) ( xt -- fixup )
     #! 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
     HEX: e9 compile-byte  (JUMP) ;
 
-: CALL ( xt -- fixup )
+: CALL ( -- fixup )
     HEX: e8 compile-byte  (JUMP) ;
 
-: JE ( xt -- fixup )
-    HEX: 0f compile-byte HEX: 84 compile-byte (JUMP) ;
+: JE ( -- fixup )
+    HEX: 0f compile-byte HEX: 84 compile-byte  (JUMP) ;
 
 : RET ( -- )
     HEX: c3 compile-byte ;
index 83562f4906cbed5afb2f006ecca4a7ac6133a311..552a0b3e736c62d137469231f4f619753759e31e 100644 (file)
@@ -28,6 +28,7 @@
 IN: compiler
 USE: combinators
 USE: errors
+USE: hashtables
 USE: kernel
 USE: lists
 USE: logic
@@ -40,8 +41,69 @@ USE: unparser
 USE: vectors
 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 )
-    "compile-datastack" get vector-pop ;
+    compile-datastack get vector-pop ;
 
 : immediate? ( obj -- ? )
     #! fixnums and f have a pointerless representation, and
@@ -57,7 +119,7 @@ USE: words
     ] ifte ;
 
 : commit-literals ( -- )
-    "compile-datastack" get
+    compile-datastack get
     dup vector-empty? [
         drop
     ] [
@@ -65,46 +127,43 @@ USE: words
         0 swap set-vector-length
     ] ifte ;
 
-: postpone ( obj -- )
+: postpone-literal ( obj -- )
     #! Literals are not compiled immediately, so that words like
     #! ifte with special compilation behavior can work.
-    "compile-datastack" get vector-push ;
+    compile-datastack get vector-push ;
 
 : tail? ( -- ? )
-    "compile-callstack" get vector-empty? ;
+    compile-callstack get vector-empty? ;
 
-: compiled-xt ( word -- xt )
-    "compiled-xt" over word-property dup [
-        nip
-    ] [
-        drop word-xt
-    ] ifte ;
+: compiled? ( word -- ? )
+    #! This is a hack.
+    dup "compiled" word-property swap primitive? or ;
 
 : compile-simple-word ( word -- )
     #! Compile a JMP at the end (tail call optimization)
-    commit-literals compiled-xt
-    tail? [ JUMP ] [ CALL ] ifte drop ;
+    dup compiled? [ dup postpone-word ] unless
+    commit-literals tail? [ JUMP ] [ CALL ] ifte defer-xt ;
 
 : compile-word ( word -- )
     #! If a word has a compiling property, then it has special
     #! compilation behavior.
-    "compiling" over word-property dup [
+    dup "compiling" word-property dup [
         nip call
     ] [
         drop compile-simple-word
     ] ifte ;
 
 : begin-compiling-quot ( quot -- )
-    "compile-callstack" get vector-push ;
+    compile-callstack get vector-push ;
 
 : end-compiling-quot ( -- )
-    "compile-callstack" get vector-pop drop ;
+    compile-callstack get vector-pop drop ;
 
 : compiling ( quot -- )
     #! Called on each iteration of compile-loop, with the
     #! remaining quotation.
     [
-        "compile-callstack" get
+        compile-callstack get
         dup vector-length pred
         swap set-vector-nth
     ] [
@@ -112,7 +171,7 @@ USE: words
     ] ifte* ;
 
 : compile-atom ( obj -- )
-    dup word? [ compile-word ] [ postpone ] ifte ;
+    dup word? [ compile-word ] [ postpone-literal ] ifte ;
 
 : compile-loop ( quot -- )
     [
@@ -126,23 +185,23 @@ USE: words
 
 : with-compiler ( quot -- )
     [
-        10 <vector> "compile-datastack" set
-        10 <vector> "compile-callstack" set
+        10 <vector> compile-datastack set
+        10 <vector> compile-callstack set
         call
+        fixup-deferred-xts
+        commit-xts
     ] with-scope ;
 
-: begin-compiling ( word -- )
-    cell compile-aligned
-    compiled-offset "compiled-xt" rot set-word-property ;
+: (compile) ( word -- )
+    #! Should be called inside the with-compiler scope.
+    intern dup save-xt word-parameter compile-quot RET ;
 
-: end-compiling ( word -- xt )
-    "compiled-xt" over word-property over set-word-xt
-    f "compiled-xt" rot set-word-property ;
+: compile-postponed ( -- )
+    compile-words get [
+        uncons compile-words set (compile) compile-postponed
+    ] when* ;
 
 : compile ( word -- )
-    intern dup
-    begin-compiling
-    dup word-parameter [ compile-quot RET ] with-compiler
-    end-compiling ;
+    [ postpone-word compile-postponed ] with-compiler ;
 
 : compiled word compile ; parsing
index 95a08cee955b26dc5ed8639f184f2d3b4761b09c..b70cbe744b11c2937acc5c680aab312d38d444b8 100644 (file)
@@ -38,16 +38,17 @@ USE: lists
     POP-DS
     ! ptr to condition is now in EAX
     f address EAX CMP-I-[R]
-    compiled-offset JE ;
+    ! jump w/ address added later
+    JE ;
 
 : branch-target ( fixup -- )
-    cell compile-aligned compiled-offset swap fixup ;
+    cell compile-aligned compiled-offset swap JUMP-FIXUP ;
 
 : compile-else ( fixup -- fixup )
     #! Push addr where we write the branch target address,
     #! and fixup branch target address from compile-f-test.
     #! Push f for the fixup if we're tail position.
-    tail? [ RET f ] [ JUMP ] ifte swap branch-target ;
+    tail? [ RET f ] [ JUMP ] ifte swap branch-target ;
 
 : compile-end-if ( fixup -- )
     tail? [ drop RET ] [ branch-target ] ifte ;
@@ -63,5 +64,5 @@ USE: lists
 [
     [ ifte compile-ifte ]
 ] [
-    unswons "compiling" swap set-word-property
+    unswons "compiling" set-word-property
 ] each
index 2b64d12c850195b967d2360e3dd50acb34f18003..cae355d0c8ea9b01015f3d334e99001c6ed858d2 100644 (file)
@@ -190,7 +190,7 @@ DEFER: unparse-float
 IN: image
 
 : primitives, ( -- )
-    1 [
+    2 [
         execute
         call
         ifte
index d374b14bd40218d320328752c9b3d98bb54fe715..beb2580b3607e7984fb99d142d2ca1345abe4894 100644 (file)
@@ -63,8 +63,8 @@ USE: words
 
 : word-line/file ( word -- line dir file )
     #! Note that line numbers here start from 1
-    "line" over word-property swap
-    "file" swap word-property word-file ;
+    dup "line" word-property swap "file" word-property
+    word-file ;
 
 : jedit ( word -- )
     intern dup [
index 8cdd0e4438386536ce86f6535b4c2a350b81e23f..78bb33c2d472292c006ab920c8ec2dd3ed06d2f5 100644 (file)
@@ -46,6 +46,15 @@ USE: stack
     #! Prepend x to the list stored in var.
     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 all occurrences of the object from the list
     #! stored in the variable.
index 0fa4764999d79910e3e3d7a8f64439b984aac69f..96468aa9ee31e8a3df0cef1c1ed5d6fe32b495fc 100644 (file)
@@ -374,7 +374,11 @@ DEFER: tree-contains?
 : cdr= swap cdr swap cdr = ;
 
 : 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 )
     dup 0 = [
index 6f716402a1fe77c8c35a464dd9c6d3d1208d64ef..dd4bf4f13e64d2d2f26156e6ed575e3a0a80d18c 100644 (file)
 ! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 IN: init
+USE: combinators
+USE: errors
 USE: kernel
 USE: lists
 USE: parser
 USE: stack
+USE: strings
 USE: stdio
 
 "Cold boot in progress..." print
-
 [
     "/library/platform/native/kernel.factor"
     "/library/platform/native/stack.factor"
index 5b4e332adc0e1ae4e49e729f883cb8be35b8774e..0cc2ac58d87c6cf4f662a5ac36d7e303d2535848 100644 (file)
@@ -68,13 +68,13 @@ USE: unparser
 ! Colon defs
 : CREATE ( -- word )
     scan "in" get create dup set-word
-    f "documentation" pick set-word-property
-    f "stack-effect" pick set-word-property ;
+    f over "documentation" set-word-property
+    f over "stack-effect" set-word-property ;
 
 : remember-where ( word -- )
-    "line-number" get "line" pick set-word-property
-    "col"         get "col"  pick set-word-property
-    "file"        get "file" pick set-word-property
+    "line-number" get over "line" set-word-property
+    "col"         get over "col"  set-word-property
+    "file"        get over "file" set-word-property
     drop ;
 
 : :
@@ -91,6 +91,9 @@ USE: unparser
     nreverse
     ;-hook ; parsing
 
+! Symbols
+: SYMBOL: CREATE define-symbol ; parsing
+
 ! Vocabularies
 : DEFER: CREATE drop ; parsing
 : USE: scan "use" cons@ ; parsing
@@ -157,7 +160,7 @@ USE: unparser
 
 : parsed-stack-effect ( parsed str -- parsed )
     over doc-comment-here? [
-        "stack-effect" word set-word-property
+        word "stack-effect" set-word-property
     ] [
         drop
     ] ifte ;
@@ -168,11 +171,11 @@ USE: unparser
 
 : documentation+ ( str word -- )
     [
-        "documentation" swap word-property [
+        "documentation" word-property [
             swap "\n" swap cat3
         ] when*
     ] keep
-    "documentation" swap set-word-property ;
+    "documentation" set-word-property ;
 
 : parsed-documentation ( parsed str -- parsed )
     over doc-comment-here? [
index 1a91594c9ff68eabaf1ecd3f2a372b11091fd718..01f07436e14eb1608bacc66e6272e9a2202b95cb 100644 (file)
@@ -50,7 +50,7 @@ USE: unparser
 
 : parsing? ( word -- ? )
     dup word? [
-        "parsing" swap word-property
+        "parsing" word-property
     ] [
         drop f
     ] ifte ;
@@ -59,7 +59,7 @@ USE: unparser
     #! Mark the most recently defined word to execute at parse
     #! time, rather than run time. The word can use 'scan' to
     #! read ahead in the input stream.
-    t "parsing" word set-word-property ;
+    t word "parsing" set-word-property ;
 
 : end? ( -- ? )
     "col" get "line" get str-length >= ;
@@ -185,4 +185,4 @@ USE: unparser
 ! Once this file has loaded, we can use 'parsing' normally.
 ! This hack is needed because in Java Factor, 'parsing' is
 ! not parsing, but in CFactor, it is.
-t "parsing" "parsing" [ "parser" ] search set-word-property
+t "parsing" [ "parser" ] search "parsing" set-word-property
index 9c80ae3ba35931a89e5269492cfc9e743f1366a6..63d719254c347dc8f39112b2b309f353c3250606 100644 (file)
@@ -236,5 +236,5 @@ USE: words
     [ set-alien-1            | " n alien off -- " ]
     [ heap-stats             | " -- instances bytes " ]
 ] [
-    unswons "stack-effect" swap set-word-property
+    unswons "stack-effect" set-word-property
 ] each
index 5fead95f81a32f6b1017860a23b280113a503396..25c3d352c55b0141a44f2523562c8ba37c616286 100644 (file)
@@ -57,14 +57,18 @@ USE: stack
     #! Check if two vectors are equal. Two vectors are
     #! considered equal if they have the same length and contain
     #! equal elements.
-    over vector? [
-        2dup vector-length= [
-            0 -rot (vector=)
+    2dup eq? [
+        2drop t
+    ] [
+        over vector? [
+            2dup vector-length= [
+                0 -rot (vector=)
+            ] [
+                2drop f
+            ] ifte
         ] [
             2drop f
         ] ifte
-    ] [
-        2drop f
     ] ifte ;
 
 : ?vector-nth ( n vec -- obj/f )
index c25f0a6f1db327e5db25192ddd5a98a21022ea7b..61df6a0652fc90a143eba885cd04685f383d61d1 100644 (file)
@@ -33,11 +33,11 @@ USE: logic
 USE: namespaces
 USE: stack
 
-: word-property ( pname word -- pvalue )
-    word-plist assoc ;
+: word-property ( word pname -- pvalue )
+    swap word-plist assoc ;
 
-: set-word-property ( pvalue pname word -- )
-    dup >r word-plist set-assoc r> set-word-plist ;
+: set-word-property ( pvalue word pname -- )
+    swap [ word-plist set-assoc ] keep set-word-plist ;
 
 : defined? ( obj -- ? )
     dup word? [ word-primitive 0 = not ] [ drop f ] ifte ;
@@ -48,6 +48,9 @@ USE: stack
 : primitive? ( obj -- ? )
     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.
 : comment? drop f ;
 
@@ -61,8 +64,12 @@ USE: stack
     over set-word-parameter
     1 swap set-word-primitive ;
 
+: define-symbol ( word -- )
+    dup dup set-word-parameter
+    2 swap set-word-primitive ;
+
 : stack-effect ( word -- str )
-    "stack-effect" swap word-property ;
+    "stack-effect" word-property ;
 
 : documentation ( word -- str )
-    "documentation" swap word-property ;
+    "documentation" word-property ;
index 8f430e135906307b60583d7af9c45efdb88f2a8a..ef46dba23250a44591c4ccf2bf0206c652b1fe62 100644 (file)
@@ -199,9 +199,8 @@ DEFER: prettyprint*
     tab-size - ;
 
 : prettyprint-plist ( word -- )
-    "parsing" over word-property [ " parsing" write ] when
-    "inline" over word-property [ " inline" write ] when
-    drop ;
+    dup "parsing" word-property [ " parsing" write ] when
+    "inline" word-property [ " inline" write ] when ;
 
 : . ( obj -- )
     [
index a632147879028ef9c80fe56cfed7a9f101ace8b9..6ecce2f2f21f1febe6b5d3443b31ed8e60057375 100644 (file)
@@ -40,11 +40,6 @@ USE: words
 
 [ 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()
 ~<< 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
 
-: 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
 ! everything on the callstack.
 [ ] [ ] [ f unit dup dup set-cdr >r callstack r> 2drop ] test-word
index 2a1e4bdcdc695e188e5839d42338643aa0242a73..838d23c28ba6bde3d4c5f28dfb10bb3142c3082c 100644 (file)
@@ -8,3 +8,10 @@ USE: test
 [ [ 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
+
+[ [ [ 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
index 3332f175d0c6b882d9494cd1fb15b537b2f8a581..042591472508692173eedaf6b3ba6b3a7e3229ce 100644 (file)
@@ -2,8 +2,23 @@ IN: scratchpad
 USE: math
 USE: test
 USE: words
+USE: namespaces
+USE: logic
+USE: lists
 
 [ 4 ] [
     "poo" "scratchpad" create [ 2 2 + ] define-compound
     "poo" [ "scratchpad" ] search execute
 ] 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
index 5624ed9e86c68c9cb20efe0863267ece6f7a1b38..f8fc00c3bb27d621e79133e993a7c09849f17cf5 100644 (file)
@@ -7,23 +7,29 @@ USE: kernel
 USE: combinators
 USE: words
 
+"Hi." USE: stdio print
+
 : no-op ; compiled
 
 [ ] [ no-op ] unit-test
 
 : literals 3 5 ; compiled
 
+: tail-call fixnum+ ; compiled
+
+[ 4 ] [ 1 3 tail-call ] 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
 
-: two-calls dup * ; compiled
+: two-calls dup fixnum* ; compiled
 
 [ 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
 
@@ -50,7 +56,7 @@ garbage-collection
 
 [ 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
 
@@ -58,7 +64,7 @@ garbage-collection
     dup 1 <= [
         drop 1
     ] [
-        1 - dup swap 1 - +
+        1 fixnum- dup swap 1 fixnum- fixnum+
     ] ifte ;
 
 [ 17 ] [ 10 dummy-ifte-6 ] unit-test
@@ -80,3 +86,10 @@ garbage-collection
     t [ ] [ ] ifte 5 ; compiled
 
 [ 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
index dfdbaa49d9ea438c55cc94f06e22200bbd46ac38..35fc4cec68ec7b99fd505f6139cfa587747d445a 100644 (file)
@@ -34,16 +34,16 @@ USE: namespaces
 USE: stack
 
 : word-name ( word -- name )
-    "name" swap word-property ;
+    "name" word-property ;
 
 : set-word-name ( word name -- )
-    "name" swap set-word-property ;
+    "name" set-word-property ;
 
 : word-vocabulary ( word -- vocab )
-    "vocabulary" swap word-property ;
+    "vocabulary" word-property ;
 
 : set-word-vocabulary ( word vocab -- )
-    "vocabulary" swap set-word-property ;
+    "vocabulary" set-word-property ;
 
 : each-word ( quot -- )
     #! Apply a quotation to each word in the image.
index de8e9fb4cad5f571eed0fc13b076c5d95ec83dff..9d9fea979dc211f3787dab28c6d33f6a37d7c0ee 100644 (file)
@@ -3,6 +3,7 @@
 XT primitives[] = {
        undefined,
        docol,
+       dosym,
        primitive_execute,
        primitive_call,
        primitive_ifte,
index bf3cca526c9527b071f6523c7b2ae3b75d30717a..fcaddc66ee1bd273e0eb4fe84adede44e7612a65 100644 (file)
@@ -1,4 +1,4 @@
 extern XT primitives[];
-#define PRIMITIVE_COUNT 193
+#define PRIMITIVE_COUNT 194
 
 CELL primitive_to_xt(CELL primitive);
index 92f2a3979d2ae363cf2608d470fe20a02b863d01..9c547662b12fe3c0a3f4e81f3a2906294187f055 100644 (file)
@@ -91,6 +91,12 @@ void docol(void)
        call(executing->parameter);
 }
 
+/* pushes word parameter */
+void dosym(void)
+{
+       dpush(executing->parameter);
+}
+
 void primitive_execute(void)
 {
        executing = untag_word(dpop());
index f2d883fe099e63c75453f9405a4fc24309f246d7..79959bee61e287dd16a7919268c7e814b4aa9fd8 100644 (file)
@@ -103,6 +103,7 @@ void clear_environment(void);
 void run(void);
 void undefined(void);
 void docol(void);
+void dosym(void);
 void primitive_execute(void);
 void primitive_call(void);
 void primitive_ifte(void);