diff --git a/TODO.FACTOR.txt b/TODO.FACTOR.txt index 595c42402c..4c27ad70ae 100644 --- a/TODO.FACTOR.txt +++ b/TODO.FACTOR.txt @@ -6,6 +6,7 @@ [ 1 2 3 4 5 6 7 8 9 10 10 10 10 10 10 10 10 10 10 11 11 11 113 ] +- unix i/o: problems with passing f to syscalls - if a primitive throws an error, :c doesn't show the call frame there - "benchmark/help": without a yield UI runs out of memory - x11 title bars are funny @@ -37,9 +38,7 @@ - better line spacing in ui and html - related issue + tabular formatting in UI - - $values - other help aspects - - setting grid gap + fix compiled gc check - there was a performance hit, investigate diff --git a/doc/handbook/alien.facts b/doc/handbook/alien.facts index 958f11dd47..b81963dd44 100644 --- a/doc/handbook/alien.facts +++ b/doc/handbook/alien.facts @@ -60,19 +60,20 @@ $terpri ARTICLE: "c-types-numeric" "Integer and floating point C types" "The following numerical types are available; a " { $snippet "u" } " prefix denotes an unsigned type:" -{ $list - { { $snippet "char" } " - always 1 byte" } +{ $table + { "C type" "Notes" } + { { $snippet "char" } "always 1 byte" } { $snippet "uchar" } - { { $snippet "short" } " - always 2 bytes" } + { { $snippet "short" } "always 2 bytes" } { $snippet "ushort" } - { { $snippet "int" } " - always 4 bytes" } + { { $snippet "int" } "always 4 bytes" } { $snippet "uint" } - { { $snippet "long" } " - same size as CPU word size and " { $snippet "void*" } ", except on 64-bit Windows, where it is 4 bytes" } - { $snippet "ulong" } - { { $snippet "longlong" } " - always 8 bytes" } - { $snippet "ulonglong" } - { $snippet "float" } - { { $snippet "double" } " - same format as " { $link float } " objects" } + { { $snippet "long" } { "same size as CPU word size and " { $snippet "void*" } ", except on 64-bit Windows, where it is 4 bytes" } } + { { $snippet "ulong" } { } + { { $snippet "longlong" } "always 8 bytes" } + { { $snippet "ulonglong" } { } + { { $snippet "float" } { } } + { { $snippet "double" } "same format as " { $link float } " objects" } } "When making alien calls, Factor numbers are converted to and from the above types in a canonical way. Converting a Factor number to a C value may result in a loss of precision." $terpri @@ -113,9 +114,10 @@ $terpri ARTICLE: "c-types-strings" "C string types" "The C library interface defines two types of C strings:" -{ $list - { { $snippet "char*" } " - 8-bit per character null-terminated ASCII" } - { { $snippet "ushort*" } " - 16-bit per character null-terminated UTF16" } +{ $table + { "C type" "Notes" } + { { $snippet "char*" } "8-bit per character null-terminated ASCII" } + { { $snippet "ushort*" } "16-bit per character null-terminated UTF16" } } "Passing an instance of " { $link c-ptr } " to a C function expecting a C string will simply pass in the address of the " { $link c-ptr } "." $terpri diff --git a/doc/handbook/parser.facts b/doc/handbook/parser.facts index fd06624c9b..31d21ceaf7 100644 --- a/doc/handbook/parser.facts +++ b/doc/handbook/parser.facts @@ -44,11 +44,12 @@ ARTICLE: "parsing-word-nest" "Nested structure" "The first thing to look at is how the parse tree is built. When parsing begins, " { $link f } " is pushed on the data stack; when a new object is parsed, " { $link ?push } " is called to add it to the parse tree. The first call to " { $link ?push } " creates a new one-element vector, and subsequent calls add elements to the end of this vector. When parsing is complete, the vector is converted into a quotation." $terpri "Lets look at a simple example; the parsing of " { $snippet "1 2 3" } ":" -{ $list - { "Initial stack after parsing begins:" { $snippet "f" } } - { "Token: " { $snippet "1" } " - stack top: " { $snippet "V{ 1 }" } } - { "Token: " { $snippet "2" } " - stack top: " { $snippet "V{ 1 2 }" } } - { "Token: " { $snippet "3" } " - stack top: " { $snippet "V{ 1 2 3 }" } } +{ $table + { "Action" "Stack" } + { "Initial stack after parsing begins" { $snippet "f" } } + { { "Token: " { $snippet "1" } } { $snippet "V{ 1 }" } } + { { "Token: " { $snippet "2" } } { $snippet "V{ 1 2 }" } } + { { "Token: " { $snippet "3" } } { $snippet "V{ 1 2 3 }" } } { "Final stack upon completion:" { $snippet "[ 1 2 3 ]" } } } "Nested structure is a bit more involved. The basic idea is that parsing words can push " { $link f } " on the stack to begin a new level of nesting, then all subsequent objects are pushed onto this sequence, until another parsing word adds this sequence to the vector underneath." @@ -58,15 +59,16 @@ $terpri { $subsection POSTPONE: ] } "Let us ponder, then, how one particular string will parse:" { $snippet "\"1 [ 2 3 ] 4\"" } -{ $list - { "Initial stack after parsing begins:" { $snippet "f" } } - { "Token: " { $snippet "1" } " - stack top: " { $snippet "V{ 1 }" } } - { "Token: " { $snippet "[" } " - stack top: " { $snippet "V{ 1 } f" } } - { "Token: " { $snippet "2" } " - stack top: " { $snippet "V{ 1 } V{ 2 }" } } - { "Token: " { $snippet "3" } " - stack top: " { $snippet "V{ 1 } V{ 2 3 }" } } - { "Token: " { $snippet "]" } " - stack top: " { $snippet "V{ 1 [ 2 3 ] }" } } - { "Token: " { $snippet "4" } " - stack top: " { $snippet "V{ 1 [ 2 3 ] 4 }" } } - { "Final stack upon completion:" { $snippet "[ 1 [ 2 3 ] 4 ]" } } +{ $table + { "Action" "Stack" } + { "Initial stack after parsing begins" { $snippet "f" } } + { { "Token: " { $snippet "1" } } { $snippet "V{ 1 }" } } + { { "Token: " { $snippet "[" } } { $snippet "V{ 1 } f" } } + { { "Token: " { $snippet "2" } } { $snippet "V{ 1 } V{ 2 }" } } + { { "Token: " { $snippet "3" } } { $snippet "V{ 1 } V{ 2 3 }" } } + { { "Token: " { $snippet "]" } } { $snippet "V{ 1 [ 2 3 ] }" } } + { { "Token: " { $snippet "4" } } { $snippet "V{ 1 [ 2 3 ] 4 }" } } + { "Final stack upon completion" { $snippet "[ 1 [ 2 3 ] 4 ]" } } } "Notice how in the definition of the quotation parsing words, the final word " { $link POSTPONE: ] } " does all the work. A closely related set of parsing words for reading various other literal types implements another useful idiom." $terpri diff --git a/doc/handbook/syntax.facts b/doc/handbook/syntax.facts index db74cd4d95..bdad3db628 100644 --- a/doc/handbook/syntax.facts +++ b/doc/handbook/syntax.facts @@ -168,16 +168,16 @@ ARTICLE: "syntax-strings" "Character and string syntax" "Strings are documented in " { $link "strings" } "." ; ARTICLE: "escape" "Character escape codes" -"The following escape codes may be used:" -{ $list - { { $snippet "\\\\" } " - " { $snippet "\\" } } - { { $snippet "\\s" } " - a space" } - { { $snippet "\\t" } " - a tab" } - { { $snippet "\\n" } " - a newline" } - { { $snippet "\\r" } " - a carriage return" } - { { $snippet "\\0" } " - a null byte (ASCII 0)" } - { { $snippet "\\e" } " - escape (ASCII 27)" } - { { $snippet "\\\"" } " - " { $snippet "\"" } } +{ $table + { "Escape code" "Meaning" } + { { $snippet "\\\\" } { $snippet "\\" } } + { { $snippet "\\s" } "a space" } + { { $snippet "\\t" } "a tab" } + { { $snippet "\\n" } "a newline" } + { { $snippet "\\r" } "a carriage return" } + { { $snippet "\\0" } "a null byte (ASCII 0)" } + { { $snippet "\\e" } "escape (ASCII 27)" } + { { $snippet "\\\"" } { $snippet "\"" } } } "A Unicode character can be specified by its code number by writing " { $snippet "\\u" } " followed by a four-digit hexadecimal number. That is, the following two expressions are equivalent:" { $code diff --git a/doc/handbook/tutorial.facts b/doc/handbook/tutorial.facts deleted file mode 100644 index 65ae12e48d..0000000000 --- a/doc/handbook/tutorial.facts +++ /dev/null @@ -1,198 +0,0 @@ -IN: help -USING: io ; - -ARTICLE: "tutorial-overview" "The view from 10,000 feet" -{ $list - "Everything is an object" - "A word is a basic unit of code" - "Words are identified by names, and organized in vocabularies" - "Words pass parameters on the stack" - "Code blocks can be passed as parameters to words" - "Word definitions are very short with very high code reuse" -} ; - -ARTICLE: "tutorial-syntax" "Basic syntax" -"Factor code is made up of whitespace-separated tokens. Recall the example from the first page:" -{ $code "\"hello world\" print" } -{ $list - { "The first token (" { $snippet "\"hello world\"" } ") is a string." } - { "The second token (" { $snippet "print" } ") is a word." } - "The string is pushed on the stack, and the print word prints it." -} ; - -ARTICLE: "tutorial-stack" "The stack" -"The stack is like a pile of papers. You can ``push'' papers on the top of the pile and ``pop'' papers from the top of the pile. Here is another code example:" -{ $code "2 3 + ." } -"Try running it in the listener now." ; - -ARTICLE: "tutorial-postfix" "Postfix arithmetic" -"What happened when you ran it? The two numbers (2 3) are pushed on the stack. Then, the + word pops them and pushes the result (5). Then, the . word prints this result." -{ $list - "This is called postfix arithmetic." - { "Traditional arithmetic is called infix: " { $snippet "3 + (6 * 2)" } } - { "Lets translate this into postfix: " { $snippet "3 6 2 * + ." } } -} ; - -ARTICLE: "tutorial-colon-def" "Colon definitions" -"We can define new words in terms of existing words." -{ $code ": twice 2 * ;" } -"This defines a new word named " { $snippet "twice" } " that calls " { $snippet "2 *" } ". Try the following in the listener:" -{ $code "3 twice twice ." } -"The result is the same as if you wrote:" -{ $code "3 2 * 2 * ." } ; - -ARTICLE: "tutorial-stack-effects" "Stack effects" -"When we look at the definition of the " { $snippet "twice" } " word, it is intuitively obvious that it takes one value from the stack, and leaves one value behind. However, with more complex definitions, it is better to document this so-called " { $emphasis "stack effect" } ". A stack effect comment is written between ( and ). Factor ignores stack effect comments. Don't you!" -$terpri -"The stack effect of " { $snippet "twice" } " is " { $snippet "( x -- 2*x )" } "." -$terpri -"The stack effect of " { $snippet "+" } " is " { $snippet "( x y -- x+y )" } "." -$terpri -"The stack effect of " { $snippet "." } " is " { $snippet "( object -- )" } "." ; - -ARTICLE: "tutorial-input" "Reading user input" -"User input is read using the " { $snippet "readln ( -- string )" } " word. Note its stack effect; it puts a string on the stack." -"This program will ask your name, then greet you:" -{ $code "\"What is your name?\" print\nreadln \"Hello, \" write print" } ; - -ARTICLE: "tutorial-shuffle" "Shuffle words" -"The word " { $snippet "twice" } " we defined is useless. Let's try something more useful: squaring a number." -$terpri -"We want a word with stack effect " { $snippet "( n -- n*n )" } ". We cannot use " { $snippet "*" } " by itself, since its stack effect is " { $snippet "( x y -- x*y )" } "; it expects two inputs." -$terpri -"However, we can use the word " { $snippet "dup ( object -- object object )" } ". The " { $snippet "dup" } " word is known as a shuffle word." ; - -ARTICLE: "tutorial-squared" "The squared word" -"Try entering the following word definition:" -{ $code ": square ( n -- n*n ) dup * ;" } -"Shuffle words solve the problem where we need to compose two words, but their stack effects do not ``fit''." -$terpri -"Some of the most commonly-used shuffle words:" -{ $code "drop ( object -- )\nswap ( obj1 obj2 -- obj2 obj1 )\nover ( obj1 obj2 -- obj1 obj2 obj1 )" } ; - -ARTICLE: "tutorial-shuffle-again" "Another shuffle example" -"Now let us write a word that negates a number." -"Start by entering the following in the listener" -{ $code "0 10 - ." } -"It will print -10, as expected. Now notice that this the same as:" -{ $code "10 0 swap - ." } -"So indeed, we can factor out the definition " { $snippet "0 swap -" } ":" -{ $code ": negate ( n -- -n ) 0 swap - ;" } ; - -ARTICLE: "tutorial-see" "Seeing words" -"If you have entered every definition in this tutorial, you will now have several new colon definitions:" -{ $code "twice\nsquare\nnegate" } -"You can look at previously-entered word definitions using " { $snippet "see" } ". Try the following:" -{ $code "\\ negate see" } -"Prefixing a word with " { $snippet "\\" } " pushes it on the stack, instead of executing it. So the see word has stack effect " { $snippet "( word -- )" } "." ; - -ARTICLE: "tutorial-branches" "Branches" -"Now suppose we want to write a word that computes the absolute value of a number; that is, if it is less than 0, the number will be negated to yield a positive result." -{ $code ": absolute ( x -- |x| ) dup 0 < [ negate ] when ;" } -"If the top of the stack is negative, the word negates it again, making it positive. The < ( x y -- x explain" } -"A tuple is a collection of named slots. Tuples support custom constructors, delegation... see the developer's handbook for details." ; - -ARTICLE: "tutorial-library" "The library" -"Offers a good selection of highly-reusable words:" -{ $list - "Operations on sequences" - "Variety of mathematical functions" - "Web server and web application framework" - "Graphical user interface framework" -} -"Browsing the library:" -{ $list - { - "To list all vocabularies:" - { $code "vocabs ." } - } - { - "To list all words in a vocabulary:" - { $code "\"sequences\" words ." } - } - { - "To show a word definition:" - { $code "\\ reverse see" } - } -} ; - -ARTICLE: "tutorial-more" "Learning more" -"Hopefully this tutorial has sparked your interest in Factor." -"You can learn more by reading the Factor developer's handbook:" -$terpri -{ $url "http://factorcode.org/handbook.pdf" } -$terpri -"Also, point your IRC client to irc.freenode.net and hop in the #concatenative channel to chat with other Factor geeks." ; - -ARTICLE: "tutorial" "Factor tutorial" -"Welcome to the Factor tutorial!" -$terpri -"Factor is interactive, which means you can test out the code in this tutorial immediately." -$terpri -"Code examples will insert themselves in the listener's input area when clicked:" -{ $code "\"hello world\" print" } -"You can then press ENTER to execute the code, or edit it first." -{ $url "http://factorcode.org" } -{ $subsection "tutorial-overview" } -{ $subsection "tutorial-syntax" } -{ $subsection "tutorial-stack" } -{ $subsection "tutorial-postfix" } -{ $subsection "tutorial-colon-def" } -{ $subsection "tutorial-stack-effects" } -{ $subsection "tutorial-input" } -{ $subsection "tutorial-shuffle" } -{ $subsection "tutorial-squared" } -{ $subsection "tutorial-shuffle-again" } -{ $subsection "tutorial-see" } -{ $subsection "tutorial-branches" } -{ $subsection "tutorial-combinators" } -{ $subsection "tutorial-sequences" } -{ $subsection "tutorial-seq-combinators" } -{ $subsection "tutorial-rationals" } -{ $subsection "tutorial-oop" } -{ $subsection "tutorial-classes" } -{ $subsection "tutorial-library" } -{ $subsection "tutorial-more" } ; diff --git a/library/bootstrap/boot-stage1.factor b/library/bootstrap/boot-stage1.factor index 26326d1d4b..20015d1ddc 100644 --- a/library/bootstrap/boot-stage1.factor +++ b/library/bootstrap/boot-stage1.factor @@ -296,7 +296,6 @@ vectors words ; "/doc/handbook/streams.facts" "/doc/handbook/syntax.facts" "/doc/handbook/tools.facts" - "/doc/handbook/tutorial.facts" "/doc/handbook/words.facts" } [ parse-resource* % ] each diff --git a/library/help/markup.factor b/library/help/markup.factor index cfb017f1ac..aa017f5029 100644 --- a/library/help/markup.factor +++ b/library/help/markup.factor @@ -154,10 +154,12 @@ M: f >link ; : $see-also ( content -- ) "See also" $heading [ 1array $link ] textual-list ; +: $table ( content -- ) [ print-element ] tabular-output ; + : $values ( content -- ) "Arguments and values" $heading - [ unclip $snippet " -- " format* print-element ] - [ terpri ] interleave ; + [ first2 >r \ $snippet swap 2array r> 2array ] map + $table ; : $predicate ( content -- ) { { "object" "an object" } } $values @@ -167,12 +169,7 @@ M: f >link ; " class." , ] { } make $description ; -: $list ( content -- ) - [ - [ - list-element-style [ print-element ] with-nesting* - ] ($block) - ] each ; +: $list ( content -- ) [ "-" swap 2array ] map $table ; : $errors ( content -- ) "Errors" $heading print-element ; diff --git a/library/help/stylesheet.factor b/library/help/stylesheet.factor index 12630b4236..e7720ce68d 100644 --- a/library/help/stylesheet.factor +++ b/library/help/stylesheet.factor @@ -63,6 +63,3 @@ USING: styles ; { border-color { 1 0 0 1 } } { border-width 5 } } ; - -: list-element-style - H{ { border-color { 0.8 0.8 0.8 1 } } { border-width 5 } } ; diff --git a/library/tools/memory.factor b/library/tools/memory.factor index 27082e03d4..97412b91da 100644 --- a/library/tools/memory.factor +++ b/library/tools/memory.factor @@ -9,26 +9,31 @@ sequences strings vectors words ; ! Printing an overview of heap usage. -: kb. - 1024 /i number>string - 6 CHAR: \s pad-left write - " KB" write ; +: total/used/free, ( free total str -- ) + [ + , + dup number>string , + over - number>string , + number>string , + ] { } make , ; -: (room.) ( free total -- ) - 2dup swap - swap ( free used total ) - kb. " total " write - kb. " used " write - kb. " free" print ; +: total, ( n str -- ) + [ , number>string , "" , "" , ] { } make , ; + +: room-table ( -- table ) + room [ + { "" "Total" "Used" "Free" } , + 0 [ + "Generation " pick number>string append + >r first2 r> total/used/free, 1+ + ] reduce drop + "Semi-space" total, + "Cards" total, + "Code space" total/used/free, + ] [ ] make ; : room. ( -- ) - room - 0 swap [ - "Generation " write over pprint ":" write - first2 (room.) 1+ - ] each drop - "Semi-space: " write kb. terpri - "Cards: " write kb. terpri - "Code space: " write (room.) ; + room-table [ write ] tabular-output ; ! Some words for iterating through the heap. @@ -76,13 +81,12 @@ M: object each-slot ( obj quot -- ) H{ } clone H{ } clone [ >r 2dup r> heap-stat-step ] each-object ; -: heap-stat. ( instances bytes class -- ) - pprint ": " write - pprint " bytes, " write - pprint " instances" print ; - : heap-stats. ( -- ) heap-stats dup hash-keys natural-sort [ - ( hash hash key -- ) - [ [ pick hash ] keep pick hash ] keep heap-stat. - ] each 2drop ; + { "Class" "Bytes" "Instances" } , + [ + ( hash hash key -- ) + [ dup , dup pick hash , pick hash , ] { } make , + ] each 2drop + ] { } make + [ dup string? [ write ] [ pprint ] if ] tabular-output ; diff --git a/library/ui/gadgets/grids.factor b/library/ui/gadgets/grids.factor index ab4713a8c1..2f095475a9 100644 --- a/library/ui/gadgets/grids.factor +++ b/library/ui/gadgets/grids.factor @@ -36,10 +36,15 @@ C: grid ( children -- grid ) : with-grid ( grid quot -- | quot: horiz vert -- ) [ >r grid set compute-grid r> call ] with-scope ; inline -: +gap+ + grid get grid-gap + ; +: gap grid get grid-gap ; M: grid pref-dim* ( grid -- dim ) - [ [ 0 [ +gap+ ] reduce ] 2apply 0 3array ] with-grid ; + [ + [ + [ 0 [ + ] reduce ] keep length + 1- 0 max gap * + + ] 2apply 0 3array + ] with-grid ; : pair-up ( horiz vert -- dims ) [ swap [ swap 0 3array ] map-with ] map-with ; @@ -50,7 +55,7 @@ M: grid pref-dim* ( grid -- dim ) ] 2each drop ; inline : position-grid ( horiz vert -- ) - [ 0 [ +gap+ ] accumulate ] 2apply + [ 0 [ + gap + ] accumulate ] 2apply pair-up [ set-rect-loc ] do-grid ; : resize-grid ( horiz vert -- ) diff --git a/library/ui/gadgets/panes.factor b/library/ui/gadgets/panes.factor index 957b3cce34..1dbaf42015 100644 --- a/library/ui/gadgets/panes.factor +++ b/library/ui/gadgets/panes.factor @@ -141,5 +141,6 @@ M: pane stream-close ( pane -- ) drop ; [ swap with-pane ] keep ; inline M: pane with-stream-table ( quot grid pane -- ) - >r [ [ swap make-pane ] map-with ] map-with + >r [ [ swap make-pane ] map-with ] map-with + 5 over set-grid-gap r> [ write-gadget ] keep stream-terpri ;