diff --git a/Makefile b/Makefile index ad1f392d9e..19f65506da 100644 --- a/Makefile +++ b/Makefile @@ -3,8 +3,8 @@ CC = gcc BINARY = f IMAGE = factor.image BUNDLE = Factor.app -DISK_IMAGE_DIR = Factor-0.81 -DISK_IMAGE = Factor-0.81.dmg +DISK_IMAGE_DIR = Factor-0.82 +DISK_IMAGE = Factor-0.82.dmg ifdef DEBUG DEFAULT_CFLAGS = -g @@ -110,13 +110,16 @@ macosx.app: mkdir -p $(BUNDLE)/Contents/Resources/fonts/ cp -R fonts/*.ttf $(BUNDLE)/Contents/Resources/fonts/ - find doc library contrib \( -name '*.factor' \ + chmod +x cp_dir + find doc library contrib examples \( -name '*.factor' \ -o -name '*.facts' \ -o -name '*.txt' \ -o -name '*.html' \ -o -name '*.js' \) \ -exec ./cp_dir {} $(BUNDLE)/Contents/Resources/{} \; + cp version.factor $(BUNDLE)/Contents/Resources/ + cp $(IMAGE) $(BUNDLE)/Contents/Resources/factor.image install_name_tool \ @@ -128,7 +131,7 @@ macosx.app: Factor.app/Contents/MacOS/Factor macosx.dmg: - rm $(DISK_IMAGE) + rm -f $(DISK_IMAGE) rm -rf $(DISK_IMAGE_DIR) mkdir $(DISK_IMAGE_DIR) cp -R $(BUNDLE) $(DISK_IMAGE_DIR)/$(BUNDLE) diff --git a/README.txt b/README.txt index c6c9a4cf2d..602262a74c 100644 --- a/README.txt +++ b/README.txt @@ -4,6 +4,19 @@ The Factor programming language This file covers installation and basic usage of the Factor implementation. It is not an introduction to the language itself. +* Contents + +- Platform support +- Compiling Factor +- Building Factor +- Running Factor on Unix with X11 +- Running Factor on Mac OS X +- Running Factor on Windows +- Source organization +- Learning Factor +- Community +- Credits + * Platform support Factor is fully supported on the following platforms: @@ -28,9 +41,8 @@ Other platforms are not supported. The Factor runtime is written in C, and is built with GNU make and gcc. -Note that on x86 systems, Factor _cannot_ be compiled with gcc 3.3. This -is due to a bug in gcc and there is nothing we can do about it. Please -use gcc 2.95, 3.4, or 4.0. +Factor requires gcc 3.4 or later. On x86, it /will not/ build using gcc +3.3 or earlier. Run 'make' (or 'gmake' on non-Linux platforms) with one of the following parameters to build the Factor runtime: @@ -48,9 +60,9 @@ The following options can be given to make: DEBUG=1 The former allows optimization flags to be specified, for example -"-march=pentium4 -ffast-math -O3". Optimization flags can make a *huge* -difference in Factor's performance, so willing hackers should -experiment. +"-march=pentium4 -ffast-math -O3". Nowadays most of the hard work is +done by Factor compiled code, so optimizing the runtime is not that +important. Usually the defaults are fine. The DEBUG flag disables optimization and builds an executable with debug symbols. This is probably only of interest to people intending to @@ -85,72 +97,69 @@ completes, a 'factor.image' file will be generated. Note that this image is both CPU and OS-specific, so in general cannot be shared between machines. -* Running Factor +* Running Factor on Unix with X11 -To run the Factor system, issue the following command: +On Unix, Factor can either run a graphical user interface using X11, or +a terminal listener. + +If your DISPLAY environment variable is set, the UI will start +automatically: ./f factor.image -This will start the interactive listener where Factor expressions may -be entered. +To run an interactive terminal listener: -To run the graphical user interface, issue the following command: + ./f factor.image -shell=tty - ./f factor.image -shell=ui +If you're inside a terminal session, you can start the UI with one of +the following two commands: -Note that on Windows, this is the default. + ui + [ ui ] in-thread + +The latter keeps the terminal listener running. -On Unix, this might fail if the SDL libraries are not installed, or are -installed under unconventional names. This can be solved by explicitly -naming the libraries during bootstrap, as in the next section. +* Running Factor on Mac OS X -* Setting up SDL libraries for use with Factor +On Mac OS X, a Cocoa UI is available in addition to the terminal +listener. -The Windows binary package for Factor includes all prerequisite DLLs. -On Unix, you need recent versions of SDL and FreeType. +The 'f' executable runs the terminal listener: -If you have installed these libraries but the UI still fails with an -error, you will need to find out the exact names that they are installed -as, and issue a command similar to the following to bootstrap Factor: + ./f factor.image - ./f boot.image. -libraries:sdl:name=libSDL-1.2.so - -libraries:freetype:name=libfreetype.so +The Cocoa UI requires that after bootstrapping you build the Factor.app +application bundle: + + make macosx.app + +This copies the runtime executable, factor.image (which must exist at +this point), and the library source into a self-contained Factor.app. + +Factor.app runs the UI when double-clicked and can be transported +between PowerPC Macs. + +* Running Factor on Windows + +On Windows, double-clicking f.exe will start running the Win32-based UI +with the factor.image in the same directory as the executable. + +Bootstrap runs in a Windows command prompt, however after bootstrapping +only the UI can be used. * Source organization doc/ - the developer's handbook, and various other bits and pieces native/ - sources for the Factor runtime, written in C library/ - sources for the library, written in Factor - alien/ - C library interface - bootstrap/ - code for generating boot images - cocoa/ - Mac OS X Cocoa API and Objective-C runtime binding - collections/ - data types including but not limited to lists, - vectors, hashtables, and operations on them - compiler/ - optimizing native compiler - freetype/ - FreeType binding, rendering glyphs to OpenGL textures - generic/ - generic words, for object oriented programming style - help/ - online help system - inference/ - stack effect inference, used by compiler, as well as a - useful development tool of its own - io/ - input and output streams - math/ - integers, ratios, floats, complex numbers, vectors, matrices - opengl/ - OpenGL graphics library binding - syntax/ - parser and object prettyprinter - test/ - unit test framework and test suite - tools/ - interactive development tools - ui/ - UI framework - unix/ - Unix-specific I/O code - win32/ - Windows-specific I/O code contrib/ - various handy libraries not part of the core examples/ - small examples illustrating various language features fonts/ - TrueType fonts used by UI * Learning Factor -The UI has a simple tutorial that will show you the most basic concepts. - -There is a detailed language and library reference available at -http://factorcode.org/handbook.pdf. +The UI has a tutorial and defailed reference documentation. You can +browse it in the UI or by running the HTTP server (contrib/httpd). You can browse the source code; it is organized into small, well-commented files and should be easy to follow once you have a good diff --git a/TODO.FACTOR.txt b/TODO.FACTOR.txt index 71281d07b8..5dd3e978bf 100644 --- a/TODO.FACTOR.txt +++ b/TODO.FACTOR.txt @@ -1,27 +1,11 @@ should fix in 0.82: -- amd64 %box-struct +- another i/o bug: on factorcode eventually all i/o times out - get factor running on mac intel -- when generating a 32-bit image on a 64-bit system, large numbers which should - be bignums become fixnums -- httpd fep -- defining methods returning structs in objc -- expired aliens in view hash -- clicks sent twice -- speed up ideas: - - only do clipping for certain gadgets - - use glRect -- remove , , set-char*-nth, set-ushort*-nth since they - have incorrect semantics -- cocoa: global menu bar with useful commands - -+ portability: - -- win64 port -- amd64 %unbox-struct + io: +- gdb triggers 'mutliple i/o ops on port' error - stream server can hang because of exception handler limitations - better i/o scheduler - yield in a loop starves i/o @@ -29,6 +13,11 @@ should fix in 0.82: + ui/help: +- clicks sent twice +- speed up ideas: + - only do clipping for certain gadgets + - use glRect +- polish OS X menu bar code - help search - reimplement clicking input - reimplement tab completion @@ -56,14 +45,19 @@ should fix in 0.82: + compiler/ffi: +- free up r11, r12 as a vreg on ppc +- float= on powerpc doesn't consider nans equal +- intrinsic fixnum>float float>fixnum +- win64 port +- amd64 %unbox-struct +- constant branch folding - core foundation should use unicode strings - alien>utf16-string, utf16-string>alien words - can only be called with an alien? -- improve callback efficiency -- float intrinsics +- remove , , set-char*-nth, set-ushort*-nth since they + have incorrect semantics - complex float type - complex float intrinsics -- out of memory from overflow check - remove literal table - C functions returning structs by value - FIELD: char key_vector[32]; @@ -73,13 +67,12 @@ should fix in 0.82: - [ [ dup call ] dup call ] infer hangs - the invalid recursion form case needs to be fixed, for inlines too - code gc -- compiled gc check slows things down +- fix compiled gc check + misc: +- 3 >n fep - code walker & exceptions - slice: if sequence or seq start is changed, abstraction violation - make 3.4 bits>double an error -- colorcoded prettyprinting for vocabularies -- signal handler should not lose stack pointers - code walker and callbacks is broken? diff --git a/boot.image.amd64 b/boot.image.amd64 index b539a20d73..34932e70f4 100644 Binary files a/boot.image.amd64 and b/boot.image.amd64 differ diff --git a/boot.image.pentium4 b/boot.image.pentium4 new file mode 100644 index 0000000000..8b7bb2d9cd Binary files /dev/null and b/boot.image.pentium4 differ diff --git a/boot.image.ppc b/boot.image.ppc index f595c3a583..2608f0bed6 100644 Binary files a/boot.image.ppc and b/boot.image.ppc differ diff --git a/boot.image.x86 b/boot.image.x86 index dc0024058c..60c9bce931 100644 Binary files a/boot.image.x86 and b/boot.image.x86 differ diff --git a/contrib/coroutines.factor b/contrib/coroutines.factor index 8facf45139..2471c4ebed 100644 --- a/contrib/coroutines.factor +++ b/contrib/coroutines.factor @@ -56,8 +56,8 @@ TUPLE: coroutine resumecc exitcc ; USE: prettyprint USE: sequences -: test1 ( -- co ) - [ swap [ over coyield 2drop ] tree-each f swap coyield ] cocreate ; +: test1 ( list -- co ) + [ swap [ over coyield 2drop ] each f swap coyield ] cocreate ; : test2 ( -- co ) [ 1 over coyield drop 2 over coyield drop 3 over coyield ] cocreate ; diff --git a/contrib/factory/factory.factor b/contrib/factory/factory.factor index fe0b6a34fd..5568fdf700 100644 --- a/contrib/factory/factory.factor +++ b/contrib/factory/factory.factor @@ -151,6 +151,7 @@ TUPLE: wm-root ; ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! M: wm-root handle-map-request-event ( event -- ) +"handle-map-request-event called on wm-root" print flush drop XMapRequestEvent-window id>obj ! obj { { [ dup wm-frame? ] @@ -164,6 +165,9 @@ M: wm-root handle-map-request-event ( event -- ) "new window has override_redirect attribute set." print flush drop ] } + { [ dup window-id window-parent+ id>obj wm-frame? ] + [ "Window is already managed" print flush drop ] } + { [ t ] [ window-id manage-window ] } } cond ; @@ -332,7 +336,9 @@ TUPLE: wm-frame child ; ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! : manage-window ( window -- ) + flush-dpy grab-server + flush-dpy create-wm-child ! child create-wm-frame ! frame @@ -360,8 +366,11 @@ TUPLE: wm-frame child ; dup map-subwindows% dup wm-frame-child PropertyChangeMask swap select-input% - - flush-dpy 0 sync-dpy ungrab-server ; + + flush-dpy + 0 sync-dpy + ungrab-server + flush-dpy ; ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -558,15 +567,15 @@ SYMBOL: window-list : not-transient? ( frame -- ? ) wm-frame-child get-transient-for-hint% not ; : add-window-to-list ( window-list frame -- window-list ) - dup ! window-list frame frame - wm-frame-child ! window-list frame child - fetch-name% ! window-list frame name-or-f - dup ! window-list frame name-or-f name-or-f + dup ! window-list frame frame + wm-frame-child ! window-list frame child + fetch-name% ! window-list frame name-or-f + dup ! window-list frame name-or-f name-or-f [ ] [ drop "*untitled*" ] if ! window-list frame name - swap ! window-list name frame - [ map-window% ] ! window-list name frame [ map-window% ] - cons ! window-list name action - pick ! window-list name action window-list + swap ! window-list name frame + [ map-window% ] ! window-list name frame [ map-window% ] + cons ! window-list name action + pick ! window-list name action window-list add-popup-menu-item ; : refresh-window-list ( window-list -- ) @@ -591,16 +600,9 @@ SYMBOL: window-list ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -: xlib-error-handler ( -- xt ) "void" { "Display*" "XErrorEvent*" } -[ "X11 : error-handler called" print flush ] alien-callback ; compiled - -: install-error-handler ( -- ) xlib-error-handler XSetErrorHandler drop ; - -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - : start-factory ( dpy-string -- ) initialize-x - install-error-handler + [ "X11 : error-handler called" print flush ] set-error-handler root get [ make-drag-gc ] with-win drag-gc set root get [ black-pixel get set-window-background clear-window ] with-win root get create-wm-root diff --git a/contrib/httpd/cont-responder.factor b/contrib/httpd/cont-responder.factor index d16486e7cd..65e7e78f92 100644 --- a/contrib/httpd/cont-responder.factor +++ b/contrib/httpd/cont-responder.factor @@ -1,29 +1,10 @@ ! Copyright (C) 2004 Chris Double. -! -! Redistribution and use in source and binary forms, with or without -! modification, are permitted provided that the following conditions are met: -! -! 1. Redistributions of source code must retain the above copyright notice, -! this list of conditions and the following disclaimer. -! -! 2. Redistributions in binary form must reproduce the above copyright notice, -! this list of conditions and the following disclaimer in the documentation -! and/or other materials provided with the distribution. -! -! THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, -! INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -! FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -! DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -! SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -! PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -! OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -! WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -IN: cont-responder +! See http://factorcode.org/license.txt for BSD license. + USING: http httpd math namespaces io - lists strings kernel html hashtables - parser generic sequences ; +lists strings kernel html hashtables +parser generic sequences ; +IN: cont-responder #! Used inside the session state of responders to indicate whether the #! next request should use the post-refresh-get pattern. It is set to @@ -31,95 +12,95 @@ USING: http httpd math namespaces io SYMBOL: post-refresh-get? : expiry-timeout ( -- timeout-seconds ) - #! Number of seconds to timeout continuations in - #! continuation table. This value will need to be - #! tuned. I leave it at 24 hours but it can be - #! higher/lower as needed. Default to 15 minutes for - #! testing. - 900 ; + #! Number of seconds to timeout continuations in + #! continuation table. This value will need to be + #! tuned. I leave it at 24 hours but it can be + #! higher/lower as needed. Default to 15 minutes for + #! testing. + 900 ; : get-random-id ( -- id ) - #! Generate a random id to use for continuation URL's - [ "ID" % 32 [ 9 random-int CHAR: 0 + , ] times ] "" make ; + #! Generate a random id to use for continuation URL's + [ "ID" % 32 [ 9 random-int CHAR: 0 + , ] times ] "" make ; SYMBOL: table : continuation-table ( -- ) - #! Return the global table of continuations - table global hash ; - -: reset-continuation-table ( -- ) - #! Create the initial global table - continuation-table clear-hash ; + #! Return the global table of continuations + table get-global ; -H{ } clone table global set-hash +: reset-continuation-table ( -- ) + #! Create the initial global table + continuation-table clear-hash ; + +H{ } clone table set-global #! Tuple for holding data related to a continuation. TUPLE: item expire? quot id time-added ; : continuation-item ( expire? quot id -- ) - #! A continuation item is the actual item stored - #! in the continuation table. It contains the id, - #! quotation/continuation, time added, etc. If - #! expire? is true then the continuation will - #! be expired after a certain amount of time. - millis ; + #! A continuation item is the actual item stored + #! in the continuation table. It contains the id, + #! quotation/continuation, time added, etc. If + #! expire? is true then the continuation will + #! be expired after a certain amount of time. + millis ; : seconds>millis ( seconds -- millis ) - #! Convert a number of seconds to milliseconds - 1000 * ; + #! Convert a number of seconds to milliseconds + 1000 * ; : expired? ( timeout-seconds -- bool ) - #! Return true if the continuation item is expirable - #! and has expired (ie. was added to the table more than - #! timeout milliseconds ago). - [ item-time-added swap seconds>millis + millis - 0 < ] keep item-expire? and ; + #! Return true if the continuation item is expirable + #! and has expired (ie. was added to the table more than + #! timeout milliseconds ago). + [ item-time-added swap seconds>millis + millis - 0 < ] keep item-expire? and ; : expire-continuations ( timeout-seconds -- ) - #! Expire all continuations in the continuation table - #! if they are 'timeout-seconds' old (ie. were added - #! more than 'timeout-seconds' ago. - continuation-table clone [ ( timeout-seconds [[ id item ]] -- ) - swapd expired? [ - continuation-table remove-hash - ] [ - drop - ] if - ] hash-each-with ; + #! Expire all continuations in the continuation table + #! if they are 'timeout-seconds' old (ie. were added + #! more than 'timeout-seconds' ago. + continuation-table clone [ + swapd expired? [ + continuation-table remove-hash + ] [ + drop + ] if + ] hash-each-with ; : expirable ( quot -- t quot ) - #! Set the stack up for a register-continuation call - #! so that the given quotation is registered that it can - #! be expired. - t swap ; + #! Set the stack up for a register-continuation call + #! so that the given quotation is registered that it can + #! be expired. + t swap ; : permanent ( quot -- f quot ) - #! Set the stack up for a register-continuation call - #! so that the given quotation is never expired after - #! registration. - f swap ; + #! Set the stack up for a register-continuation call + #! so that the given quotation is never expired after + #! registration. + f swap ; : register-continuation ( expire? quot -- id ) - #! Store a continuation in the table and associate it with - #! a random id. That continuation will be expired after - #! a certain period of time if 'expire?' is true. - get-random-id - [ continuation-item ] keep ( item id -- ) - [ continuation-table set-hash ] keep ; - + #! Store a continuation in the table and associate it with + #! a random id. That continuation will be expired after + #! a certain period of time if 'expire?' is true. + get-random-id + [ continuation-item ] keep ( item id -- ) + [ continuation-table set-hash ] keep ; + : register-continuation* ( expire? quots -- id ) - #! Like register-continuation but registers a quotation - #! that will call all quotations in the list, in the order given. - concat register-continuation ; + #! Like register-continuation but registers a quotation + #! that will call all quotations in the list, in the order given. + concat register-continuation ; : get-continuation-item ( id -- ) - #! Get the continuation item associated with the id. - continuation-table hash ; + #! Get the continuation item associated with the id. + continuation-table hash ; : id>url ( id -- string ) - #! Convert the continuation id to an URL suitable for - #! embedding in an HREF or other HTML. - url-encode "?id=" swap append ; + #! Convert the continuation id to an URL suitable for + #! embedding in an HREF or other HTML. + url-encode "?id=" swap append ; DEFER: show-final DEFER: show @@ -127,268 +108,262 @@ DEFER: show TUPLE: resume value stdio ; : (expired-page-handler) ( alist -- ) - #! Display a page has expired message. - #! TODO: Need to handle this better to enable - #! returning back to root continuation. + #! Display a page has expired message. + #! TODO: Need to handle this better to enable + #! returning back to root continuation. - -

"This page has expired." write

- - flush ; - -: (expired-page-handler) ( alist -- ) - #! Display a page has expired message. - #! TODO: Need to handle this better to enable - #! returning back to root continuation. - drop - - -

"This page has expired." write

- + +

"This page has expired." write

+ flush ; : expired-page-handler ( alist -- ) - [ (expired-page-handler) ] show-final ; + [ (expired-page-handler) ] show-final ; : >callable ( quot|interp|f -- interp ) - dup continuation? [ - [ continue-with ] cons - ] when ; + dup continuation? [ + [ continue-with ] cons + ] when ; : get-registered-continuation ( id -- cont ) - #! Return the continuation or quotation - #! associated with the given id. - #! TODO: handle expired pages better. - expiry-timeout expire-continuations - get-continuation-item [ - item-quot - ] [ - [ (expired-page-handler) ] - ] if* >callable ; + #! Return the continuation or quotation + #! associated with the given id. + #! TODO: handle expired pages better. + expiry-timeout expire-continuations + get-continuation-item [ + item-quot + ] [ + [ (expired-page-handler) ] + ] if* >callable ; : resume-continuation ( resumed-data id -- ) - #! Call the continuation associated with the given id, - #! with 'value' on the top of the stack. - get-registered-continuation call ; + #! Call the continuation associated with the given id, + #! with 'value' on the top of the stack. + get-registered-continuation call ; #! Name of the variable holding the continuation used to exit #! back to the httpd responder, returning any generated HTML. SYMBOL: exit-cc : exit-continuation ( -- exit ) - #! Get the current exit continuation - exit-cc get ; + #! Get the current exit continuation + exit-cc get ; : call-exit-continuation ( value -- ) - #! Call the exit continuation, passing it the given value on the - #! top of the stack. - exit-cc get continue-with ; + #! Call the exit continuation, passing it the given value on the + #! top of the stack. + exit-cc get continue-with ; : with-exit-continuation ( quot -- ) - #! Call the quotation with the variable exit-cc bound such that when - #! the exit continuation is called, computation will resume from the - #! end of this 'with-exit-continuation' call, with the value passed - #! to the exit continuation on the top of the stack. - [ exit-cc set call f call-exit-continuation ] callcc1 nip ; + #! Call the quotation with the variable exit-cc bound such that when + #! the exit continuation is called, computation will resume from the + #! end of this 'with-exit-continuation' call, with the value passed + #! to the exit continuation on the top of the stack. + [ exit-cc set call f call-exit-continuation ] callcc1 nip ; #! Name of variable holding the 'callback' continuation, used for #! returning back to previous 'show' calls. SYMBOL: callback-cc : store-callback-cc ( -- ) - #! Store the current continuation in the variable 'callback-cc' - #! so it can be returned to later by callbacks. Note that it - #! recalls itself when the continuation is called to ensure that - #! it resets its value back to the most recent show call. - [ ( 0 -- ) - [ ( 0 1 -- ) - callback-cc set ( 0 -- ) - stdio get swap continue-with - ] callcc1 ( 0 [ ] == ) - nip - dup resume-stdio stdio set resume-value - call - store-callback-cc stdio get - ] callcc1 stdio set ; + #! Store the current continuation in the variable 'callback-cc' + #! so it can be returned to later by callbacks. Note that it + #! recalls itself when the continuation is called to ensure that + #! it resets its value back to the most recent show call. + [ ( 0 -- ) + [ ( 0 1 -- ) + callback-cc set ( 0 -- ) + stdio get swap continue-with + ] callcc1 + nip + dup resume-stdio stdio set + resume-value call + store-callback-cc stdio get + ] callcc1 stdio set ; : forward-to-url ( url -- ) - #! When executed inside a 'show' call, this will force a - #! HTTP 302 to occur to instruct the browser to forward to - #! the request URL. - [ - "HTTP/1.1 302 Document Moved\nLocation: " % % - "\nContent-Length: 0\nContent-Type: text/plain\n\n" % - ] "" make write "" call-exit-continuation ; + #! When executed inside a 'show' call, this will force a + #! HTTP 302 to occur to instruct the browser to forward to + #! the request URL. + [ + "HTTP/1.1 302 Document Moved\nLocation: " % % + "\nContent-Length: 0\nContent-Type: text/plain\n\n" % + ] "" make write "" call-exit-continuation ; : forward-to-id ( id -- ) - #! When executed inside a 'show' call, this will force a - #! HTTP 302 to occur to instruct the browser to forward to - #! the request URL. - >r "request" get r> id>url append forward-to-url ; + #! When executed inside a 'show' call, this will force a + #! HTTP 302 to occur to instruct the browser to forward to + #! the request URL. + >r "request" get r> id>url append forward-to-url ; : redirect-to-here ( -- ) - #! Force a redirect to the client browser so that the browser - #! goes to the current point in the code. This forces an URL - #! change on the browser so that refreshing that URL will - #! immediately run from this code point. This prevents the - #! "this request will issue a POST" warning from the browser - #! and prevents re-running the previous POST logic. This is - #! known as the 'post-refresh-get' pattern. - post-refresh-get? get [ - [ - expirable register-continuation forward-to-id - ] callcc1 resume-stdio stdio set - ] [ - t post-refresh-get? set - ] if ; + #! Force a redirect to the client browser so that the browser + #! goes to the current point in the code. This forces an URL + #! change on the browser so that refreshing that URL will + #! immediately run from this code point. This prevents the + #! "this request will issue a POST" warning from the browser + #! and prevents re-running the previous POST logic. This is + #! known as the 'post-refresh-get' pattern. + post-refresh-get? get [ + [ + expirable register-continuation forward-to-id + ] callcc1 resume-stdio stdio set + ] [ + t post-refresh-get? set + ] if ; : (show) ( quot -- namespace ) - #! See comments for show. The difference is the - #! quotation MUST set the content-type using 'serving-html' - #! or similar. - store-callback-cc redirect-to-here - [ - expirable register-continuation id>url swap - with-scope "" call-exit-continuation - ] callcc1 - nip dup resume-stdio stdio set resume-value ; - + #! See comments for show. The difference is the + #! quotation MUST set the content-type using 'serving-html' + #! or similar. + store-callback-cc redirect-to-here + [ + expirable register-continuation id>url swap + with-scope "" call-exit-continuation + ] callcc1 + nip dup resume-stdio stdio set resume-value ; + : show ( quot -- namespace ) - #! Call the quotation with the URL associated with the current - #! continuation. All output from the quotation goes to the client - #! browser. When the URL is later referenced then - #! computation will resume from this 'show' call with a namespace on - #! the stack containing any query or post parameters. - #! NOTE: On return from 'show' the stack is exactly the same as - #! initial entry with 'quot' popped off an put on. Even - #! if the quotation consumes items on the stack. - \ serving-html swons (show) ; + #! Call the quotation with the URL associated with the current + #! continuation. All output from the quotation goes to the client + #! browser. When the URL is later referenced then + #! computation will resume from this 'show' call with a namespace on + #! the stack containing any query or post parameters. + #! NOTE: On return from 'show' the stack is exactly the same as + #! initial entry with 'quot' popped off an put on. Even + #! if the quotation consumes items on the stack. + \ serving-html swons (show) ; : (show-final) ( quot -- namespace ) - #! See comments for show-final. The difference is the - #! quotation MUST set the content-type using 'serving-html' - #! or similar. - store-callback-cc redirect-to-here - with-scope "" call-exit-continuation ; + #! See comments for show-final. The difference is the + #! quotation MUST set the content-type using 'serving-html' + #! or similar. + store-callback-cc redirect-to-here + with-scope "" call-exit-continuation ; : show-final ( quot -- namespace ) - #! Similar to 'show', except the quotation does not receive the URL - #! to resume computation following 'show-final'. No continuation is - #! stored for this resumption. As a result, 'show-final' is for use - #! when a page is to be displayed with no further action to occur. Its - #! use is an optimisation to save having to generate and save a continuation - #! in that special case. - \ serving-html swons (show-final) ; + #! Similar to 'show', except the quotation does not receive the URL + #! to resume computation following 'show-final'. No continuation is + #! stored for this resumption. As a result, 'show-final' is for use + #! when a page is to be displayed with no further action to occur. Its + #! use is an optimisation to save having to generate and save a continuation + #! in that special case. + \ serving-html swons (show-final) ; #! Name of variable for holding initial continuation id that starts #! the responder. SYMBOL: root-continuation : id-or-root ( -- id ) - #! Return the continuation id for the current requested continuation - #! or the root continuation if no id is supplied. - "id" "query" get hash [ root-continuation get ] unless* ; + #! Return the continuation id for the current requested continuation + #! or the root continuation if no id is supplied. + "id" "query" get hash [ root-continuation get ] unless* ; : cont-get/post-responder ( id-or-f -- ) - #! httpd responder that retrieves a continuation and calls it. - #! The continuation id must be in a query parameter called 'id'. - #! If it does not exist the root continuation is called. If - #! no root continuation exists the expired continuation handler - #! should be called. - drop [ - "response" get stdio get - id-or-root [ - resume-continuation - ] [ - (expired-page-handler) "" call-exit-continuation - ] if* - ] with-exit-continuation drop ; + #! httpd responder that retrieves a continuation and calls it. + #! The continuation id must be in a query parameter called 'id'. + #! If it does not exist the root continuation is called. If + #! no root continuation exists the expired continuation handler + #! should be called. + [ + drop [ + "response" get stdio get + id-or-root [ + resume-continuation + ] [ + (expired-page-handler) "" call-exit-continuation + ] if* + ] with-exit-continuation drop + ] with-scope ; : callback-quot ( quot -- quot ) - #! Convert the given quotation so it works as a callback - #! by returning a quotation that will pass the original - #! quotation to the callback continuation. - [ , \ stdio , \ get , \ , callback-cc get , \ continue-with , ] [ ] make ; + #! Convert the given quotation so it works as a callback + #! by returning a quotation that will pass the original + #! quotation to the callback continuation. + [ + , \ stdio , \ get , \ , callback-cc get , + \ continue-with , + ] [ ] make ; : quot-url ( quot -- url ) - callback-quot expirable register-continuation id>url ; + callback-quot expirable register-continuation id>url ; : quot-href ( text quot -- ) - #! Write to standard output an HTML HREF where the href, - #! when referenced, will call the quotation and then return - #! back to the most recent 'show' call (via the callback-cc). - #! The text of the link will be the 'text' argument on the - #! stack. - write ; + #! Write to standard output an HTML HREF where the href, + #! when referenced, will call the quotation and then return + #! back to the most recent 'show' call (via the callback-cc). + #! The text of the link will be the 'text' argument on the + #! stack. + write ; : init-session-namespace ( -- ) - #! Setup the initial session namespace. Currently this only - #! sets the redirect flag so that the initial request of the - #! responder will not do a post-refresh-get style redirect. - #! This prevents the initial request to a responder from redirecting - #! to an URL with a continuation id. This word must be run from - #! within the session namespace. - f post-refresh-get? set dup resume-stdio stdio set ; + #! Setup the initial session namespace. Currently this only + #! sets the redirect flag so that the initial request of the + #! responder will not do a post-refresh-get style redirect. + #! This prevents the initial request to a responder from redirecting + #! to an URL with a continuation id. This word must be run from + #! within the session namespace. + f post-refresh-get? set dup resume-stdio stdio set ; : install-cont-responder ( name quot -- ) - #! Install a cont-responder with the given name - #! that will initially run the given quotation. - #! - #! Convert the quotation so it is run within a session namespace - #! and that namespace is initialized first. - \ init-session-namespace swons [ , \ with-scope , ] [ ] make - [ - [ cont-get/post-responder ] "get" set - [ cont-get/post-responder ] "post" set - swap "responder" set - permanent register-continuation root-continuation set - ] make-responder ; + #! Install a cont-responder with the given name + #! that will initially run the given quotation. + #! + #! Convert the quotation so it is run within a session namespace + #! and that namespace is initialized first. + \ init-session-namespace swons [ , \ with-scope , ] [ ] make + [ + [ cont-get/post-responder ] "get" set + [ cont-get/post-responder ] "post" set + swap "responder" set + permanent register-continuation root-continuation set + ] make-responder ; : simple-page ( title quot -- ) - #! Call the quotation, with all output going to the - #! body of an html page with the given title. - - swap write - call - ; + #! Call the quotation, with all output going to the + #! body of an html page with the given title. + + swap write + call + ; : styled-page ( title stylesheet-quot quot -- ) - #! Call the quotation, with all output going to the - #! body of an html page with the given title. stylesheet-quot - #! is called to generate the required stylesheet. - - - rot write - swap call - - call - ; + #! Call the quotation, with all output going to the + #! body of an html page with the given title. stylesheet-quot + #! is called to generate the required stylesheet. + + + rot write + swap call + + call + ; : paragraph ( str -- ) - #! Output the string as an html paragraph -

write

; + #! Output the string as an html paragraph +

write

; : show-message-page ( message -- ) - #! Display the message in an HTML page with an OK button. - [ - "Press OK to Continue" [ - swap paragraph - "OK" write - ] simple-page - ] show 2drop ; + #! Display the message in an HTML page with an OK button. + [ + "Press OK to Continue" [ + swap paragraph + "OK" write + ] simple-page + ] show 2drop ; : vertical-layout ( list -- ) - #! Given a list of HTML components, arrange them vertically. - + #! Given a list of HTML components, arrange them vertically. +
[ ] each -
call
; + ; : horizontal-layout ( list -- ) - #! Given a list of HTML components, arrange them horizontally. - - [ ] each -
call
; + #! Given a list of HTML components, arrange them horizontally. + + [ ] each +
call
; : button ( label -- ) - #! Output an HTML submit button with the given label. - ; + #! Output an HTML submit button with the given label. + ; diff --git a/contrib/math/infix.factor b/contrib/math/infix.factor index 46f5639be0..f0c8e1df70 100644 --- a/contrib/math/infix.factor +++ b/contrib/math/infix.factor @@ -89,6 +89,8 @@ UNION: value number string ; #! The semicolon token T{ tok f CHAR: ; } ; +: unswons uncons swap ; + : nest-apply ( [ ast ] -- apply ) unswons unit swap [ swap unit diff --git a/contrib/parser-combinators/parser-combinators.factor b/contrib/parser-combinators/parser-combinators.factor index c85599044c..eed33ff8b8 100644 --- a/contrib/parser-combinators/parser-combinators.factor +++ b/contrib/parser-combinators/parser-combinators.factor @@ -237,6 +237,8 @@ M: list pdrop ( n object -- object ) >r uncons r> ( x1 xs2 x ) swap cons cons ; +: unswons uncons swap ; + : <&>-do-parser2 ( [[ x xs ]] parser2 -- result ) #! Called by the <&>-parser on each result of the #! successfull parse of parser1. It's input is the diff --git a/contrib/random-tester/random-tester.factor b/contrib/random-tester/random-tester.factor index 5c995d2b0e..20dca6fc48 100644 --- a/contrib/random-tester/random-tester.factor +++ b/contrib/random-tester/random-tester.factor @@ -241,7 +241,7 @@ SYMBOL: first-arg dup . [ last-quot set ] keep [ call ] keep - [ last car update-xt ] keep call + [ peek update-xt ] keep call 2dup swap unparse write " " write unparse print = [ "update-xt problem" throw ] unless ; diff --git a/contrib/splay-trees.factor b/contrib/splay-trees.factor index fe9bfa33c7..7f8b7e20b8 100644 --- a/contrib/splay-trees.factor +++ b/contrib/splay-trees.factor @@ -111,5 +111,5 @@ DEFER: (splay) USING: namespaces words ; "foo" set -[ dup word-name "foo" get set-splay ] each-word -[ dup word-name "foo" get get-splay drop ] each-word +all-words [ dup word-name "foo" get set-splay ] each +all-words [ dup word-name "foo" get get-splay drop ] each diff --git a/contrib/x11/concurrent-widgets.factor b/contrib/x11/concurrent-widgets.factor index 81fb535354..4593787067 100644 --- a/contrib/x11/concurrent-widgets.factor +++ b/contrib/x11/concurrent-widgets.factor @@ -58,21 +58,21 @@ GENERIC: handle-property-event : handle-event ( event obj -- ) over XAnyEvent-type - { { [ dup Expose = ] [ drop handle-expose-event ] } - { [ dup KeyPress = ] [ drop handle-key-press-event ] } - { [ dup KeyRelease = ] [ drop handle-key-release-event ] } - { [ dup ButtonPress = ] [ drop handle-button-press-event ] } - { [ dup ButtonRelease = ] [ drop handle-button-release-event ] } - { [ dup ConfigureNotify = ] [ drop handle-configure-event ] } - { [ dup EnterNotify = ] [ drop handle-enter-window-event ] } - { [ dup LeaveNotify = ] [ drop handle-leave-window-event ] } - { [ dup DestroyNotify = ] [ drop handle-destroy-window-event ] } - { [ dup MapRequest = ] [ drop handle-map-request-event ] } - { [ dup MapNotify = ] [ drop handle-map-event ] } - { [ dup ConfigureRequest = ] [ drop handle-configure-request-event ] } - { [ dup UnmapNotify = ] [ drop handle-unmap-event ] } - { [ dup PropertyNotify = ] [ drop handle-property-event ] } - { [ t ] [ "handle-event ignoring event" print flush 3drop ] } } + { { [ dup Expose = ] [ drop handle-expose-event ] } + { [ dup KeyPress = ] [ drop handle-key-press-event ] } + { [ dup KeyRelease = ] [ drop handle-key-release-event ] } + { [ dup ButtonPress = ] [ drop handle-button-press-event ] } + { [ dup ButtonRelease = ] [ drop handle-button-release-event ] } + { [ dup ConfigureNotify = ] [ drop handle-configure-event ] } + { [ dup EnterNotify = ] [ drop handle-enter-window-event ] } + { [ dup LeaveNotify = ] [ drop handle-leave-window-event ] } + { [ dup DestroyNotify = ] [ drop handle-destroy-window-event ] } + { [ dup MapRequest = ] [ drop handle-map-request-event ] } + { [ dup MapNotify = ] [ drop handle-map-event ] } + { [ dup ConfigureRequest = ] [ drop handle-configure-request-event ] } + { [ dup UnmapNotify = ] [ drop handle-unmap-event ] } + { [ dup PropertyNotify = ] [ drop handle-property-event ] } + { [ t ] [ "handle-event ignoring event" print flush 3drop ] } } cond ; M: window handle-configure-event ( event obj -- ) diff --git a/contrib/x11/x.factor b/contrib/x11/x.factor index 9e63f83281..4242058b4c 100644 --- a/contrib/x11/x.factor +++ b/contrib/x11/x.factor @@ -1,5 +1,6 @@ +USING: namespaces kernel compiler math arrays strings alien sequences io +prettyprint xlib rectangle ; -USING: namespaces kernel math arrays strings alien sequences xlib rectangle ; IN: x SYMBOL: dpy @@ -133,12 +134,99 @@ DEFER: with-win : get-window-attributes ( -- ) dpy get win get "XWindowAttributes" dup >r XGetWindowAttributes drop r> ; +: window-root get-window-attributes XWindowAttributes-root ; + : window-map-state get-window-attributes XWindowAttributes-map_state ; +: window-event-mask +get-window-attributes XWindowAttributes-your_event_mask ; + +: window-all-event-masks +get-window-attributes XWindowAttributes-all_event_masks ; + : window-override-redirect get-window-attributes XWindowAttributes-override_redirect ; +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +SYMBOL: event-masks + +{ { "NoEventMask" 0 } + { "KeyPressMask" 1 } + { "KeyReleaseMask" 2 } + { "ButtonPressMask" 4 } + { "ButtonReleaseMask" 8 } + { "EnterWindowMask" 16 } + { "LeaveWindowMask" 32 } + { "PointerMotionMask" 64 } + { "PointerMotionHintMask" 128 } + { "Button1MotionMask" 256 } + { "Button2MotionMask" 512 } + { "Button3MotionMask" 1024 } + { "Button4MotionMask" 2048 } + { "Button5MotionMask" 4096 } + { "ButtonMotionMask" 8192 } + { "KeymapStateMask" 16384 } + { "ExposureMask" 32768 } + { "VisibilityChangeMask" 65536 } + { "StructureNotifyMask" 131072 } + { "ResizeRedirectMask" 262144 } + { "SubstructureNotifyMask" 524288 } + { "SubstructureRedirectMask" 1048576 } + { "FocusChangeMask" 2097152 } + { "PropertyChangeMask" 4194304 } + { "ColormapChangeMask" 8388608 } + { "OwnerGrabButtonMask" 16777216 } +} event-masks set-global + +: bit-test ( a b -- t-or-f ) bitand 0 = not ; + +: name>event-mask ( str -- i ) +event-masks get [ first over = ] find 2nip second ; + +: event-mask>name ( i -- str ) +event-masks get [ second over = ] find 2nip first ; + +: event-mask-names ( -- seq ) event-masks get [ first ] map ; + +: event-mask>names ( mask -- seq ) +event-mask-names [ name>event-mask bit-test ] subset-with ; + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +! Pretty printing window information +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +: print-field ( name value -- ) swap "=" append write pprint ; + +: spc ( -- ) " " write ; + +: print-window-geometry ( -- ) +window-width pprint "x" write window-height pprint "+" write +window-x pprint "+" write window-y pprint ; + +: print-map-state ( -- ) +"map-state=" write +window-map-state +{ { [ dup 0 = ] [ drop "IsUnmapped" write ] } + { [ dup 1 = ] [ drop "IsUnviewable" write ] } + { [ dup 2 = ] [ drop "IsViewable" write ] } +} cond ; + +: print-window-info ( -- ) +"id" win get print-field spc +"parent" window-parent print-field spc +"root" window-root print-field spc +print-window-geometry terpri +"children" window-children print-field terpri +"override-redirect" window-override-redirect print-field spc +print-map-state terpri +"event-mask" window-event-mask event-mask>names print-field terpri +"all-event-masks" window-all-event-masks event-mask>names print-field +terpri ; + +: .win print-window-info ; + ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! 6 - Color Management Functions ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -205,14 +293,15 @@ dup length 1 - [ swap 2nth draw-line ] each-with ; ! 8.6 - Drawing Text -: draw-string ( { x y } string -- ) - >r >r dpy get win get gcontext get r> [ ] each r> dup length XDrawString drop ; +: draw-string ( { x y } string -- ) >r >r +dpy get win get gcontext get r> [ ] each r> dup length XDrawString drop ; ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! 9 - Window and Session Manager Functions ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -: reparent-window ( parent -- ) >r dpy get win get r> 0 0 XReparentWindow drop ; +: reparent-window ( parent -- ) >r +dpy get win get r> 0 0 XReparentWindow drop ; : add-to-save-set ( -- ) dpy get win get XAddToSaveSet drop ; @@ -238,6 +327,16 @@ dpy get "XEvent" dup >r XNextEvent drop r> ; : events-queued ( mode -- n ) >r dpy get r> XEventsQueued ; +! 11.8 - Handling Protocol Errors + +SYMBOL: error-handler-quot + +: error-handler-callback ( -- xt ) "void" { "Display*" "XErrorEvent*" } +[ error-handler-quot get call ] alien-callback ; compiled + +: set-error-handler ( quot -- ) +error-handler-quot set error-handler-callback XSetErrorHandler drop ; + ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! 12 - Input Device Functions ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -246,8 +345,8 @@ dpy get "XEvent" dup >r XNextEvent drop r> ; >r >r dpy get win get r> r> XSetInputFocus drop ; : grab-pointer ( mask -- ) - >r dpy get win get False r> GrabModeAsync GrabModeAsync None None CurrentTime - XGrabPointer drop ; +>r dpy get win get False r> GrabModeAsync GrabModeAsync None None CurrentTime +XGrabPointer drop ; : ungrab-pointer ( time -- ) >r dpy get r> XUngrabPointer drop ; @@ -284,6 +383,7 @@ dpy get "XEvent" dup >r XNextEvent drop r> ; : destroy-window+ [ destroy-window ] with-win ; : map-window+ [ map-window ] with-win ; : unmap-window+ [ unmap-window ] with-win ; +: window-parent+ [ window-parent ] with-win ; ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! diff --git a/contrib/x11/xlib.factor b/contrib/x11/xlib.factor index 0033cab2d6..4bba879a5f 100644 --- a/contrib/x11/xlib.factor +++ b/contrib/x11/xlib.factor @@ -472,11 +472,11 @@ FUNCTION: Status XKillClient ( Display* display, XID resource ) ; : MotionNotify 6 ; : EnterNotify 7 ; : LeaveNotify 8 ; -: FocusIn 9 ; +: FocusIn 9 ; : FocusOut 10 ; : KeymapNotify 11 ; -: Expose 12 ; -: GraphicsExpose 13 ; +: Expose 12 ; +: GraphicsExpose 13 ; : NoExpose 14 ; : VisibilityNotify 15 ; : CreateNotify 16 ; @@ -484,24 +484,22 @@ FUNCTION: Status XKillClient ( Display* display, XID resource ) ; : UnmapNotify 18 ; : MapNotify 19 ; : MapRequest 20 ; -: ReparentNotify 21 ; -: ConfigureNotify 22 ; +: ReparentNotify 21 ; +: ConfigureNotify 22 ; : ConfigureRequest 23 ; : GravityNotify 24 ; : ResizeRequest 25 ; -: CirculateNotify 26 ; +: CirculateNotify 26 ; : CirculateRequest 27 ; -: PropertyNotify 28 ; -: SelectionClear 29 ; +: PropertyNotify 28 ; +: SelectionClear 29 ; : SelectionRequest 30 ; -: SelectionNotify 31 ; -: ColormapNotify 32 ; +: SelectionNotify 31 ; +: ColormapNotify 32 ; : ClientMessage 33 ; : MappingNotify 34 ; : LASTEvent 35 ; - - BEGIN-STRUCT: XAnyEvent FIELD: int type FIELD: ulong serial diff --git a/cp_dir b/cp_dir old mode 100644 new mode 100755 diff --git a/doc/handbook/changes.facts b/doc/handbook/changes.facts index b8d98523f7..fdf85b462d 100644 --- a/doc/handbook/changes.facts +++ b/doc/handbook/changes.facts @@ -1,6 +1,16 @@ USING: generic help inspector memory sequences ; ARTICLE: "changes" "Changes in the latest release" +{ $subheading "Factor 0.82" } +{ $list + "New code generator framework in compiler" + "Floating point operations are now open-coded, resulting in a performance gain" + { "Remove " { $snippet "unswons" } " word" } + "Implement value type struct inputs to callbacks on AMD64" + "Fix some Unix I/O bugs" + "Standard OS X-style menu bar in the Cocoa UI (Kevin Reid)" + "Objective C methods defined in Factor can now return C structures by value" +} { $subheading "Factor 0.81" } { $subtopic "UI" { $list diff --git a/doc/handbook/collections.facts b/doc/handbook/collections.facts index b16c7b504e..ac5991e962 100644 --- a/doc/handbook/collections.facts +++ b/doc/handbook/collections.facts @@ -52,7 +52,6 @@ ARTICLE: "hashtables-lookup" "Looking up keys in hashtables" ARTICLE: "hashtables-mutation" "Storing keys in hashtables" { $subsection set-hash } -{ $subsection ?set-hash } { $subsection remove-hash } { $subsection clear-hash } ; @@ -140,7 +139,6 @@ ARTICLE: "namespaces-make" "Constructing sequences" ARTICLE: "namespaces-internals" "Namespace implementation details" "The namestack holds namespaces." -{ $subsection namestack* } { $subsection namestack } { $subsection set-namestack } "A pair of words push and pop namespaces on the namestack." diff --git a/doc/handbook/streams.facts b/doc/handbook/streams.facts index 16bf07225a..bb66229cba 100644 --- a/doc/handbook/streams.facts +++ b/doc/handbook/streams.facts @@ -24,7 +24,7 @@ GLOSSARY: "output stream" "an object responding to the output words of the " { $ GLOSSARY: "bidirectional stream" "an object that is both an input and output stream" ; ARTICLE: "stream-protocol" "Stream protocol" -"The stream protocol consits of a large number of generic words, many of which are optional." +"The stream protocol consists of a large number of generic words, many of which are optional." $terpri "A word required to be implemented for all streams:" { $subsection stream-close } @@ -86,8 +86,6 @@ ARTICLE: "character-styles" "Character styles" "Character styles for " { $link stream-format } ":" { $subsection foreground } { $subsection background } -{ $subsection foreground } -{ $subsection background } { $subsection font } { $subsection font-size } { $subsection font-style } diff --git a/examples/homology.factor b/examples/homology.factor new file mode 100644 index 0000000000..a4c495e302 --- /dev/null +++ b/examples/homology.factor @@ -0,0 +1,156 @@ +IN: homology +USING: kernel sequences arrays math words namespaces +hashtables prettyprint io ; + +! Utilities +: S{ [ [ dup ] map>hash ] [ ] ; parsing + +: (lengthen) ( seq n -- seq ) + over length - f append ; + +: lengthen ( sim sim -- sim sim ) + 2dup max-length tuck (lengthen) >r (lengthen) r> ; + +: unswons* 1 over tail swap first ; + +: swons* 1array swap append ; + +: rot-seq ( seq -- seq ) unswons* add ; + +: ( -- sim ) gensym 1array ; + +: (C) ( point sim -- sim ) + [ [ append natural-sort ] map-with ] map-with ; + +: (\/) ( sim sim -- sim ) lengthen [ append natural-sort ] 2map ; + +: ( from to -- seq ) dup ; + +! Simplicial complexes +SYMBOL: basepoint + +: {*} ( -- sim ) + #! Initial object in category + { { { basepoint } } } ; + +: \/ ( sim sim -- sim ) + #! Glue two complexes at base point + (\/) [ prune ] map ; + +: +point ( sim -- sim ) + #! Adjoint an isolated point + unswons* add swons* ; + +: C ( sim -- sim ) + #! Cone on a space + over first over add >r swap (C) r> swons* ; + +: S ( sim -- sim ) + #! Suspension + [ + 2dup 2array >r + pick (C) >r swap (C) r> (\/) r> swons* + ] keep (\/) ; + +: S^0 ( -- sim ) + #! Degenerate sphere -- two points + {*} +point ; + +: S^ ( n -- sim ) + #! Sphere + S^0 swap [ S ] times ; + +: D^ ( n -- sim ) + #! Disc + 1- S^ C ; + +! Mod 2 matrix algebra +: remove-1 ( n seq -- seq ) + >r { } swap dup 1+ r> replace-slice ; + +: symmetric-diff ( hash hash -- hash ) + clone swap [ + drop dup pick hash [ + over remove-hash + ] [ + dup pick set-hash + ] if + ] hash-each ; + +SYMBOL: row-basis +SYMBOL: matrix +SYMBOL: current-row + +: rows ( -- n ) matrix get length ; + +: exchange-rows ( m n -- ) + 2dup = [ 2drop ] [ matrix get exchange ] if ; + +: row ( n -- row ) matrix get nth ; + +: set-row ( row n -- ) matrix get set-nth ; + +: add-row ( src# dst# -- ) + [ [ row ] 2apply symmetric-diff ] keep set-row ; + +: pivot-row ( basis-elt -- n ) + current-row get rows + [ row hash-member? ] find-with nip ; + +: kill-column ( basis-elt pivot -- ) + dup 1+ rows [ + pick over row hash-member? [ dupd add-row ] [ drop ] if + ] each 2drop ; + +: with-matrix ( matrix basis quot -- matrix ) + [ + >r row-basis set matrix set r> call matrix get + ] with-scope ; inline + +: (row-reduce) + 0 current-row set + row-basis get [ + dup pivot-row dup [ + current-row get exchange-rows + current-row get kill-column + current-row inc + ] [ + 2drop + ] if + ] each ; + +: ker/im ( -- ker im ) + matrix get [ hash-empty? ] subset length + row-basis get [ + matrix get [ hash-member? ] contains-with? + ] subset length ; + +: row-reduce ( matrix basis -- rowsp colsp matrix ) + [ (row-reduce) ker/im ] with-matrix ; + +! Mod 2 homology +: (boundary) ( seq -- chain ) + dup length 1 <= [ + H{ } + ] [ + dup length [ over remove-1 dup ] map>hash + ] if nip ; + +: boundary ( chain -- chain ) + H{ } swap [ drop (boundary) symmetric-diff ] hash-each ; + +: homology ( sim -- seq ) + dup [ [ (boundary) ] map ] map rot-seq + [ row-reduce drop 2array ] 2map ; + +: print-matrix ( matrix basis -- ) + swap [ + swap [ + ( row basis-elt ) + swap hash-member? 1 0 ? pprint bl + ] each-with terpri + ] each-with ; + +2 S^ [ [ [ (boundary) ] map ] map unswons* drop ] keep +[ [ row-reduce 2nip ] 2map ] keep +[ print-matrix terpri ] 2each diff --git a/examples/mandel.factor b/examples/mandel.factor index c50491867b..ae74192ba5 100644 --- a/examples/mandel.factor +++ b/examples/mandel.factor @@ -70,7 +70,7 @@ strings test ; ] map-with ; : iter ( c z nb-iter -- x ) - over absq 4.0 >= over 0 = or + over absq 4.0 >= over zero? or [ 2nip ] [ 1- >r sq dupd + r> iter ] if ; inline SYMBOL: cols @@ -88,7 +88,7 @@ SYMBOL: cols : render ( -- ) height [ width [ - 2dup swap c 0 nb-iter iter dup 0 = [ + 2dup swap c 0 nb-iter iter dup zero? [ drop "\0\0\0" ] [ cols get [ length mod ] keep nth diff --git a/examples/numbers-game.factor b/examples/numbers-game.factor index ab99e51f5b..75e3b382db 100644 --- a/examples/numbers-game.factor +++ b/examples/numbers-game.factor @@ -1,5 +1,5 @@ IN: numbers-game -USING: kernel math parser random io ; +USING: kernel math parser io ; : read-number ( -- n ) readln string>number ; diff --git a/examples/raytracer.factor b/examples/raytracer.factor index 38867117a7..60eafd6b32 100644 --- a/examples/raytracer.factor +++ b/examples/raytracer.factor @@ -2,7 +2,7 @@ ! http://www.ffconsultancy.com/free/ray_tracer/languages.html USING: arrays compiler generic io kernel lists math namespaces -sequences test ; +sequences test words ; IN: ray ! parameters @@ -27,24 +27,26 @@ GENERIC: intersect-scene ( hit ray scene -- hit ) TUPLE: sphere center radius ; : sphere-v ( sphere ray -- v ) - swap sphere-center swap ray-orig v- ; + swap sphere-center swap ray-orig v- ; inline -: sphere-b ( ray v -- b ) swap ray-dir v. ; +: sphere-b ( ray v -- b ) swap ray-dir v. ; inline : sphere-disc ( sphere v b -- d ) - sq swap norm-sq - swap sphere-radius sq + ; + sq swap norm-sq - swap sphere-radius sq + ; inline -: -+ ( x y -- x-y x+y ) [ - ] 2keep + ; +: -+ ( x y -- x-y x+y ) [ - ] 2keep + ; inline : sphere-b/d ( b d -- t ) - -+ dup 0.0 < [ 2drop 1.0/0.0 ] [ >r [ 0.0 > ] keep r> ? ] if ; + -+ dup 0.0 < [ 2drop 1.0/0.0 ] [ >r [ 0.0 > ] keep r> ? ] if ; inline : ray-sphere ( sphere ray -- t ) 2dup sphere-v tuck sphere-b [ sphere-disc ] keep over 0.0 < [ 2drop 1.0/0.0 ] [ swap sqrt sphere-b/d ] if ; + inline : sphere-n ( ray sphere l -- n ) pick ray-dir n*v swap sphere-center v- swap ray-orig v+ ; + inline : if-ray-sphere ( hit ray sphere quot -- hit ) #! quot: hit ray sphere l -- hit @@ -69,20 +71,20 @@ M: group intersect-scene ( hit ray group -- hit ) drop ] if-ray-sphere ; -: initial-hit T{ hit f { 0.0 0.0 0.0 } 1.0/0.0 } ; +: initial-hit T{ hit f { 0.0 0.0 0.0 } 1.0/0.0 } ; inline : initial-intersect ( ray scene -- hit ) - initial-hit -rot intersect-scene ; + initial-hit -rot intersect-scene ; inline : ray-o ( ray hit -- o ) over ray-dir over hit-lambda v*n swap hit-normal delta v*n v+ - swap ray-orig v+ ; + swap ray-orig v+ ; inline : sray-intersect ( ray scene hit -- ray ) - swap >r ray-o light vneg r> initial-intersect ; + swap >r ray-o light vneg r> initial-intersect ; inline -: ray-g ( hit -- g ) hit-normal light v. ; +: ray-g ( hit -- g ) hit-normal light v. ; inline : cast-ray ( ray scene -- g ) 2dup initial-intersect dup hit-lambda 1.0/0.0 = [ @@ -90,9 +92,10 @@ M: group intersect-scene ( hit ray group -- hit ) ] [ dup ray-g >r sray-intersect hit-lambda 1.0/0.0 = [ r> neg ] [ r> drop 0.0 ] if - ] if ; + ] if ; inline -: create-center ( c r d -- c2 ) >r 3.0 12.0 sqrt / * r> n*v v+ ; +: create-center ( c r d -- c2 ) + >r 3.0 12.0 sqrt / * r> n*v v+ ; inline DEFER: create ( level c r -- scene ) diff --git a/examples/turing.factor b/examples/turing.factor index 945cab37de..72987a56fb 100644 --- a/examples/turing.factor +++ b/examples/turing.factor @@ -38,7 +38,7 @@ SYMBOL: position SYMBOL: tape ! Initial tape -20 zero-array >vector tape set +20 0 >vector tape set : sym ( -- sym ) #! Symbol at head position. diff --git a/library/bootstrap/boot-stage1.factor b/library/bootstrap/boot-stage1.factor index 4446b4029d..c34d189715 100644 --- a/library/bootstrap/boot-stage1.factor +++ b/library/bootstrap/boot-stage1.factor @@ -9,6 +9,17 @@ vectors words ; "/library/bootstrap/primitives.factor" run-resource +: parse-resource* ( path -- ) + [ parse-resource ] catch [ + dup error. + "Try again? [yn]" print flush readln "yY" subseq? + [ drop parse-resource* ] [ rethrow ] if + ] when* ; + +: if-arch ( arch seq -- ) + architecture get rot member? + [ [ parse-resource* % ] each ] [ drop ] if ; + ! The [ ] make form creates a boot quotation [ \ boot , @@ -77,7 +88,7 @@ vectors words ; "/library/generic/math-combination.factor" "/library/generic/tuple.factor" - "/library/alien/aliens.factor" + "/library/compiler/alien/aliens.factor" "/library/syntax/prettyprint.factor" "/library/syntax/see.factor" @@ -109,39 +120,37 @@ vectors words ; "/library/io/server.factor" "/library/tools/jedit.factor" - "/library/compiler/architecture.factor" + "/library/compiler/inference/shuffle.factor" + "/library/compiler/inference/dataflow.factor" + "/library/compiler/inference/inference.factor" + "/library/compiler/inference/branches.factor" + "/library/compiler/inference/words.factor" + "/library/compiler/inference/stack.factor" + "/library/compiler/inference/known-words.factor" - "/library/inference/shuffle.factor" - "/library/inference/dataflow.factor" - "/library/inference/inference.factor" - "/library/inference/branches.factor" - "/library/inference/words.factor" - "/library/inference/class-infer.factor" - "/library/inference/kill-literals.factor" - "/library/inference/optimizer.factor" - "/library/inference/inline-methods.factor" - "/library/inference/known-words.factor" - "/library/inference/stack.factor" - "/library/inference/call-optimizers.factor" - "/library/inference/print-dataflow.factor" + "/library/compiler/optimizer/specializers.factor" + "/library/compiler/optimizer/class-infer.factor" + "/library/compiler/optimizer/kill-literals.factor" + "/library/compiler/optimizer/optimizer.factor" + "/library/compiler/optimizer/inline-methods.factor" + "/library/compiler/optimizer/call-optimizers.factor" + "/library/compiler/optimizer/print-dataflow.factor" + + "/library/compiler/generator/architecture.factor" + "/library/compiler/generator/assembler.factor" + "/library/compiler/generator/templates.factor" + "/library/compiler/generator/xt.factor" + "/library/compiler/generator/generator.factor" - "/library/compiler/assembler.factor" - "/library/compiler/vops.factor" - "/library/compiler/linearizer.factor" - "/library/compiler/xt.factor" - "/library/compiler/stack.factor" - "/library/compiler/intrinsics.factor" - "/library/compiler/generator.factor" - "/library/compiler/basic-blocks.factor" "/library/compiler/compiler.factor" - "/library/alien/malloc.factor" - "/library/alien/c-types.factor" - "/library/alien/structs.factor" - "/library/alien/compiler.factor" - "/library/alien/alien-invoke.factor" - "/library/alien/alien-callback.factor" - "/library/alien/syntax.factor" + "/library/compiler/alien/malloc.factor" + "/library/compiler/alien/c-types.factor" + "/library/compiler/alien/structs.factor" + "/library/compiler/alien/compiler.factor" + "/library/compiler/alien/alien-invoke.factor" + "/library/compiler/alien/alien-callback.factor" + "/library/compiler/alien/syntax.factor" "/library/io/buffer.factor" @@ -193,13 +202,6 @@ vectors words ; "/library/kernel.facts" "/library/threads.facts" "/library/words.facts" - "/library/alien/alien-callback.facts" - "/library/alien/alien-invoke.facts" - "/library/alien/aliens.facts" - "/library/alien/c-types.facts" - "/library/alien/malloc.facts" - "/library/alien/structs.facts" - "/library/alien/syntax.facts" "/library/bootstrap/image.facts" "/library/collections/growable.facts" "/library/collections/arrays.facts" @@ -217,6 +219,14 @@ vectors words ; "/library/collections/flatten.facts" "/library/collections/vectors.facts" "/library/collections/virtual-sequences.facts" + "/library/compiler/alien/alien-callback.facts" + "/library/compiler/alien/alien-invoke.facts" + "/library/compiler/alien/aliens.facts" + "/library/compiler/alien/c-types.facts" + "/library/compiler/alien/malloc.facts" + "/library/compiler/alien/structs.facts" + "/library/compiler/alien/syntax.facts" + "/library/compiler/inference/inference.facts" "/library/compiler/compiler.facts" "/library/generic/early-generic.facts" "/library/generic/generic.facts" @@ -224,7 +234,6 @@ vectors words ; "/library/generic/slots.facts" "/library/generic/standard-combination.facts" "/library/generic/tuple.facts" - "/library/inference/inference.facts" "/library/io/binary.facts" "/library/io/buffer.facts" "/library/io/c-streams.facts" @@ -277,49 +286,34 @@ vectors words ; "/doc/handbook/tools.facts" "/doc/handbook/tutorial.facts" "/doc/handbook/words.facts" - } [ parse-resource % ] each + } [ parse-resource* % ] each - architecture get { - { - [ dup "x86" = ] [ - { - "/library/compiler/x86/assembler.factor" - "/library/compiler/x86/architecture.factor" - "/library/compiler/x86/generator.factor" - "/library/compiler/x86/slots.factor" - "/library/compiler/x86/stack.factor" - "/library/compiler/x86/fixnum.factor" - "/library/compiler/x86/alien.factor" - } - ] - } { - [ dup "ppc" = ] [ - { - "/library/compiler/ppc/assembler.factor" - "/library/compiler/ppc/architecture.factor" - "/library/compiler/ppc/generator.factor" - "/library/compiler/ppc/slots.factor" - "/library/compiler/ppc/stack.factor" - "/library/compiler/ppc/fixnum.factor" - "/library/compiler/ppc/alien.factor" - } - ] - } { - [ dup "amd64" = ] [ - { - "/library/compiler/x86/assembler.factor" - "/library/compiler/amd64/architecture.factor" - "/library/compiler/x86/generator.factor" - "/library/compiler/amd64/generator.factor" - "/library/compiler/x86/slots.factor" - "/library/compiler/amd64/slots.factor" - "/library/compiler/x86/stack.factor" - "/library/compiler/x86/fixnum.factor" - "/library/compiler/amd64/alien.factor" - } - ] - } - } cond [ parse-resource % ] each drop + { "x86" "pentium4" } { + "/library/compiler/x86/assembler.factor" + "/library/compiler/x86/architecture.factor" + "/library/compiler/x86/alien.factor" + "/library/compiler/x86/intrinsics.factor" + } if-arch + + { "pentium4" } { + "/library/compiler/x86/intrinsics-sse2.factor" + } if-arch + + { "ppc" } { + "/library/compiler/ppc/assembler.factor" + "/library/compiler/ppc/architecture.factor" + "/library/compiler/ppc/intrinsics.factor" + } if-arch + + { "amd64" } { + "/library/compiler/x86/assembler.factor" + "/library/compiler/x86/architecture.factor" + "/library/compiler/amd64/architecture.factor" + "/library/compiler/amd64/alien.factor" + "/library/compiler/x86/intrinsics.factor" + "/library/compiler/x86/intrinsics-sse2.factor" + "/library/compiler/amd64/intrinsics.factor" + } if-arch [ "/library/bootstrap/boot-stage2.factor" run-resource @@ -339,3 +333,6 @@ vocabularies get [ "Building generic words..." print flush all-words [ generic? ] subset [ make-generic ] each + +FORGET: if-arch +FORGET: parse-resource* diff --git a/library/bootstrap/boot-stage2.factor b/library/bootstrap/boot-stage2.factor index 1cd2362d80..7d5d4d7c4b 100644 --- a/library/bootstrap/boot-stage2.factor +++ b/library/bootstrap/boot-stage2.factor @@ -1,20 +1,20 @@ ! Copyright (C) 2004, 2006 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: compiler compiler-backend help io io-internals kernel +USING: compiler generic help io io-internals kernel kernel-internals lists math memory namespaces optimizer parser sequences sequences-internals words ; -"Cross-referencing..." print -xref-words -xref-articles +"Cross-referencing..." print flush +H{ } clone crossref set-global xref-words +H{ } clone help-graph set-global xref-articles "compile" get [ "native-io" get [ unix? [ "/library/unix/load.factor" run-resource ] when - ] when + windows? [ "/library/windows/load.factor" run-resource ] when @@ -23,15 +23,14 @@ xref-articles "Compiling base..." print flush - { - uncons 1+ 1- + <= > >= mod length - nth-unsafe set-nth-unsafe - = string>number number>string scan - kill-values (generate) - } [ compile ] each - - "Compiling system..." print flush - compile-all + [ + \ + compile + \ = compile + { "kernel" "sequences" "assembler" } compile-vocabs + + "Compiling system..." print flush + compile-all + ] with-classstring write " ms" print "Bootstrapping is complete." print "Now, you can run ./f factor.image" print flush -"factor.image" save-image +"factor.image" resource-path save-image 0 exit diff --git a/library/bootstrap/image.factor b/library/bootstrap/image.factor index 06387cf3fc..79bfff5635 100644 --- a/library/bootstrap/image.factor +++ b/library/bootstrap/image.factor @@ -62,9 +62,6 @@ SYMBOL: architecture : word-type 16 ; inline : tuple-type 17 ; inline -: immediate ( x tag -- tagged ) swap tag-bits shift bitor ; -: >header ( id -- tagged ) object-tag immediate ; - ( Image header ) : base 1024 ; @@ -104,11 +101,7 @@ GENERIC: ' ( obj -- ptr ) : align-here ( -- ) here 8 mod 4 = [ 0 emit ] when ; -( Fixnums ) - -: emit-fixnum ( n -- ) fixnum-tag immediate emit ; - -M: fixnum ' ( n -- tagged ) fixnum-tag immediate ; +: emit-fixnum ( n -- ) fixnum-tag tag-address emit ; ( Bignums ) @@ -136,14 +129,25 @@ M: fixnum ' ( n -- tagged ) fixnum-tag immediate ; M: bignum ' ( bignum -- tagged ) #! This can only emit 0, -1 and 1. bignum-tag here-as >r - bignum-tag >header emit + bignum-tag tag-header emit emit-bignum align-here r> ; +( Fixnums ) + +M: fixnum ' ( n -- tagged ) + #! When generating a 32-bit image on a 64-bit system, + #! some fixnums should be bignums. + dup most-negative-fixnum most-positive-fixnum between? [ + fixnum-tag tag-address + ] [ + >bignum ' + ] if ; + ( Floats ) M: float ' ( float -- tagged ) float-tag here-as >r - float-tag >header emit + float-tag tag-header emit align-here double>bits emit-64 r> ; @@ -177,7 +181,7 @@ M: f ' ( obj -- ptr ) dup word-vocabulary ' >r dup word-name ' >r object-tag here-as over objects get set-hash - word-type >header emit + word-type tag-header emit hashcode emit-fixnum r> emit r> emit @@ -209,7 +213,7 @@ M: word ' ( word -- pointer ) ; M: wrapper ' ( wrapper -- pointer ) wrapped ' object-tag here-as >r - wrapper-type >header emit + wrapper-type tag-header emit emit r> ; ( Conses ) @@ -234,7 +238,7 @@ M: complex ' ( c -- tagged ) >rect complex-tag emit-cons ; : emit-string ( string -- ptr ) object-tag here-as swap - string-type >header emit + string-type tag-header emit dup length emit-fixnum dup hashcode emit-fixnum pack-string emit-chars @@ -250,7 +254,7 @@ M: string ' ( string -- pointer ) : emit-array ( list type -- pointer ) >r [ ' ] map r> object-tag here-as >r - >header emit + tag-header emit dup length emit-fixnum ( elements -- ) emit-seq align-here r> ; @@ -270,7 +274,7 @@ M: array ' ( array -- pointer ) M: vector ' ( vector -- pointer ) dup underlying ' swap length object-tag here-as >r - vector-type >header emit + vector-type tag-header emit emit-fixnum ( length ) emit ( array ptr ) align-here r> ; @@ -278,7 +282,7 @@ M: vector ' ( vector -- pointer ) M: sbuf ' ( sbuf -- pointer ) dup underlying ' swap length object-tag here-as >r - sbuf-type >header emit + sbuf-type tag-header emit emit-fixnum ( length ) emit ( array ptr ) align-here r> ; @@ -288,7 +292,7 @@ M: sbuf ' ( sbuf -- pointer ) M: hashtable ' ( hashtable -- pointer ) [ hash-array ' ] keep object-tag here-as >r - hashtable-type >header emit + hashtable-type tag-header emit dup hash-count emit-fixnum hash-deleted emit-fixnum emit ( array ptr ) @@ -337,7 +341,7 @@ M: hashtable ' ( hashtable -- pointer ) ] if ; : image-name - "boot.image." architecture get append ; + "boot.image." architecture get append resource-path ; : write-image ( image -- ) "Writing image to " write dup write "..." print flush @@ -361,4 +365,4 @@ M: hashtable ' ( hashtable -- pointer ) ] with-scope ; : make-images ( -- ) - { "x86" "ppc" "amd64" } [ make-image ] each ; + { "x86" "pentium4" "ppc" "amd64" } [ make-image ] each ; diff --git a/library/bootstrap/primitives.factor b/library/bootstrap/primitives.factor index ccad6ca33b..7b2757e9cb 100644 --- a/library/bootstrap/primitives.factor +++ b/library/bootstrap/primitives.factor @@ -11,13 +11,14 @@ vectors words ; "Creating primitives and basic runtime structures..." print flush H{ } clone c-types set -"/library/alien/primitive-types.factor" parse-resource +"/library/compiler/alien/primitive-types.factor" parse-resource ! These symbols need the same hashcode in the target as in the -! host. +! host. They must be symbols -- colon definitions are not +! permitted to be carried over { vocabularies typemap builtins c-types - cell crossref articles terms + crossref articles terms } ! Bring up a bare cross-compiling vocabulary. @@ -59,7 +60,9 @@ call { "bits>double" "math" } { "" "math-internals" } { "fixnum+" "math-internals" } + { "fixnum+fast" "math-internals" } { "fixnum-" "math-internals" } + { "fixnum-fast" "math-internals" } { "fixnum*" "math-internals" } { "fixnum/i" "math-internals" } { "fixnum/f" "math-internals" } @@ -256,35 +259,39 @@ num-types f builtins set "fixnum?" "math" create t "inline" set-word-prop "fixnum" "math" create 0 "fixnum?" "math" create { } define-builtin -"fixnum" "math" create 0 "math-priority" set-word-prop "fixnum" "math" create ">fixnum" "math" lookup unit "coercer" set-word-prop "bignum?" "math" create t "inline" set-word-prop "bignum" "math" create 1 "bignum?" "math" create { } define-builtin -"bignum" "math" create 1 "math-priority" set-word-prop "bignum" "math" create ">bignum" "math" lookup unit "coercer" set-word-prop "cons?" "lists" create t "inline" set-word-prop "cons" "lists" create 2 "cons?" "lists" create -{ { 0 { "car" "lists" } f } { 1 { "cdr" "lists" } f } } define-builtin +{ + { 0 object { "car" "lists" } f } + { 1 object { "cdr" "lists" } f } +} define-builtin "ratio?" "math" create t "inline" set-word-prop "ratio" "math" create 4 "ratio?" "math" create -{ { 0 { "numerator" "math" } f } { 1 { "denominator" "math" } f } } define-builtin -"ratio" "math" create 2 "math-priority" set-word-prop +{ + { 0 integer { "numerator" "math" } f } + { 1 integer { "denominator" "math" } f } +} define-builtin "float?" "math" create t "inline" set-word-prop "float" "math" create 5 "float?" "math" create { } define-builtin -"float" "math" create 3 "math-priority" set-word-prop "float" "math" create ">float" "math" lookup unit "coercer" set-word-prop "complex?" "math" create t "inline" set-word-prop "complex" "math" create 6 "complex?" "math" create -{ { 0 { "real" "math" } f } { 1 { "imaginary" "math" } f } } define-builtin -"complex" "math" create 4 "math-priority" set-word-prop +{ + { 0 real { "real" "math" } f } + { 1 real { "imaginary" "math" } f } +} define-builtin "alien" "alien" create 7 "alien?" "alien" create -{ { 1 { "underlying-alien" "alien" } f } } define-builtin +{ { 1 object { "underlying-alien" "alien" } f } } define-builtin "array?" "arrays" create t "inline" set-word-prop "array" "arrays" create 8 "array?" "arrays" create @@ -296,49 +303,115 @@ num-types f builtins set "hashtable?" "hashtables" create t "inline" set-word-prop "hashtable" "hashtables" create 10 "hashtable?" "hashtables" create { - { 1 { "hash-count" "hashtables" } { "set-hash-count" "hashtables-internals" } } - { 2 { "hash-deleted" "hashtables" } { "set-hash-deleted" "hashtables-internals" } } - { 3 { "hash-array" "hashtables-internals" } { "set-hash-array" "hashtables-internals" } } + { + 1 + fixnum + { "hash-count" "hashtables" } + { "set-hash-count" "hashtables-internals" } + } { + 2 + fixnum + { "hash-deleted" "hashtables" } + { "set-hash-deleted" "hashtables-internals" } + } { + 3 + array + { "hash-array" "hashtables-internals" } + { "set-hash-array" "hashtables-internals" } + } } define-builtin "vector?" "vectors" create t "inline" set-word-prop "vector" "vectors" create 11 "vector?" "vectors" create { - { 1 { "length" "sequences" } { "set-fill" "sequences-internals" } } - { 2 { "underlying" "sequences-internals" } { "set-underlying" "sequences-internals" } } + { + 1 + fixnum + { "length" "sequences" } + { "set-fill" "sequences-internals" } + } { + 2 + array + { "underlying" "sequences-internals" } + { "set-underlying" "sequences-internals" } + } } define-builtin "string?" "strings" create t "inline" set-word-prop "string" "strings" create 12 "string?" "strings" create { - { 1 { "length" "sequences" } f } - { 2 { "string-hashcode" "kernel-internals" } { "set-string-hashcode" "kernel-internals" } } + { + 1 + fixnum + { "length" "sequences" } + f + } { + 2 + fixnum + { "string-hashcode" "kernel-internals" } + { "set-string-hashcode" "kernel-internals" } + } } define-builtin "sbuf?" "strings" create t "inline" set-word-prop "sbuf" "strings" create 13 "sbuf?" "strings" create { - { 1 { "length" "sequences" } { "set-fill" "sequences-internals" } } - { 2 { "underlying" "sequences-internals" } { "set-underlying" "sequences-internals" } } + { + 1 + fixnum + { "length" "sequences" } + { "set-fill" "sequences-internals" } + } + { + 2 + string + { "underlying" "sequences-internals" } + { "set-underlying" "sequences-internals" } + } } define-builtin "wrapper?" "kernel" create t "inline" set-word-prop "wrapper" "kernel" create 14 "wrapper?" "kernel" create -{ { 1 { "wrapped" "kernel" } f } } define-builtin +{ { 1 object { "wrapped" "kernel" } f } } define-builtin "dll?" "alien" create t "inline" set-word-prop "dll" "alien" create 15 "dll?" "alien" create -{ { 1 { "dll-path" "alien" } f } } define-builtin +{ { 1 object { "dll-path" "alien" } f } } define-builtin "word?" "words" create t "inline" set-word-prop "word" "words" create 16 "word?" "words" create { - { 1 { "hashcode" "kernel" } f } - { 2 { "word-name" "words" } f } - { 3 { "word-vocabulary" "words" } { "set-word-vocabulary" "words" } } - { 4 { "word-primitive" "words" } { "set-word-primitive" "words" } } - { 5 { "word-def" "words" } { "set-word-def" "words" } } - { 6 { "word-props" "words" } { "set-word-props" "words" } } + { 1 fixnum { "hashcode" "kernel" } f } + { + 2 + object + { "word-name" "words" } + f + } + { + 3 + object + { "word-vocabulary" "words" } + { "set-word-vocabulary" "words" } + } + { + 4 + object + { "word-primitive" "words" } + { "set-word-primitive" "words" } + } + { + 5 + object + { "word-def" "words" } + { "set-word-def" "words" } + } + { + 6 + object + { "word-props" "words" } + { "set-word-props" "words" } + } } define-builtin "tuple?" "kernel" create t "inline" set-word-prop diff --git a/library/bootstrap/profile-pentium4.factor b/library/bootstrap/profile-pentium4.factor new file mode 100644 index 0000000000..daa47e4f52 --- /dev/null +++ b/library/bootstrap/profile-pentium4.factor @@ -0,0 +1,6 @@ +USING: image kernel-internals namespaces ; + +! Do not load this file into a running image, ever. + +4 \ cell set +big-endian off diff --git a/library/cli.factor b/library/cli.factor index a2dba89ccf..3dd48f7999 100644 --- a/library/cli.factor +++ b/library/cli.factor @@ -12,7 +12,7 @@ parser sequences strings ; ] when ; : set-path ( value seq -- ) - unswons over [ nest [ set-path ] bind ] [ nip set ] if ; + uncons swap over [ nest [ set-path ] bind ] [ nip set ] if ; : cli-var-param ( name value -- ) swap ":" split >list set-path ; diff --git a/library/cocoa/callback.factor b/library/cocoa/callback.factor new file mode 100644 index 0000000000..0343f3e967 --- /dev/null +++ b/library/cocoa/callback.factor @@ -0,0 +1,27 @@ +IN: objc-FactorCallback +DEFER: FactorCallback + +IN: cocoa +USING: hashtables kernel namespaces objc objc-NSObject ; + +SYMBOL: callbacks + +H{ } clone callbacks set + +"NSObject" "FactorCallback" { + { "perform:" "void" { "id" "SEL" "id" } + [ nip swap callbacks get hash call ] + } + + { "dealloc" "void" { "id" "SEL" } + [ + drop + dup callbacks get remove-hash + SUPER-> [dealloc] + ] + } +} { } define-objc-class + +: ( quot -- id | quot: id -- ) + FactorCallback [alloc] [init] + [ callbacks get set-hash ] keep ; \ No newline at end of file diff --git a/library/cocoa/load.factor b/library/cocoa/load.factor index 5896c419a4..b97e0434c7 100644 --- a/library/cocoa/load.factor +++ b/library/cocoa/load.factor @@ -7,9 +7,11 @@ USING: compiler io parser sequences words ; "/library/cocoa/core-foundation.factor" "/library/cocoa/types.factor" "/library/cocoa/init-cocoa.factor" + "/library/cocoa/callback.factor" "/library/cocoa/application-utils.factor" "/library/cocoa/window-utils.factor" "/library/cocoa/view-utils.factor" + "/library/cocoa/menu-bar.factor" "/library/cocoa/ui.factor" } [ run-resource diff --git a/library/cocoa/menu-bar.factor b/library/cocoa/menu-bar.factor new file mode 100644 index 0000000000..0f18221105 --- /dev/null +++ b/library/cocoa/menu-bar.factor @@ -0,0 +1,142 @@ +USING: kernel sequences objc cocoa objc-NSObject objc-NSApplication objc-NSWindow objc-NSMenu objc-NSMenuItem objc-FactorCallback gadgets gadgets-layouts gadgets-listener words compiler strings lists ; + +! for words used by menu bar actions (copied from launchpad.factor) +USING: gadgets gadgets-browser gadgets-listener help inspector io kernel memory namespaces sequences gadgets-launchpad ; + +IN: cocoa + +: NSApp NSApplication [sharedApplication] ; + +! ------------------------------------------------------------------------- + +GENERIC: to-target-and-action ( selector-string-or-quotation -- target action ) + +M: string to-target-and-action sel_registerName f swap ; +M: f to-target-and-action f ; +M: list to-target-and-action \ drop swons "perform:" sel_registerName ; + + +: NSMenu [alloc] swap [initWithTitle:] [autorelease] ; + +: set-main-menu NSApp swap [setMainMenu:] ; + +: ( title action equivalent -- item ) + >r >r >r + NSMenuItem [alloc] + r> + r> dup [ sel_registerName ] when + r> + [initWithTitle:action:keyEquivalent:] [autorelease] ; + +: make-menu-item-2 ( title selector-string-or-quotation equivalent -- item ) + swap to-target-and-action swap >r swap dup r> [setTarget:] ; + +: submenu-to-item ( menu -- item ) + dup [title] CF>string f "" dup rot [setSubmenu:] ; + +: add-submenu ( menu submenu -- ) + submenu-to-item [addItem:] ; + +: and-modifiers ( item key-equivalent-modifier-mask -- item ) + dupd [setKeyEquivalentModifierMask:] ; +: and-alternate ( item -- item ) + dup 1 [setAlternate:] ; +: and-option-equivalent-modifier 1572864 and-modifiers ; + +! ------------------------------------------------------------------------- + +DEFER: described-menu + +! { } => separator + +! { { ... } } or +! { { ... } modify-quotation } => submenu as described in inner sequence + +! { title action equivalent } or +! { title action equivalent modify-quotation } => item + +! this is a mess +: described-item ( desc -- menu-item ) + dup length 0 = [ + drop NSMenuItem [separatorItem] + ] [ + dup first string? [ + [ first3 make-menu-item-2 ] keep + dup length 4 = [ fourth call ] [ drop ] if + ] [ + [ first described-menu ] keep + dup length 2 = [ second call ] [ drop ] if + submenu-to-item + ] if + ] if ; + +: and-described-item ( menu desc -- same-menu ) + described-item dupd [addItem:] ; + +: described-menu ( { title items* } -- menu ) + [ first ] keep + 1 swap tail [ and-described-item ] each ; + +: and-described-submenu ( menu { title items* } -- menu ) + described-menu dupd add-submenu ; + +! ------------------------------------------------------------------------- + + +: default-main-menu + { + "" + { { + "Factor" + ! About goes here + ! Preferences goes here + { { + "Services" + } [ dup NSApp swap [setServicesMenu:] ] } + { } + { "Hide Factor" "hide:" "h" } + { "Hide Others" "hideOtherApplications:" "h" [ and-option-equivalent-modifier ] } + { "Show All" "unhideAllApplications:" "" } + { } + { "Save Image" [ save ] "s" } + { } + { "Quit" "terminate:" "q" } + } [ dup NSApp swap [setAppleMenu:] ] } + { { + ! Tools is standing in for the File menu + "Tools" + { "Listener" [ listener-window ] "n" } + { "Vocabulary List" [ [ vocabs. ] "Vocabularies" pane-window ] "y" } + { "Globals" [ global browser-window ] "u" } + { "Memory" [ [ heap-stats. terpri room. ] "Memory" pane-window ] "u" } + } } + { { + "Edit" + { "Undo" "undo:" "z" } + { "Redo" "redo:" "Z" } + { } + { "Cut" "cut:" "x" } + { "Copy" "copy:" "c" } + { "Paste" "paste:" "v" } + { "Paste and Match Style" "pasteAsPlainText:" "V" [ and-option-equivalent-modifier ] } + { "Delete" "delete:" "" } + { "Select All" "selectAll:" "a" } + ! { } + ! Find, Spelling, and Speech submenus go here + } } + { { + "Window" + { "Close" "performClose:" "w" } + { "Zoom" "performZoom:" "" } + { "Minimize" "performMiniaturize:" "m" } + { "Minimize All" "miniaturizeAll:" "m" [ and-alternate and-option-equivalent-modifier ] } + { } + { "Bring All to Front" "arrangeInFront:" "" } + } [ dup NSApp swap [setWindowsMenu:] ] } + { { + "Help" + { "Factor Documentation" [ handbook-window ] "?" } + { "Help Index" [ [ articles. ] "Help index" pane-window ] "" } + { "Vocabularies" [ [ vocabs. ] "Vocabularies" pane-window ] "" } + } } + } described-menu set-main-menu ; diff --git a/library/cocoa/subclassing.factor b/library/cocoa/subclassing.factor index c231027dff..d84a3505d9 100644 --- a/library/cocoa/subclassing.factor +++ b/library/cocoa/subclassing.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. IN: objc USING: alien arrays compiler hashtables kernel kernel-internals -libc math namespaces sequences strings words ; +libc lists math namespaces sequences strings words ; : init-method ( method alien -- ) >r first3 r> @@ -64,13 +64,19 @@ libc math namespaces sequences strings words ; >r 1array r> append [ [ alien>objc-types get hash % CHAR: 0 , ] each ] "" make ; -: prepare-method ( { name ret types quot } -- { name type imp } ) - [ first3 encode-types ] keep - [ 1 swap tail % \ alien-callback , ] [ ] make compile-quot - 3array ; +: struct-return ( ret types quot -- ret types quot ) + pick c-struct? [ + pick c-size [ memcpy ] curry append + >r { "void*" } swap append >r drop "void" r> r> + ] when ; + +: prepare-method ( ret types quot -- type imp ) + >r [ encode-types ] 2keep r> + [ struct-return 3array % \ alien-callback , ] [ ] make + compile-quot ; : prepare-methods ( methods -- methods ) - [ prepare-method ] map ; + [ first4 prepare-method 3array ] map ; : define-objc-class ( superclass name imeth cmeth -- ) pick >r diff --git a/library/cocoa/types.factor b/library/cocoa/types.factor index d1dbcedf5c..54ef1635e4 100644 --- a/library/cocoa/types.factor +++ b/library/cocoa/types.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2006 Slava Pestov ! See http://factorcode.org/license.txt for BSD license. IN: cocoa -USING: alien kernel ; +USING: alien kernel math ; BEGIN-STRUCT: NSRect FIELD: float x @@ -20,6 +20,15 @@ TYPEDEF: NSRect CGRect [ set-NSRect-y ] keep [ set-NSRect-x ] keep ; +: NSRect-x-y ( rect -- origin-x origin-y ) + [ NSRect-x ] keep NSRect-y ; + +: NSRect-x-far-y ( rect -- origin-x far-y ) + [ NSRect-x-y ] keep NSRect-h + ; + +: ( x y w h -- rect ) + rot dupd swap - -rot ; + BEGIN-STRUCT: NSPoint FIELD: float x FIELD: float y diff --git a/library/cocoa/ui.factor b/library/cocoa/ui.factor index fb0ba981e2..e098ed011e 100644 --- a/library/cocoa/ui.factor +++ b/library/cocoa/ui.factor @@ -2,12 +2,14 @@ ! See http://factorcode.org/license.txt for BSD license. IN: objc-FactorView DEFER: FactorView +IN: objc-FactorUIWindowDelegate +DEFER: FactorUIWindowDelegate -USING: arrays cocoa errors freetype gadgets gadgets-launchpad -gadgets-layouts gadgets-listener gadgets-panes hashtables kernel -lists math namespaces objc objc-NSApplication objc-NSEvent -objc-NSObject objc-NSOpenGLContext objc-NSOpenGLView objc-NSView -objc-NSWindow sequences threads ; +USING: alien arrays cocoa errors freetype gadgets +gadgets-launchpad gadgets-layouts gadgets-listener gadgets-panes +hashtables kernel lists math namespaces objc objc-NSApplication +objc-NSEvent objc-NSObject objc-NSOpenGLContext +objc-NSOpenGLView objc-NSView objc-NSWindow sequences threads ; ! Cocoa backend for Factor UI @@ -18,6 +20,11 @@ SYMBOL: views H{ } clone views set-global +: purge-views ( hash -- hash ) + global [ + views [ [ drop expired? not ] hash-subset ] change + ] bind ; + : view ( handle -- world ) views get hash ; : mouse-location ( view event -- loc ) @@ -166,13 +173,42 @@ H{ } clone views set-global FactorView over rect-dim [ over set-world-handle dup add-notify register-view ] keep ; + +: window-root-gadget-pref-dim [contentView] view pref-dim ; + +: frame-rect-for-window-content-rect ( window rect -- rect ) + swap [styleMask] NSWindow -rot [frameRectForContentRect:styleMask:] ; + +: content-rect-for-window-frame-rect ( window rect -- rect ) + swap [styleMask] NSWindow -rot [contentRectForFrameRect:styleMask:] ; + +: window-content-rect ( window -- rect ) + dup [frame] content-rect-for-window-frame-rect ; + +"NSObject" "FactorUIWindowDelegate" { + { "windowWillUseStandardFrame:defaultFrame:" "NSRect" { "id" "SEL" "id" "NSRect" } + [ + drop 2nip ( self sel window default-frame -- window ) + dup window-content-rect NSRect-x-far-y ( window -- window x y ) + pick window-root-gadget-pref-dim first2 ( window x y -- window x y w h ) + + frame-rect-for-window-content-rect + ] + } +} { } define-objc-class + +: install-window-delegate ( window -- ) + FactorUIWindowDelegate [alloc] [init] [setDelegate:] ; + IN: gadgets : redraw-world ( handle -- ) world-handle 1 [setNeedsDisplay:] ; : open-window* ( world title -- ) - >r r> [contentView] [release] ; + >r r> + dup install-window-delegate + [contentView] [release] ; : select-gl-context ( handle -- ) [openGLContext] [makeCurrentContext] ; @@ -189,7 +225,8 @@ IN: shells [ [ init-ui - launchpad-window + purge-views + default-main-menu listener-window finish-launching event-loop diff --git a/library/cocoa/utilities.factor b/library/cocoa/utilities.factor index f35555a915..966e456f3e 100644 --- a/library/cocoa/utilities.factor +++ b/library/cocoa/utilities.factor @@ -119,9 +119,6 @@ H{ : class-methods ( classname -- seq ) objc-meta-class objc-methods ; -: make-dip ( quot n -- quot ) - dup \ >r -rot \ r> append3 ; - : ( receiver class -- super ) "objc-super" [ set-objc-super-class ] keep diff --git a/library/collections/graphs.factor b/library/collections/graphs.factor index 5b4175a198..fe909eb504 100644 --- a/library/collections/graphs.factor +++ b/library/collections/graphs.factor @@ -17,8 +17,7 @@ USING: hashtables kernel namespaces sequences ; swap [ swap (add-vertex) ] each-with ] if-graph ; -: (remove-vertex) ( vertex graph -- ) - nest remove-hash ; +: (remove-vertex) ( vertex graph -- ) nest remove-hash ; : remove-vertex ( vertex edges graph -- ) [ diff --git a/library/collections/growable.factor b/library/collections/growable.factor index 1beed28947..4c9d13ebec 100644 --- a/library/collections/growable.factor +++ b/library/collections/growable.factor @@ -13,7 +13,7 @@ GENERIC: set-fill : capacity ( seq -- n ) underlying length ; inline : expand ( len seq -- ) - [ underlying resize ] keep set-underlying ; + [ underlying resize ] keep set-underlying ; inline : new-size ( n -- n ) 3 * dup 50 < [ drop 50 ] when ; @@ -22,7 +22,7 @@ GENERIC: set-fill >r 1+ r> 2dup capacity > [ over new-size over expand ] when 2dup set-fill - ] when 2drop ; + ] when 2drop ; inline TUPLE: bounds-error index seq ; @@ -35,7 +35,8 @@ TUPLE: bounds-error index seq ; 2dup bounds-check? [ bounds-error ] unless ; inline : grow-length ( len seq -- ) - growable-check 2dup capacity > [ 2dup expand ] when set-fill ; + growable-check 2dup capacity > [ 2dup expand ] when set-fill + ; inline : clone-growable ( obj -- obj ) - (clone) dup underlying clone over set-underlying ; + (clone) dup underlying clone over set-underlying ; inline diff --git a/library/collections/hashtables.factor b/library/collections/hashtables.factor index 85519d0d30..0d625d6721 100644 --- a/library/collections/hashtables.factor +++ b/library/collections/hashtables.factor @@ -9,9 +9,10 @@ TUPLE: tombstone ; : ((empty)) T{ tombstone f } ; inline : ((tombstone)) T{ tombstone t } ; inline -: hash@ ( key keys -- n ) >r hashcode r> length 2 /i rem 2 * ; +: hash@ ( key keys -- n ) + >r hashcode r> length 2 /i rem 2 * ; inline -: probe ( heys i -- hash i ) 2 + over length mod ; +: probe ( heys i -- hash i ) 2 + over length mod ; inline : (key@) ( key keys i -- n ) 3dup swap nth-unsafe { @@ -21,51 +22,58 @@ TUPLE: tombstone ; { [ t ] [ probe (key@) ] } } cond ; -: key@ ( key hash -- n ) hash-array 2dup hash@ (key@) ; +: key@ ( key hash -- n ) + hash-array 2dup hash@ (key@) ; inline : if-key ( key hash true false -- | true: index key hash -- ) >r >r [ key@ ] 2keep pick -1 > r> r> if ; inline -: ( n -- array ) 1+ 4 * ((empty)) ; +: ( n -- array ) + 1+ 4 * ((empty)) ; inline + +: init-hash ( hash -- ) + 0 over set-hash-count 0 swap set-hash-deleted ; : reset-hash ( n hash -- ) - swap over set-hash-array - 0 over set-hash-count 0 swap set-hash-deleted ; + swap over set-hash-array init-hash ; : (new-key@) ( key keys i -- n ) 3dup swap nth-unsafe dup tombstone? [ 2drop 2nip ] [ = [ 2nip ] [ probe (new-key@) ] if - ] if ; + ] if ; inline : new-key@ ( key hash -- n ) - hash-array 2dup hash@ (new-key@) ; + hash-array 2dup hash@ (new-key@) ; inline : nth-pair ( n seq -- key value ) - [ nth-unsafe ] 2keep >r 1+ r> nth-unsafe ; + [ nth-unsafe ] 2keep >r 1+ r> nth-unsafe ; inline : set-nth-pair ( value key n seq -- ) - [ set-nth-unsafe ] 2keep >r 1+ r> set-nth-unsafe ; + [ set-nth-unsafe ] 2keep >r 1+ r> set-nth-unsafe ; inline -: hash-count+ dup hash-count 1+ swap set-hash-count ; +: hash-count+ + dup hash-count 1+ swap set-hash-count ; inline -: hash-deleted+ dup hash-deleted 1+ swap set-hash-deleted ; +: hash-deleted+ + dup hash-deleted 1+ swap set-hash-deleted ; inline -: hash-deleted- dup hash-deleted 1- swap set-hash-deleted ; +: hash-deleted- + dup hash-deleted 1- swap set-hash-deleted ; inline : change-size ( hash old -- ) dup ((tombstone)) eq? [ drop hash-deleted- ] [ ((empty)) eq? [ hash-count+ ] [ drop ] if - ] if ; + ] if ; inline : (set-hash) ( value key hash -- ) 2dup new-key@ swap [ hash-array 2dup nth-unsafe ] keep ( value key n hash-array old hash ) - swap change-size set-nth-pair ; + swap change-size set-nth-pair ; inline : (each-pair) ( quot array i -- | quot: k v -- ) over length over number= [ @@ -124,7 +132,7 @@ IN: hashtables dup [ hash ] [ 2drop f ] if ; : clear-hash ( hash -- ) - [ hash-array length ] keep reset-hash ; + dup init-hash hash-array [ drop ((empty)) ] inject ; : remove-hash ( key hash -- ) [ @@ -135,7 +143,8 @@ IN: hashtables 3drop ] if-key ; -: hash-size ( hash -- n ) dup hash-count swap hash-deleted - ; +: hash-size ( hash -- n ) + dup hash-count swap hash-deleted - ; inline : hash-empty? ( hash -- ? ) hash-size zero? ; @@ -146,7 +155,7 @@ IN: hashtables : ?grow-hash ( hash -- ) dup hash-count 3 * over hash-array length > - [ dup grow-hash ] when drop ; + [ dup grow-hash ] when drop ; inline : set-hash ( value key hash -- ) [ (set-hash) ] keep ?grow-hash ; @@ -235,9 +244,6 @@ M: hashtable hashcode ( hash -- n ) : ?hash* ( key hash/f -- value/f ) dup [ hash* ] [ 2drop f f ] if ; flushable -: ?set-hash ( value key hash/f -- hash ) - [ [ set-hash ] keep ] [ associate ] if ; - : hash-stack ( key seq -- value ) [ dupd hash-member? ] find-last nip ?hash ; flushable diff --git a/library/collections/hashtables.facts b/library/collections/hashtables.facts index c27f9b1bce..d39ed9c04a 100644 --- a/library/collections/hashtables.facts +++ b/library/collections/hashtables.facts @@ -146,11 +146,6 @@ HELP: set-hash "( value key hash -- )" { $description "Stores an entry into the hashtable." } { $see-also hash remove-hash } ; -HELP: ?set-hash "( value key hash/f -- hash )" -{ $values { "value" "a value" } { "key" "a key" } { "hash/f" "a hashtable or " { $link f } } } -{ $description "If the mapping is " { $link f } ", constructs a new hashtable storing the given key/value pair. Otherwise, stores the key/value pair into the hashtable." } -{ $see-also hash remove-hash } ; - HELP: hash-keys "( hash -- keys )" { $values { "hash" "a hashtable" } { "keys" "an array of keys" } } { $description "Outputs an array of all keys in the hashtable." } diff --git a/library/collections/lists.factor b/library/collections/lists.factor index 79c6aa5ff8..f8017a7a29 100644 --- a/library/collections/lists.factor +++ b/library/collections/lists.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2003, 2005 Slava Pestov. ! See http://factor.sf.net/license.txt for BSD license. -IN: lists USING: errors generic kernel math sequences ; +IN: lists USING: arrays errors generic kernel math sequences ; M: f car ; M: f cdr ; @@ -16,7 +16,6 @@ PREDICATE: general-list list ( list -- ? ) [ cdr list? ] [ t ] if* ; : uncons ( [[ car cdr ]] -- car cdr ) dup car swap cdr ; inline -: unswons ( [[ car cdr ]] -- cdr car ) dup cdr swap car ; inline : swons ( cdr car -- [[ car cdr ]] ) swap cons ; inline : unit ( a -- [ a ] ) f cons ; inline @@ -79,6 +78,9 @@ M: cons = ( obj cons -- ? ) : curry ( obj quot -- quot ) >r literalize r> cons ; +: make-dip ( quot n -- quot ) + dup \ >r -rot \ r> append3 >list ; + : (>list) ( n i seq -- list ) pick pick <= [ 3drop [ ] diff --git a/library/collections/namespaces.factor b/library/collections/namespaces.factor index 856e64d33f..70b0cab312 100644 --- a/library/collections/namespaces.factor +++ b/library/collections/namespaces.factor @@ -1,18 +1,23 @@ -! Copyright (C) 2003, 2005 Slava Pestov. +! Copyright (C) 2003, 2006 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. +IN: kernel-internals +USING: vectors ; + +: namestack* ( -- ns ) 3 getenv { vector } declare ; inline + IN: namespaces USING: arrays hashtables kernel kernel-internals lists math -sequences strings vectors words ; +sequences strings words ; -: namestack* ( -- ns ) 3 getenv ; inline : namestack ( -- ns ) namestack* clone ; inline -: set-namestack ( ns -- ) clone 3 setenv ; inline -: namespace ( -- namespace ) namestack* peek ; inline -: >n ( namespace -- n:namespace ) namestack* push ; inline -: n> ( n:namespace -- namespace ) namestack* pop ; inline -: global ( -- g ) 4 getenv ; inline +: set-namestack ( ns -- ) >vector 3 setenv ; inline +: namespace ( -- namespace ) namestack* peek ; +: >n ( namespace -- n:namespace ) namestack* push ; +: n> ( n:namespace -- namespace ) namestack* pop ; +: ndrop ( n:namespace -- ) namestack* pop* ; +: global ( -- g ) 4 getenv { hashtable } declare ; inline : get ( variable -- value ) namestack* hash-stack ; flushable -: set ( value variable -- ) namespace set-hash ; +: set ( value variable -- ) namespace set-hash ; inline : on ( var -- ) t swap set ; inline : off ( var -- ) f swap set ; inline : get-global ( var -- value ) global hash ; inline @@ -30,13 +35,13 @@ sequences strings vectors words ; : dec ( var -- ) -1 swap +@ ; inline -: bind ( namespace quot -- ) swap >n call n> drop ; inline +: bind ( namespace quot -- ) swap >n call ndrop ; inline : counter ( var -- n ) global [ dup inc get ] bind ; : make-hash ( quot -- hash ) H{ } clone >n call n> ; inline -: with-scope ( quot -- ) make-hash drop ; inline +: with-scope ( quot -- ) H{ } clone >n call ndrop ; inline ! Building sequences SYMBOL: building diff --git a/library/collections/namespaces.facts b/library/collections/namespaces.facts index cf476d92d9..886f82ae2b 100644 --- a/library/collections/namespaces.facts +++ b/library/collections/namespaces.facts @@ -1,5 +1,5 @@ IN: namespaces -USING: help ; +USING: help kernel-internals ; HELP: get "( variable -- value )" { $values { "variable" "a variable, by convention a symbol" } { "value" "the value, or " { $link f } } } diff --git a/library/collections/sequence-combinators.facts b/library/collections/sequence-combinators.facts index fa38347f6c..0b21654f74 100644 --- a/library/collections/sequence-combinators.facts +++ b/library/collections/sequence-combinators.facts @@ -3,7 +3,7 @@ USING: help math sequences-internals ; HELP: collect "( n quot -- array )" { $values { "n" "a non-negative integer" } { "quot" "a quotation with stack effect " { $snippet "( n -- value )" } } { "array" "an array with " { $snippet "n" } " elements" } } -{ $description "A primitive mapping operation that applies a quotation to all integers from 0 up to but not including " { $snippet "n" } ", and collects the results in a new array. Client code should use " { $snippet map } " instead." } ; +{ $description "A primitive mapping operation that applies a quotation to all integers from 0 up to but not including " { $snippet "n" } ", and collects the results in a new array. Client code should use " { $link map } " instead." } ; HELP: each "( seq quot -- )" { $values { "seq" "a sequence" } { "quot" "a quotation with stack effect " { $snippet "( elt -- )" } } } diff --git a/library/collections/sequence-eq.factor b/library/collections/sequence-eq.factor index 563bc0d93b..ac28e1644c 100644 --- a/library/collections/sequence-eq.factor +++ b/library/collections/sequence-eq.factor @@ -13,7 +13,7 @@ UNION: sequence array string sbuf vector ; dup length [ >r 2dup r> 2nth-unsafe = ] all? 2nip ] [ 2drop f - ] if ; inline + ] if ; M: sequence = ( obj seq -- ? ) 2dup eq? [ diff --git a/library/collections/sequences-epilogue.factor b/library/collections/sequences-epilogue.factor index f37f61c5c0..e2450e434e 100644 --- a/library/collections/sequences-epilogue.factor +++ b/library/collections/sequences-epilogue.factor @@ -1,17 +1,17 @@ ! Copyright (C) 2005, 2006 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. IN: sequences -USING: errors generic kernel kernel-internals math +USING: arrays errors generic kernel kernel-internals math sequences-internals strings vectors words ; : first2 ( { x y } -- x y ) - 1 swap bounds-check nip first2-unsafe ; inline + 1 swap bounds-check nip first2-unsafe ; flushable : first3 ( { x y z } -- x y z ) - 2 swap bounds-check nip first3-unsafe ; inline + 2 swap bounds-check nip first3-unsafe ; flushable : first4 ( { x y z w } -- x y z w ) - 3 swap bounds-check nip first4-unsafe ; inline + 3 swap bounds-check nip first4-unsafe ; flushable M: object like drop ; @@ -82,6 +82,11 @@ M: object like drop ; : add ( seq elt -- seq ) swap [ push ] immutable ; flushable +: add* ( seq elt -- seq ) + over >r + over thaw [ push ] keep [ swap nappend ] keep + r> like ; flushable + : diff ( seq1 seq2 -- seq2-seq1 ) [ swap member? not ] subset-with ; flushable @@ -93,10 +98,10 @@ M: object like drop ; : pop* ( sequence -- ) [ length 1- ] keep [ 0 -rot set-nth ] 2keep - set-length ; inline + set-length ; : pop ( sequence -- element ) - dup peek swap pop* ; inline + dup peek swap pop* ; M: object reverse-slice ( seq -- seq ) ; diff --git a/library/collections/sequences-epilogue.facts b/library/collections/sequences-epilogue.facts index 7d9e56ee75..1057e37c2e 100644 --- a/library/collections/sequences-epilogue.facts +++ b/library/collections/sequences-epilogue.facts @@ -40,8 +40,8 @@ HELP: memq? "( obj seq -- ? )" } { $see-also index index* member? } ; -HELP: remove "( elt seq -- ? )" -{ $values { "elt" "an object" } { "seq" "a sequence" } } +HELP: remove "( elt seq -- newseq )" +{ $values { "elt" "an object" } { "seq" "a sequence" } { "newseq" "a new sequence" } } { $description "Outputs a new sequence containing all elements of the input sequence except those equal to the given element." } ; HELP: subst "( newseq oldseq seq -- )" diff --git a/library/collections/sequences.factor b/library/collections/sequences.factor index 40d2636b95..fbcd04dfbb 100644 --- a/library/collections/sequences.factor +++ b/library/collections/sequences.factor @@ -12,7 +12,7 @@ GENERIC: like ( seq seq -- seq ) flushable GENERIC: reverse ( seq -- seq ) flushable GENERIC: reverse-slice ( seq -- seq ) flushable -: empty? ( seq -- ? ) length zero? ; +: empty? ( seq -- ? ) length zero? ; inline : first 0 swap nth ; inline : second 1 swap nth ; inline @@ -20,13 +20,13 @@ GENERIC: reverse-slice ( seq -- seq ) flushable : fourth 3 swap nth ; inline : push ( element sequence -- ) - dup length swap set-nth ; inline + dup length swap set-nth ; : ?push ( elt seq/f -- seq ) [ 1 ] unless* [ push ] keep ; : bounds-check? ( n seq -- ? ) - over 0 >= [ length < ] [ 2drop f ] if ; + over 0 >= [ length < ] [ 2drop f ] if ; inline : ?nth ( n seq/f -- elt/f ) 2dup bounds-check? [ nth ] [ 2drop f ] if ; diff --git a/library/collections/slicing.factor b/library/collections/slicing.factor index 7099e80d7e..3784cab3c6 100644 --- a/library/collections/slicing.factor +++ b/library/collections/slicing.factor @@ -104,8 +104,7 @@ strings vectors ; tuck swap tail-slice >r swap tail-slice r> ; : unpair ( seq -- firsts seconds ) - 2 swap group flip - dup empty? [ drop { } { } ] [ first2 ] if ; + flip dup empty? [ drop { } { } ] [ first2 ] if ; : concat ( seq -- seq ) dup empty? [ [ [ % ] each ] over first make ] unless ; diff --git a/library/alien/alien-callback.factor b/library/compiler/alien/alien-callback.factor similarity index 67% rename from library/alien/alien-callback.factor rename to library/compiler/alien/alien-callback.factor index bf80103403..375b982020 100644 --- a/library/alien/alien-callback.factor +++ b/library/compiler/alien/alien-callback.factor @@ -1,9 +1,8 @@ ! Copyright (C) 2006 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. IN: alien -USING: compiler-backend compiler-frontend errors generic -hashtables inference inspector kernel lists namespaces sequences -strings words ; +USING: compiler errors generic hashtables inference inspector +kernel lists namespaces sequences strings words ; TUPLE: alien-callback return parameters quot xt ; C: alien-callback make-node ; @@ -33,35 +32,34 @@ M: alien-callback-error summary ( error -- ) ] "infer" set-word-prop : box-parameters ( parameters -- ) - [ box-parameter ] map-parameters % ; + [ box-parameter ] each-parameter ; : registers>objects ( parameters -- ) - dup \ %freg>stack move-parameters % - "nest_stacks" f %alien-invoke , box-parameters ; + dup \ %freg>stack move-parameters + "nest_stacks" f %alien-invoke box-parameters ; : unbox-return ( node -- ) alien-callback-return [ - "unnest_stacks" f %alien-invoke , + "unnest_stacks" f %alien-invoke ] [ c-type [ "reg-class" get "unboxer-function" get - %callback-value , + %callback-value ] bind ] if-void ; -: linearize-callback ( node -- ) - dup alien-callback-xt [ - dup stack-reserve* %prologue , +: generate-callback ( node -- ) + [ alien-callback-xt ] keep [ dup alien-callback-parameters registers>objects - dup alien-callback-quot \ init-error-handler swons - %alien-callback , + dup alien-callback-quot \ init-error-handler add* + %alien-callback unbox-return - %return , - ] make-linear ; + %return + ] generate-block ; -M: alien-callback linearize* ( node -- ) - compile-gc linearize-callback iterate-next ; +M: alien-callback generate-node ( node -- ) + end-basic-block compile-gc generate-callback iterate-next ; M: alien-callback stack-reserve* alien-callback-parameters stack-space ; diff --git a/library/alien/alien-callback.facts b/library/compiler/alien/alien-callback.facts similarity index 100% rename from library/alien/alien-callback.facts rename to library/compiler/alien/alien-callback.facts diff --git a/library/alien/alien-invoke.factor b/library/compiler/alien/alien-invoke.factor similarity index 76% rename from library/alien/alien-invoke.factor rename to library/compiler/alien/alien-invoke.factor index 64500b44fa..096826f9ba 100644 --- a/library/alien/alien-invoke.factor +++ b/library/compiler/alien/alien-invoke.factor @@ -1,8 +1,8 @@ ! Copyright (C) 2004, 2006 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. IN: alien -USING: arrays assembler compiler compiler-backend -compiler-frontend errors generic hashtables inference inspector +USING: arrays assembler compiler compiler +errors generic hashtables inference inspector io kernel kernel-internals lists math namespaces parser prettyprint sequences strings words ; @@ -39,48 +39,50 @@ M: alien-invoke-error summary ( error -- ) node, ] "infer" set-word-prop -: unbox-parameter ( stack# type -- node ) +: unbox-parameter ( stack# type -- ) c-type [ "reg-class" get "unboxer" get call ] bind ; : unbox-parameters ( parameters -- ) - [ unbox-parameter , ] reverse-each-parameter ; + [ unbox-parameter ] reverse-each-parameter ; : objects>registers ( parameters -- ) #! Generate code for boxing a list of C types, then generate #! code for moving these parameters to register on #! architectures where parameters are passed in registers #! (PowerPC, AMD64). - dup unbox-parameters "save_stacks" f %alien-invoke , - \ %stack>freg move-parameters % ; + dup unbox-parameters "save_stacks" f %alien-invoke + \ %stack>freg move-parameters ; : box-return ( node -- ) - alien-invoke-return [ ] [ f swap box-parameter , ] if-void ; + alien-invoke-return [ ] [ f swap box-parameter ] if-void ; -: linearize-cleanup ( node -- ) +: generate-cleanup ( node -- ) dup alien-invoke-library library-abi "stdcall" = [ drop ] [ - alien-invoke-parameters stack-space %cleanup , + alien-invoke-parameters stack-space %cleanup ] if ; -M: alien-invoke linearize* ( node -- ) - compile-gc +M: alien-invoke generate-node ( node -- ) + end-basic-block compile-gc dup alien-invoke-parameters objects>registers - dup alien-invoke-dlsym %alien-invoke , - dup linearize-cleanup box-return + dup alien-invoke-dlsym %alien-invoke + dup generate-cleanup box-return iterate-next ; M: alien-invoke stack-reserve* alien-invoke-parameters stack-space ; : parse-arglist ( return seq -- types stack-effect ) - unpair rot dup "void" = [ drop { } ] [ 1array ] if 2array + 2 swap group unpair + rot dup "void" = [ drop { } ] [ 1array ] if 2array effect>string ; : (define-c-word) ( type lib func types stack-effect -- ) >r over create-in >r - [ alien-invoke ] cons cons cons cons r> swap define-compound - word r> "stack-effect" set-word-prop ; + [ alien-invoke ] curry curry curry curry + r> swap define-compound word r> + "stack-effect" set-word-prop ; : define-c-word ( return library function parameters -- ) [ "()" subseq? not ] subset >r pick r> parse-arglist diff --git a/library/alien/alien-invoke.facts b/library/compiler/alien/alien-invoke.facts similarity index 100% rename from library/alien/alien-invoke.facts rename to library/compiler/alien/alien-invoke.facts diff --git a/library/alien/aliens.factor b/library/compiler/alien/aliens.factor similarity index 100% rename from library/alien/aliens.factor rename to library/compiler/alien/aliens.factor diff --git a/library/alien/aliens.facts b/library/compiler/alien/aliens.facts similarity index 100% rename from library/alien/aliens.facts rename to library/compiler/alien/aliens.facts diff --git a/library/alien/c-types.factor b/library/compiler/alien/c-types.factor similarity index 89% rename from library/alien/c-types.factor rename to library/compiler/alien/c-types.factor index 4224bb431f..d720775670 100644 --- a/library/alien/c-types.factor +++ b/library/compiler/alien/c-types.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2004, 2006 Slava Pestov. ! See http://factor.sf.net/license.txt for BSD license. IN: alien -USING: arrays compiler compiler-backend errors generic +USING: arrays compiler errors generic hashtables kernel kernel-internals libc lists math namespaces parser sequences strings words ; @@ -53,10 +53,10 @@ SYMBOL: c-types : define-deref ( name vocab -- ) >r dup "*" swap append r> create - swap c-getter 0 swons define-compound ; + swap c-getter 0 add* define-compound ; : (define-nth) ( word type quot -- ) - >r c-size [ rot * ] curry r> append define-compound ; + >r c-size [ rot * ] swap add* r> append define-compound ; : define-nth ( name vocab -- ) >r dup "-nth" append r> create @@ -67,8 +67,8 @@ SYMBOL: c-types swap dup c-setter (define-nth) ; : define-out ( name vocab -- ) - over [ tuck 0 ] over c-setter append - >r >r constructor-word r> r> cons define-compound ; + over [ tuck 0 ] over c-setter append swap + >r >r constructor-word r> r> add* define-compound ; : init-c-type ( name vocab -- ) over define-pointer define-nth ; diff --git a/library/alien/c-types.facts b/library/compiler/alien/c-types.facts similarity index 100% rename from library/alien/c-types.facts rename to library/compiler/alien/c-types.facts diff --git a/library/alien/compiler.factor b/library/compiler/alien/compiler.factor similarity index 74% rename from library/alien/compiler.factor rename to library/compiler/alien/compiler.factor index a9a7ce7672..76898257fe 100644 --- a/library/alien/compiler.factor +++ b/library/compiler/alien/compiler.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2006 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. IN: alien -USING: arrays compiler-backend generic hashtables kernel +USING: arrays compiler generic hashtables kernel kernel-internals math namespaces sequences words ; : parameter-size c-size cell align ; @@ -27,7 +27,8 @@ kernel-internals math namespaces sequences words ; #! n is a stack location, and the value of the class #! variable is a register number. c-type "reg-class" swap hash dup reg-class-full? - [ spill-param ] [ fastcall-param ] if ; + [ spill-param ] [ fastcall-param ] if + [ fastcall-regs nth ] keep ; : flatten-value-types ( params -- params ) #! Convert value type structs to consecutive void*s. @@ -36,22 +37,25 @@ kernel-internals math namespaces sequences words ; [ c-size cell / "void*" ] [ 1array ] if ] map concat ; +: each-parameter ( parameters quot -- ) + >r [ parameter-sizes ] keep r> 2each ; inline + : reverse-each-parameter ( parameters quot -- ) >r [ parameter-sizes ] keep [ reverse-slice ] 2apply r> 2each ; inline -: map-parameters ( parameters quot -- seq ) - >r [ parameter-sizes ] keep r> 2map ; inline +: reset-freg-counts ( -- ) + 0 { int-regs float-regs stack-params } [ set ] each-with ; -: move-parameters ( params vop -- seq ) - #! Moves values from C stack to registers (if vop is - #! %stack>freg) and registers to C stack (if vop is +: move-parameters ( params word -- ) + #! Moves values from C stack to registers (if word is + #! %stack>freg) and registers to C stack (if word is #! %freg>stack). swap [ flatten-value-types - 0 { int-regs float-regs stack-params } [ set ] each-with - [ pick >r alloc-parameter r> execute ] map-parameters - nip + reset-freg-counts + [ pick >r alloc-parameter r> execute ] each-parameter + drop ] with-scope ; inline : box-parameter ( stack# type -- node ) diff --git a/library/alien/malloc.factor b/library/compiler/alien/malloc.factor similarity index 100% rename from library/alien/malloc.factor rename to library/compiler/alien/malloc.factor diff --git a/library/alien/malloc.facts b/library/compiler/alien/malloc.facts similarity index 100% rename from library/alien/malloc.facts rename to library/compiler/alien/malloc.facts diff --git a/library/alien/primitive-types.factor b/library/compiler/alien/primitive-types.factor similarity index 98% rename from library/alien/primitive-types.factor rename to library/compiler/alien/primitive-types.factor index dffe561967..f2415f36d7 100644 --- a/library/alien/primitive-types.factor +++ b/library/compiler/alien/primitive-types.factor @@ -1,5 +1,4 @@ -USING: alien compiler-backend kernel kernel-internals -math namespaces ; +USING: alien compiler kernel kernel-internals math namespaces ; [ [ alien-unsigned-cell ] "getter" set diff --git a/library/alien/structs.factor b/library/compiler/alien/structs.factor similarity index 88% rename from library/alien/structs.factor rename to library/compiler/alien/structs.factor index 65a86504e6..b86ca7973d 100644 --- a/library/alien/structs.factor +++ b/library/compiler/alien/structs.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2004, 2005 Slava Pestov. ! See http://factor.sf.net/license.txt for BSD license. IN: alien -USING: assembler compiler compiler-backend errors generic +USING: assembler compiler errors generic hashtables kernel kernel-internals lists math namespaces parser sequences strings words ; @@ -10,12 +10,12 @@ sequences strings words ; : define-getter ( offset type name -- ) #! Define a word with stack effect ( alien -- obj ) in the #! current 'in' vocabulary. - create-in >r c-getter cons r> swap define-compound ; + create-in >r c-getter swap add* r> swap define-compound ; : define-setter ( offset type name -- ) #! Define a word with stack effect ( obj alien -- ) in the #! current 'in' vocabulary. - "set-" swap append create-in >r c-setter cons r> + "set-" swap append create-in >r c-setter swap add* r> swap define-compound ; : define-field ( offset type name -- offset ) diff --git a/library/alien/structs.facts b/library/compiler/alien/structs.facts similarity index 100% rename from library/alien/structs.facts rename to library/compiler/alien/structs.facts diff --git a/library/alien/syntax.factor b/library/compiler/alien/syntax.factor similarity index 100% rename from library/alien/syntax.factor rename to library/compiler/alien/syntax.factor diff --git a/library/alien/syntax.facts b/library/compiler/alien/syntax.facts similarity index 100% rename from library/alien/syntax.facts rename to library/compiler/alien/syntax.facts diff --git a/library/compiler/amd64/alien.factor b/library/compiler/amd64/alien.factor index 657be36d3b..6b26137a75 100644 --- a/library/compiler/amd64/alien.factor +++ b/library/compiler/amd64/alien.factor @@ -1,92 +1,80 @@ ! Copyright (C) 2005, 2006 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -IN: compiler-backend +IN: compiler USING: alien arrays assembler kernel kernel-internals math sequences ; -GENERIC: freg>stack ( stack reg reg-class -- ) - -GENERIC: stack>freg ( stack reg reg-class -- ) - : stack@ RSP swap [+] ; -M: int-regs freg>stack drop >r stack@ r> MOV ; +M: int-regs %freg>stack drop >r stack@ r> MOV ; -M: int-regs stack>freg drop swap stack@ MOV ; +M: int-regs %stack>freg drop swap stack@ MOV ; -: MOVSS/LPD float-regs-size 4 = [ MOVSS ] [ MOVLPD ] if ; +: MOVSS/D float-regs-size 4 = [ MOVSS ] [ MOVSD ] if ; -M: float-regs freg>stack >r >r stack@ r> r> MOVSS/LPD ; +M: float-regs %freg>stack >r >r stack@ r> r> MOVSS/D ; -M: float-regs stack>freg >r swap stack@ r> MOVSS/LPD ; +M: float-regs %stack>freg >r swap stack@ r> MOVSS/D ; -M: stack-params stack>freg +M: stack-params %stack>freg drop >r R11 swap stack@ MOV r> stack@ R11 MOV ; -M: stack-params freg>stack - >r stack-increment + cell + swap r> stack>freg ; +M: stack-params %freg>stack + >r stack-increment + cell + swap r> %stack>freg ; -M: %unbox-struct generate-node ( vop -- ) - drop +: struct-ptr/size ( n reg-class size func -- ) + rot drop ! Load destination address - RDI RSP MOV - RDI 0 input ADD + >r RDI RSP MOV + RDI rot ADD ! Load struct size - RSI 2 input MOV + RSI swap MOV ! Copy the struct to the stack - "unbox_value_struct" f compile-c-call ; + r> f compile-c-call ; -M: %unbox generate-node ( vop -- ) - drop +: %unbox-struct ( n reg-class size -- ) + "unbox_value_struct" struct-ptr/size ; + +: %unbox ( n reg-class func -- ) ! Call the unboxer - 2 input f compile-c-call + f compile-c-call ! Store the return value on the C stack - 0 input 1 input [ return-reg ] keep freg>stack ; + [ return-reg ] keep %freg>stack ; -: (%move) 0 input 1 input 2 input [ fastcall-regs nth ] keep ; - -M: %stack>freg generate-node ( vop -- ) - ! Move a value from the C stack into the fastcall register - drop (%move) stack>freg ; - -M: %freg>stack generate-node ( vop -- ) - ! Move a value from a fastcall register to the C stack - drop (%move) freg>stack ; - -: reset-sse RAX RAX XOR ; - -M: %alien-invoke generate-node - reset-sse - drop 0 input 1 input load-library compile-c-call ; +: %box-struct ( n reg-class size -- ) + "box_value_struct" struct-ptr/size ; : load-return-value ( reg-class -- ) dup fastcall-regs first swap return-reg 2dup eq? [ 2drop ] [ MOV ] if ; -M: %box generate-node ( vop -- ) - drop - 0 input [ - 1 input [ fastcall-regs first ] keep stack>freg +: %box ( n reg-class func -- ) + rot [ + rot [ fastcall-regs first ] keep %stack>freg ] [ - 1 input load-return-value + swap load-return-value ] if* - 2 input f compile-c-call ; + f compile-c-call ; -M: %alien-callback generate-node ( vop -- ) - drop - RDI 0 input load-indirect - "run_callback" f compile-c-call ; +: reset-sse RAX RAX XOR ; -: save-return 0 swap [ return-reg ] keep freg>stack ; -: load-return 0 swap [ return-reg ] keep stack>freg ; +: %alien-invoke ( symbol dll -- ) + reset-sse compile-c-call ; -M: %callback-value generate-node ( vop -- ) - drop +: %alien-callback ( quot -- ) + RDI load-indirect "run_callback" f compile-c-call ; + +: save-return 0 swap [ return-reg ] keep %freg>stack ; +: load-return 0 swap [ return-reg ] keep %stack>freg ; + +: %callback-value ( reg-class func -- ) ! Call the unboxer - 1 input f compile-c-call + f compile-c-call ! Save return register - 0 input save-return + dup save-return ! Restore data/callstacks "unnest_stacks" f compile-c-call ! Restore return register - 0 input load-return ; + load-return ; + +: %cleanup ( n -- ) drop ; diff --git a/library/compiler/amd64/architecture.factor b/library/compiler/amd64/architecture.factor index 2c11013128..632a6c3d83 100644 --- a/library/compiler/amd64/architecture.factor +++ b/library/compiler/amd64/architecture.factor @@ -1,59 +1,60 @@ ! Copyright (C) 2005, 2006 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -IN: compiler-backend -USING: alien arrays assembler compiler compiler-frontend kernel -kernel-internals math namespaces sequences ; +IN: compiler +USING: alien arrays assembler generic kernel kernel-internals +math namespaces sequences ; ! AMD64 register assignments -! RAX RCX RDX RSI RDI R8 R9 R10 R11 vregs +! RAX RCX RDX RSI RDI R8 R9 R10 integer vregs +! XMM0 - XMM7 float vregs ! R13 cards_offset ! R14 datastack ! R15 callstack -: fixnum-imm? ( -- ? ) - #! Can fixnum operations take immediate operands? - f ; inline - : ds-reg R14 ; inline : cs-reg R15 ; inline : remainder-reg RDX ; inline - -: vregs { RAX RCX RDX RSI RDI R8 R9 R10 R11 } ; inline +: alloc-tmp-reg RBX ; inline M: int-regs return-reg drop RAX ; - +M: int-regs vregs drop { RAX RCX RDX RSI RDI R8 R9 R10 R11 } ; M: int-regs fastcall-regs drop { RDI RSI RDX RCX R8 R9 } ; +M: float-regs return-reg drop XMM0 ; +M: float-regs vregs drop { XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 } ; +M: float-regs fastcall-regs vregs ; + +: address-operand ( address -- operand ) + #! On AMD64, we have to load 64-bit addresses into a + #! scratch register first. The usage of R11 here is a hack. + #! This word can only be called right before a subroutine + #! call, where all vregs have been flushed anyway. + R11 [ swap MOV ] keep ; inline + : compile-c-call ( symbol dll -- ) - 2dup dlsym R10 swap MOV - rel-absolute-cell rel-dlsym R10 CALL ; + 2dup dlsym address-operand + >r rel-absolute-cell rel-dlsym r> CALL ; : compile-c-call* ( symbol dll args -- ) T{ int-regs } fastcall-regs swap [ MOV ] 2each compile-c-call ; -M: float-regs return-reg drop XMM0 ; - -M: float-regs fastcall-regs - drop { XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 } ; - -: address-operand ( address -- operand ) - #! On AMD64, we have to load 64-bit addresses into a - #! scratch register first. The usage of R11 here is a hack. - #! We cannot write '0 scratch' since scratch registers are - #! not permitted inside basic-block VOPs. - R11 [ swap MOV ] keep ; inline - : fixnum>slot@ drop ; inline : prepare-division CQO ; inline -: load-indirect ( dest literal -- ) +: load-indirect ( vreg literal -- ) + swap add-literal from 3 - [] MOV ; + +M: object load-literal ( literal vreg -- ) #! We use RIP-relative addressing. The '3' is a hardcoded #! instruction length. - add-literal from 3 - [] MOV ; inline + v>operand load-indirect ; : stack-increment \ stack-reserve get 16 align 8 + ; -: compile-epilogue ( -- ) - RSP stack-increment ADD ; inline +: %prologue ( n -- ) + \ stack-reserve set RSP stack-increment SUB ; + +: %epilogue ( -- ) + RSP stack-increment ADD ; diff --git a/library/compiler/amd64/generator.factor b/library/compiler/amd64/generator.factor deleted file mode 100644 index 986a0c3819..0000000000 --- a/library/compiler/amd64/generator.factor +++ /dev/null @@ -1,9 +0,0 @@ -! Copyright (C) 2006 Slava Pestov. -! See http://factorcode.org/license.txt for BSD license. -IN: compiler-backend -USING: assembler compiler-frontend kernel math namespaces ; - -M: %prologue generate-node ( vop -- ) - drop - 0 input \ stack-reserve set - RSP stack-increment SUB ; diff --git a/library/compiler/amd64/intrinsics.factor b/library/compiler/amd64/intrinsics.factor new file mode 100644 index 0000000000..b95d82f645 --- /dev/null +++ b/library/compiler/amd64/intrinsics.factor @@ -0,0 +1,9 @@ +! Copyright (C) 2006 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: assembler ; +IN: compiler + +: generate-write-barrier ( -- ) + #! Mark the card pointed to by vreg. + "obj" operand card-bits SHR + "obj" operand R13 [+] card-mark OR ; diff --git a/library/compiler/amd64/slots.factor b/library/compiler/amd64/slots.factor deleted file mode 100644 index 66697924f5..0000000000 --- a/library/compiler/amd64/slots.factor +++ /dev/null @@ -1,11 +0,0 @@ -! Copyright (C) 2006 Slava Pestov. -! See http://factorcode.org/license.txt for BSD license. -IN: compiler-backend -USING: alien arrays assembler compiler inference kernel -kernel-internals lists math memory namespaces sequences words ; - -M: %write-barrier generate-node ( vop -- ) - #! Mark the card pointed to by vreg. - drop - 0 input-operand card-bits SHR - 0 input-operand R13 [+] card-mark OR ; diff --git a/library/compiler/architecture.factor b/library/compiler/architecture.factor deleted file mode 100644 index 1acecc89b5..0000000000 --- a/library/compiler/architecture.factor +++ /dev/null @@ -1,10 +0,0 @@ -IN: compiler-backend - -! A few things the front-end needs to know about the back-end. - -DEFER: fixnum-imm? ( -- ? ) -#! Can fixnum operations take immediate operands? - -DEFER: vregs ( -- regs ) - -DEFER: compile-c-call ( library function -- ) diff --git a/library/compiler/basic-blocks.factor b/library/compiler/basic-blocks.factor deleted file mode 100644 index 5abd56c0ee..0000000000 --- a/library/compiler/basic-blocks.factor +++ /dev/null @@ -1,177 +0,0 @@ -! Copyright (C) 2005 Slava Pestov. -! See http://factor.sf.net/license.txt for BSD license. -IN: compiler-backend -USING: arrays hashtables kernel lists math namespaces sequences ; - -! Optimizations performed here: -! - combining %inc-d/%inc-r within a single basic block -! - if a literal is loaded into a vreg but the vreg is -! overwritten before being read, the literal load is deleted -! - if a %replace is writing a vreg to a stack location already -! holding that vreg, or a stack location that is not read -! before being popped, the %replace is deleted -! - if a %peek is reading a stack location into a vreg that -! already holds that vreg, or if the vreg is overwritten -! before being read, the %peek is deleted -! - removing dead loads of stack locations into vregs -! - removing dead stores of vregs into stack locations - -: vop-in ( vop n -- input ) swap vop-inputs nth ; -: set-vop-in ( input vop n -- ) swap vop-inputs set-nth ; -: vop-out ( vop n -- input ) swap vop-outputs nth ; - -: (split-blocks) ( n linear -- ) - 2dup length = [ - dup like , drop - ] [ - 2dup nth basic-block? [ - >r 1+ r> (split-blocks) - ] [ - (cut) >r , 1 r> (cut) >r , 0 r> (split-blocks) - ] if - ] if ; - -: split-blocks ( linear -- blocks ) - [ 0 swap (split-blocks) ] { } make ; - -SYMBOL: d-height -SYMBOL: r-height - -! combining %inc-d/%inc-r -GENERIC: simplify-stack* ( vop -- ) - -M: tuple simplify-stack* ( vop -- ) drop ; - -: accum-height ( vop var -- ) - >r dup 0 vop-in r> [ + ] change 0 swap 0 set-vop-in ; - -M: %inc-d simplify-stack* ( vop -- ) d-height accum-height ; - -M: %inc-r simplify-stack* ( vop -- ) r-height accum-height ; - -GENERIC: update-loc ( loc -- ) - -M: ds-loc update-loc - dup ds-loc-n d-height get - swap set-ds-loc-n ; - -M: cs-loc update-loc - dup cs-loc-n r-height get - swap set-cs-loc-n ; - -M: %peek simplify-stack* ( vop -- ) 0 vop-in update-loc ; - -M: %replace simplify-stack* ( vop -- ) 0 vop-out update-loc ; - -: simplify-stack ( block -- ) - #! Combine all %inc-d/%inc-r into two final ones. - #! Destructively modifies the VOPs in the block. - [ simplify-stack* ] each ; - -: each-tail ( seq quot -- | quot: tail -- ) - >r dup length [ swap tail-slice ] map-with r> each ; inline - -! removing dead loads/stores -: preserves-location? ( exitcc location vop -- ? ) - #! If the VOP writes the register, call the loop exit - #! continuation with 'f'. - { - { [ 2dup vop-inputs member? ] [ 3drop t ] } - { [ 2dup vop-outputs member? ] [ 2drop f swap continue-with ] } - { [ t ] [ 3drop f ] } - } cond ; - -GENERIC: live@end? ( location -- ? ) - -M: tuple live@end? drop t ; - -M: ds-loc live@end? ds-loc-n d-height get + 0 >= ; - -M: cs-loc live@end? cs-loc-n r-height get + 0 >= ; - -: location-live? ( location tail -- ? ) - #! A location is not live if and only if it is overwritten - #! before the end of the basic block. - [ - -rot [ >r 2dup r> preserves-location? ] contains? - [ dup live@end? ] unless* - ] callcc1 2nip ; - -! Used for elimination of dead loads from the stack: -! we keep a map of vregs to ds-loc/cs-loc/f. -SYMBOL: vreg-contents - -GENERIC: trim-dead* ( tail vop -- ) - -: forget-vregs ( vop -- ) - vop-outputs [ vreg-contents get remove-hash ] each ; - -M: tuple trim-dead* ( tail vop -- ) dup forget-vregs , drop ; - -: ?, [ , ] [ drop ] if ; - -: simplify-inc ( vop -- ) dup 0 vop-in zero? not ?, ; - -M: %inc-d trim-dead* ( tail vop -- ) simplify-inc drop ; - -M: %inc-r trim-dead* ( tail vop -- ) simplify-inc drop ; - -: live-load? ( tail vop -- ? ) - #! If the VOP's output location is overwritten before being - #! read again, kill the VOP. - 0 vop-out swap location-live? ; - -: remember-peek ( vop -- ) - dup 0 vop-in swap 0 vop-out vreg-contents get set-hash ; - -: redundant-peek? ( vop -- ? ) - dup 0 vop-in swap 0 vop-out vreg-contents get hash = ; - -M: %peek trim-dead* ( tail vop -- ) - dup redundant-peek? >r tuck live-load? not r> or - [ dup remember-peek dup , ] unless drop ; - -: redundant-replace? ( vop -- ? ) - dup 0 vop-out swap 0 vop-in vreg-contents get hash = ; - -: forget-stack-loc ( loc -- ) - #! Forget that any vregs hold this stack location. - vreg-contents [ [ nip swap = not ] hash-subset-with ] change ; - -: remember-replace ( vop -- ) - #! If a vreg claims to hold the stack location we are - #! writing to, we must forget this fact, since that stack - #! location no longer holds this value! - dup 0 vop-out forget-stack-loc - dup 0 vop-out swap 0 vop-in vreg-contents get set-hash ; - -M: %replace trim-dead* ( tail vop -- ) - dup redundant-replace? >r tuck live-load? not r> or - [ dup remember-replace dup , ] unless drop ; - -: ?dead-literal dup forget-vregs tuck live-load? ?, ; - -M: %immediate trim-dead* ( tail vop -- ) ?dead-literal ; - -M: %indirect trim-dead* ( tail vop -- ) ?dead-literal ; - -: trim-dead ( block -- ) - #! Remove dead loads and stores. - [ dup first >r 1 swap tail-slice r> trim-dead* ] each-tail ; - -: simplify-block ( block -- block ) - #! Destructively modifies the VOPs in the block. - [ - 0 d-height set - 0 r-height set - H{ } clone vreg-contents set - dup simplify-stack - d-height get %inc-d r-height get %inc-r 2array append - trim-dead - ] { } make ; - -: keep-simplifying ( block -- block ) - dup length >r simplify-block dup length r> = - [ keep-simplifying ] unless ; - -: simplify ( blocks -- blocks ) - #! Simplify basic block IR. - [ keep-simplifying ] map ; diff --git a/library/compiler/compiler.factor b/library/compiler/compiler.factor index e1c356abaf..ad191cb707 100644 --- a/library/compiler/compiler.factor +++ b/library/compiler/compiler.factor @@ -1,28 +1,20 @@ ! Copyright (C) 2004, 2006 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. IN: compiler -USING: compiler-backend compiler-frontend errors hashtables -inference io kernel lists math namespaces optimizer prettyprint -sequences test words ; +USING: errors hashtables inference io kernel lists math +namespaces optimizer prettyprint sequences test words ; : (compile) ( word -- ) - #! Should be called inside the with-compiler scope. - dup word-def dataflow optimize linearize - [ split-blocks simplify generate ] hash-each ; - -: benchmark-compile - [ [ (compile) ] keep ] benchmark nip - "compile-time" set-word-prop ; + dup specialized-def dataflow optimize generate ; : inform-compile ( word -- ) "Compiling " write . flush ; : compile-postponed ( -- ) compile-words get dup empty? [ - dup pop - dup inform-compile - benchmark-compile - compile-postponed - ] unless drop ; + drop + ] [ + pop dup inform-compile (compile) compile-postponed + ] if ; : compile ( word -- ) [ postpone-word compile-postponed ] with-compiler ; diff --git a/library/compiler/generator.factor b/library/compiler/generator.factor deleted file mode 100644 index 05d4b6e1f9..0000000000 --- a/library/compiler/generator.factor +++ /dev/null @@ -1,69 +0,0 @@ -! Copyright (C) 2004, 2005 Slava Pestov. -! See http://factor.sf.net/license.txt for BSD license. -IN: compiler-backend -USING: alien assembler compiler errors inference kernel -kernel-internals lists math memory namespaces sequences strings -vectors words ; - -! Compile a VOP. -GENERIC: generate-node ( vop -- ) - -: generate-code ( word linear -- length ) - compiled-offset >r - compile-aligned - swap save-xt - [ [ dup [ generate-node ] with-vop ] each ] each - compile-aligned - compiled-offset r> - ; - -: generate-reloc ( -- length ) - relocation-table get - dup [ assemble-cell ] each - length cells ; - -: (generate) ( word linear -- ) - #! Compile a word definition from linear IR. - V{ } clone relocation-table set - begin-assembly swap >r >r - generate-code - generate-reloc - r> set-compiled-cell - r> set-compiled-cell ; - -SYMBOL: previous-offset - -: generate ( word linear -- ) - #! If generation fails, reset compiled offset. - [ - compiled-offset previous-offset set - (generate) - ] [ - previous-offset get set-compiled-offset - rethrow - ] recover ; - -! A few VOPs have trivial generators. - -M: %label generate-node ( vop -- ) - vop-label save-xt ; - -M: %target-label generate-node ( vop -- ) - drop label 0 assemble-cell absolute-cell ; - -M: %cleanup generate-node ( vop -- ) drop ; - -M: %freg>stack generate-node ( vop -- ) drop ; - -M: %stack>freg generate-node ( vop -- ) drop ; - -M: %alien-invoke generate-node - #! call a C function. - drop 0 input 1 input compile-c-call ; - -: dest/src ( -- dest src ) 0 output-operand 0 input-operand ; - -! These constants must match native/card.h -: card-bits 7 ; -: card-mark HEX: 80 ; - -: string-offset 3 cells object-tag - ; diff --git a/library/compiler/generator/architecture.factor b/library/compiler/generator/architecture.factor new file mode 100644 index 0000000000..be0263f48a --- /dev/null +++ b/library/compiler/generator/architecture.factor @@ -0,0 +1,133 @@ +IN: compiler +USING: arrays generic kernel kernel-internals math memory +namespaces sequences ; + +! A scratch register for computations +TUPLE: vreg n ; + +C: vreg ( n reg-class -- vreg ) + [ set-delegate ] keep [ set-vreg-n ] keep ; + +! Register classes +TUPLE: int-regs ; +TUPLE: float-regs size ; + +: ( n -- vreg ) T{ int-regs } ; +: ( n -- vreg ) T{ float-regs f 8 } ; + +! A pseudo-register class for parameters spilled on the stack +TUPLE: stack-params ; + +! Return values of this class go here +GENERIC: return-reg ( register-class -- reg ) + +! Sequence of registers used for parameter passing in class +GENERIC: fastcall-regs ( register-class -- regs ) + +! Sequence mapping vreg-n to native assembler registers +GENERIC: vregs ( register-class -- regs ) + +! Map a sequence of literals to f or float +DEFER: literal-template ( literals -- template ) + +! Load a literal (immediate or indirect) +G: load-literal ( obj vreg -- ) 1 standard-combination ; + +! Set up caller stack frame (PowerPC and AMD64) +: %prologue ( n -- ) drop ; inline + +! Tear down stack frame (PowerPC and AMD64) +: %epilogue ( -- ) ; inline + +! Tail call another word +DEFER: %jump ( label -- ) + +! Call another word +DEFER: %call ( label -- ) + +! Local jump for branches or tail calls in nested #label +DEFER: %jump-label ( label -- ) + +! Test if vreg is 'f' or not +DEFER: %jump-t ( label vreg -- ) + +! Jump table of addresses (one cell each) is right after this +DEFER: %dispatch ( vreg -- ) + +! Return to caller +DEFER: %return ( -- ) + +! Change datastack height +DEFER: %inc-d ( n -- ) + +! Change callstack height +DEFER: %inc-r ( n -- ) + +! Load stack into vreg +GENERIC: (%peek) ( vreg loc reg-class -- ) +: %peek ( vreg loc -- ) over (%peek) ; + +! Store vreg to stack +GENERIC: (%replace) ( vreg loc reg-class -- ) +: %replace ( vreg loc -- ) over (%replace) ; + +! Move one vreg to another +DEFER: %move-int>int ( dst src -- ) +DEFER: %move-int>float ( dst src -- ) + +: %move ( dst src -- ) + 2dup = [ + 2drop + ] [ + 2dup [ delegate class ] 2apply 2array { + { [ dup { int-regs int-regs } = ] [ drop %move-int>int ] } + { [ dup { float-regs int-regs } = ] [ drop %move-int>float ] } + } cond + ] if ; + +! FFI stuff +DEFER: %unbox ( n reg-class func -- ) + +DEFER: %unbox-struct ( n reg-class size -- ) + +DEFER: %box ( n reg-class func -- ) + +DEFER: %box-struct ( n reg-class size -- ) + +GENERIC: %freg>stack ( stack reg reg-class -- ) + +GENERIC: %stack>freg ( stack reg reg-class -- ) + +DEFER: %alien-invoke ( library function -- ) + +DEFER: %cleanup ( n -- ) + +DEFER: %alien-callback ( quot -- ) + +DEFER: %callback-value ( reg-class func -- ) + +M: stack-params fastcall-regs drop 0 ; + +GENERIC: reg-size ( register-class -- n ) + +GENERIC: inc-reg-class ( register-class -- ) + +M: int-regs reg-size drop cell ; + +: (inc-reg-class) + dup class inc + macosx? [ reg-size stack-params +@ ] [ drop ] if ; + +M: int-regs inc-reg-class + (inc-reg-class) ; + +M: float-regs reg-size float-regs-size ; + +M: float-regs inc-reg-class + dup (inc-reg-class) + macosx? [ reg-size 4 / int-regs +@ ] [ drop ] if ; + +GENERIC: v>operand +M: integer v>operand tag-bits shift ; +M: vreg v>operand dup vreg-n swap vregs nth ; +M: f v>operand address ; diff --git a/library/compiler/assembler.factor b/library/compiler/generator/assembler.factor similarity index 100% rename from library/compiler/assembler.factor rename to library/compiler/generator/assembler.factor diff --git a/library/compiler/generator/generator.factor b/library/compiler/generator/generator.factor new file mode 100644 index 0000000000..088f1851bd --- /dev/null +++ b/library/compiler/generator/generator.factor @@ -0,0 +1,242 @@ +! Copyright (C) 2004, 2006 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +IN: compiler +USING: arrays assembler errors generic hashtables inference +kernel kernel-internals lists math namespaces queues sequences +words ; + +GENERIC: stack-reserve* + +M: object stack-reserve* drop 0 ; + +: stack-reserve ( node -- n ) + 0 swap [ stack-reserve* max ] each-node ; + +: intrinsic ( #call -- quot ) + node-param "intrinsic" word-prop ; + +: if-intrinsic ( #call -- quot ) + node-param "if-intrinsic" word-prop ; + +DEFER: #terminal? + +PREDICATE: #merge #terminal-merge node-successor #terminal? ; + +PREDICATE: #call #terminal-call + dup node-successor #if? + over node-successor node-successor #terminal? and + swap if-intrinsic and ; + +UNION: #terminal + POSTPONE: f #return #values #terminal-merge ; + +: tail-call? ( -- ? ) + node-stack get [ + dup #terminal-call? swap node-successor #terminal? or + ] all? ; + +: generate-code ( word node quot -- length | quot: node -- ) + compiled-offset >r + compile-aligned + rot save-xt + over stack-reserve %prologue + call + compile-aligned + compiled-offset r> - ; + +: generate-reloc ( -- length ) + relocation-table get + dup [ assemble-cell ] each + length cells ; + +SYMBOL: previous-offset + +: begin-generating ( -- code-len-fixup reloc-len-fixup ) + compiled-offset previous-offset set + V{ } clone relocation-table set + init-templates begin-assembly swap ; + +: generate-1 ( word node quot -- | quot: node -- ) + #! If generation fails, reset compiled offset. + [ + begin-generating >r >r + generate-code + generate-reloc + r> set-compiled-cell + r> set-compiled-cell + ] [ + previous-offset get set-compiled-offset rethrow + ] recover ; + +SYMBOL: generate-queue + +: generate-loop ( -- ) + generate-queue get dup queue-empty? [ + drop + ] [ + deque first3 generate-1 generate-loop + ] if ; + +: generate-block ( word node quot -- | quot: node -- ) + 3array generate-queue get enque ; + +GENERIC: generate-node ( node -- ) + +: generate-nodes ( node -- ) + [ node@ generate-node ] iterate-nodes end-basic-block ; + +: generate-word ( node -- ) + [ [ generate-nodes ] with-node-iterator ] + generate-block ; + +: generate ( word node -- ) + [ + generate-queue set + generate-word generate-loop + ] with-scope ; + +! node +M: node generate-node ( node -- next ) drop iterate-next ; + +! #label +: generate-call ( label -- next ) + end-basic-block + tail-call? [ %jump f ] [ %call iterate-next ] if ; + +M: #label generate-node ( node -- next ) + #! We remap the IR node's label to a new label object here, + #! to avoid problems with two IR #label nodes having the + #! same label in different lexical scopes. + dup node-param dup generate-call >r + swap node-child generate-word r> ; + +! #if +: end-false-branch ( label -- ) + tail-call? [ %return drop ] [ %jump-label ] if ; + +: generate-if ( node label -- next ) +