-- sometimes fep when closing window
-- windows rollover broken again
-- compile error after reloading library/math/float.factor
-- move window while factor is busy: mouse gets messed up!
++ 0.87:
-+ ui:
-
-- docs: don't pass volatile aliens to callbacks
+- cocoa: move window while factor is busy: mouse gets messed up!
- live search: timer delay would be nice
- menu should stay up if mouse button released
- roundoff is still not quite right with tracks
- grid displays quickly now, but constructing large amounts of gadgets
is slow: eg, 10000 [ dup number>string ] map describe
- completion is not ideal: eg, C+e "buttons"
-- some way of intercepting all gestures
- slider needs to be modelized
- better help result ranking
- help search looks funny
- graphical crossref tool
- ui browser: show currently selected vocab & words
- auto-update browser and help when sources reload
+- amd64 structs-by-value bug
+- intrinsic fixnum>float float>fixnum
+- mac intel: struct returns from objc methods
+- faster apropos
+- infer which variables are read, written in a quotation
+- compiled call traces
+- if listener is busy open a new listener when doing listener operations
+
++ ui:
+
+- some way of intercepting all gestures
- how do we refer to command shortcuts in the docs?
- fix top level window positioning
- editor:
+ module system:
-- modules should support definition protocol
- track a list of assets loaded from each module's file
- C types should be words
- TYPEDEF: float { ... } { ... } ; ==> \ float T{ c-type ... } "c-type" swp
- %allot-bignum-signed-2 is broken on both platforms
- cross-word type inference
- callback scheduling issue
-- amd64 structs-by-value bug
-- intrinsic fixnum>float float>fixnum
- we may be able to remove the dlsym primitive
- [ [ dup call ] dup call ] infer hangs
- stdcall callbacks
recursive
- ppc64 backend
- arm backend
-- mac intel: struct returns from objc methods
- float= doesn't consider nans equal
- C functions returning structs by value
-- infer which variables are read, written in a quotation
- compiled continuations
-- compiled call traces
+ prettyprinter:
+ misc:
-- faster apropos
- growable data heap
- minor GC takes too long now, we should card mark code heap
- buffer-ptr should be an alien
- swap nappend ==> nappend
-- gdb triggers 'mutliple i/o ops on port' error
+- gdb triggers 'multiple i/o ops on port' error
- incremental GC
- UDP
- slice: if sequence or seq start is changed, abstraction violation
ARTICLE: "cookbook-philosophy" "Factor philosophy"
"Factor is a high-level language with automatic memory management, runtime type checking, and strong typing. Factor code should be as simple as possible, but not simpler. If you are coming to Factor from another programming language, one of your first observations might me related to the amount of code you " { $emphasis "don't" } " have to write."
$terpri
-"One of Factor's goals is to implement as much of itself as possible in Factor, including the compiler and as much as possible of the runtime. One consequence is that Factor does not prevent you from shooting yourself in the foot; if you need to, you can drop down and manually allocate memory, perform pointer arithmetic, write inline assembly code, and do much worse. Usually there is no reason to, but the need can arise, for example when interfacing with C libraries."
-$terpri
"If you try to write Factor word definitions which are longer than a couple of lines, you will find it hard to keep track of the stack contents. Well-written Factor code is " { $emphasis "factored" } " into short definitions, where each definition is easy to test interactively, and has a clear purpose. Well-chosen word names are critical, and having a thesaurus on hand really helps."
$terpri
"If you run into problems with stack shuffling, take a deep breath and a step back, and reconsider the problem. A much simpler solution is waiting right around the corner, a natural solution which requires far less stack shuffling and far less code. As a last resort, if no simple solution exists, consider defining a domain-specific language."
$terpri
"In addition to writing short definitions and testing them interactively, a great habit to get into is writing unit tests. Factor provides good support for unit testing; see " { $link "testing-modules" } "."
$terpri
-"The Factor core consists of the development environment together with a minimal library to host it. Additional functionality which other languages integrate is often a separate module in Factor; see " { $link "modules" } "." ;
+"The Factor core consists of the development environment together with a minimal library to host it. Additional functionality which other languages integrate is often a separate module in Factor; see " { $link "modules" } "."
+$terpri
+"Factor tries to implement as much of itself as possible, because this improves simplicity and performance. One consequence is that Factor gives you the option of using low-level features not usually associated with high-level languages, such manual memory management, pointer arithmetic, and inline assembly code."
+$terpri
+"Unsafe features are tucked away so that you will not invoke them by accident, or have to use them to solve conventional programming problems. However when the need arises, unsafe features are invaluable, for example you might have to do some pointer arithmetic when interfacing directly with C libraries." ;
M: word-link definition
link-name "help" word-prop t ;
-
-M: word-link see (see) ;
! See http://factorcode.org/license.txt for BSD license.
IN: modules
USING: hashtables io kernel namespaces parser sequences
-test words strings arrays math help ;
+test words strings arrays math help prettyprint-internals
+definitions ;
SYMBOL: modules
-TUPLE: module name files tests main help ;
+TUPLE: module name loc files tests help main ;
: module-def ( name -- path )
"resource:" over ".factor" append3
drop "resource:" swap "/load.factor" append3
] if ;
-: prefix-paths ( name seq -- newseq )
- [ path+ "resource:" swap append ] map-with ;
-
-C: module ( name files tests help -- module )
- [ set-module-help ] keep
- [ >r >r over r> prefix-paths r> set-module-tests ] keep
- [ >r dupd prefix-paths r> set-module-files ] keep
- [ set-module-name ] keep ;
-
M: module <=> [ module-name ] 2apply <=> ;
: module modules get [ module-name = ] find-with nip ;
: require ( name -- )
dup module [ drop ] [ load-module ] if do-parse-hook ;
-: process-files ( seq -- newseq )
+: process-files ( name seq -- newseq )
[ dup string? [ [ t ] 2array ] when ] map
[ second call ] subset
- 0 <column> >array ;
+ 0 <column> >array
+ [ path+ "resource:" swap append ] map-with ;
+
+: module-files* ( module -- seq )
+ dup module-name swap module-files process-files ;
+
+: module-tests* ( module -- seq )
+ dup module-name swap module-tests process-files ;
: remove-module ( name -- )
module [ modules get delete ] when* ;
-: provide ( name hash -- )
- over remove-module [
- +files+ get process-files
- +tests+ get process-files
- +help+ get
- ] bind <module>
- [ module-files run-files ] keep
+: alist>module ( name loc hash -- module )
+ alist>hash [
+ +files+ get +tests+ get +help+ get
+ ] bind f <module> ;
+
+: module>alist ( module -- hash )
+ [
+ +files+ over module-files 2array ,
+ +tests+ over module-tests 2array ,
+ +help+ swap module-help 2array ,
+ ] { } make ;
+
+: provide ( name loc hash -- )
+ pick remove-module
+ alist>module
+ [ module-files* run-files ] keep
modules get push ;
-: test-module ( name -- ) module module-tests run-tests ;
+: test-module ( name -- ) module module-tests* run-tests ;
: test-modules ( -- )
- modules get [ module-tests ] map concat run-tests ;
+ modules get [ module-tests* ] map concat run-tests ;
: modules. ( -- )
modules get natural-sort
dup module-name module-def source-modified? [
module-name load-module
] [
- module-files [ source-modified? ] subset run-files
+ module-files* [ source-modified? ] subset run-files
] if ;
: reload-modules ( -- )
: modules-help ( -- seq )
modules get [ module-help ] map [ ] subset ;
+
+M: module synopsis* \ PROVIDE: pprint-word module-name text ;
+
+M: module definition module>alist t ;
+
+M: module where* module-loc ;
IN: modules
USING: help io parser ;
-HELP: prefix-paths
-{ $values { "name" "a module name string" } { "seq" "a sequence of strings" } { "newseq" "a new sequence of path name strings" } }
-{ $description "Prepend the location of the module named " { $snippet "name" } " to every file name in " { $snippet "seq" } "." } ;
-
HELP: module-def
{ $values { "name" "a module name string" } { "path" "a path name string" } }
{ $description "Outputs the location of the module definition file. This word looks for the module definition in two locations:"
{ $notes "Module definitions should use the " { $link POSTPONE: REQUIRES: } " parsing word instead. In the listener, the " { $link require } " word might be more useful since it recompiles new words after loading the module." } ;
HELP: provide
-{ $values { "name" "a string" } { "hash" "a hashtable" } }
+{ $values { "name" "a string" } { "hash" "a hashtable" } { "loc" "a pair holding a path name and line number" } }
{ $description "Registers a module definition and loads its source files. The possible hashtable keys are documented in the " { $link POSTPONE: PROVIDE: } " word. Usually instead of calling this word, module definitions use the parsing word " { $link POSTPONE: PROVIDE: } " instead." } ;
HELP: test-module
: !FORGET: scan use get hash-stack [ forget ] when* ; parsing
-: !PROVIDE:
- scan [ alist>hash provide ] f ; parsing
+: !PROVIDE: scan location [ provide ] f ; parsing
: !REQUIRES:
string-mode on [
] if newline
] with-pprint ;
-M: method-spec see (see) ;
+M: object see (see) ;
GENERIC: see-class* ( word -- )
{ +listener+ t }
} define-operation
+[ drop t ] H{
+ { +name+ "Prettyprint" }
+ { +quot+ [ . ] }
+ { +listener+ t }
+} define-operation
+
[ drop t ] H{
{ +name+ "Push" }
{ +quot+ [ ] }
{ +quot+ [ help-gadget call-tool ] }
} define-operation
+[ word? ] H{
+ { +name+ "Edit documentation" }
+ { +quot+ [ <link> edit ] }
+} define-operation
+
[ word? ] H{
{ +name+ "Usage" }
{ +keyboard+ T{ key-down f { A+ } "u" } }
{ +quot+ [ vocab-link-name forget-vocab ] }
} define-operation
-! Module
+! Modules
[ module? ] H{
{ +name+ "Run" }
{ +quot+ [ module-name run-module ] }
{ +quot+ [ module-help [ help-gadget call-tool ] when* ] }
} define-operation
+[ module? ] H{
+ { +name+ "Edit" }
+ { +quot+ [ edit ] }
+} define-operation
+
[ module? ] H{
{ +name+ "Reload" }
{ +quot+ [ reload-module ] }
{ +listener+ t }
} define-operation
+[ module? ] H{
+ { +name+ "See" }
+ { +quot+ [ see ] }
+ { +listener+ t }
+} define-operation
+
! Link
[ link? ] H{
{ +default+ t }