[ "Hello" % " world" % ] make-string
Now, the former raises a type error.
-
+
+- The string-compare primitive has been replaced with the lexi word
+ which now operates on any pair of sequences of numbers. The
+ string> word has been replaced with lexi>.
+
- The stream-write, stream-write-attr, write and write-attr generic
words no longer accept a character as an argument. Use the new
stream-write1 and write1 generic words to write single characters.
- rollovers broken with menus\r
- menu dragging\r
- fix up the min thumb size hack\r
-- bevel borders\r
- nicer scrollbars with up/down buttons\r
- gaps in pack layout\r
- fix listener prompt display after presentation commands invoked\r
- stack display bugs\r
-- simple tutorial\r
+- tutorial: clickable code snippets\r
- parser::skip clean up\r
\r
+ misc\r
[ "dispatch" "kernel-internals" [ [ fixnum vector ] [ ] ] ]
[ "cons" "lists" [ [ object object ] [ cons ] ] ]
[ "<vector>" "vectors" [ [ integer ] [ vector ] ] ]
- [ "string-compare" "strings" [ [ string string ] [ integer ] ] ]
[ "rehash-string" "strings" [ [ string ] [ ] ] ]
[ "<sbuf>" "strings" [ [ integer ] [ sbuf ] ] ]
[ "sbuf>string" "strings" [ [ sbuf ] [ string ] ] ]
] [
over type over type eq? [ sequence= ] [ 2drop f ] ifte
] ifte ;
+
+M: string = ( obj str -- ? )
+ over string? [
+ over hashcode over hashcode number=
+ [ sequence= ] [ 2drop f ] ifte
+ ] [
+ 2drop f
+ ] ifte ;
#! Is every element of seq1 in seq2
swap [ swap member? ] all-with? ;
+! Lexicographic comparison
+: (lexi) ( seq seq i limit -- n )
+ 2dup >= [
+ 2drop swap length swap length -
+ ] [
+ >r 3dup 2nth 2dup = [
+ 2drop 1 + r> (lexi)
+ ] [
+ r> drop - >r 3drop r>
+ ] ifte
+ ] ifte ;
+
+: lexi ( s1 s2 -- n )
+ #! Lexicographically compare two sequences of numbers
+ #! (usually strings). Negative if s1<s2, zero if s1=s2,
+ #! positive if s1>s2.
+ 0 pick length pick length min (lexi) ;
+
+: lexi> ( seq seq -- ? )
+ #! Test if the first sequence follows the second
+ #! lexicographically.
+ lexi 0 > ;
+
IN: kernel
: depth ( -- n )
USING: generic kernel kernel-internals lists math namespaces
sequences strings ;
-: empty-sbuf ( len -- sbuf )
- dup <sbuf> [ set-length ] keep ;
+: empty-sbuf ( len -- sbuf ) dup <sbuf> [ set-length ] keep ;
: fill ( count char -- string ) <repeated> >string ;
M: string like ( seq sbuf -- string ) drop >string ;
-M: sbuf clone ( sbuf -- sbuf )
- [ length <sbuf> dup ] keep nappend ;
+M: sbuf clone ( sbuf -- sbuf ) >sbuf ;
M: sbuf like ( seq sbuf -- sbuf ) drop >sbuf ;
DEFER: string?
BUILTIN: string 12 string? [ 1 length f ] [ 2 hashcode f ] ;
-M: string =
- over string? [
- over hashcode over hashcode number= [
- string-compare 0 eq?
- ] [
- 2drop f
- ] ifte
- ] [
- 2drop f
- ] ifte ;
-
-M: string nth ( n str -- ch )
- bounds-check char-slot ;
+M: string nth ( n str -- ch ) bounds-check char-slot ;
GENERIC: >string ( seq -- string )
M: string >string ;
-: string> ( str1 str2 -- ? )
- ! Returns if the first string lexicographically follows str2
- string-compare 0 > ;
-
! Characters
PREDICATE: integer blank " \t\n\r" member? ;
PREDICATE: integer letter CHAR: a CHAR: z between? ;
IN: vectors
-: empty-vector ( len -- vec )
- #! Creates a vector with 'len' elements set to f. Unlike
- #! <vector>, which gives an empty vector with a certain
- #! capacity.
- dup <vector> [ set-length ] keep ;
+: empty-vector ( len -- vec ) dup <vector> [ set-length ] keep ;
: >vector ( list -- vector )
dup length <vector> [ swap nappend ] keep ;
M: repeated thaw >vector ;
-M: vector clone ( vector -- vector )
- >vector ;
+M: vector clone ( vector -- vector ) >vector ;
-: zero-vector ( n -- vector )
- 0 <repeated> >vector ;
+: zero-vector ( n -- vector ) 0 <repeated> >vector ;
M: general-list thaw >vector ;
#! Write out the HTML for the list of words in a vocabulary.
<select name= "words" style= "width: 200" size= "20" onchange= "document.forms.main.submit()" select>
words [
- word-name dup "current-word" get [ "" ] unless* string-compare 0 = [
+ word-name dup "current-word" get [ "" ] unless* = [
"<option selected>" write
] [
"<option>" write
: path+ ( path path -- path ) "/" swap append3 ;
: exists? ( file -- ? ) stat >boolean ;
: directory? ( file -- ? ) stat car ;
-: directory ( dir -- list ) (directory) [ string> ] sort ;
+: directory ( dir -- list ) (directory) [ lexi> ] sort ;
: file-length ( file -- length ) stat third ;
: file-extension ( filename -- extension )
"." split cdr dup [ peek ] when ;
[ "fdsfs" [ > ] sort ] unit-test-fails
[ [ ] ] [ [ ] [ > ] sort ] unit-test
-[ [ "2 + 2" ] ] [ [ "2 + 2" ] [ string> ] sort ] unit-test
+[ [ "2 + 2" ] ] [ [ "2 + 2" ] [ lexi> ] sort ] unit-test
[ [ 1 2 3 4 5 6 7 ] ] [ [ 6 4 5 7 2 1 3 ] [ > ] sort ] unit-test
[ f ] [ [ { } { } "Hello" ] [ = ] fiber? ] unit-test
[ t ] [ CHAR: 0 digit? ] unit-test
[ f ] [ CHAR: x digit? ] unit-test
-[ t ] [ "abc" "abd" string-compare 0 < ] unit-test
-[ t ] [ "z" "abd" string-compare 0 > ] unit-test
+[ t ] [ "abc" "abd" lexi 0 < ] unit-test
+[ t ] [ "z" "abd" lexi 0 > ] unit-test
[ f ] [ [ 0 10 "hello" subseq ] [ not ] catch ] unit-test
[ f ] [ \ testing generic? ] unit-test
+[ f ] [ gensym interned? ] unit-test
+
+: forgotten ;
+: another-forgotten ;
+
+[ f ] [ \ forgotten interned? ] unit-test
+
+FORGET: forgotten
+
+[ f ] [ \ another-forgotten interned? ] unit-test
+
+FORGET: another-forgotten
+: another-forgotten ;
+
+[ t ] [ \ car interned? ] unit-test
+
! This has to be the last test in the file.
: test-last ( -- ) ;
word word-name "last-word-test" set
seq-transpose
[ " | " join ] map ;
-: interned? ( word -- ? )
- dup word-name swap word-vocabulary vocab hash ;
-
: class-banner ( word -- )
dup metaclass dup [
"This is a class whose behavior is specifed by the " write
#! Print heap allocation breakdown.
0 heap-stats [ dupd uncons heap-stat. 1 + ] each drop ;
-: orphan? ( word -- ? )
- #! Test if the word is not a member of its vocabulary.
- dup dup word-name swap word-vocabulary dup [
- vocab dup [ hash eq? not ] [ 3drop t ] ifte
- ] [
- 3drop t
- ] ifte ;
-
: orphans ( word -- list )
#! Orphans are forgotten but still referenced.
- [ word? ] instances [ orphan? ] subset ;
+ [ word? ] instances [ interned? not ] subset ;
gadget-children { 0 0 0 } [ pref-dim vmax ] reduce ;
M: book layout* ( book -- )
- dup shape-dim over gadget-children [
+ dup rectangle-dim over gadget-children [
f over set-gadget-visible?
- { 0 0 0 } over set-shape-loc
+ { 0 0 0 } over set-rectangle-loc
set-gadget-dim
] each-with
dup book-page swap gadget-children nth
<bevel-gadget> { 5 5 0 } <border> ;
: layout-border-loc ( border -- )
- dup border-size swap gadget-child set-shape-loc ;
+ dup border-size swap gadget-child set-rectangle-loc ;
: layout-border-dim ( border -- )
- dup shape-dim over border-size 2 v*n v-
+ dup rectangle-dim over border-size 2 v*n v-
swap gadget-child set-gadget-dim ;
M: border pref-dim ( border -- dim )
] with-editor ;
: click-editor ( editor -- )
- dup hand relative shape-x over set-caret-x request-focus ;
+ dup hand relative first over set-caret-x request-focus ;
: editor-actions ( editor -- )
[
0 0 3vector ;
: caret-dim ( editor -- w h )
- shape-dim { 0 1 1 } v* { 1 0 0 } v+ ;
+ rectangle-dim { 0 1 1 } v* { 1 0 0 } v+ ;
M: editor user-input* ( ch editor -- ? )
[ insert-char ] with-editor t ;
M: editor layout* ( editor -- )
dup editor-caret over caret-dim swap set-gadget-dim
- dup editor-caret swap caret-loc swap set-shape-loc ;
+ dup editor-caret swap caret-loc swap set-rectangle-loc ;
M: editor draw-gadget* ( editor -- )
dup delegate draw-gadget*
var-frame-bottom ;
: move-gadget ( x y gadget -- )
- >r 0 3vector r> set-shape-loc ;
+ >r 0 3vector r> set-rectangle-loc ;
: reshape-gadget ( x y w h gadget -- )
[ >r 0 3vector r> set-gadget-dim ] keep move-gadget ;
dup add-invalid (relayout-down) ;
: set-gadget-dim ( dim gadget -- )
- 2dup shape-dim =
- [ 2drop ] [ [ set-shape-dim ] keep relayout-down ] ifte ;
+ 2dup rectangle-dim =
+ [ 2drop ] [ [ set-rectangle-dim ] keep relayout-down ] ifte ;
GENERIC: pref-dim ( gadget -- dim )
-M: gadget pref-dim shape-dim ;
+M: gadget pref-dim rectangle-dim ;
GENERIC: layout* ( gadget -- )
#! enter gesture, since the mouse did not enter. Otherwise,
#! fire an enter gesture and go on to the parent.
[
- [ shape-loc v+ ] keep
+ [ rectangle-loc v+ ] keep
2dup inside? [ mouse-enter ] hierarchy-gesture
] each-parent 2drop ;
#! leave gesture, since the mouse did not leave. Otherwise,
#! fire a leave gesture and go on to the parent.
[
- [ shape-loc v+ ] keep
+ [ rectangle-loc v+ ] keep
2dup inside? [ mouse-leave ] hierarchy-gesture
] each-parent 2drop ;
#! in any subgadget. If not, see if it is contained in the
#! box delegate.
dup gadget-visible? >r 2dup inside? r> drop [
- [ translate ] keep 2dup
+ [ rectangle-loc v- ] keep 2dup
(pick-up) [ pick-up ] [ nip ] ?ifte
] [
2drop f
[ hand-buttons remove ] keep set-hand-buttons ;
: fire-leave ( hand gadget -- )
- [ swap shape-loc swap screen-loc v- ] keep mouse-leave ;
+ [ swap rectangle-loc swap screen-loc v- ] keep mouse-leave ;
: fire-enter ( oldpos hand -- )
hand-gadget [ screen-loc v- ] keep mouse-enter ;
: update-hand-gadget ( hand -- )
- [ world get pick-up ] keep set-hand-gadget ;
+ [ rectangle-loc world get pick-up ] keep set-hand-gadget ;
: motion-gesture ( hand gadget gesture -- )
#! Send a gesture like [ drag 2 ].
[ dup hand-clicked [ drag ] motion-gesture ] [ drop ] ifte ;
: move-hand ( loc hand -- )
- dup shape-loc >r
- [ set-shape-loc ] keep
+ dup rectangle-loc >r
+ [ set-rectangle-loc ] keep
dup hand-gadget >r
dup update-hand-gadget
dup r> fire-leave
: update-hand ( hand -- )
#! Called when a gadget is removed or added.
- dup shape-loc swap move-hand ;
+ dup rectangle-loc swap move-hand ;
: request-focus ( gadget -- )
focusable-child
#! is the gadget itself.
dup [ dup gadget-parent parents cons ] when ;
+: find-parent ( gadget quot -- ? )
+ >r parents r> find nip ;
+
: each-parent ( gadget quot -- ? )
#! Keep executing the quotation on higher and higher
#! parents until it returns f.
: screen-loc ( gadget -- point )
#! The position of the gadget on the screen.
- parents { 0 0 0 } [ shape-loc v+ ] reduce ;
+ parents { 0 0 0 } [ rectangle-loc v+ ] reduce ;
: relative ( g1 g2 -- g2-g1 )
screen-loc swap screen-loc v- ;
: next-cursor ( gadget incremental -- cursor )
[
- swap shape-dim swap incremental-cursor
+ swap rectangle-dim swap incremental-cursor
2dup v+ >r vmax r>
] keep pack-vector set-axis ;
: incremental-loc ( gadget incremental -- )
dup incremental-cursor swap pack-vector v*
- swap set-shape-loc ;
+ swap set-rectangle-loc ;
: prefer-incremental ( gadget -- )
- dup pref-dim swap set-shape-dim ;
+ dup pref-dim swap set-rectangle-dim ;
: add-incremental ( gadget incremental -- )
2dup (add-gadget)
prefer-incremental ;
: clear-incremental ( incremental -- )
- dup (clear-gadget) { 0 0 0 } swap set-incremental-cursor ;
+ dup (clear-gadget)
+ { 0 0 0 } over set-incremental-cursor
+ gadget-parent [ relayout ] when* ;
! See http://factor.sf.net/license.txt for BSD license.
IN: gadgets
USING: generic io kernel listener math namespaces prettyprint
-sequences styles threads ;
+sequences styles threads words ;
SYMBOL: stack-display
[
pane get [
[ ui.s ] listener-hook set
- clear print-banner listener
+ clear print-banner
+ "Tutorial" [ [ tutorial ] pane get pane-call ] <button> gadget.
+ listener
] with-stream
] in-thread
: packed-dim-2 ( gadget sizes -- list )
[
- over shape-dim { 1 1 1 } vmax over v-
+ over rectangle-dim { 1 1 1 } vmax over v-
rot pack-fill v*n v+
] map-with ;
{ 0 0 0 } [ v+ ] accumulate ;
: packed-loc-2 ( gadget sizes -- list )
- >r dup shape-dim { 1 1 1 } vmax over r>
+ >r dup rectangle-dim { 1 1 1 } vmax over r>
packed-dim-2 [ v- ] map-with
- >r dup pack-align swap shape-dim { 1 1 1 } vmax r>
+ >r dup pack-align swap rectangle-dim { 1 1 1 } vmax r>
[ >r 2dup r> v- n*v ] map 2nip ;
: (packed-locs) ( gadget sizes -- list )
: packed-locs ( gadget sizes -- )
over gadget-children >list >r (packed-locs) r>
- zip [ uncons set-shape-loc ] each ;
+ zip [ uncons set-rectangle-loc ] each ;
: packed-layout ( gadget sizes -- )
2dup packed-locs packed-dims ;
USING: generic kernel lists math namespaces sequences ;
: show-menu ( menu -- )
- hand screen-loc over set-shape-loc show-glass ;
+ hand screen-loc over set-rectangle-loc show-glass ;
: menu-item-border ( child -- border )
<plain-gadget> { 1 1 0 } <border> ;
dup first [ 3dup gradient-y ] repeat 2drop ;
M: gradient draw-interior ( gadget gradient -- )
- swap shape-dim { 1 1 1 } vmax
+ swap rectangle-dim { 1 1 1 } vmax
over gradient-vector { 1 0 0 } =
[ horiz-gradient ] [ vert-gradient ] ifte ;
#! Ugly code.
bevel-width [
[
- >r x get y get 0 3vector over shape-dim over v+ r>
+ >r origin over rectangle-dim over v+ r>
{ 1 1 0 } n*v tuck v- { 1 1 0 } v- >r v+ r>
rot draw-bevel
] 2keep
: viewport-dim gadget-child pref-dim ;
: fix-scroll ( origin viewport -- origin )
- dup shape-dim swap viewport-dim v- vmax { 0 0 0 } vmin ;
+ dup rectangle-dim swap viewport-dim v- vmax { 0 0 0 } vmin ;
: scroll ( origin viewport -- )
[ fix-scroll ] keep [ set-viewport-origin ] keep relayout ;
M: viewport layout* ( viewport -- )
dup gadget-child dup prefer
- >r viewport-origin* r> set-shape-loc ;
+ >r viewport-origin* r> set-rectangle-loc ;
M: viewport focusable-child* ( viewport -- gadget )
gadget-child ;
: visible-portion ( viewport -- vector )
- dup shape-dim { 1 1 1 } vmax
+ dup rectangle-dim { 1 1 1 } vmax
swap viewport-dim { 1 1 1 } vmax
v/ { 1 1 1 } vmin ;
: slider-dim { 16 16 16 } ;
: thumb-dim ( slider -- h )
- [ shape-dim dup ] keep >thumb slider-dim vmax vmin ;
+ [ rectangle-dim dup ] keep >thumb slider-dim vmax vmin ;
M: slider pref-dim drop slider-dim ;
M: slider layout* ( slider -- )
dup thumb-loc over slider-vector v*
- over slider-thumb set-shape-loc
+ over slider-thumb set-rectangle-loc
dup thumb-dim over slider-vector v* slider-dim vmax
swap slider-thumb set-gadget-dim ;
: origin ( -- loc ) x get y get 0 3vector ;
+TUPLE: rectangle loc dim ;
+
GENERIC: inside? ( loc shape -- ? )
-GENERIC: shape-loc ( shape -- loc )
-GENERIC: set-shape-loc ( loc shape -- )
-GENERIC: shape-dim ( shape -- dim )
-GENERIC: set-shape-dim ( dim shape -- )
-: shape-x shape-loc first ;
-: shape-y shape-loc second ;
-: shape-w shape-dim first ;
-: shape-h shape-dim second ;
+: shape-x rectangle-loc first ;
+: shape-y rectangle-loc second ;
+: shape-w rectangle-dim first ;
+: shape-h rectangle-dim second ;
: with-trans ( shape quot -- )
#! All drawing done inside the quotation is translated
r> call
] with-scope ; inline
-: shape-pos ( shape -- pos )
- dup shape-x swap shape-y rect> ;
-
: shape-bounds ( shape -- loc dim )
- dup shape-loc swap shape-dim ;
+ dup rectangle-loc swap rectangle-dim ;
: shape-extent ( shape -- loc dim )
- dup shape-loc dup rot shape-dim v+ ;
-
-: translate ( shape shape -- point )
- #! Translate a point relative to the shape.
- swap shape-loc swap shape-loc v- ;
-
-M: vector shape-loc ;
-M: vector shape-dim drop { 0 0 0 } ;
-
-TUPLE: rectangle loc dim ;
-
-M: rectangle shape-loc rectangle-loc ;
-M: rectangle set-shape-loc set-rectangle-loc ;
-
-M: rectangle shape-dim rectangle-dim ;
-M: rectangle set-shape-dim set-rectangle-dim ;
+ dup rectangle-loc dup rot rectangle-dim v+ ;
: screen-bounds ( shape -- rect )
shape-bounds >r origin v+ r> <rectangle> ;
: divider-motion ( splitter -- )
dup hand>split
- over shape-dim { 1 1 1 } vmax v/ over pack-vector v.
+ over rectangle-dim { 1 1 1 } vmax v/ over pack-vector v.
0 max 1 min over set-splitter-split relayout ;
: divider-actions ( thumb -- )
{ 1 0 0 } <splitter> ;
: splitter-part ( splitter -- vec )
- dup splitter-split swap shape-dim
+ dup splitter-split swap rectangle-dim
n*v divider-size 1/2 v*n v- ;
: splitter-layout ( splitter -- [ a b c ] )
[
dup splitter-part ,
divider-size ,
- dup shape-dim divider-size v- swap splitter-part v- ,
+ dup rectangle-dim divider-size v- swap splitter-part v- ,
] make-list ;
M: splitter layout* ( splitter -- )
dup 18 font-size set-paint-prop\r
<book-browser> ;\r
\r
-: tutorial <tutorial> gadget. ;\r
+: tutorial ( -- )\r
+ ensure-ui <tutorial> gadget. ;\r
#! dimensions.
ttf-init
?init-world
- world get shape-dim 2unseq 0 SDL_RESIZABLE [
+ world get rectangle-dim 2unseq 0 SDL_RESIZABLE [
0 x set 0 y set [
"Factor " version append dup SDL_WM_SetCaption
start-world
! Copyright (C) 2004, 2005 Slava Pestov.
! See http://factor.sf.net/license.txt for BSD license.
-IN: words USING: hashtables kernel lists namespaces strings
-sequences ;
+IN: words
+USING: hashtables kernel lists namespaces strings sequences ;
SYMBOL: vocabularies
: vocabs ( -- list )
#! Push a list of vocabularies.
- vocabularies get hash-keys [ string> ] sort ;
+ vocabularies get hash-keys [ lexi> ] sort ;
: vocab ( name -- vocab )
#! Get a vocabulary.
dup uncrossref
dup word-vocabulary vocab [ word-name off ] bind ;
+: interned? ( word -- ? )
+ #! Test if the word is a member of its vocabulary.
+ dup dup word-name swap word-vocabulary dup [
+ vocab dup [ hash eq? ] [ 3drop f ] ifte
+ ] [
+ 3drop f
+ ] ifte ;
+
: init-search-path ( -- )
! For files
"scratchpad" "file-in" set
: word-sort ( list -- list )
#! Sort a list of words by name.
- [ swap word-name swap word-name string> ] sort ;
+ [ swap word-name swap word-name lexi> ] sort ;
! The cross-referencer keeps track of word dependencies, so that
! words can be recompiled when redefined.
#include "factor.h"
+F_FIXNUM string_compare(F_STRING* s1, F_STRING* s2)
+{
+ CELL len1 = string_capacity(s1);
+ CELL len2 = string_capacity(s2);
+
+ CELL limit = (len1 < len2 ? len1 : len2);
+
+ CELL i = 0;
+ while(i < limit)
+ {
+ u16 c1 = string_nth(s1,i);
+ u16 c2 = string_nth(s2,i);
+ if(c1 != c2)
+ return c1 - c2;
+ i++;
+ }
+
+ return len1 - len2;
+}
+
/* Implements some Factor library words in C, to dump a stack in a semi-human-readable
form without any Factor code executing.. This is not used during normal execution, only
when the runtime dies. */
primitive_dispatch,
primitive_cons,
primitive_vector,
- primitive_string_compare,
primitive_rehash_string,
primitive_sbuf,
primitive_sbuf_to_string,
CELL value = untag_fixnum_fast(dpop());
set_string_nth(string,index,value);
}
-
-F_FIXNUM string_compare(F_STRING* s1, F_STRING* s2)
-{
- CELL len1 = string_capacity(s1);
- CELL len2 = string_capacity(s2);
-
- CELL limit = (len1 < len2 ? len1 : len2);
-
- CELL i = 0;
- while(i < limit)
- {
- u16 c1 = string_nth(s1,i);
- u16 c2 = string_nth(s2,i);
- if(c1 != c2)
- return c1 - c2;
- i++;
- }
-
- return len1 - len2;
-}
-
-void primitive_string_compare(void)
-{
- F_STRING* s2 = untag_string(dpop());
- F_STRING* s1 = untag_string(dpop());
-
- dpush(tag_fixnum(string_compare(s1,s2)));
-}
void primitive_char_slot(void);
void primitive_set_char_slot(void);
-F_FIXNUM string_compare(F_STRING* s1, F_STRING* s2);
-void primitive_string_compare(void);