release
import-0.83
commit
b60e439ccd
13
.cvskeywords
13
.cvskeywords
|
@ -1,10 +1,3 @@
|
|||
./library/windows/win32-io-internals.factor:! $Id: win32-io-internals.factor,v 1.15 2006/01/28 20:49:31 spestov Exp $
|
||||
./library/windows/win32-io.factor:! $Id: win32-io.factor,v 1.4 2005/07/23 06:11:07 eiz Exp $
|
||||
./library/windows/win32-stream.factor:! $Id: win32-stream.factor,v 1.16 2006/01/28 20:49:31 spestov Exp $
|
||||
./library/windows/win32-errors.factor:! $Id: win32-errors.factor,v 1.11 2005/12/22 02:30:00 erg Exp $
|
||||
./library/windows/win32-server.factor:! $Id: win32-server.factor,v 1.13 2006/01/28 20:49:31 spestov Exp $
|
||||
./library/windows/winsock.factor:! $Id: winsock.factor,v 1.8 2005/09/12 15:10:33 erg Exp $
|
||||
./library/bootstrap/win32-io.factor:! $Id: win32-io.factor,v 1.10 2005/09/29 19:26:32 eiz Exp $
|
||||
./native/s48_bignum.c:$Id: s48_bignum.c,v 1.12 2005/12/21 02:36:52 spestov Exp $
|
||||
./native/s48_bignumint.h:$Id: s48_bignumint.h,v 1.14 2005/12/21 02:36:52 spestov Exp $
|
||||
./native/s48_bignum.h:$Id: s48_bignum.h,v 1.13 2005/12/21 02:36:52 spestov Exp $
|
||||
./vm/bignum.h:$Id: s48_bignum.h,v 1.13 2005/12/21 02:36:52 spestov Exp $
|
||||
./vm/bignumint.h:$Id: s48_bignumint.h,v 1.14 2005/12/21 02:36:52 spestov Exp $
|
||||
./vm/bignum.c:$Id: s48_bignum.c,v 1.12 2005/12/21 02:36:52 spestov Exp $
|
||||
|
|
|
@ -12,5 +12,59 @@
|
|||
<string>Factor</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleDocumentTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>*</string>
|
||||
</array>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Any</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>CFBundleTypeOSTypes</key>
|
||||
<array>
|
||||
<string>****</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>NSServices</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>NSMenuItem</key>
|
||||
<dict>
|
||||
<key>default</key>
|
||||
<string>Factor/Evaluate in Listener</string>
|
||||
</dict>
|
||||
<key>NSMessage</key>
|
||||
<string>evalInListener</string>
|
||||
<key>NSPortName</key>
|
||||
<string>Factor</string>
|
||||
<key>NSSendTypes</key>
|
||||
<array>
|
||||
<string>NSStringPboardType</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>NSMenuItem</key>
|
||||
<dict>
|
||||
<key>default</key>
|
||||
<string>Factor/Evaluate Selection</string>
|
||||
</dict>
|
||||
<key>NSMessage</key>
|
||||
<string>evalToString</string>
|
||||
<key>NSPortName</key>
|
||||
<string>Factor</string>
|
||||
<key>NSSendTypes</key>
|
||||
<array>
|
||||
<string>NSStringPboardType</string>
|
||||
</array>
|
||||
<key>NSReturnTypes</key>
|
||||
<array>
|
||||
<string>NSStringPboardType</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
157
Makefile
157
Makefile
|
@ -3,82 +3,51 @@ CC = gcc
|
|||
BINARY = f
|
||||
IMAGE = factor.image
|
||||
BUNDLE = Factor.app
|
||||
DISK_IMAGE_DIR = Factor-0.82
|
||||
DISK_IMAGE = Factor-0.82.dmg
|
||||
DISK_IMAGE_DIR = Factor-0.83
|
||||
DISK_IMAGE = Factor-0.83.dmg
|
||||
|
||||
ifdef DEBUG
|
||||
DEFAULT_CFLAGS = -g
|
||||
CFLAGS = -g
|
||||
STRIP = touch
|
||||
else
|
||||
DEFAULT_CFLAGS = -Wall -O3 -ffast-math -fomit-frame-pointer $(SITE_CFLAGS)
|
||||
CFLAGS = -Wall -O3 -ffast-math -fomit-frame-pointer $(SITE_CFLAGS)
|
||||
STRIP = strip
|
||||
endif
|
||||
|
||||
DEFAULT_LIBS = -lm
|
||||
|
||||
ifdef NO_UI
|
||||
UNIX_UI_LIBS =
|
||||
X11_UI_LIBS =
|
||||
else
|
||||
UNIX_UI_LIBS = -lfreetype -lGL -lGLU -L/usr/X11R6/lib -lX11
|
||||
X11_UI_LIBS = -lfreetype -lGL -lGLU -L/usr/X11R6/lib -lX11
|
||||
endif
|
||||
|
||||
WINDOWS_OBJS = native/windows/ffi.o \
|
||||
native/windows/file.o \
|
||||
native/windows/misc.o \
|
||||
native/windows/run.o \
|
||||
native/windows/memory.o
|
||||
|
||||
UNIX_OBJS = native/unix/file.o \
|
||||
native/unix/signal.o \
|
||||
native/unix/ffi.o \
|
||||
native/unix/memory.o \
|
||||
native/unix/icache.o
|
||||
|
||||
MACOSX_OBJS = $(UNIX_OBJS) \
|
||||
native/macosx/run.o \
|
||||
native/macosx/mach_signal.o
|
||||
|
||||
GENERIC_UNIX_OBJS = $(UNIX_OBJS) \
|
||||
native/unix/run.o
|
||||
|
||||
ifdef WINDOWS
|
||||
PLAF_OBJS = $(WINDOWS_OBJS)
|
||||
PLAF_SUFFIX = .exe
|
||||
else
|
||||
ifdef MACOSX
|
||||
PLAF_OBJS = $(MACOSX_OBJS)
|
||||
else
|
||||
PLAF_OBJS = $(GENERIC_UNIX_OBJS)
|
||||
endif
|
||||
ifdef CONFIG
|
||||
include $(CONFIG)
|
||||
endif
|
||||
|
||||
OBJS = $(PLAF_OBJS) native/array.o native/bignum.o \
|
||||
native/s48_bignum.o \
|
||||
native/complex.o native/cons.o native/error.o \
|
||||
native/factor.o native/fixnum.o \
|
||||
native/float.o native/gc.o \
|
||||
native/image.o native/memory.o \
|
||||
native/misc.o native/primitives.o \
|
||||
native/ratio.o native/relocate.o \
|
||||
native/run.o \
|
||||
native/sbuf.o native/stack.o \
|
||||
native/string.o native/cards.o native/vector.o \
|
||||
native/word.o native/compiler.o \
|
||||
native/alien.o native/dll.o \
|
||||
native/boolean.o \
|
||||
native/debug.o \
|
||||
native/hashtable.o \
|
||||
native/io.o \
|
||||
native/wrapper.o \
|
||||
native/ffi_test.o
|
||||
OBJS = $(PLAF_OBJS) \
|
||||
vm/alien.o \
|
||||
vm/bignum.o \
|
||||
vm/debug.o \
|
||||
vm/factor.o \
|
||||
vm/ffi_test.o \
|
||||
vm/image.o \
|
||||
vm/io.o \
|
||||
vm/math.o \
|
||||
vm/memory.o \
|
||||
vm/primitives.o \
|
||||
vm/run.o \
|
||||
vm/stack.o \
|
||||
vm/types.o
|
||||
|
||||
default:
|
||||
@echo "Run 'make' with one of the following parameters:"
|
||||
@echo ""
|
||||
@echo "bsd"
|
||||
@echo "linux"
|
||||
@echo "freebsd"
|
||||
@echo "linux-x86"
|
||||
@echo "linux-amd64"
|
||||
@echo "linux-ppc"
|
||||
@echo "macosx"
|
||||
@echo "macosx-x86"
|
||||
@echo "macosx-ppc"
|
||||
@echo "solaris"
|
||||
@echo "windows"
|
||||
@echo ""
|
||||
|
@ -91,30 +60,46 @@ default:
|
|||
@echo ""
|
||||
@echo "export SITE_CFLAGS=\"-march=pentium4 -ffast-math\""
|
||||
|
||||
bsd:
|
||||
$(MAKE) $(BINARY) \
|
||||
CFLAGS="$(DEFAULT_CFLAGS) -export-dynamic -pthread" \
|
||||
LIBS="$(DEFAULT_LIBS) $(UI_LIBS)"
|
||||
freebsd:
|
||||
$(MAKE) $(BINARY) CONFIG=vm/Config.freebsd
|
||||
|
||||
macosx-freetype:
|
||||
ln -sf libfreetype.6.dylib \
|
||||
Factor.app/Contents/Frameworks/libfreetype.dylib
|
||||
|
||||
macosx-ppc: macosx-freetype
|
||||
$(MAKE) $(BINARY) CONFIG=vm/Config.macosx.ppc
|
||||
|
||||
macosx-x86: macosx-freetype
|
||||
$(MAKE) $(BINARY) CONFIG=vm/Config.macosx
|
||||
|
||||
linux-x86 linux-amd64:
|
||||
$(MAKE) $(BINARY) CONFIG=vm/Config.linux
|
||||
$(STRIP) $(BINARY)
|
||||
|
||||
macosx:
|
||||
$(MAKE) $(BINARY) \
|
||||
CFLAGS="$(DEFAULT_CFLAGS)" \
|
||||
LIBS="$(DEFAULT_LIBS) -framework Cocoa -framework OpenGL -lfreetype" \
|
||||
MACOSX=y
|
||||
linux-ppc:
|
||||
$(MAKE) $(BINARY) CONFIG=vm/Config.linux.ppc
|
||||
$(STRIP) $(BINARY)
|
||||
|
||||
solaris solaris-x86 solaris-amd64:
|
||||
$(MAKE) $(BINARY) CONFIG=vm/Config.solaris
|
||||
$(STRIP) $(BINARY)
|
||||
|
||||
windows:
|
||||
$(MAKE) $(BINARY) CONFIG=vm/Config.windows
|
||||
|
||||
macosx.app:
|
||||
cp $(BINARY) $(BUNDLE)/Contents/MacOS/Factor
|
||||
|
||||
rm -rf $(BUNDLE)/Contents/Resources/
|
||||
mkdir -p $(BUNDLE)/Contents/Resources/fonts/
|
||||
cp -R fonts/*.ttf $(BUNDLE)/Contents/Resources/fonts/
|
||||
|
||||
chmod +x cp_dir
|
||||
find doc library contrib examples \( -name '*.factor' \
|
||||
find doc library contrib examples fonts \( -name '*.factor' \
|
||||
-o -name '*.facts' \
|
||||
-o -name '*.txt' \
|
||||
-o -name '*.html' \
|
||||
-o -name '*.ttf' \
|
||||
-o -name '*.js' \) \
|
||||
-exec ./cp_dir {} $(BUNDLE)/Contents/Resources/{} \;
|
||||
|
||||
|
@ -131,41 +116,20 @@ macosx.app:
|
|||
Factor.app/Contents/MacOS/Factor
|
||||
|
||||
macosx.dmg:
|
||||
rm -f $(DISK_IMAGE)
|
||||
rm $(DISK_IMAGE)
|
||||
rm -rf $(DISK_IMAGE_DIR)
|
||||
mkdir $(DISK_IMAGE_DIR)
|
||||
cp -R $(BUNDLE) $(DISK_IMAGE_DIR)/$(BUNDLE)
|
||||
hdiutil create -srcfolder "$(DISK_IMAGE_DIR)" -fs HFS+ \
|
||||
-volname "$(DISK_IMAGE_DIR)" "$(DISK_IMAGE)"
|
||||
|
||||
linux linux-x86 linux-amd64:
|
||||
$(MAKE) $(BINARY) \
|
||||
CFLAGS="$(DEFAULT_CFLAGS) -export-dynamic" \
|
||||
LIBS="-ldl $(DEFAULT_LIBS) $(UNIX_UI_LIBS)"
|
||||
$(STRIP) $(BINARY)
|
||||
|
||||
linux-ppc:
|
||||
$(MAKE) $(BINARY) \
|
||||
CFLAGS="$(DEFAULT_CFLAGS) -export-dynamic -mregnames" \
|
||||
LIBS="-ldl $(DEFAULT_LIBS) $(UNIX_UI_LIBS)"
|
||||
$(STRIP) $(BINARY)
|
||||
|
||||
solaris solaris-x86:
|
||||
$(MAKE) $(BINARY) \
|
||||
CFLAGS="$(DEFAULT_CFLAGS) -D_STDC_C99 -Drestrict=\"\" " \
|
||||
LIBS="-ldl -lsocket -lnsl $(DEFAULT_LIBS) -R/opt/PM/lib -R/opt/csw/lib -R/usr/local/lib -R/usr/sfw/lib -R/usr/X11R6/lib -R/opt/sfw/lib $(UNIX_UI_LIBS)"
|
||||
$(STRIP) $(BINARY)
|
||||
|
||||
windows:
|
||||
$(MAKE) $(BINARY) \
|
||||
CFLAGS="$(DEFAULT_CFLAGS) -DWINDOWS" \
|
||||
LIBS="$(DEFAULT_LIBS)" WINDOWS=y
|
||||
|
||||
f: $(OBJS)
|
||||
$(CC) $(LIBS) $(CFLAGS) -o $@$(PLAF_SUFFIX) $(OBJS)
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS)
|
||||
rm -f $(OBJS) $(UNIX_OBJS) $(WINDOWS_OBJS) $(MACOSX_OBJS)
|
||||
rm -rf $(BUNDLE)/Contents/Resources/
|
||||
rm -f $(BUNDLE)/Contents/MacOS/Factor
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(CFLAGS) -o $@ $<
|
||||
|
@ -175,8 +139,3 @@ clean:
|
|||
|
||||
.m.o:
|
||||
$(CC) -c $(CFLAGS) -o $@ $<
|
||||
|
||||
boot:
|
||||
echo "USE: image \"$(ARCH)\" make-image bye" | ./f factor.image
|
||||
./f boot.image.$(ARCH) $(BOOTSTRAP_FLAGS)
|
||||
|
||||
|
|
53
README.txt
53
README.txt
|
@ -13,7 +13,6 @@ implementation. It is not an introduction to the language itself.
|
|||
- Running Factor on Mac OS X
|
||||
- Running Factor on Windows
|
||||
- Source organization
|
||||
- Learning Factor
|
||||
- Community
|
||||
- Credits
|
||||
|
||||
|
@ -23,19 +22,21 @@ Factor is fully supported on the following platforms:
|
|||
|
||||
Linux/x86
|
||||
Linux/AMD64
|
||||
Mac OS X/x86
|
||||
Mac OS X/PowerPC
|
||||
Solaris/x86
|
||||
Microsoft Windows 2000 or later
|
||||
MS Windows XP
|
||||
|
||||
The following platforms should work, but are not tested on a
|
||||
regular basis:
|
||||
|
||||
FreeBSD/x86
|
||||
FreeBSD/AMD64
|
||||
Linux/PowerPC
|
||||
Solaris/x86
|
||||
Solaris/AMD64
|
||||
Linux/PowerPC
|
||||
|
||||
Other platforms are not supported.
|
||||
Please donate time or hardware if you wish to see Factor running on
|
||||
other platforms.
|
||||
|
||||
* Compiling Factor
|
||||
|
||||
|
@ -47,12 +48,13 @@ Factor requires gcc 3.4 or later. On x86, it /will not/ build using gcc
|
|||
Run 'make' (or 'gmake' on non-Linux platforms) with one of the following
|
||||
parameters to build the Factor runtime:
|
||||
|
||||
bsd
|
||||
linux
|
||||
freebsd
|
||||
linux-x86
|
||||
linux-amd64
|
||||
linux-ppc
|
||||
macosx
|
||||
macosx-x86
|
||||
macosx-ppc
|
||||
solaris
|
||||
windows
|
||||
|
||||
The following options can be given to make:
|
||||
|
||||
|
@ -76,9 +78,10 @@ Compilation will yield an executable named 'f'.
|
|||
|
||||
* Building Factor
|
||||
|
||||
The Factor source distribution ships with three boot image files:
|
||||
The Factor source distribution ships with four boot image files:
|
||||
|
||||
boot.image.x86
|
||||
boot.image.pentium4 -- uses SSE2, only for Pentium 4 and later
|
||||
boot.image.ppc
|
||||
boot.image.amd64
|
||||
|
||||
|
@ -89,9 +92,6 @@ The system is bootstrapped with the following command line:
|
|||
|
||||
./f boot.image.<foo>
|
||||
|
||||
Additional options may be specified to load external C libraries; see
|
||||
the next section for details.
|
||||
|
||||
Bootstrap can take a while, depending on your system. When the process
|
||||
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
|
||||
|
@ -141,29 +141,22 @@ 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.
|
||||
If you did not download the binary package, you can bootstrap Factor in
|
||||
the command prompt:
|
||||
|
||||
Bootstrap runs in a Windows command prompt, however after bootstrapping
|
||||
only the UI can be used.
|
||||
f.exe boot.image.pentium4 (or boot.image.x86)
|
||||
|
||||
Once bootstrapped, double-clicking f.exe starts the Factor UI. There is
|
||||
no option to run the listener in the command prompt on Windows.
|
||||
|
||||
* 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
|
||||
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 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
|
||||
grasp of the language.
|
||||
library/ - sources for the library, written in Factor
|
||||
vm/ - sources for the Factor runtime, written in C
|
||||
|
||||
* Community
|
||||
|
||||
|
@ -179,7 +172,9 @@ The following people have contributed code to the Factor core:
|
|||
|
||||
Slava Pestov: Lead developer
|
||||
Alex Chapman: OpenGL binding
|
||||
Doug Coleman: Mersenne Twister random number generator
|
||||
Doug Coleman: Mersenne Twister RNG, Windows port
|
||||
Eduardo Cavazos: X11 binding
|
||||
Joshua Grams: PowerPC instruction cache flush code
|
||||
Mackenzie Straight: Windows port
|
||||
Trent Buck: Debian package
|
||||
|
||||
|
|
171
TODO.FACTOR.txt
171
TODO.FACTOR.txt
|
@ -1,78 +1,129 @@
|
|||
should fix in 0.82:
|
||||
|
||||
- another i/o bug: on factorcode eventually all i/o times out
|
||||
- get factor running on mac intel
|
||||
|
||||
+ io:
|
||||
|
||||
- unix i/o: problems with passing f to syscalls
|
||||
- factorcode httpd started using 99% CPU, but still received connections;
|
||||
closing read-fds solved it
|
||||
- sometimes darcs get fails with the httpd
|
||||
- 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
|
||||
- "localhost" 50 <client> won't fail
|
||||
|
||||
+ ui/help:
|
||||
+ ui:
|
||||
|
||||
- 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
|
||||
- x11 input methods
|
||||
- "benchmark/help" runs out of memory
|
||||
- shortcuts:
|
||||
- find a listener
|
||||
- find a browser
|
||||
- find a help window
|
||||
- they'll either focus such a window, or if the current window is of
|
||||
that type, cycle
|
||||
- thumb min size
|
||||
- support x11's large selections, if needed
|
||||
- own-selection violates ICCCM
|
||||
- one-column table doesn't need borders...?
|
||||
- make-frame should compile
|
||||
- editor:
|
||||
- undo and redo
|
||||
- transpose char/word/line
|
||||
- autoscroll
|
||||
- page up/down
|
||||
- search and replace
|
||||
- only redraw visible lines
|
||||
- more efficient multi-line inserts
|
||||
- editor should support stream output protocol
|
||||
- scroll to caret
|
||||
- better listener multi-line expression handling
|
||||
- history doesn't work in a good way if you ^K the input
|
||||
- history: move caret to end
|
||||
- finish gui stepper
|
||||
- cocoa: windows are not updated while resizing
|
||||
- graphical module manager tool
|
||||
- add some handy services:
|
||||
- base conversion
|
||||
- search help for selection
|
||||
- make factor a services client
|
||||
- services do not launch if factor not running
|
||||
- grid slows down with 2000 lines
|
||||
- integrated error documentation
|
||||
- roundoff is still not quite right with tracks
|
||||
- 'show' doesn't work if invoked from a listener on an object which is
|
||||
itself inspected in the listener
|
||||
- ui uses too much cpu time idling
|
||||
- see if its possible to only repaint dirty regions
|
||||
- x11 title bars are funny
|
||||
- cocoa:
|
||||
- don't multiplex in the event loop if there is no pending i/o
|
||||
- horizontal scrolling
|
||||
- fix mouse-overs...
|
||||
- display lists
|
||||
- saving the image should save window configuration
|
||||
- make the UI look better, something like this:
|
||||
http://twb.ath.cx/~twb/darcs/OBSOLETE/factor/final.html
|
||||
- fix remaining HTML stream issues
|
||||
- fix up the min thumb size hack
|
||||
- automatically update help graph when adding/removing articles/words
|
||||
- document conventions
|
||||
- new turtle graphics tutorial
|
||||
- better line spacing in ui and html
|
||||
- tabular formatting - for inspector, changes and $values in help
|
||||
- grid layout
|
||||
- variable width word wrap
|
||||
- fix top level window positioning
|
||||
- changing window titles
|
||||
- prettyprinter's highlighting of non-leaves doesn't really work
|
||||
- rollover is not updated on window focus changes
|
||||
- x11 input methods
|
||||
- cocoa:
|
||||
- horizontal wheel scrolling
|
||||
- polish OS X menu bar code
|
||||
- variable width word wrap
|
||||
- slider needs to be modelized
|
||||
|
||||
+ module system:
|
||||
|
||||
- 'see' should show tuple constructors
|
||||
- forgetting a class should remove its methods from all generic words
|
||||
- offer to remove generic words which are not called and have no
|
||||
methods
|
||||
- forgetting a tuple class should forget the constructor
|
||||
- seeing a tuple class should show the constructor
|
||||
- C types should be words
|
||||
- TYPEDEF: float { ... } { ... } ; ==> \ float T{ c-type ... } "c-type" swp
|
||||
- TYPEDEF: float FTFloat ; ==> \ float \ FTFloat "c-type" swp
|
||||
- make typedef aliasing explicit
|
||||
- seeing a C struct word should show its def
|
||||
- see by itself only shows the G: def
|
||||
- { class generic } see supports forms:
|
||||
{ f generic } to show all methods
|
||||
{ class f } to show all methods
|
||||
- modularize core
|
||||
- TUPLE: module files tests articles article main ;
|
||||
- methods: remember their file/line
|
||||
- { class generic } jedit, reload DTRT
|
||||
- requesting a list of assets loaded from a specific file
|
||||
- T{ link f "foo" "bar" } see
|
||||
- T{ link f "foo" "bar" } jedit
|
||||
- T{ link f "foo" "bar" } reload
|
||||
- generic 'define ( asset def -- )'
|
||||
- file out
|
||||
- make 'forget' generic
|
||||
|
||||
+ 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 <void*> only be called with an alien?
|
||||
- remove <char*>, <ushort*>, set-char*-nth, set-ushort*-nth since they
|
||||
have incorrect semantics
|
||||
- complex float type
|
||||
- complex float intrinsics
|
||||
- remove literal table
|
||||
- C functions returning structs by value
|
||||
- FIELD: char key_vector[32];
|
||||
- FIELD: union { char b[20]; short s[10]; long l[5]; } data;
|
||||
- MEMBER: long pad[24];
|
||||
- C structs: use new-style string mode parsing
|
||||
- nasty inference regressions
|
||||
- [ [ dup call ] dup call ] infer hangs
|
||||
- the invalid recursion form case needs to be fixed, for inlines too
|
||||
- code gc
|
||||
- instead of decompiling words, add them to a 'recompile' set; compiler
|
||||
treats words in the recompile set as if they were not compiled
|
||||
- mac intel: struct returns from objc methods
|
||||
- see if alien calls can be made faster
|
||||
- faster sequence= for UI
|
||||
- fix compiled gc check
|
||||
- there was a performance hit, investigate
|
||||
- float boxing and overflow checks need a gc check too
|
||||
- constant branch folding
|
||||
- type inference at branch merge points
|
||||
- float= doesn't consider nans equal
|
||||
- intrinsic fixnum>float float>fixnum
|
||||
- remove literal table
|
||||
- C functions returning structs by value
|
||||
- code gc
|
||||
- infer which variables are read, written in a quotation
|
||||
|
||||
+ misc:
|
||||
|
||||
- 3 >n fep
|
||||
- code walker & exceptions
|
||||
- consider: swap tail --> tail, swap head --> head
|
||||
- mach_signal: fault address reporting is not reliable
|
||||
- slice: if sequence or seq start is changed, abstraction violation
|
||||
- make 3.4 bits>double an error
|
||||
- code walker and callbacks is broken?
|
||||
- hashed generic method dispatch
|
||||
- fix this:
|
||||
|
||||
[ 1 2 3 4 5 6 7 8 9 10 10 10 10 10 10 10 10 10 10 11 11 11 113 ] .
|
||||
[ 1 2 3 4 5 6 7 8 9 10 10 10 10 10 10 10 10 10 10 11 11 11 113
|
||||
]
|
||||
|
||||
- code walker & exceptions -- test and debug problems
|
||||
- break: perhaps use current stdio to run break listener
|
||||
- httpd search tools
|
||||
- remaining HTML issues need fixing
|
||||
|
|
BIN
boot.image.amd64
BIN
boot.image.amd64
Binary file not shown.
Binary file not shown.
BIN
boot.image.ppc
BIN
boot.image.ppc
Binary file not shown.
BIN
boot.image.x86
BIN
boot.image.x86
Binary file not shown.
|
@ -1,43 +1,32 @@
|
|||
This directory contains Factor code that is not part of the core
|
||||
library, but is useful enough to ship with the Factor distribution.
|
||||
|
||||
- contrib/aim/ -- AOL Instant Messenger client library (Doug Coleman)
|
||||
Modules can be loaded from the listener:
|
||||
|
||||
- contrib/algebra/ -- infix math syntax (Daniel Ehrenberg)
|
||||
"modulename" require
|
||||
|
||||
- contrib/cairo/ -- cairo bindings (Sampo Vuori)
|
||||
Credits:
|
||||
|
||||
- contrib/concurrency/ -- Erlang/Termite-style concurrency (Chris Double)
|
||||
|
||||
- contrib/cont-responder/ -- additional examples and tools for the
|
||||
continuation-based web framework (Chris Double)
|
||||
|
||||
- contrib/crypto/ -- MD5 and SHA1 cryptographic hashes (Doug Coleman)
|
||||
|
||||
- contrib/factory/ -- X11 window manager (Eduardo Cavazos)
|
||||
|
||||
- contrib/httpd/ -- HTTP server and client (Slava Pestov, Chris Double)
|
||||
|
||||
- contrib/math/ -- extended math library (Doug Coleman)
|
||||
|
||||
- contrib/parser-combinators/ -- Lazy lists and Haskell-style parser
|
||||
combinators (Chris Double)
|
||||
|
||||
- contrib/postgresql/ -- PostgreSQL binding (Doug Coleman)
|
||||
|
||||
- contrib/random-tester/ -- Random compiler tester (Doug Coleman)
|
||||
|
||||
- contrib/space-invaders/ -- Intel 8080-based Space Invaders arcade
|
||||
machine emulator (Chris Double)
|
||||
|
||||
- contrib/sqlite/ -- SQLite binding (Chris Double)
|
||||
|
||||
- contrib/x11 -- X Window System client library (Eduardo Cavazos)
|
||||
|
||||
- contrib/coroutines.factor -- coroutines (Chris Double)
|
||||
|
||||
- contrib/dlists.factor -- double-linked-lists (Mackenzie Straight)
|
||||
|
||||
- contrib/splay-trees.factor -- Splay trees (Mackenzie Straight)
|
||||
|
||||
- contrib/xml.factor -- XML parser and writer (Daniel Ehrenberg)
|
||||
- automata -- Graphics demo for the UI (Eduardo Cavazos)
|
||||
- boids -- Graphics demo for the UI (Eduardo Cavazos)
|
||||
- cairo -- cairo bindings (Sampo Vuori)
|
||||
- calendar -- timestamp/calendar with timezones (Doug Coleman)
|
||||
- concurrency -- Erlang/Termite-style concurrency (Chris Double)
|
||||
- coroutines -- coroutines (Chris Double)
|
||||
- crypto -- Various cryptographic algorithms (Doug Coleman)
|
||||
- dlists -- double-linked-lists (Mackenzie Straight)
|
||||
- factory -- X11 window manager (Eduardo Cavazos)
|
||||
- gap-buffer -- Efficient text editor buffer (Alex Chapman)
|
||||
- hexdump -- Hexdump routine (Doug Coleman)
|
||||
- httpd -- Web framework (HTTP server, client, XML parser, HTML generation...) (Slava Pestov, Chris Double, Daniel Ehrenberg)
|
||||
- lazy-lists -- Lazy evaluation lists (Chris Double, Matthew Willis)
|
||||
- math -- extended math library (Doug Coleman, Slava Pestov)
|
||||
- parser-combinators -- Haskell-style parser combinators (Chris Double)
|
||||
- postgresql -- PostgreSQL binding (Doug Coleman)
|
||||
- process -- Run external programs (Slava Pestov)
|
||||
- random-tester -- Random compiler tester (Doug Coleman)
|
||||
- slate -- Graphics canvas for the UI (Eduardo Cavazos)
|
||||
- space-invaders -- Intel 8080-based Space Invaders arcade machine emulator (Chris Double)
|
||||
- splay-trees -- Splay trees (Mackenzie Straight)
|
||||
- sqlite -- SQLite binding (Chris Double)
|
||||
- x11 -- X Window System client library (Eduardo Cavazos)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,9 +0,0 @@
|
|||
IN: scratchpad
|
||||
USING: kernel parser sequences words compiler ;
|
||||
|
||||
"/contrib/crypto/load.factor" run-resource
|
||||
|
||||
{
|
||||
"net-bytes"
|
||||
"aim"
|
||||
} [ "/contrib/aim/" swap ".factor" append3 run-resource ] each
|
|
@ -1,189 +0,0 @@
|
|||
IN: aim-internals
|
||||
USING: kernel sequences lists prettyprint strings namespaces math threads vectors errors parser interpreter test io crypto arrays ;
|
||||
|
||||
SYMBOL: big-endian t big-endian set
|
||||
SYMBOL: unscoped-stream
|
||||
SYMBOL: unscoped-stack
|
||||
|
||||
! Examples:
|
||||
! 1 2 3 4 4 >nvector .
|
||||
! { 1 2 3 4 }
|
||||
|
||||
! { 1 2 3 4 } { >byte >short >int >long } papply .
|
||||
! "\u0001\0\u0002\0\0\0\u0003\0\0\0\0\0\0\0\u0004"
|
||||
|
||||
! [ 1 >short 6 >long ] make-packet .
|
||||
! "\0\u0001\0\0\0\0\0\0\0\u0006"
|
||||
|
||||
: int>ip ( n -- str )
|
||||
[ HEX: ff000000 over bitand -24 shift unparse % CHAR: . ,
|
||||
HEX: 00ff0000 over bitand -16 shift unparse % CHAR: . ,
|
||||
HEX: 0000ff00 over bitand -8 shift unparse % CHAR: . ,
|
||||
HEX: 000000ff bitand unparse % ] "" make ;
|
||||
|
||||
|
||||
! doesn't compile
|
||||
! : >nvector ( elems n -- )
|
||||
! { } clone swap [ drop swap add ] each reverse ;
|
||||
|
||||
: 4vector ( elems -- )
|
||||
V{ } clone 4 [ drop swap add ] each reverse ;
|
||||
|
||||
! TODO: make this work for types other than ""
|
||||
: papply ( seq seq -- seq )
|
||||
[ [ 2array >list call % ] 2each ] "" make ;
|
||||
|
||||
: writeln ( string -- )
|
||||
write terpri ;
|
||||
|
||||
! NEEDS REFACTORING, GOSH!
|
||||
! Hexdump
|
||||
: (print-offset) ( lineno -- )
|
||||
16 * >hex 8 CHAR: 0 pad-left write "h: " write ;
|
||||
|
||||
: (print-hex-digit) ( digit -- )
|
||||
>hex 2 CHAR: 0 pad-left write ;
|
||||
|
||||
: (print-hex-line) ( lineno string -- )
|
||||
over (print-offset)
|
||||
dup length dup 16 =
|
||||
[ [ 2dup swap nth (print-hex-digit) " " write ] repeat ] ! full line
|
||||
[ ! partial line
|
||||
[ 2dup swap nth (print-hex-digit) " " write ] repeat
|
||||
dup length 16 swap - [ " " write ] repeat
|
||||
] if
|
||||
dup length
|
||||
[ 2dup swap nth dup printable? [ write1 ] [ "." write drop ] if ] repeat
|
||||
terpri drop ;
|
||||
|
||||
: (num-full-lines) ( bytes -- )
|
||||
length 16 / floor ;
|
||||
|
||||
: (get-slice) ( lineno bytes -- <slice> )
|
||||
>r dup 16 * dup 16 + r> <slice> ;
|
||||
|
||||
: (get-last-slice) ( bytes -- <slice> )
|
||||
dup length dup 16 mod - over length rot <slice> ;
|
||||
|
||||
: (print-bytes) ( bytes -- )
|
||||
dup (num-full-lines) [ over (get-slice) (print-hex-line) ] repeat
|
||||
dup (num-full-lines) over (get-last-slice) dup empty? [ 3drop ] [ (print-hex-line) 2drop ] if ;
|
||||
|
||||
: (print-length) ( len -- )
|
||||
[
|
||||
"Length: " %
|
||||
dup unparse %
|
||||
", " %
|
||||
>hex %
|
||||
"h\n" %
|
||||
] "" make write ;
|
||||
|
||||
: hexdump ( str -- )
|
||||
dup length (print-length) (print-bytes) ;
|
||||
|
||||
|
||||
|
||||
: save-current-scope
|
||||
unscoped-stack get [ V{ } clone unscoped-stack set ] unless
|
||||
swap dup unscoped-stream set unscoped-stack get push ;
|
||||
|
||||
: set-previous-scope
|
||||
unscoped-stack get dup length 1 > [
|
||||
[ pop ] keep nip peek unscoped-stream set ] [
|
||||
pop drop
|
||||
] if ;
|
||||
|
||||
: with-unscoped-stream ( stream quot -- )
|
||||
save-current-scope catch set-previous-scope
|
||||
[ dup [ unscoped-stream get stream-close ] when rethrow ] when ;
|
||||
|
||||
: close-unscoped-stream ( -- )
|
||||
unscoped-stream get stream-close ;
|
||||
|
||||
: >endian ( obj n -- str )
|
||||
big-endian get [ >be ] [ >le ] if ;
|
||||
|
||||
: endian> ( obj n -- str )
|
||||
big-endian get [ be> ] [ le> ] if ;
|
||||
|
||||
: (>byte) ( byte -- str )
|
||||
unit >string ;
|
||||
|
||||
: (>short) ( short -- str )
|
||||
2 >endian ;
|
||||
|
||||
: (>int) ( int -- str )
|
||||
4 >endian ;
|
||||
|
||||
: (>longlong) ( longlong -- str )
|
||||
8 >endian ;
|
||||
|
||||
: (>u128) ( u128 -- str )
|
||||
16 >endian ;
|
||||
|
||||
: (>cstring) ( str -- str )
|
||||
"\0" append ;
|
||||
|
||||
: >byte ( byte -- )
|
||||
(>byte) % ;
|
||||
|
||||
: >short ( short -- )
|
||||
(>short) % ;
|
||||
|
||||
: >int ( int -- )
|
||||
(>int) % ;
|
||||
|
||||
: >longlong ( longlong -- )
|
||||
(>longlong) % ;
|
||||
|
||||
: >u128 ( u128 -- )
|
||||
(>u128) % ;
|
||||
|
||||
: >cstring ( str -- )
|
||||
(>cstring) % ;
|
||||
|
||||
|
||||
! doesn't compile
|
||||
! : make-packet ( quot -- )
|
||||
! depth >r call depth r> - [ drop append ] each ;
|
||||
: make-packet
|
||||
"" make ;
|
||||
|
||||
: (head-short) ( str -- short )
|
||||
2 swap head endian> ;
|
||||
: (head-int) ( str -- int )
|
||||
4 swap head endian> ;
|
||||
: (head-longlong) ( str -- longlong )
|
||||
8 swap head endian> ;
|
||||
: (head-u128) ( str -- u128 )
|
||||
16 swap head endian> ;
|
||||
|
||||
! 8 bits
|
||||
: head-byte ( -- byte )
|
||||
1 unscoped-stream get stream-read first ;
|
||||
|
||||
! 16 bits
|
||||
: head-short ( -- short )
|
||||
2 unscoped-stream get stream-read (head-short) ;
|
||||
|
||||
! 32 bits
|
||||
: head-int ( -- int )
|
||||
4 unscoped-stream get stream-read (head-int) ;
|
||||
|
||||
! 64 bits
|
||||
: head-longlong ( -- longlong )
|
||||
8 unscoped-stream get stream-read (head-longlong) ;
|
||||
|
||||
! 128 bits
|
||||
: head-u128 ( -- u128 )
|
||||
16 unscoped-stream get stream-read (head-u128) ;
|
||||
|
||||
: head-string ( n -- str )
|
||||
unscoped-stream get stream-read >string ;
|
||||
|
||||
! : head-cstring ( -- str )
|
||||
! head-byte ]
|
||||
|
||||
: head-contents ( -- str )
|
||||
unscoped-stream get contents ;
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
USING: kernel modules words ;
|
||||
|
||||
REQUIRES: automata boids cairo calendar concurrency coroutines
|
||||
crypto dlists embedded gap-buffer hexdump httpd math postgresql process
|
||||
random-tester slate splay-trees sqlite topology units vars ;
|
||||
|
||||
"x11" vocab [
|
||||
"factory" require
|
||||
"x11" require
|
||||
] when
|
|
@ -0,0 +1,188 @@
|
|||
! Copyright (C) 2006 Eduardo Cavazos.
|
||||
|
||||
! To run:
|
||||
! USE: automata
|
||||
! automata-window
|
||||
|
||||
REQUIRES: math slate vars ;
|
||||
|
||||
USING: parser kernel hashtables namespaces sequences math io
|
||||
math-contrib threads strings arrays prettyprint
|
||||
gadgets gadgets-editors gadgets-frames gadgets-buttons gadgets-grids
|
||||
vars slate ;
|
||||
|
||||
IN: automata
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
! set-rule
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: char>digit ( c -- i ) 48 - ;
|
||||
|
||||
: string>digits ( s -- seq ) >array [ char>digit ] map ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
SYMBOL: rule SYMBOL: rule-number
|
||||
|
||||
: init-rule ( -- ) 8 <hashtable> rule set ;
|
||||
|
||||
: rule-keys ( -- { ... } )
|
||||
{ { 1 1 1 }
|
||||
{ 1 1 0 }
|
||||
{ 1 0 1 }
|
||||
{ 1 0 0 }
|
||||
{ 0 1 1 }
|
||||
{ 0 1 0 }
|
||||
{ 0 0 1 }
|
||||
{ 0 0 0 } } ;
|
||||
|
||||
: rule-values ( n -- seq ) >bin 8 CHAR: 0 pad-left string>digits ;
|
||||
|
||||
: set-rule ( n -- )
|
||||
dup rule-number set
|
||||
rule-values rule-keys [ rule get set-hash ] 2each ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
! step-capped-line
|
||||
! step-wrapped-line
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: 3nth ( n seq -- slice ) >r dup 3 + r> <slice> ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: map3-i ( seq -- i ) length 2 - ;
|
||||
|
||||
: map3-quot ( quot -- quot ) [ swap 3nth ] swap append ;
|
||||
|
||||
: map3 ( seq quot -- seq ) over map3-i swap map3-quot map-with ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: last ( seq -- elt ) dup length 1- swap nth ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: pattern>state ( { a b c } -- state ) rule get hash ;
|
||||
|
||||
: cap-line ( line -- 0-line-0 ) { 0 } swap append { 0 } append ;
|
||||
|
||||
: wrap-line ( a-line-z -- za-line-za )
|
||||
dup last 1array swap dup first 1array append append ;
|
||||
|
||||
: step-line ( line -- new-line ) [ >array pattern>state ] map3 ;
|
||||
|
||||
: step-capped-line ( line -- new-line ) cap-line step-line ;
|
||||
|
||||
: step-wrapped-line ( line -- new-line ) wrap-line step-line ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
! Display the rule
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: random-line ( -- line ) window-width [ drop 2 random-int ] map ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: center-i ( -- i ) window-width dup 2 / >fixnum ;
|
||||
|
||||
: center-line ( -- line ) center-i window-width [ = [ 1 ] [ 0 ] if ] map-with ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
! show-line
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: show-point ( { x y } p -- ) 1 = [ draw-point ] [ drop ] if ;
|
||||
|
||||
: (show-line) ( { x y } line -- ) [ dupd show-point { 1 0 } v+ ] each drop ;
|
||||
|
||||
: show-line ( y line -- ) 0 rot 2array swap (show-line) yield ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
! run-rule
|
||||
! start-random
|
||||
! start-center
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
VAR: last-line
|
||||
|
||||
: estimate-capacity ( -- ) window-width window-height * 2 * capacity set ;
|
||||
|
||||
: check-capacity ( -- )
|
||||
"capacity: " write capacity get number>string write terpri
|
||||
"dlist length: " write dlist get length number>string write terpri ;
|
||||
|
||||
: start-slate ( -- )
|
||||
estimate-capacity reset-slate
|
||||
white set-clear-color black set-color clear-window ;
|
||||
|
||||
: finish-slate ( -- ) check-capacity flush-dlist flush-slate ;
|
||||
|
||||
: run-line ( line y -- line ) swap tuck show-line step-capped-line ;
|
||||
|
||||
: run-lines ( -- ) last-line> window-height [ run-line ] each >last-line ;
|
||||
|
||||
: run-rule ( -- ) start-slate run-lines finish-slate ;
|
||||
|
||||
: start-random ( -- ) random-line >last-line run-rule ;
|
||||
|
||||
: start-center ( -- ) center-line >last-line run-rule ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: random-item ( seq -- item ) dup length random-int swap nth ;
|
||||
|
||||
: interesting ( -- seq )
|
||||
{ 18 22 26 30 41 45 54 60 73 75 82 86 89 90 97 101 102 105 106 107 109
|
||||
110 120 121 122 124 126 129 137 146 147 149 150 151 153 154 161 165 } ;
|
||||
|
||||
|
||||
: mild ( -- seq )
|
||||
{ 6 9 11 57 62 74 118 } ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
! : automata ( -- )
|
||||
! <slate> dup self set "Cellular Automata" open-titled-window
|
||||
! init-rule interesting random-item set-rule 1000 sleep start-random ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
! automata-window
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: bind-button ( ns button -- )
|
||||
tuck button-quot \ bind 3array >quotation swap set-button-quot ;
|
||||
|
||||
VARS: ns editor frame ;
|
||||
|
||||
: init-slate ( -- ) <slate> t over set-gadget-clipped? self set ;
|
||||
|
||||
: init-editor ( -- ) "" <editor> >editor ;
|
||||
|
||||
: set-editor-rule ( n -- ) number>string editor> set-editor-text ;
|
||||
|
||||
: open-rule ( -- ) editor> editor-text string>number set-rule start-center ;
|
||||
|
||||
: automata-window ( -- )
|
||||
<frame> >frame
|
||||
[ ] make-hash >ns
|
||||
ns> [ init-rule init-slate init-editor ] bind
|
||||
ns> [ editor> ] bind 1array
|
||||
ns>
|
||||
{ { "Open" [ open-rule ] }
|
||||
{ "Center" [ start-center ] }
|
||||
{ "Random" [ start-random ] }
|
||||
{ "Continue" [ run-rule ] } }
|
||||
[ first2 <bevel-button> tuck bind-button ]
|
||||
map-with append make-pile 1 over set-pack-fill
|
||||
frame> @left grid-add
|
||||
ns> [ self get ] bind
|
||||
frame> @center grid-add
|
||||
frame> "Cellular Automata" open-titled-window
|
||||
1000 sleep
|
||||
ns> [ interesting random-item set-editor-rule open-rule ] bind ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
PROVIDE: automata ;
|
|
@ -0,0 +1,423 @@
|
|||
! Eduardo Cavazos - wayo.cavazos@gmail.com
|
||||
|
||||
! To run the demo do:
|
||||
! USE: boids
|
||||
! boids-window
|
||||
!
|
||||
! There are currently a few bugs. To work around them and to get better
|
||||
! results, increase the size of the window (larger than 400x400 is
|
||||
! good). Then press the "Reset" button to start the demo over.
|
||||
|
||||
REQUIRES: math slate vars ;
|
||||
|
||||
USING: generic threads namespaces math kernel sequences arrays gadgets
|
||||
math-contrib slate vars ;
|
||||
|
||||
IN: boids
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
SYMBOL: separation-radius
|
||||
SYMBOL: alignment-radius
|
||||
SYMBOL: cohesion-radius
|
||||
|
||||
SYMBOL: separation-view-angle
|
||||
SYMBOL: alignment-view-angle
|
||||
SYMBOL: cohesion-view-angle
|
||||
|
||||
SYMBOL: separation-weight
|
||||
SYMBOL: alignment-weight
|
||||
SYMBOL: cohesion-weight
|
||||
|
||||
: init-variables ( -- )
|
||||
25 separation-radius set
|
||||
50 alignment-radius set
|
||||
75 cohesion-radius set
|
||||
|
||||
180 separation-view-angle set
|
||||
180 alignment-view-angle set
|
||||
180 cohesion-view-angle set
|
||||
|
||||
1.0 separation-weight set
|
||||
1.0 alignment-weight set
|
||||
1.0 cohesion-weight set ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
SYMBOL: world-size
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
TUPLE: boid pos vel ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
VAR: time-slice
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
! random-boid and random-boids
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: random-range ( a b -- n ) 1 + dupd swap - random-int + ;
|
||||
|
||||
: random-pos ( -- pos ) world-size get [ random-int ] map ;
|
||||
|
||||
: random-vel ( -- vel ) 2 >array [ drop -10 10 random-range ] map ;
|
||||
|
||||
: random-boid ( -- boid ) random-pos random-vel <boid> ;
|
||||
|
||||
: random-boids ( n -- boids ) [ drop random-boid ] map ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
SYMBOL: boids
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
! draw-boid
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: boid-point-a ( boid -- a ) boid-pos ;
|
||||
|
||||
: boid-point-b ( boid -- b ) dup boid-pos swap boid-vel normalize 20 v*n v+ ;
|
||||
|
||||
: boid-points ( boid -- point-a point-b ) dup boid-point-a swap boid-point-b ;
|
||||
|
||||
: draw-boid ( boid -- ) boid-points draw-line ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: distance ( boid boid -- n ) boid-pos swap boid-pos v- norm ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: constrain ( n a b -- n ) rot min max ;
|
||||
|
||||
: angle-between ( vec vec -- angle )
|
||||
2dup v. -rot norm swap norm * / -1 1 constrain acos rad>deg ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: relative-position ( self other -- v ) boid-pos swap boid-pos v- ;
|
||||
|
||||
: relative-angle ( self other -- angle )
|
||||
over boid-vel -rot relative-position angle-between ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: vsum ( vector-of-vectors --- vec ) { 0 0 } [ v+ ] reduce ;
|
||||
|
||||
: vaverage ( seq-of-vectors -- seq ) dup vsum swap length v/n ;
|
||||
|
||||
: average-position ( boids -- pos ) [ boid-pos ] map vaverage ;
|
||||
|
||||
: average-velocity ( boids -- vel ) [ boid-vel ] map vaverage ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: subset-with ( obj seq quot -- seq ) [ dupd ] swap append subset ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: within-radius? ( self other radius -- ? ) >r distance r> <= ;
|
||||
|
||||
: within-view-angle? ( self other view-angle -- ? )
|
||||
>r relative-angle r> 2 / <= ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: within-separation-radius? ( self other -- ? )
|
||||
separation-radius get within-radius? ;
|
||||
|
||||
: within-separation-view? ( self other -- ? )
|
||||
separation-view-angle get within-view-angle? ;
|
||||
|
||||
: within-separation-neighborhood? ( self other -- ? )
|
||||
[ eq? not ] 2keep
|
||||
[ within-separation-radius? ] 2keep
|
||||
within-separation-view?
|
||||
and and ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: within-alignment-radius? ( self other -- ? )
|
||||
alignment-radius get within-radius? ;
|
||||
|
||||
: within-alignment-view? ( self other -- ? )
|
||||
alignment-view-angle get within-view-angle? ;
|
||||
|
||||
: within-alignment-neighborhood? ( self other -- ? )
|
||||
[ eq? not ] 2keep
|
||||
[ within-alignment-radius? ] 2keep
|
||||
within-alignment-view?
|
||||
and and ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: within-cohesion-radius? ( self other -- ? )
|
||||
cohesion-radius get within-radius? ;
|
||||
|
||||
: within-cohesion-view? ( self other -- ? )
|
||||
cohesion-view-angle get within-view-angle? ;
|
||||
|
||||
: within-cohesion-neighborhood? ( self other -- ? )
|
||||
[ eq? not ] 2keep
|
||||
[ within-cohesion-radius? ] 2keep
|
||||
within-cohesion-view?
|
||||
and and ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: separation-force ( self -- force )
|
||||
! boids get [ within-separation-neighborhood? ] subset-with
|
||||
boids get [ >r dup r> within-separation-neighborhood? ] subset
|
||||
dup length 0 =
|
||||
[ drop drop { 0 0 } ]
|
||||
[ average-position
|
||||
>r boid-pos r> v-
|
||||
normalize
|
||||
separation-weight get
|
||||
v*n ]
|
||||
if ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: alignment-force ( self -- force )
|
||||
! boids get [ within-alignment-neighborhood? ] subset-with
|
||||
boids get [ >r dup r> within-alignment-neighborhood? ] subset swap drop
|
||||
dup length 0 =
|
||||
[ drop { 0 0 } ]
|
||||
[ average-velocity
|
||||
normalize
|
||||
alignment-weight get
|
||||
v*n ]
|
||||
if ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: cohesion-force ( self -- force )
|
||||
! boids get [ within-cohesion-neighborhood? ] subset-with
|
||||
boids get [ >r dup r> within-cohesion-neighborhood? ] subset
|
||||
dup length 0 =
|
||||
[ drop drop { 0 0 } ]
|
||||
[ average-position
|
||||
swap ! avg-pos self
|
||||
boid-pos v-
|
||||
normalize
|
||||
cohesion-weight get
|
||||
v*n ]
|
||||
if ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
! F = m a
|
||||
!
|
||||
! We let m be equal to 1 so then this is simply: F = a
|
||||
|
||||
: acceleration ( boid -- acceleration )
|
||||
dup dup
|
||||
separation-force rot
|
||||
alignment-force rot
|
||||
cohesion-force v+ v+ ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
! iterate-boid
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: world-width ( -- w ) world-size get first ;
|
||||
|
||||
: world-height ( -- w ) world-size get second ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: below? ( n a b -- ? ) drop < ;
|
||||
|
||||
: above? ( n a b -- ? ) nip > ;
|
||||
|
||||
: wrap ( n a b -- n )
|
||||
{ { [ 3dup below? ]
|
||||
[ 2nip ] }
|
||||
{ [ 3dup above? ]
|
||||
[ drop nip ] }
|
||||
{ [ t ]
|
||||
[ 2drop ] } }
|
||||
cond ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: wrap-x ( x -- x ) 0 world-width 1- wrap ;
|
||||
|
||||
: wrap-y ( y -- y ) 0 world-height 1- wrap ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
! : new-pos ( boid -- pos )
|
||||
! dup >r boid-pos r> boid-vel time-slice get v*n v+ ;
|
||||
|
||||
! : new-vel ( boid -- vel )
|
||||
! dup >r boid-vel r> acceleration time-slice get v*n v+ ;
|
||||
|
||||
! : new-vel ( boid -- vel )
|
||||
! dup boid-vel swap acceleration time-slice get v*n v+ ;
|
||||
|
||||
! : wrap-x ( x -- x )
|
||||
! dup 0 world-size get nth >= [ drop 0 ] when
|
||||
! dup 0 < [ drop 0 world-size get nth 1 - ] when ;
|
||||
|
||||
! : wrap-y ( y -- y )
|
||||
! dup 1 world-size get nth >= [ drop 0 ] when
|
||||
! dup 0 < [ drop 1 world-size get nth 1 - ] when ;
|
||||
|
||||
: new-pos ( boid -- pos ) dup boid-vel time-slice> v*n swap boid-pos v+ ;
|
||||
|
||||
! : new-vel ( boid -- vel ) dup acceleration time-slice> v*n swap boid-vel v+ ;
|
||||
|
||||
: new-vel ( boid -- vel )
|
||||
dup acceleration time-slice> v*n swap boid-vel v+ normalize ;
|
||||
|
||||
: wrap-pos ( pos -- pos ) first2 wrap-y swap wrap-x swap 2array ;
|
||||
|
||||
: iterate-boid ( self -- self ) dup >r new-pos wrap-pos r> new-vel <boid> ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: iterate-boids ( -- ) boids get [ iterate-boid ] map boids set ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
! : draw-boids ( -- ) boids get [ draw-boid ] each flush-dpy ;
|
||||
|
||||
: draw-boids ( -- )
|
||||
reset-slate white set-clear-color black set-color clear-window
|
||||
boids get [ draw-boid ] each flush-dlist flush-slate ;
|
||||
|
||||
! : run-boids ( -- ) iterate-boids clear-window draw-boids 1 sleep run-boids ;
|
||||
|
||||
SYMBOL: stop?
|
||||
|
||||
: run-boids ( -- )
|
||||
self get rect-dim world-size set
|
||||
iterate-boids draw-boids 1 sleep
|
||||
stop? get [ ] [ run-boids ] if ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: boids-go ( -- )
|
||||
init-variables
|
||||
0.1 time-slice set
|
||||
! 1.0 >min-speed
|
||||
! 1.0 >max-speed
|
||||
<slate> dup self set open-window
|
||||
100 capacity set
|
||||
self get rect-dim world-size set
|
||||
50 random-boids boids set
|
||||
1000 sleep
|
||||
f stop? set
|
||||
run-boids ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
! Boids ui
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
USING: gadgets-frames gadgets-labels gadgets-theme gadgets-grids
|
||||
gadgets-editors gadgets-buttons ;
|
||||
|
||||
! USING: kernel arrays gadgets gadgets-labels gadgets-editors vars ;
|
||||
|
||||
TUPLE: field label editor quot ;
|
||||
|
||||
VAR: field
|
||||
|
||||
C: field ( label-text editor-text quot -- <field> )
|
||||
[ field ]
|
||||
[ field> set-field-quot
|
||||
<editor> field> set-field-editor
|
||||
<label> field> set-field-label
|
||||
field> field-label field> field-editor 2array make-shelf
|
||||
field> set-gadget-delegate
|
||||
field> ]
|
||||
let ;
|
||||
|
||||
M: field gadget-gestures
|
||||
drop H{ { T{ key-down f f "RETURN" } [ dup field-quot call ] } } ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: [bind] ( ns quot -- quot ) \ bind 3array >quotation ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
VARS: ns frame ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: number-symbol-field ( label init symbol -- <field> )
|
||||
1array >quotation [ set ] append
|
||||
[ field-editor editor-text string>number ]
|
||||
swap append
|
||||
ns> swap [bind]
|
||||
<field> ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: init-slate ( -- ) <slate> t over set-gadget-clipped? self set ;
|
||||
|
||||
: boids-window ( -- )
|
||||
<frame> >frame
|
||||
[ ] make-hash >ns
|
||||
|
||||
ns> [ init-slate
|
||||
init-variables
|
||||
10 time-slice set
|
||||
100 capacity set
|
||||
{ 100 100 } world-size set
|
||||
50 random-boids boids set
|
||||
f stop? set
|
||||
] bind
|
||||
|
||||
"Weight" <label> dup title-theme 1array
|
||||
"Alignment: " "1" alignment-weight number-symbol-field
|
||||
"Cohesion: " "1" cohesion-weight number-symbol-field
|
||||
"Separation: " "1" separation-weight number-symbol-field
|
||||
3array append
|
||||
|
||||
"Radius" <label> dup title-theme 1array
|
||||
"Alignment: " "50" alignment-radius number-symbol-field
|
||||
"Cohesion: " "75" cohesion-radius number-symbol-field
|
||||
"Separation: " "25" separation-radius number-symbol-field
|
||||
3array append
|
||||
|
||||
"View angle" <label> dup title-theme 1array
|
||||
"Alignment: " "180" alignment-view-angle number-symbol-field
|
||||
"Cohesion: " "180" cohesion-view-angle number-symbol-field
|
||||
"Separation: " "180" separation-view-angle number-symbol-field
|
||||
3array append
|
||||
|
||||
"" <label> dup title-theme 1array
|
||||
|
||||
"Time slice: " "10" time-slice number-symbol-field 1array
|
||||
|
||||
"Stop" ns> [ t stop? set ] [bind] <bevel-button>
|
||||
"Start" ns> [ f stop? set [ run-boids ] in-thread ] [bind] <bevel-button>
|
||||
"Reset" ns> [ 50 random-boids boids set ] [bind] <bevel-button>
|
||||
3array
|
||||
|
||||
append append append append append
|
||||
make-pile 1 over set-pack-fill frame> @left grid-add
|
||||
|
||||
ns> [ self get ] bind frame> @center grid-add
|
||||
frame> "Boids" open-titled-window
|
||||
ns> [ 1000 sleep [ run-boids ] in-thread ] bind
|
||||
;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
! Comments from others:
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
! slava foo get blah foo set ==> foo [ blah ] change
|
||||
! slava dup >r blah r> ==> [ blah ] keep
|
||||
|
||||
! : execute-with ( item [ word word ... ] -- results ... )
|
||||
! [ over >r execute r> ] each drop ;
|
||||
|
||||
PROVIDE: boids ;
|
||||
|
|
@ -1,25 +1,12 @@
|
|||
! Cairo stuff
|
||||
!
|
||||
! To run this code, bootstrap Factor like so:
|
||||
!
|
||||
! ./f boot.image.le32
|
||||
! -libraries:sdl:name=libSDL.so
|
||||
! -libraries:sdl-gfx:name=libSDL_gfx
|
||||
! -libraries:cairo:name=libcairo
|
||||
!
|
||||
! (But all on one line)
|
||||
!
|
||||
|
||||
! Cairo binding
|
||||
IN: cairo
|
||||
USING: hashtables ;
|
||||
USE: hashtables
|
||||
USE: compiler
|
||||
USE: alien
|
||||
USE: errors
|
||||
USE: kernel
|
||||
USE: lists
|
||||
USE: math
|
||||
USE: namespaces
|
||||
USE: sdl
|
||||
USE: vectors
|
||||
USE: prettyprint
|
||||
USE: io
|
||||
|
@ -190,174 +177,174 @@ C-ENUM:
|
|||
;
|
||||
|
||||
: cairo_create ( cairo_surface_t -- cairo_t )
|
||||
"cairo_t*" "cairo" "cairo_create" [ "void*" ] alien-invoke ; compiled
|
||||
"cairo_t*" "cairo" "cairo_create" [ "void*" ] alien-invoke ;
|
||||
|
||||
: cairo_destroy ( cairo_t -- )
|
||||
"void" "cairo" "cairo_destroy" [ "cairo_t*" ] ; compiled
|
||||
"void" "cairo" "cairo_destroy" [ "cairo_t*" ] ;
|
||||
|
||||
: cairo_set_operator ( cairo_t cairo_operator_t -- )
|
||||
"void" "cairo" "cairo_set_operator" [ "cairo_t*" "int" ] ; compiled
|
||||
"void" "cairo" "cairo_set_operator" [ "cairo_t*" "int" ] ;
|
||||
|
||||
: cairo_image_surface_create_for_data ( data format width height stride -- cairo_surface_t)
|
||||
"void*" "cairo" "cairo_image_surface_create_for_data" [ "void*" "uint" "int" "int" "int" ] alien-invoke ; compiled
|
||||
"void*" "cairo" "cairo_image_surface_create_for_data" [ "void*" "uint" "int" "int" "int" ] alien-invoke ;
|
||||
|
||||
: cairo_set_source_rgb ( cairo_t red green blue -- )
|
||||
"void" "cairo" "cairo_set_source_rgb" [ "cairo_t*" "double" "double" "double" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_set_source_rgb" [ "cairo_t*" "double" "double" "double" ] alien-invoke ;
|
||||
|
||||
: cairo_set_source_rgba ( cairo_t red green blue alpha -- )
|
||||
"void" "cairo" "cairo_set_source_rgb" [ "cairo_t*" "double" "double" "double" "double" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_set_source_rgb" [ "cairo_t*" "double" "double" "double" "double" ] alien-invoke ;
|
||||
|
||||
: cairo_set_source_surface ( cairo_t cairo_surface_t x y -- )
|
||||
"void" "cairo" "cairo_set_source_surface" [ "cairo_t*" "void*" "double" "double" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_set_source_surface" [ "cairo_t*" "void*" "double" "double" ] alien-invoke ;
|
||||
|
||||
: cairo_set_tolerance ( cairo_t tolerance -- )
|
||||
"void" "cairo" "cairo_set_tolerance" [ "cairo_t*" "double" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_set_tolerance" [ "cairo_t*" "double" ] alien-invoke ;
|
||||
|
||||
: cairo_set_antialias ( cairo_t cairo_antialias_t -- )
|
||||
"void" "cairo" "cairo_set_antialias" [ "cairo_t*" "int" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_set_antialias" [ "cairo_t*" "int" ] alien-invoke ;
|
||||
|
||||
: cairo_set_fill_rule ( cairo_t cairo_fill_rule_t -- )
|
||||
"void" "cairo" "cairo_set_fill_rule" [ "cairo_t*" "int" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_set_fill_rule" [ "cairo_t*" "int" ] alien-invoke ;
|
||||
|
||||
: cairo_set_line_width ( cairo_t width -- )
|
||||
"void" "cairo" "cairo_set_line_width" [ "cairo_t*" "double" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_set_line_width" [ "cairo_t*" "double" ] alien-invoke ;
|
||||
|
||||
: cairo_set_line_cap ( cairo_t cairo_line_cap_t -- )
|
||||
"void" "cairo" "cairo_set_line_cap" [ "cairo_t*" "int" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_set_line_cap" [ "cairo_t*" "int" ] alien-invoke ;
|
||||
|
||||
: cairo_set_line_join ( cairo_t cairo_line_join_t -- )
|
||||
"void" "cairo" "cairo_set_line_join" [ "cairo_t*" "int" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_set_line_join" [ "cairo_t*" "int" ] alien-invoke ;
|
||||
|
||||
: cairo_set_dash ( cairo_t dashes num_dashes offset -- )
|
||||
"void" "cairo" "cairo_set_dash" [ "cairo_t*" "double" "int" "double" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_set_dash" [ "cairo_t*" "double" "int" "double" ] alien-invoke ;
|
||||
|
||||
: cairo_set_miter_limit ( cairo_t limit -- )
|
||||
"void" "cairo" "cairo_set_miter_limit" [ "cairo_t*" "double" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_set_miter_limit" [ "cairo_t*" "double" ] alien-invoke ;
|
||||
|
||||
: cairo_translate ( cairo_t x y -- )
|
||||
"void" "cairo" "cairo_translate" [ "cairo_t*" "double" "double" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_translate" [ "cairo_t*" "double" "double" ] alien-invoke ;
|
||||
|
||||
: cairo_scale ( cairo_t sx sy -- )
|
||||
"void" "cairo" "cairo_scale" [ "cairo_t*" "double" "double" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_scale" [ "cairo_t*" "double" "double" ] alien-invoke ;
|
||||
|
||||
: cairo_rotate ( cairo_t angle -- )
|
||||
"void" "cairo" "cairo_rotate" [ "cairo_t*" "double" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_rotate" [ "cairo_t*" "double" ] alien-invoke ;
|
||||
|
||||
|
||||
! cairo path creating functions
|
||||
|
||||
: cairo_new_path ( cairo_t -- )
|
||||
"void" "cairo" "cairo_new_path" [ "cairo_t*" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_new_path" [ "cairo_t*" ] alien-invoke ;
|
||||
|
||||
: cairo_move_to ( cairo_t x y -- )
|
||||
"void" "cairo" "cairo_move_to" [ "cairo_t*" "double" "double" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_move_to" [ "cairo_t*" "double" "double" ] alien-invoke ;
|
||||
|
||||
: cairo_line_to ( cairo_t x y -- )
|
||||
"void" "cairo" "cairo_line_to" [ "cairo_t*" "double" "double" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_line_to" [ "cairo_t*" "double" "double" ] alien-invoke ;
|
||||
|
||||
: cairo_curve_to ( cairo_t x1 y1 x2 y2 x3 y3 -- )
|
||||
"void" "cairo" "cairo_curve_to" [ "cairo_t*" "double" "double" "double" "double" "double" "double" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_curve_to" [ "cairo_t*" "double" "double" "double" "double" "double" "double" ] alien-invoke ;
|
||||
|
||||
: cairo_arc ( cairo_t xc yc radius angle1 angle2 -- )
|
||||
"void" "cairo" "cairo_arc" [ "cairo_t*" "double" "double" "double" "double" "double" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_arc" [ "cairo_t*" "double" "double" "double" "double" "double" ] alien-invoke ;
|
||||
|
||||
: cairo_arc_negative ( cairo_t xc yc radius angle1 angle2 -- )
|
||||
"void" "cairo" "cairo_arc_negative" [ "cairo_t*" "double" "double" "double" "double" "double" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_arc_negative" [ "cairo_t*" "double" "double" "double" "double" "double" ] alien-invoke ;
|
||||
|
||||
: cairo_rel_move_to ( cairo_t dx dy -- )
|
||||
"void" "cairo" "cairo_rel_move_to" [ "cairo_t*" "double" "double" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_rel_move_to" [ "cairo_t*" "double" "double" ] alien-invoke ;
|
||||
|
||||
: cairo_rel_line_to ( cairo_t dx dy -- )
|
||||
"void" "cairo" "cairo_rel_line_to" [ "cairo_t*" "double" "double" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_rel_line_to" [ "cairo_t*" "double" "double" ] alien-invoke ;
|
||||
|
||||
: cairo_rel_curve_to ( cairo_t dx1 dy1 dx2 dy2 dx3 dy3 -- )
|
||||
"void" "cairo" "cairo_rel_curve_to" [ "cairo_t*" "double" "double" "double" "double" "double" "double" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_rel_curve_to" [ "cairo_t*" "double" "double" "double" "double" "double" "double" ] alien-invoke ;
|
||||
|
||||
: cairo_rectangle ( cairo_t x y width height -- )
|
||||
"void" "cairo" "cairo_rectangle" [ "cairo_t*" "double" "double" "double" "double" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_rectangle" [ "cairo_t*" "double" "double" "double" "double" ] alien-invoke ;
|
||||
|
||||
: cairo_close_path ( cairo_t -- )
|
||||
"void" "cairo" "cairo_close_path" [ "cairo_t*" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_close_path" [ "cairo_t*" ] alien-invoke ;
|
||||
|
||||
! painting functions
|
||||
: cairo_paint ( cairo_t -- )
|
||||
"void" "cairo" "cairo_paint" [ "cairo_t*" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_paint" [ "cairo_t*" ] alien-invoke ;
|
||||
|
||||
: cairo_paint_with_alpha ( cairo_t alpha -- )
|
||||
"void" "cairo" "cairo_paint_with_alpha" [ "cairo_t*" "double" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_paint_with_alpha" [ "cairo_t*" "double" ] alien-invoke ;
|
||||
|
||||
: cairo_mask ( cairo_t cairo_pattern_t -- )
|
||||
"void" "cairo" "cairo_mask" [ "cairo_t*" "void*" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_mask" [ "cairo_t*" "void*" ] alien-invoke ;
|
||||
|
||||
: cairo_mask_surface ( cairo_t cairo_pattern_t surface-x surface-y -- )
|
||||
"void" "cairo" "cairo_mask_surface" [ "cairo_t*" "void*" "double" "double" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_mask_surface" [ "cairo_t*" "void*" "double" "double" ] alien-invoke ;
|
||||
|
||||
: cairo_stroke ( cairo_t -- )
|
||||
"void" "cairo" "cairo_stroke" [ "cairo_t*" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_stroke" [ "cairo_t*" ] alien-invoke ;
|
||||
|
||||
: cairo_stroke_preserve ( cairo_t -- )
|
||||
"void" "cairo" "cairo_stroke_preserve" [ "cairo_t*" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_stroke_preserve" [ "cairo_t*" ] alien-invoke ;
|
||||
|
||||
: cairo_fill ( cairo_t -- )
|
||||
"void" "cairo" "cairo_fill" [ "cairo_t*" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_fill" [ "cairo_t*" ] alien-invoke ;
|
||||
|
||||
: cairo_fill_preserve ( cairo_t -- )
|
||||
"void" "cairo" "cairo_fill_preserve" [ "cairo_t*" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_fill_preserve" [ "cairo_t*" ] alien-invoke ;
|
||||
|
||||
: cairo_copy_page ( cairo_t -- )
|
||||
"void" "cairo" "cairo_copy_page" [ "cairo_t*" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_copy_page" [ "cairo_t*" ] alien-invoke ;
|
||||
|
||||
: cairo_show_page ( cairo_t -- )
|
||||
"void" "cairo" "cairo_show_page" [ "cairo_t*" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_show_page" [ "cairo_t*" ] alien-invoke ;
|
||||
|
||||
! insideness testing
|
||||
: cairo_in_stroke ( cairo_t x y -- t/f )
|
||||
"int" "cairo" "cairo_in_stroke" [ "cairo_t*" "double" "double" ] alien-invoke ; compiled
|
||||
"int" "cairo" "cairo_in_stroke" [ "cairo_t*" "double" "double" ] alien-invoke ;
|
||||
|
||||
: cairo_in_fill ( cairo_t x y -- t/f )
|
||||
"int" "cairo" "cairo_in_fill" [ "cairo_t*" "double" "double" ] alien-invoke ; compiled
|
||||
"int" "cairo" "cairo_in_fill" [ "cairo_t*" "double" "double" ] alien-invoke ;
|
||||
|
||||
! rectangular extents
|
||||
: cairo_stroke_extents ( cairo_t x1 y1 x2 y2 -- )
|
||||
"void" "cairo" "cairo_stroke_extents" [ "cairo_t*" "double" "double" "double" "double" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_stroke_extents" [ "cairo_t*" "double" "double" "double" "double" ] alien-invoke ;
|
||||
|
||||
: cairo_fill_extents ( cairo_t x1 y1 x2 y2 -- )
|
||||
"void" "cairo" "cairo_fill_extents" [ "cairo_t*" "double" "double" "double" "double" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_fill_extents" [ "cairo_t*" "double" "double" "double" "double" ] alien-invoke ;
|
||||
|
||||
! clipping
|
||||
: cairo_reset_clip ( cairo_t -- )
|
||||
"void" "cairo" "cairo_reset_clip" [ "cairo_t*" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_reset_clip" [ "cairo_t*" ] alien-invoke ;
|
||||
|
||||
: cairo_clip ( cairo_t -- )
|
||||
"void" "cairo" "cairo_clip" [ "cairo_t*" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_clip" [ "cairo_t*" ] alien-invoke ;
|
||||
|
||||
: cairo_clip_preserve ( cairo_t -- )
|
||||
"void" "cairo" "cairo_clip_preserve" [ "cairo_t*" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_clip_preserve" [ "cairo_t*" ] alien-invoke ;
|
||||
|
||||
: cairo_set_source ( cairo_t cairo_pattern_t -- )
|
||||
"void" "cairo" "cairo_set_source" [ "cairo_t*" "void*" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_set_source" [ "cairo_t*" "void*" ] alien-invoke ;
|
||||
|
||||
: cairo_pattern_create_linear ( x0 y0 x1 y1 -- cairo_pattern_t )
|
||||
"void*" "cairo" "cairo_pattern_create_linear" [ "double" "double" "double" "double" ] alien-invoke ; compiled
|
||||
"void*" "cairo" "cairo_pattern_create_linear" [ "double" "double" "double" "double" ] alien-invoke ;
|
||||
|
||||
: cairo_pattern_create_radial ( cx0 cy0 radius0 cx1 cy1 radius1 -- cairo_pattern_t )
|
||||
"void*" "cairo" "cairo_pattern_create_radial" [ "double" "double" "double" "double" "double" "double" ] alien-invoke ; compiled
|
||||
"void*" "cairo" "cairo_pattern_create_radial" [ "double" "double" "double" "double" "double" "double" ] alien-invoke ;
|
||||
|
||||
: cairo_pattern_add_color_stop_rgba ( pattern offset red green blue alpha -- status )
|
||||
"uint" "cairo" "cairo_pattern_add_color_stop_rgba" [ "void*" "double" "double" "double" "double" "double" ] alien-invoke ; compiled
|
||||
"uint" "cairo" "cairo_pattern_add_color_stop_rgba" [ "void*" "double" "double" "double" "double" "double" ] alien-invoke ;
|
||||
|
||||
: cairo_show_text ( cairo_t msg_utf8 -- )
|
||||
"void" "cairo" "cairo_show_text" [ "cairo_t*" "char*" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_show_text" [ "cairo_t*" "char*" ] alien-invoke ;
|
||||
|
||||
: cairo_text_path ( cairo_t msg_utf8 -- )
|
||||
"void" "cairo" "cairo_text_path" [ "cairo_t*" "char*" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_text_path" [ "cairo_t*" "char*" ] alien-invoke ;
|
||||
|
||||
: cairo_select_font_face ( cairo_t family font_slant font_weight -- )
|
||||
"void" "cairo" "cairo_select_font_face" [ "cairo_t*" "char*" "uint" "uint" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_select_font_face" [ "cairo_t*" "char*" "uint" "uint" ] alien-invoke ;
|
||||
|
||||
: cairo_set_font_size ( cairo_t scale -- )
|
||||
"void" "cairo" "cairo_set_font_size" [ "cairo_t*" "double" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_set_font_size" [ "cairo_t*" "double" ] alien-invoke ;
|
||||
|
||||
: cairo_identity_matrix ( cairo_t -- )
|
||||
"void" "cairo" "cairo_identity_matrix" [ "cairo_t*" ] alien-invoke ; compiled
|
||||
"void" "cairo" "cairo_identity_matrix" [ "cairo_t*" ] alien-invoke ;
|
||||
|
||||
|
|
|
@ -1,13 +1,3 @@
|
|||
IN: scratchpad
|
||||
USING: alien kernel parser compiler words sequences ;
|
||||
USING: alien ;
|
||||
|
||||
{
|
||||
{ "cairo" "libcairo" }
|
||||
{ "sdl-gfx" "libSDL_gfx" }
|
||||
{ "sdl" "libSDL" }
|
||||
} [ first2 add-simple-library ] each
|
||||
|
||||
{
|
||||
"cairo"
|
||||
"cairo_sdl"
|
||||
} [ "/contrib/cairo/" swap ".factor" append3 run-resource ] each
|
||||
PROVIDE: cairo { "cairo.factor" } ;
|
||||
|
|
|
@ -0,0 +1,276 @@
|
|||
USING: arrays errors generic hashtables io kernel math
|
||||
namespaces sequences strings prettyprint inspector ;
|
||||
IN: calendar
|
||||
|
||||
TUPLE: timestamp year month day hour minute second gmt-offset ;
|
||||
TUPLE: dt year month day hour minute second ;
|
||||
|
||||
SYMBOL: gmt-offset
|
||||
7 gmt-offset set-global
|
||||
|
||||
: month-names
|
||||
{
|
||||
"Not a month" "January" "February" "March" "April" "May" "June"
|
||||
"July" "August" "September" "October" "November" "December"
|
||||
} ;
|
||||
|
||||
: months-abbreviations
|
||||
{
|
||||
"Not a month"
|
||||
"Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"
|
||||
} ;
|
||||
|
||||
: day-names
|
||||
{
|
||||
"Sunday" "Monday" "Tuesday" "Wednesday" "Thursday" "Friday" "Saturday"
|
||||
} ;
|
||||
|
||||
: day-abbreviations2 { "Su" "Mo" "Tu" "We" "Th" "Fr" "Sa" } ;
|
||||
: day-abbreviations3 { "Sun" "Mon" "Tue" "Wed" "Thu" "Fri" "Sat" } ;
|
||||
|
||||
: average-month ( -- x )
|
||||
#! length of average month in days
|
||||
30.41666666666667 ;
|
||||
|
||||
: time>array ( dt -- vec ) tuple>array 2 swap tail ;
|
||||
|
||||
: compare-timestamps ( tuple tuple -- n )
|
||||
[ time>array ] 2apply <=> ;
|
||||
|
||||
SYMBOL: a
|
||||
SYMBOL: b
|
||||
SYMBOL: c
|
||||
SYMBOL: d
|
||||
SYMBOL: e
|
||||
SYMBOL: y
|
||||
SYMBOL: m
|
||||
|
||||
: julian-day-number ( year month day -- n )
|
||||
#! Returns a composite date number
|
||||
#! Not valid before year -4800
|
||||
[
|
||||
14 pick - 12 /i a set
|
||||
pick 4800 + a get - y set
|
||||
over 12 a get * + 3 - m set
|
||||
2nip 153 m get * 2 + 5 /i + 365 y get * +
|
||||
y get 4 /i + y get 100 /i - y get 400 /i + 32045 -
|
||||
] with-scope ;
|
||||
|
||||
: julian-day-number>date ( n -- year month day )
|
||||
#! Inverse of julian-day-number
|
||||
[
|
||||
32044 + a set
|
||||
4 a get * 3 + 146097 /i b set
|
||||
a get 146097 b get * 4 /i - c set
|
||||
4 c get * 3 + 1461 /i d set
|
||||
c get 1461 d get * 4 /i - e set
|
||||
5 e get * 2 + 153 /i m set
|
||||
100 b get * d get + 4800 -
|
||||
m get 10 /i + m get 3 +
|
||||
12 m get 10 /i * -
|
||||
e get 153 m get * 2 + 5 /i - 1+
|
||||
] with-scope ;
|
||||
|
||||
: set-date ( year month day timestamp -- )
|
||||
[ set-timestamp-day ] keep
|
||||
[ set-timestamp-month ] keep
|
||||
set-timestamp-year ;
|
||||
|
||||
: set-time ( hour minute second timestamp -- )
|
||||
[ set-timestamp-second ] keep
|
||||
[ set-timestamp-minute ] keep
|
||||
set-timestamp-hour ;
|
||||
|
||||
: date ( timestamp -- year month day )
|
||||
[ timestamp-year ] keep
|
||||
[ timestamp-month ] keep
|
||||
timestamp-day ;
|
||||
|
||||
: time ( timestamp -- hour minute second )
|
||||
[ timestamp-hour ] keep
|
||||
[ timestamp-minute ] keep
|
||||
timestamp-second ;
|
||||
|
||||
: zero-dt ( -- <dt> ) 0 0 0 0 0 0 <dt> ;
|
||||
: years ( n -- dt ) zero-dt [ set-dt-year ] keep ;
|
||||
: months ( n -- dt ) zero-dt [ set-dt-month ] keep ;
|
||||
: weeks ( n -- dt ) 7 * zero-dt [ set-dt-day ] keep ;
|
||||
: days ( n -- dt ) zero-dt [ set-dt-day ] keep ;
|
||||
: hours ( n -- dt ) zero-dt [ set-dt-hour ] keep ;
|
||||
: minutes ( n -- dt ) zero-dt [ set-dt-minute ] keep ;
|
||||
: seconds ( n -- dt ) zero-dt [ set-dt-second ] keep ;
|
||||
|
||||
: julian-day-number>timestamp ( n -- timestamp )
|
||||
julian-day-number>date 0 0 0 0 <timestamp> ;
|
||||
|
||||
GENERIC: +year ( timestamp x -- timestamp )
|
||||
GENERIC: +month ( timestamp x -- timestamp )
|
||||
GENERIC: +day ( timestamp x -- timestamp )
|
||||
GENERIC: +hour ( timestamp x -- timestamp )
|
||||
GENERIC: +minute ( timestamp x -- timestamp )
|
||||
GENERIC: +second ( timestamp x -- timestamp )
|
||||
|
||||
: /rem ( f n -- q r )
|
||||
#! q is positive or negative, r is positive from 0 <= r < n
|
||||
[ /f floor >bignum ] 2keep rem ;
|
||||
|
||||
: float>whole-part ( float -- int float )
|
||||
[ floor >bignum ] keep dupd swap - ;
|
||||
|
||||
: leap-year? ( year -- ? )
|
||||
dup 100 mod zero? 400 4 ? mod zero? ;
|
||||
|
||||
: adjust-leap-year ( timestamp -- timestamp )
|
||||
dup date 29 = swap 2 = and swap leap-year? not and [
|
||||
dup >r timestamp-year 3 1 r> [ set-date ] keep
|
||||
] when ;
|
||||
|
||||
M: integer +year ( timestamp n -- timestamp )
|
||||
over timestamp-year + swap [ set-timestamp-year ] keep
|
||||
adjust-leap-year ;
|
||||
M: real +year ( timestamp n -- timestamp )
|
||||
float>whole-part rot swap 365.2425 * +day swap +year ;
|
||||
|
||||
M: integer +month ( timestamp n -- timestamp )
|
||||
over timestamp-month + 12 /rem
|
||||
dup zero? [ drop 12 >r 1- r> ] when pick set-timestamp-month
|
||||
+year ;
|
||||
M: real +month ( timestamp n -- timestamp )
|
||||
float>whole-part rot swap average-month * +day swap +month ;
|
||||
|
||||
M: integer +day ( timestamp n -- timestamp )
|
||||
swap [
|
||||
date julian-day-number + julian-day-number>timestamp
|
||||
] keep swap >r time r> [ set-time ] keep ;
|
||||
M: real +day ( timestamp n -- timestamp )
|
||||
float>whole-part rot swap 24 * +hour swap +day ;
|
||||
|
||||
M: integer +hour ( timestamp n -- timestamp )
|
||||
over timestamp-hour + 24 /rem pick set-timestamp-hour
|
||||
+day ;
|
||||
M: real +hour ( timestamp n -- timestamp )
|
||||
float>whole-part rot swap 60 * +minute swap +hour ;
|
||||
|
||||
M: integer +minute ( timestamp n -- timestamp )
|
||||
over timestamp-minute + 60 /rem pick
|
||||
set-timestamp-minute +hour ;
|
||||
M: real +minute ( timestamp n -- timestamp )
|
||||
float>whole-part rot swap 60 * +second swap +minute ;
|
||||
|
||||
M: number +second ( timestamp n -- timestamp )
|
||||
over timestamp-second + 60 /rem >r >bignum r>
|
||||
pick set-timestamp-second +minute ;
|
||||
|
||||
: +dt ( timestamp dt -- timestamp )
|
||||
dupd
|
||||
[ dt-second +second ] keep
|
||||
[ dt-minute +minute ] keep
|
||||
[ dt-hour +hour ] keep
|
||||
[ dt-day +day ] keep
|
||||
[ dt-month +month ] keep
|
||||
dt-year +year
|
||||
swap timestamp-gmt-offset over set-timestamp-gmt-offset ;
|
||||
|
||||
: make-timestamp ( year month day hour minute second gmt-offset -- timestamp )
|
||||
<timestamp> [ 0 seconds +dt ] keep
|
||||
[ = [ "invalid timestamp" throw ] unless ] keep ;
|
||||
|
||||
: array>dt ( vec -- dt ) { dt f } swap append >tuple ;
|
||||
: +dts ( dt dt -- dt ) [ time>array ] 2apply v+ array>dt ;
|
||||
|
||||
: dt>years ( dt -- x )
|
||||
#! Uses average month/year length since dt loses calendar
|
||||
#! data
|
||||
time>array
|
||||
{ 1 12 365.2425 8765.82 525949.2 31556952.0 }
|
||||
[ / ] 2map sum ;
|
||||
: dt>months ( dt -- x ) dt>years 12 * ;
|
||||
: dt>days ( dt -- x ) dt>years 365.2425 * ;
|
||||
: dt>hours ( dt -- x ) dt>years 8765.82 * ;
|
||||
: dt>minutes ( dt -- x ) dt>years 525949.2 * ;
|
||||
: dt>seconds ( dt -- x ) dt>years 31556952 * ;
|
||||
|
||||
: convert-timezone ( timestamp n -- timestamp )
|
||||
[ over timestamp-gmt-offset - hours +dt ] keep
|
||||
over set-timestamp-gmt-offset ;
|
||||
|
||||
: >local-time ( timestamp -- timestamp )
|
||||
gmt-offset get convert-timezone ;
|
||||
|
||||
: >gmt ( timestamp -- timestamp )
|
||||
0 convert-timezone ;
|
||||
|
||||
: gmt ( -- timestamp )
|
||||
#! GMT time, right now
|
||||
1970 1 1 0 0 0 0 <timestamp> millis 1000 /f seconds +dt ;
|
||||
|
||||
: timestamp- ( timestamp timestamp -- dt )
|
||||
[ >gmt time>array ] 2apply v- array>dt ;
|
||||
|
||||
: now ( -- timestamp ) gmt >local-time ;
|
||||
: before ( dt -- -dt ) time>array [ neg ] map array>dt ;
|
||||
: from-now ( dt -- timestamp ) now swap +dt ;
|
||||
: ago ( dt -- timestamp ) before from-now ;
|
||||
|
||||
: days-in-year ( year -- n ) leap-year? 366 365 ? ;
|
||||
: day-counts { 0 31 28 31 30 31 30 31 31 30 31 30 31 } ;
|
||||
: days-in-month ( year month -- n )
|
||||
swap leap-year? [
|
||||
[ day-counts nth ] keep 2 = [ 1+ ] when
|
||||
] [
|
||||
day-counts nth
|
||||
] if ;
|
||||
|
||||
: zeller-congruence ( year month day -- n )
|
||||
#! Zeller Congruence
|
||||
#! http://web.textfiles.com/computers/formulas.txt
|
||||
#! good for any date since October 15, 1582
|
||||
>r dup 2 <= [ 12 + >r 1- r> ] when
|
||||
>r dup [ 4 /i + ] keep [ 100 /i - ] keep 400 /i + r>
|
||||
[ 1+ 3 * 5 /i + ] keep 2 * + r>
|
||||
1+ + 7 mod ;
|
||||
|
||||
: day-of-week ( timestamp -- n )
|
||||
[ timestamp-year ] keep
|
||||
[ timestamp-month ] keep
|
||||
timestamp-day
|
||||
zeller-congruence ;
|
||||
|
||||
: day-of-year ( timestamp -- n )
|
||||
[
|
||||
[ timestamp-year leap-year? ] keep
|
||||
[ date 3array ] keep timestamp-year 3 1 3array <=>
|
||||
0 >= and 1 0 ?
|
||||
] keep
|
||||
[ timestamp-month day-counts head-slice sum + ] keep
|
||||
timestamp-day + ;
|
||||
|
||||
: print-day ( n -- )
|
||||
number>string dup length 2 < [ bl ] when write ;
|
||||
|
||||
: print-month ( year month -- )
|
||||
[ month-names nth write bl . ] 2keep
|
||||
[ 1 zeller-congruence ] 2keep
|
||||
days-in-month day-abbreviations2 " " join print
|
||||
over [ " " write ] times
|
||||
[
|
||||
[ 1+ print-day ] keep
|
||||
1+ + 7 mod zero? [ terpri ] [ bl ] if
|
||||
] each-with terpri ;
|
||||
|
||||
: print-year ( year -- )
|
||||
12 [ 1+ print-month terpri ] each-with ;
|
||||
|
||||
: timestamp>http-string ( timestamp -- string )
|
||||
#! http timestamp format
|
||||
#! Example: Tue, 15 Nov 1994 08:12:31 GMT
|
||||
>gmt
|
||||
[
|
||||
dup day-of-week day-abbreviations3 nth write ", " write
|
||||
dup timestamp-day unparse write bl
|
||||
dup timestamp-month months-abbreviations nth write bl
|
||||
dup timestamp-year unparse write bl
|
||||
dup timestamp-hour unparse 2 CHAR: 0 pad-left write ":" write
|
||||
dup timestamp-minute unparse 2 CHAR: 0 pad-left write ":" write
|
||||
dup timestamp-second >fixnum unparse 2 CHAR: 0 pad-left write " GMT" write
|
||||
] string-out ;
|
|
@ -0,0 +1,6 @@
|
|||
PROVIDE: calendar
|
||||
{
|
||||
"calendar.factor"
|
||||
} {
|
||||
"test/calendar.factor"
|
||||
} ;
|
|
@ -0,0 +1,126 @@
|
|||
USING: arrays calendar errors kernel math sequences test ;
|
||||
|
||||
[ "invalid timestamp" ] [ [ 2004 12 32 0 0 0 0 make-timestamp ] catch ] unit-test
|
||||
[ "invalid timestamp" ] [ [ 2004 2 30 0 0 0 0 make-timestamp ] catch ] unit-test
|
||||
[ "invalid timestamp" ] [ [ 2003 2 29 0 0 0 0 make-timestamp ] catch ] unit-test
|
||||
[ "invalid timestamp" ] [ [ 2004 -2 9 0 0 0 0 make-timestamp ] catch ] unit-test
|
||||
[ "invalid timestamp" ] [ [ 2004 12 0 0 0 0 0 make-timestamp ] catch ] unit-test
|
||||
[ "invalid timestamp" ] [ [ 2004 12 1 24 0 0 0 make-timestamp ] catch ] unit-test
|
||||
[ "invalid timestamp" ] [ [ 2004 12 1 23 60 0 0 make-timestamp ] catch ] unit-test
|
||||
[ "invalid timestamp" ] [ [ 2004 12 1 23 59 60 0 0 make-timestamp ] catch ] unit-test
|
||||
|
||||
[ f ] [ 1900 leap-year? ] unit-test
|
||||
[ t ] [ 1904 leap-year? ] unit-test
|
||||
[ t ] [ 2000 leap-year? ] unit-test
|
||||
[ f ] [ 2001 leap-year? ] unit-test
|
||||
[ f ] [ 2006 leap-year? ] unit-test
|
||||
|
||||
[ t ] [ 2006 10 10 0 0 0 0 make-timestamp 1 seconds +dt
|
||||
2006 10 10 0 0 1 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2006 10 10 0 0 0 0 make-timestamp 100 seconds +dt
|
||||
2006 10 10 0 1 40 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2006 10 10 0 0 0 0 make-timestamp -100 seconds +dt
|
||||
2006 10 9 23 58 20 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2006 10 10 0 0 0 0 make-timestamp 86400 seconds +dt
|
||||
2006 10 11 0 0 0 0 make-timestamp = ] unit-test
|
||||
|
||||
[ t ] [ 2006 10 10 0 0 0 0 make-timestamp 10 minutes +dt
|
||||
2006 10 10 0 10 0 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2006 10 10 0 0 0 0 make-timestamp 10.5 minutes +dt
|
||||
2006 10 10 0 10 30 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2006 10 10 0 0 0 0 make-timestamp 3/4 minutes +dt
|
||||
2006 10 10 0 0 45 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2006 10 10 0 0 0 0 make-timestamp -3/4 minutes +dt
|
||||
2006 10 9 23 59 15 0 make-timestamp = ] unit-test
|
||||
|
||||
[ t ] [ 2006 10 10 0 0 0 0 make-timestamp 7200 minutes +dt
|
||||
2006 10 15 0 0 0 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2006 10 10 0 0 0 0 make-timestamp -10 minutes +dt
|
||||
2006 10 9 23 50 0 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2006 10 10 0 0 0 0 make-timestamp -100 minutes +dt
|
||||
2006 10 9 22 20 0 0 make-timestamp = ] unit-test
|
||||
|
||||
[ t ] [ 2006 1 1 0 0 0 0 make-timestamp 1 hours +dt
|
||||
2006 1 1 1 0 0 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2006 1 1 0 0 0 0 make-timestamp 24 hours +dt
|
||||
2006 1 2 0 0 0 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2006 1 1 0 0 0 0 make-timestamp -24 hours +dt
|
||||
2005 12 31 0 0 0 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2006 1 1 0 0 0 0 make-timestamp 12 hours +dt
|
||||
2006 1 1 12 0 0 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2006 1 1 0 0 0 0 make-timestamp 72 hours +dt
|
||||
2006 1 4 0 0 0 0 make-timestamp = ] unit-test
|
||||
|
||||
[ t ] [ 2006 1 1 0 0 0 0 make-timestamp 1 days +dt
|
||||
2006 1 2 0 0 0 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2006 1 1 0 0 0 0 make-timestamp -1 days +dt
|
||||
2005 12 31 0 0 0 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2006 1 1 0 0 0 0 make-timestamp 365 days +dt
|
||||
2007 1 1 0 0 0 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2006 1 1 0 0 0 0 make-timestamp -365 days +dt
|
||||
2005 1 1 0 0 0 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2004 1 1 0 0 0 0 make-timestamp 365 days +dt
|
||||
2004 12 31 0 0 0 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2004 1 1 0 0 0 0 make-timestamp 366 days +dt
|
||||
2005 1 1 0 0 0 0 make-timestamp = ] unit-test
|
||||
|
||||
[ t ] [ 2006 1 1 0 0 0 0 make-timestamp 11 months +dt
|
||||
2006 12 1 0 0 0 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2006 1 1 0 0 0 0 make-timestamp 12 months +dt
|
||||
2007 1 1 0 0 0 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2006 1 1 0 0 0 0 make-timestamp 24 months +dt
|
||||
2008 1 1 0 0 0 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2006 1 1 0 0 0 0 make-timestamp 13 months +dt
|
||||
2007 2 1 0 0 0 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2006 1 1 0 0 0 0 make-timestamp 1 months +dt
|
||||
2006 2 1 0 0 0 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2006 1 1 0 0 0 0 make-timestamp 0 months +dt
|
||||
2006 1 1 0 0 0 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2006 1 1 0 0 0 0 make-timestamp -1 months +dt
|
||||
2005 12 1 0 0 0 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2006 1 1 0 0 0 0 make-timestamp -2 months +dt
|
||||
2005 11 1 0 0 0 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2006 1 1 0 0 0 0 make-timestamp -13 months +dt
|
||||
2004 12 1 0 0 0 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2006 1 1 0 0 0 0 make-timestamp -24 months +dt
|
||||
2004 1 1 0 0 0 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2004 2 29 0 0 0 0 make-timestamp 12 months +dt
|
||||
2005 3 1 0 0 0 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2004 2 29 0 0 0 0 make-timestamp -12 months +dt
|
||||
2003 3 1 0 0 0 0 make-timestamp = ] unit-test
|
||||
|
||||
[ t ] [ 2006 1 1 0 0 0 0 make-timestamp 0 years +dt
|
||||
2006 1 1 0 0 0 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2006 1 1 0 0 0 0 make-timestamp 1 years +dt
|
||||
2007 1 1 0 0 0 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2006 1 1 0 0 0 0 make-timestamp -1 years +dt
|
||||
2005 1 1 0 0 0 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2006 1 1 0 0 0 0 make-timestamp -100 years +dt
|
||||
1906 1 1 0 0 0 0 make-timestamp = ] unit-test
|
||||
! [ t ] [ 2004 2 29 0 0 0 0 make-timestamp -1 years +dt
|
||||
! 2003 2 28 0 0 0 0 make-timestamp = ] unit-test
|
||||
|
||||
[ 5 ] [ 2006 7 14 0 0 0 0 make-timestamp day-of-week ] unit-test
|
||||
|
||||
[ t ] [ 2006 7 14 [ julian-day-number julian-day-number>date 0 0 0 0 make-timestamp ] 3keep 0 0 0 0 make-timestamp = ] unit-test
|
||||
|
||||
[ 1 ] [ 2006 1 1 0 0 0 0 make-timestamp day-of-year ] unit-test
|
||||
[ 60 ] [ 2004 2 29 0 0 0 0 make-timestamp day-of-year ] unit-test
|
||||
[ 61 ] [ 2004 3 1 0 0 0 0 make-timestamp day-of-year ] unit-test
|
||||
[ 366 ] [ 2004 12 31 0 0 0 0 make-timestamp day-of-year ] unit-test
|
||||
[ 365 ] [ 2003 12 31 0 0 0 0 make-timestamp day-of-year ] unit-test
|
||||
[ 60 ] [ 2003 3 1 0 0 0 0 make-timestamp day-of-year ] unit-test
|
||||
|
||||
[ t ] [ 2004 12 31 0 0 0 0 make-timestamp dup = ] unit-test
|
||||
[ t ] [ 2004 1 1 0 0 0 0 make-timestamp 10 seconds 5 years +dts +dt
|
||||
2009 1 1 0 0 10 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2004 1 1 0 0 0 0 make-timestamp -10 seconds -5 years +dts +dt
|
||||
1998 12 31 23 59 50 0 make-timestamp = ] unit-test
|
||||
|
||||
[ t ] [ 2004 1 1 23 0 0 12 make-timestamp 0 convert-timezone
|
||||
2004 1 1 11 0 0 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2004 1 1 5 0 0 -11 make-timestamp 0 convert-timezone
|
||||
2004 1 1 16 0 0 0 make-timestamp = ] unit-test
|
||||
[ t ] [ 2004 1 1 23 0 0 9.5 make-timestamp 0 convert-timezone
|
||||
2004 1 1 13 30 0 0 make-timestamp = ] unit-test
|
||||
|
|
@ -23,8 +23,9 @@
|
|||
!
|
||||
! Examples of using the concurrency library.
|
||||
IN: concurrency-examples
|
||||
USING: concurrency dlists errors gadgets-theme gadgets-panes io kernel lists
|
||||
math math-contrib namespaces opengl prettyprint sequences threads ;
|
||||
USING: concurrency dlists errors gadgets gadgets-labels
|
||||
gadgets-panes gadgets-theme io kernel math namespaces opengl
|
||||
prettyprint sequences threads ;
|
||||
|
||||
: (logger) ( mailbox -- )
|
||||
#! Using the given mailbox, start a thread which
|
||||
|
@ -34,10 +35,10 @@ math math-contrib namespaces opengl prettyprint sequences threads ;
|
|||
: logger ( -- mailbox )
|
||||
#! Start a logging thread, which will log messages to the
|
||||
#! console that are put in the returned mailbox.
|
||||
make-mailbox dup [ (logger) ] cons in-thread ;
|
||||
make-mailbox dup [ (logger) ] curry in-thread ;
|
||||
|
||||
: (pong-server0) ( -- )
|
||||
receive uncons "ping" = [
|
||||
receive second "ping" = [
|
||||
"pong" swap send (pong-server0)
|
||||
] [
|
||||
"Pong server shutting down" swap send
|
||||
|
@ -146,28 +147,23 @@ M: crash-command run-rpc-command ( command -- shutdown? result )
|
|||
: test-add ( process -- )
|
||||
[
|
||||
"add" [ 1 2 3 ] <rpc-command> swap send-synchronous .
|
||||
] cons spawn drop ;
|
||||
] curry spawn drop ;
|
||||
|
||||
: test-crash ( process -- )
|
||||
[
|
||||
"crash" f <rpc-command> swap send-synchronous .
|
||||
] cons spawn drop ;
|
||||
] curry spawn drop ;
|
||||
|
||||
! ******************************
|
||||
! Experimental code below
|
||||
! ******************************
|
||||
USE: gadgets
|
||||
USE: gadgets-labels
|
||||
USE: gadgets-presentations
|
||||
USE: gadgets-layouts
|
||||
USE: generic
|
||||
|
||||
TUPLE: promised-label promise font color ;
|
||||
|
||||
C: promised-label ( promise -- promised-label )
|
||||
dup delegate>gadget dup label-theme
|
||||
[ set-promised-label-promise ] keep
|
||||
[ [ dup promised-label-promise ?promise drop relayout ] cons spawn drop ] keep ;
|
||||
[ [ dup promised-label-promise ?promise drop relayout ] curry spawn drop ] keep ;
|
||||
|
||||
: promised-label-text ( promised-label -- text )
|
||||
promised-label-promise dup promise-fulfilled? [
|
||||
|
@ -196,4 +192,4 @@ M: promised-label set-label-font set-promised-label-font ;
|
|||
1 sleep dup 2 < [ drop 1 ] [ dup 1 - fib swap 2 - fib + ] if ;
|
||||
|
||||
: test-promise-ui ( -- )
|
||||
<promise> dup <promised-label> gadget. [ 15 fib unparse swap fulfill ] cons spawn drop ;
|
||||
<promise> dup <promised-label> gadget. [ 15 fib unparse swap fulfill ] curry spawn drop ;
|
||||
|
|
|
@ -23,8 +23,7 @@
|
|||
!
|
||||
IN: concurrency
|
||||
USING: kernel concurrency concurrency-examples threads vectors
|
||||
sequences lists namespaces test errors dlists strings
|
||||
math words ;
|
||||
sequences namespaces test errors dlists strings math words ;
|
||||
|
||||
[ "junk" ] [
|
||||
<dlist>
|
||||
|
@ -81,9 +80,9 @@ USING: kernel concurrency concurrency-examples threads vectors
|
|||
[ V{ 1 2 3 } ] [
|
||||
0 <vector>
|
||||
make-mailbox
|
||||
2dup [ mailbox-get swap push ] cons cons in-thread
|
||||
2dup [ mailbox-get swap push ] cons cons in-thread
|
||||
2dup [ mailbox-get swap push ] cons cons in-thread
|
||||
2dup [ mailbox-get swap push ] curry curry in-thread
|
||||
2dup [ mailbox-get swap push ] curry curry in-thread
|
||||
2dup [ mailbox-get swap push ] curry curry in-thread
|
||||
1 over mailbox-put
|
||||
2 over mailbox-put
|
||||
3 swap mailbox-put
|
||||
|
@ -92,9 +91,9 @@ USING: kernel concurrency concurrency-examples threads vectors
|
|||
[ V{ 1 2 3 } ] [
|
||||
0 <vector>
|
||||
make-mailbox
|
||||
2dup [ [ integer? ] swap mailbox-get? swap push ] cons cons in-thread
|
||||
2dup [ [ integer? ] swap mailbox-get? swap push ] cons cons in-thread
|
||||
2dup [ [ integer? ] swap mailbox-get? swap push ] cons cons in-thread
|
||||
2dup [ [ integer? ] swap mailbox-get? swap push ] curry curry in-thread
|
||||
2dup [ [ integer? ] swap mailbox-get? swap push ] curry curry in-thread
|
||||
2dup [ [ integer? ] swap mailbox-get? swap push ] curry curry in-thread
|
||||
1 over mailbox-put
|
||||
2 over mailbox-put
|
||||
3 swap mailbox-put
|
||||
|
@ -103,10 +102,10 @@ USING: kernel concurrency concurrency-examples threads vectors
|
|||
[ V{ 1 "junk" 3 "junk2" } [ 456 ] ] [
|
||||
0 <vector>
|
||||
make-mailbox
|
||||
2dup [ [ integer? ] swap mailbox-get? swap push ] cons cons in-thread
|
||||
2dup [ [ integer? ] swap mailbox-get? swap push ] cons cons in-thread
|
||||
2dup [ [ string? ] swap mailbox-get? swap push ] cons cons in-thread
|
||||
2dup [ [ string? ] swap mailbox-get? swap push ] cons cons in-thread
|
||||
2dup [ [ integer? ] swap mailbox-get? swap push ] curry curry in-thread
|
||||
2dup [ [ integer? ] swap mailbox-get? swap push ] curry curry in-thread
|
||||
2dup [ [ string? ] swap mailbox-get? swap push ] curry curry in-thread
|
||||
2dup [ [ string? ] swap mailbox-get? swap push ] curry curry in-thread
|
||||
1 over mailbox-put
|
||||
"junk" over mailbox-put
|
||||
[ 456 ] over mailbox-put
|
||||
|
@ -174,8 +173,8 @@ USING: kernel concurrency concurrency-examples threads vectors
|
|||
[ V{ 50 50 50 } ] [
|
||||
0 <vector>
|
||||
<promise>
|
||||
2dup [ ?promise swap push ] cons cons spawn drop
|
||||
2dup [ ?promise swap push ] cons cons spawn drop
|
||||
2dup [ ?promise swap push ] cons cons spawn drop
|
||||
2dup [ ?promise swap push ] curry curry spawn drop
|
||||
2dup [ ?promise swap push ] curry curry spawn drop
|
||||
2dup [ ?promise swap push ] curry curry spawn drop
|
||||
50 swap fulfill
|
||||
] unit-test
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
!
|
||||
! Concurrency library for Factor based on Erlang/Termite style
|
||||
! concurrency.
|
||||
USING: kernel lists generic threads io namespaces errors words
|
||||
USING: kernel generic threads io namespaces errors words
|
||||
math sequences hashtables strings vectors dlists ;
|
||||
IN: concurrency
|
||||
|
||||
|
@ -158,17 +158,14 @@ TUPLE: process node links pid mailbox ;
|
|||
#! that process terminates.
|
||||
localnode swap unit gensym unparse make-mailbox <process> ;
|
||||
|
||||
#! The 'self-process' variable holds the currently executing process.
|
||||
SYMBOL: self-process
|
||||
|
||||
: self ( -- process )
|
||||
#! Returns the contents of the 'self-process' variables which
|
||||
#! is the process object for the current process.
|
||||
self-process get ;
|
||||
\ self get ;
|
||||
|
||||
: init-main-process ( -- )
|
||||
#! Setup the main process.
|
||||
make-process self-process set ;
|
||||
#! Setup the main process.
|
||||
make-process \ self set-global ;
|
||||
|
||||
init-main-process
|
||||
|
||||
|
@ -176,7 +173,7 @@ init-main-process
|
|||
#! Calls the quotation with 'self' set
|
||||
#! to the given process.
|
||||
[
|
||||
self-process set
|
||||
\ self set
|
||||
] make-hash
|
||||
swap bind ;
|
||||
|
||||
|
@ -224,7 +221,7 @@ TUPLE: linked-exception error ;
|
|||
#! Same as spawn but if the quotation throws an error that
|
||||
#! is uncaught, that error gets propogated to the process
|
||||
#! performing the spawn-link.
|
||||
[ catch [ rethrow-linked ] when* ] cons
|
||||
[ catch [ rethrow-linked ] when* ] curry
|
||||
[ in-thread ] self make-linked-process [ with-process ] over slip ;
|
||||
|
||||
#! A common operation is to send a message to a process containing
|
||||
|
@ -248,11 +245,7 @@ TUPLE: tagged-message data from tag ;
|
|||
#! 'match-quot' is a quotation with stack effect ( msg -- ). It
|
||||
#! will be called with the message on the top of the stack if
|
||||
#! the 'pred' word returned true.
|
||||
uncons >r dupd execute [
|
||||
r> car call
|
||||
] [
|
||||
r> 2drop
|
||||
] if ;
|
||||
[ first execute ] 2keep rot [ second call ] [ 2drop ] if ;
|
||||
|
||||
: recv ( forms -- )
|
||||
#! Get a message from the processes mailbox. Compare it against the
|
||||
|
@ -289,7 +282,7 @@ TUPLE: tagged-message data from tag ;
|
|||
#! is matched up with the request by generating a message tag
|
||||
#! which should be sent back with the reply.
|
||||
>r tag-message [ tagged-message-tag ] keep r> send
|
||||
unit [ car tag-match? ] cons receive-if tagged-message-data ;
|
||||
unit [ first tag-match? ] curry receive-if tagged-message-data ;
|
||||
|
||||
: reply ( tagged-message message -- )
|
||||
#! Replies to the tagged-message which should have been a result of a
|
||||
|
@ -321,7 +314,7 @@ SYMBOL: quit-cc
|
|||
[
|
||||
(spawn-server)
|
||||
"Exiting process: " write self process-pid print
|
||||
] cons spawn ;
|
||||
] curry spawn ;
|
||||
|
||||
: spawn-linked-server ( quot -- process )
|
||||
#! Similar to 'spawn-server' but the parent process will be linked
|
||||
|
@ -329,7 +322,7 @@ SYMBOL: quit-cc
|
|||
[
|
||||
(spawn-server)
|
||||
"Exiting process: " write self process-pid print
|
||||
] cons spawn-link ;
|
||||
] curry spawn-link ;
|
||||
|
||||
: send-reply ( message pred quot -- )
|
||||
#! The intent of this word is to provde an easy way to
|
||||
|
@ -379,7 +372,7 @@ SYMBOL: quit-cc
|
|||
#! and jumping back into it from a spawn and keeping the 'self'
|
||||
#! variable correct. It's a workaround until I can find out how to
|
||||
#! stop 'self' from being clobbered back to its old value.
|
||||
[ ] callcc1 dup process? [ self-process set f ] when ;
|
||||
[ ] callcc1 dup process? [ \ self set-global f ] when ;
|
||||
|
||||
: call-server-cc ( server-cc -- )
|
||||
#! Calls the server continuation passing the current 'self'
|
||||
|
@ -392,7 +385,7 @@ SYMBOL: quit-cc
|
|||
#! ?future. If the quotation has completed the result will be returned.
|
||||
#! If not, the process will block until the quotation completes.
|
||||
#! 'quot' must have stack effect ( -- X ).
|
||||
[ call self send ] cons spawn ;
|
||||
[ self send ] append spawn ;
|
||||
|
||||
: ?future ( future -- result )
|
||||
#! Block the process until the future has completed and then place the
|
||||
|
@ -443,7 +436,7 @@ SYMBOL: lazy-quot
|
|||
[ tagged-message? [ [ drop t ] [ get call ] send-reply ] ]
|
||||
] recv
|
||||
] with-scope
|
||||
] cons spawn ;
|
||||
] curry spawn ;
|
||||
|
||||
: ?lazy ( lazy -- result )
|
||||
#! Given a process spawned using 'lazy', evaluate it and return the result.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
IN: scratchpad
|
||||
USING: kernel parser compiler words sequences ;
|
||||
REQUIRES: dlists ;
|
||||
|
||||
"/contrib/dlists.factor" run-resource
|
||||
"/contrib/concurrency/concurrency.factor" run-resource
|
||||
PROVIDE: concurrency
|
||||
{ "concurrency.factor" }
|
||||
{ "concurrency-examples.factor" "concurrency-tests.factor" } ;
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
!
|
||||
IN: coroutines
|
||||
USING: kernel lists generic ;
|
||||
USING: kernel generic ;
|
||||
|
||||
TUPLE: coroutine resumecc exitcc ;
|
||||
|
||||
|
@ -32,7 +32,7 @@ TUPLE: coroutine resumecc exitcc ;
|
|||
#! on the stack and an initial value (received from coresume)
|
||||
#! when first resumed. ie. The quotation should have stack
|
||||
#! effect ( co value -- ).
|
||||
f f <coroutine> dup rot cons over set-coroutine-resumecc ;
|
||||
f f <coroutine> dup rot curry over set-coroutine-resumecc ;
|
||||
|
||||
: coresume ( v co -- result )
|
||||
#! Resume a coroutine with 'v' as the first item on the
|
||||
|
@ -48,7 +48,7 @@ TUPLE: coroutine resumecc exitcc ;
|
|||
#! Suspend a coroutine, leaving the value 'v' on the
|
||||
#! stack when control is passed to the 'coresume' caller.
|
||||
[
|
||||
[ continue-with ] cons
|
||||
[ continue-with ] curry
|
||||
over set-coroutine-resumecc
|
||||
coroutine-exitcc continue-with
|
||||
] callcc1 rot drop ;
|
||||
|
@ -69,3 +69,5 @@ test2 f swap coresume . f swap coresume . f swap coresume . drop
|
|||
|
||||
test3 f swap coresume . f swap coresume . f swap coresume . drop
|
||||
|
||||
PROVIDE: coroutines ;
|
||||
|
||||
|
|
|
@ -14,8 +14,7 @@ IN: crypto
|
|||
generate-bbs-primes * [ find-relative-prime ] keep <bbs> ;
|
||||
|
||||
IN: crypto-internals
|
||||
SYMBOL: blum-blum-shub 256 make-bbs global [ blum-blum-shub set ] bind
|
||||
IN: crypto
|
||||
SYMBOL: blum-blum-shub 256 make-bbs blum-blum-shub set-global
|
||||
|
||||
: next-bbs-bit ( bbs -- bit )
|
||||
#! x = x^2 mod n, return low bit of calculated x
|
||||
|
@ -26,5 +25,10 @@ SYMBOL: temp-bbs
|
|||
: (bbs-bits) ( numbits bbs -- n )
|
||||
temp-bbs set [ [ temp-bbs get next-bbs-bit ] swap make-bits ] with-scope ;
|
||||
|
||||
IN: crypto
|
||||
: random-bbs-bits* ( numbits bbs -- n ) (bbs-bits) ;
|
||||
: random-bbs-bits ( numbits -- n ) blum-blum-shub get (bbs-bits) ;
|
||||
: random-int ( n -- n )
|
||||
#! Cryptographically secure random number using Blum-Blum-Shub 256
|
||||
[ log2 1+ random-bbs-bits ] keep mod ;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
IN: crypto-internals
|
||||
USING: kernel io strings sequences namespaces math parser lists ;
|
||||
USING: kernel io strings sequences namespaces math parser ;
|
||||
|
||||
: w+ ( int -- int ) + HEX: ffffffff bitand ; inline
|
||||
: nth-int ( string n -- int ) 2 shift dup 4 + rot <slice> le> ; inline
|
||||
|
|
|
@ -1,28 +1,36 @@
|
|||
IN: scratchpad
|
||||
USING: kernel parser sequences words compiler ;
|
||||
REQUIRES: math ;
|
||||
|
||||
"/contrib/math/load.factor" run-resource
|
||||
|
||||
{
|
||||
"common"
|
||||
"base64"
|
||||
"barrett"
|
||||
"montgomery"
|
||||
"random"
|
||||
"miller-rabin"
|
||||
PROVIDE: crypto {
|
||||
"common.factor"
|
||||
"base64.factor"
|
||||
"barrett.factor"
|
||||
"montgomery.factor"
|
||||
"random.factor"
|
||||
"miller-rabin.factor"
|
||||
|
||||
! Rngs
|
||||
"blum-blum-shub"
|
||||
"blum-blum-shub.factor"
|
||||
|
||||
! Hash
|
||||
"crc32"
|
||||
"md5"
|
||||
"sha1"
|
||||
"crc32.factor"
|
||||
"md5.factor"
|
||||
"sha1.factor"
|
||||
|
||||
! Block ciphers
|
||||
"rc4"
|
||||
"rc4.factor"
|
||||
|
||||
! Public key
|
||||
"rsa"
|
||||
"rsa.factor"
|
||||
|
||||
} [ "/contrib/crypto/" swap ".factor" append3 run-resource ] each
|
||||
} {
|
||||
"test/common.factor"
|
||||
"test/md5.factor"
|
||||
"test/sha1.factor"
|
||||
"test/base64.factor"
|
||||
"test/miller-rabin.factor"
|
||||
"test/crc32.factor"
|
||||
"test/rsa.factor"
|
||||
"test/barrett.factor"
|
||||
"test/montgomery.factor"
|
||||
"test/blum-blum-shub.factor"
|
||||
} ;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
USING: kernel io strings sequences namespaces math parser lists crypto ;
|
||||
USING: kernel io strings sequences namespaces math parser crypto ;
|
||||
IN: crypto-internals
|
||||
|
||||
SYMBOL: a
|
||||
|
|
|
@ -50,8 +50,9 @@ SYMBOL: trials
|
|||
|
||||
IN: crypto
|
||||
|
||||
: miller-rabin* ( n trials -- bool )
|
||||
#! Probailistic primality test for n > 2, with trials as a parameter
|
||||
: miller-rabin* ( n num-trials -- bool )
|
||||
#! Probailistic primality test for n > 2, with num-trials as a parameter
|
||||
over 2 > [ "miller-rabin error: must call with n > 2" throw ] unless
|
||||
[ init-miller-rabin (miller-rabin) ] with-scope ;
|
||||
|
||||
: miller-rabin ( n -- bool )
|
||||
|
@ -70,7 +71,11 @@ IN: crypto
|
|||
large-random-bits next-miller-rabin-prime ;
|
||||
|
||||
: random-miller-rabin-prime==3(mod4) ( numbits -- p )
|
||||
dup random-miller-rabin-prime dup 4 mod 3 = [ drop random-miller-rabin-prime==3(mod4) ] [ nip ] if ;
|
||||
dup random-miller-rabin-prime dup 4 mod 3 = [
|
||||
drop random-miller-rabin-prime==3(mod4)
|
||||
] [
|
||||
nip
|
||||
] if ;
|
||||
|
||||
: (find-relative-prime) ( m g -- p )
|
||||
2dup gcd nip 1 > [ 2 + (find-relative-prime) ] [ nip ] if ;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
USING: kernel math sequences namespaces errors hashtables words arrays parser
|
||||
compiler syntax lists io threads ;
|
||||
USING: kernel math math-contrib sequences namespaces errors
|
||||
hashtables words arrays parser compiler syntax io threads ;
|
||||
IN: crypto
|
||||
: make-bits ( quot numbits -- n | quot: -- 0/1 )
|
||||
0 -rot [ drop dup call rot 1 shift bitor swap ] each drop ;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
USING: kernel io strings sequences namespaces math parser
|
||||
lists vectors hashtables kernel-internals math-contrib crypto ;
|
||||
vectors hashtables kernel-internals math-contrib crypto ;
|
||||
IN: crypto-internals
|
||||
|
||||
! Implemented according to RFC 3174.
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
USING: kernel math test namespaces crypto ;
|
||||
|
||||
[ HEX: 1f63edfb7e838622c7412eafaf0439cf0cdf3aae8bdd09e2de69b509a53883a83560d5ce50ea039e4 ] [ HEX: 827c67f31b2b46afa49ed95d7f7a3011e5875f7052d4c55437ce726d3c6ce0dc9c445fda63b6dc4e 16 barrett-mu ] unit-test
|
||||
|
||||
[ "abcdefghijklmnopqrstuvwxyz" ] [ "abcdefghijklmnopqrstuvwxyz" >base64 base64> ] unit-test
|
||||
[ "" ] [ "" >base64 base64> ] unit-test
|
||||
[ "a" ] [ "a" >base64 base64> ] unit-test
|
||||
[ "ab" ] [ "ab" >base64 base64> ] unit-test
|
||||
[ "abc" ] [ "abc" >base64 base64> ] unit-test
|
||||
|
||||
[ HEX: 7155b978fed765e2ec80b472b4eae1154d2f75dd753e7efaca0449b8eaf7c047f94564302c80c717 ] [ HEX: c8d30cdd849cc1cbccf75340f903cde3acc0e7b5e0326aa91f82f442cc1ab23f66cf042c2af22a0b montgomery-r^2 ] unit-test
|
||||
|
||||
[ HEX: 5aee1477 ] [ HEX: d681fab9 32 montgomery-n0' ] unit-test
|
||||
|
||||
[ "d41d8cd98f00b204e9800998ecf8427e" ] [ "" string>md5str ] unit-test
|
||||
[ "0cc175b9c0f1b6a831c399e269772661" ] [ "a" string>md5str ] unit-test
|
||||
[ "900150983cd24fb0d6963f7d28e17f72" ] [ "abc" string>md5str ] unit-test
|
||||
[ "f96b697d7cb7938d525a2f31aaf161d0" ] [ "message digest" string>md5str ] unit-test
|
||||
[ "c3fcd3d76192e4007dfb496cca67e13b" ] [ "abcdefghijklmnopqrstuvwxyz" string>md5str ] unit-test
|
||||
[ "d174ab98d277d9f5a5611c2c9f419d9f" ] [ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" string>md5str ] unit-test
|
||||
[ "57edf4a22be3c955ac49da2e2107b67a" ] [ "12345678901234567890123456789012345678901234567890123456789012345678901234567890" string>md5str ] unit-test
|
||||
|
||||
[ "a9993e364706816aba3e25717850c26c9cd0d89d" ] [ "abc" string>sha1str ] unit-test
|
||||
[ "84983e441c3bd26ebaae4aa1f95129e5e54670f1" ] [ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" string>sha1str ] unit-test
|
||||
! [ "34aa973cd4c4daa4f61eeb2bdbad27316534016f" ] [ 1000000 CHAR: a fill string>sha1str ] unit-test ! takes a long time...
|
||||
[ "dea356a2cddd90c7a7ecedc5ebb563934f460452" ] [ "0123456701234567012345670123456701234567012345670123456701234567" [ 10 [ dup % ] times ] "" make nip string>sha1str ] unit-test
|
||||
|
||||
[ f ] [ 473155932665450549999756893736999469773678960651272093993257221235459777950185377130233556540099119926369437865330559863 miller-rabin ] unit-test
|
||||
[ t ] [ 37 miller-rabin ] unit-test
|
||||
[ 101 ] [ 100 next-miller-rabin-prime ] unit-test
|
||||
[ 100000000000031 ] [ 100000000000000 next-miller-rabin-prime ] unit-test
|
||||
|
||||
|
||||
[ 123456789 ] [ 128 generate-rsa-keypair 123456789 over rsa-encrypt swap rsa-decrypt ] unit-test
|
||||
|
||||
[ 0 ] [ "" >crc32 ] unit-test
|
||||
[ HEX: cbf43926 ] [ "123456789" >crc32 ] unit-test
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
USING: kernel math test namespaces crypto ;
|
||||
|
||||
[ HEX: 1f63edfb7e838622c7412eafaf0439cf0cdf3aae8bdd09e2de69b509a53883a83560d5ce50ea039e4 ] [ HEX: 827c67f31b2b46afa49ed95d7f7a3011e5875f7052d4c55437ce726d3c6ce0dc9c445fda63b6dc4e 16 barrett-mu ] unit-test
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
USING: kernel math test namespaces crypto ;
|
||||
|
||||
[ "abcdefghijklmnopqrstuvwxyz" ] [ "abcdefghijklmnopqrstuvwxyz" >base64 base64> ] unit-test
|
||||
[ "" ] [ "" >base64 base64> ] unit-test
|
||||
[ "a" ] [ "a" >base64 base64> ] unit-test
|
||||
[ "ab" ] [ "ab" >base64 base64> ] unit-test
|
||||
[ "abc" ] [ "abc" >base64 base64> ] unit-test
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
USING: kernel math test namespaces crypto crypto-internals ;
|
||||
|
||||
[ 6 ] [ 5 T{ bbs f 590695557939 811977232793 } random-bbs-bits* ] unit-test
|
||||
[ 792723710536787233474130382522 ] [ 100 T{ bbs f 200352954495 846054538649 } [ random-bbs-bits* drop ] 2keep random-bbs-bits* ] unit-test
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
USING: kernel math test namespaces crypto ;
|
||||
|
||||
[ 0 ] [ 1 0 0 bitroll ] unit-test
|
||||
[ 1 ] [ 1 0 1 bitroll ] unit-test
|
||||
[ 1 ] [ 1 1 1 bitroll ] unit-test
|
||||
[ 1 ] [ 1 0 2 bitroll ] unit-test
|
||||
[ 1 ] [ 1 0 1 bitroll ] unit-test
|
||||
[ 1 ] [ 1 20 2 bitroll ] unit-test
|
||||
[ 1 ] [ 1 8 8 bitroll ] unit-test
|
||||
[ 1 ] [ 1 -8 8 bitroll ] unit-test
|
||||
[ 1 ] [ 1 -32 8 bitroll ] unit-test
|
||||
[ 128 ] [ 1 -1 8 bitroll ] unit-test
|
||||
[ 8 ] [ 1 3 32 bitroll ] unit-test
|
||||
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
USING: kernel math test namespaces crypto ;
|
||||
|
||||
[ 0 ] [ "" >crc32 ] unit-test
|
||||
[ HEX: cbf43926 ] [ "123456789" >crc32 ] unit-test
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
USING: kernel math test namespaces crypto ;
|
||||
|
||||
[ "d41d8cd98f00b204e9800998ecf8427e" ] [ "" string>md5str ] unit-test
|
||||
[ "0cc175b9c0f1b6a831c399e269772661" ] [ "a" string>md5str ] unit-test
|
||||
[ "900150983cd24fb0d6963f7d28e17f72" ] [ "abc" string>md5str ] unit-test
|
||||
[ "f96b697d7cb7938d525a2f31aaf161d0" ] [ "message digest" string>md5str ] unit-test
|
||||
[ "c3fcd3d76192e4007dfb496cca67e13b" ] [ "abcdefghijklmnopqrstuvwxyz" string>md5str ] unit-test
|
||||
[ "d174ab98d277d9f5a5611c2c9f419d9f" ] [ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" string>md5str ] unit-test
|
||||
[ "57edf4a22be3c955ac49da2e2107b67a" ] [ "12345678901234567890123456789012345678901234567890123456789012345678901234567890" string>md5str ] unit-test
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
USING: errors kernel math test namespaces crypto ;
|
||||
|
||||
[ f ] [ 473155932665450549999756893736999469773678960651272093993257221235459777950185377130233556540099119926369437865330559863 miller-rabin ] unit-test
|
||||
[ "miller-rabin error: must call with n > 2" ] [ [ 2 miller-rabin ] catch ] unit-test
|
||||
[ t ] [ 3 miller-rabin ] unit-test
|
||||
[ f ] [ 36 miller-rabin ] unit-test
|
||||
[ t ] [ 37 miller-rabin ] unit-test
|
||||
[ 101 ] [ 100 next-miller-rabin-prime ] unit-test
|
||||
[ 100000000000031 ] [ 100000000000000 next-miller-rabin-prime ] unit-test
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
USING: kernel math test namespaces crypto ;
|
||||
|
||||
|
||||
[ HEX: 7155b978fed765e2ec80b472b4eae1154d2f75dd753e7efaca0449b8eaf7c047f94564302c80c717 ] [ HEX: c8d30cdd849cc1cbccf75340f903cde3acc0e7b5e0326aa91f82f442cc1ab23f66cf042c2af22a0b montgomery-r^2 ] unit-test
|
||||
|
||||
[ HEX: 5aee1477 ] [ HEX: d681fab9 32 montgomery-n0' ] unit-test
|
||||
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
USING: kernel math test namespaces crypto ;
|
||||
|
||||
[ 123456789 ] [ 128 generate-rsa-keypair 123456789 over rsa-encrypt swap rsa-decrypt ] unit-test
|
||||
[ 123456789 ] [ 129 generate-rsa-keypair 123456789 over rsa-encrypt swap rsa-decrypt ] unit-test
|
||||
[ 123456789 ] [ 130 generate-rsa-keypair 123456789 over rsa-encrypt swap rsa-decrypt ] unit-test
|
||||
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
USING: kernel math test namespaces crypto ;
|
||||
|
||||
[ "a9993e364706816aba3e25717850c26c9cd0d89d" ] [ "abc" string>sha1str ] unit-test
|
||||
[ "84983e441c3bd26ebaae4aa1f95129e5e54670f1" ] [ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" string>sha1str ] unit-test
|
||||
! [ "34aa973cd4c4daa4f61eeb2bdbad27316534016f" ] [ 1000000 CHAR: a fill string>sha1str ] unit-test ! takes a long time...
|
||||
[ "dea356a2cddd90c7a7ecedc5ebb563934f460452" ] [ "0123456701234567012345670123456701234567012345670123456701234567" [ 10 [ dup % ] times ] "" make nip string>sha1str ] unit-test
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
! Copyright (C) 2005 Mackenzie Straight.
|
||||
! See http://factor.sf.net/license.txt for BSD license.
|
||||
IN: dlists USING: generic kernel math ;
|
||||
IN: dlists
|
||||
USING: generic kernel math modules ;
|
||||
|
||||
! Double-linked lists.
|
||||
|
||||
|
@ -60,3 +61,5 @@ C: dlist-node
|
|||
|
||||
: dlist-length ( dlist -- length )
|
||||
0 swap [ drop 1 + ] dlist-each ;
|
||||
|
||||
PROVIDE: dlists ;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
IN: embedded
|
||||
USING: sequences kernel parser math namespaces io lists ;
|
||||
USING: sequences kernel parser math namespaces io ;
|
||||
|
||||
! if example.fhtml contains:
|
||||
! <html>
|
||||
|
@ -49,17 +49,14 @@ USING: sequences kernel parser math namespaces io lists ;
|
|||
: parse-embedded ( string -- quot )
|
||||
#! simple example: "numbers: <% 3 [ 1 + pprint ] each %>"
|
||||
#! => "\"numbers: \" write 3 [ 1 + pprint ] each"
|
||||
[ embedded>factor ] f make ;
|
||||
[ embedded>factor ] [ ] make ;
|
||||
|
||||
: eval-embedded ( string -- ) parse-embedded call ;
|
||||
|
||||
: open-embedded-file ( filename -- str )
|
||||
<file-reader> lines "\n" join ;
|
||||
|
||||
: with-embedded-file ( filename quot -- )
|
||||
[
|
||||
over file set ! so that reload works properly
|
||||
>r <file-reader> lines "\n" join r> call
|
||||
>r <file-reader> contents r> call
|
||||
] with-scope ;
|
||||
|
||||
: parse-embedded-file ( filename -- quot )
|
||||
|
@ -68,3 +65,7 @@ USING: sequences kernel parser math namespaces io lists ;
|
|||
: run-embedded-file ( filename -- )
|
||||
[ eval-embedded ] with-embedded-file ;
|
||||
|
||||
: embedded-convert ( infile outfile -- )
|
||||
<file-writer> [ run-embedded-file ] with-stream ;
|
||||
|
||||
PROVIDE: embedded ;
|
|
@ -0,0 +1,81 @@
|
|||
(require 'comint)
|
||||
|
||||
(define-derived-mode factor-listener-mode comint-mode "Factor listener"
|
||||
(setq comint-prompt-regexp "^ "))
|
||||
|
||||
(defvar factor-binary "/scratch/factor-darcs/repos/Factor/f")
|
||||
(defvar factor-image "/scratch/factor-darcs/repos/Factor/factor.image")
|
||||
|
||||
(defun factor-server ()
|
||||
(interactive)
|
||||
(make-comint "factor-server" factor-binary nil factor-image "-shell=tty")
|
||||
(comint-send-string "*factor-server*" "USE: jedit telnet\n"))
|
||||
|
||||
;; (defun factor-listener ()
|
||||
;; (interactive)
|
||||
;; (factor-server)
|
||||
;; (sleep-for 0 500)
|
||||
;; (switch-to-buffer (make-comint "factor-listener" '("localhost" . 9999)))
|
||||
;; (rename-uniquely)
|
||||
;; (factor-listener-mode))
|
||||
|
||||
(defun factor-listener ()
|
||||
(interactive)
|
||||
(factor-server)
|
||||
(sleep-for 0 1000)
|
||||
(if (get-buffer "*factor-listener*")
|
||||
(save-excursion
|
||||
(set-buffer "*factor-listener*")
|
||||
(rename-uniquely)))
|
||||
(switch-to-buffer (make-comint "factor-listener" '("localhost" . 9999)))
|
||||
(factor-listener-mode))
|
||||
|
||||
(defun factor-listener-restart ()
|
||||
(interactive)
|
||||
(factor-server)
|
||||
(sleep-for 0 1000)
|
||||
(make-comint-in-buffer
|
||||
"factor-listener" (current-buffer) '("localhost" . 9999)))
|
||||
|
||||
(defun load-factor-file (file-name)
|
||||
(interactive "fLoad Factor file: ")
|
||||
(comint-send-string nil (format "\"%s\" run-file\n" file-name)))
|
||||
|
||||
(defun factor-update-stack-buffer (&optional string)
|
||||
(interactive)
|
||||
(save-excursion
|
||||
(set-buffer (get-buffer-create "*factor-stack*"))
|
||||
(erase-buffer)
|
||||
(comint-redirect-send-command-to-process
|
||||
".s" "*factor-stack*" "*factor-listener*" nil)))
|
||||
|
||||
(defvar factor-update-stackp nil "*")
|
||||
|
||||
(defun factor-send-input ()
|
||||
(interactive)
|
||||
(comint-send-input)
|
||||
(if factor-update-stackp
|
||||
(progn (sleep-for 0 250) (factor-update-stack-buffer))))
|
||||
|
||||
(defun factor-synopsis ()
|
||||
(interactive)
|
||||
(message
|
||||
(first
|
||||
(comint-redirect-results-list-from-process
|
||||
(get-buffer-process "*factor-listener*")
|
||||
(format "\\ %s synopsis print" (thing-at-point 'symbol))
|
||||
;; "[ ]*\\(.*\\)\n"
|
||||
"\\(.*\\)\n"
|
||||
1))))
|
||||
|
||||
(fset 'factor-comment-line "\C-a! ")
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; mode
|
||||
|
||||
;; syntax table
|
||||
|
||||
;; (push '("\\.factor\\'" . factor-mode) auto-mode-alist)
|
||||
|
||||
;; synopsis of word at point
|
|
@ -1,6 +1,6 @@
|
|||
USING: kernel alien compiler namespaces generic math sequences hashtables io
|
||||
arrays words prettyprint lists concurrency
|
||||
process rectangle xlib x concurrent-widgets ;
|
||||
arrays words prettyprint concurrency process
|
||||
vars rectangle x11 x concurrent-widgets ;
|
||||
|
||||
IN: factory
|
||||
|
||||
|
@ -15,6 +15,8 @@ DEFER: layout-frame
|
|||
DEFER: mapped-windows
|
||||
DEFER: workspace-1 DEFER: workspace-2 DEFER: workspace-3 DEFER: workspace-4
|
||||
DEFER: switch-to
|
||||
DEFER: update-title
|
||||
DEFER: delete-frame
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
|
@ -47,62 +49,91 @@ create-gc dup
|
|||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: MouseMask
|
||||
[ ButtonPressMask
|
||||
ButtonReleaseMask
|
||||
PointerMotionMask ] 0 [ execute bitor ] reduce ;
|
||||
VARS: event frame push position ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: drag-mouse-loop ( push last quot -- push release )
|
||||
MouseMask mask-event XAnyEvent-type ! push last quot type
|
||||
{ { [ dup MotionNotify = ]
|
||||
[ drop 3dup call nip mouse-sensor swap drag-mouse-loop ] }
|
||||
{ [ dup ButtonRelease = ]
|
||||
[ drop 3dup nip f swap call 2drop
|
||||
mouse-sensor ungrab-server CurrentTime ungrab-pointer flush-dpy ] }
|
||||
{ [ t ]
|
||||
[ drop "drag-mouse-loop ignoring event" print flush drag-mouse-loop ] }
|
||||
} cond ;
|
||||
|
||||
: drag-mouse ( quot -- push release )
|
||||
MouseMask grab-pointer grab-server mouse-sensor f rot drag-mouse-loop ;
|
||||
|
||||
: drag-mouse% [ drag-mouse ] with-window-object ;
|
||||
: event-type ( -- type ) event> XAnyEvent-type ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: ((draw-move-outline)) ( a b - )
|
||||
swap v- window-position v+ window-size <rect> root get draw-rect+ ;
|
||||
|
||||
: (draw-move-outline) ( push last -- )
|
||||
dupd dup [ ((draw-move-outline)) ] [ 2drop ] if
|
||||
mouse-sensor ((draw-move-outline)) flush-dpy ;
|
||||
|
||||
: draw-move-outline ( push last -- )
|
||||
drag-gc get [ (draw-move-outline) ] with-gcontext ;
|
||||
|
||||
: drag-move-window ( -- )
|
||||
[ draw-move-outline ] drag-mouse swap v- window-position v+ move-window ;
|
||||
|
||||
: drag-move-window% [ drag-move-window raise-window ] with-window-object ;
|
||||
: drag-offset ( -- offset ) position> push> v- ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: ((draw-resize-outline)) ( bottom-right -- )
|
||||
window-position v- window-position swap <rect> root get draw-rect+ ;
|
||||
: draw-rubber-band ( <rect> -- )
|
||||
root get [ drag-gc get [ draw-rect ] with-gcontext ] with-win ;
|
||||
|
||||
: (draw-resize-outline) ( push last -- )
|
||||
nip dup [ ((draw-resize-outline)) ] [ drop ] if
|
||||
mouse-sensor ((draw-resize-outline)) flush-dpy ;
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
! drag-move-frame
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: draw-resize-outline ( push last -- )
|
||||
drag-gc get [ (draw-resize-outline) ] with-gcontext ;
|
||||
: draw-frame-outline ( -- )
|
||||
drag-offset frame> window-position% v+ frame> window-size% <rect>
|
||||
draw-rubber-band ;
|
||||
|
||||
: drag-resize-window ( -- )
|
||||
[ draw-resize-outline ] drag-mouse nip window-position v- resize-window ;
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: drag-resize-window% [ drag-resize-window ] with-window-object ;
|
||||
: drag-move-frame-loop ( -- )
|
||||
next-event >event
|
||||
{ { [ event-type MotionNotify = ]
|
||||
[ draw-frame-outline
|
||||
event> XMotionEvent-root-position >position
|
||||
draw-frame-outline
|
||||
drag-move-frame-loop ] }
|
||||
{ [ event-type ButtonRelease = ]
|
||||
[ draw-frame-outline
|
||||
drag-offset frame> window-position% v+ frame> move-window% ] }
|
||||
{ [ t ]
|
||||
[ "[drag-move-frame-loop] Ignoring event type: " write
|
||||
event-type event-type>name write terpri flush
|
||||
drag-move-frame-loop ] } }
|
||||
cond ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: drag-move-frame ( event <wm-frame> -- )
|
||||
[ >frame >event
|
||||
event> XButtonEvent-root-position >push
|
||||
event> XButtonEvent-root-position >position
|
||||
draw-frame-outline
|
||||
drag-move-frame-loop
|
||||
frame> raise-window% ]
|
||||
with-scope ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
! drag-size-frame
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: draw-size-outline ( -- )
|
||||
frame> window-position% position> over v- <rect> draw-rubber-band ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: drag-size-frame-loop ( -- )
|
||||
next-event >event
|
||||
{ { [ event-type MotionNotify = ]
|
||||
[ draw-size-outline
|
||||
event> XMotionEvent-root-position >position
|
||||
draw-size-outline
|
||||
drag-size-frame-loop ] }
|
||||
{ [ event-type ButtonRelease = ]
|
||||
[ draw-size-outline
|
||||
position> frame> window-position% v- frame> resize-window%
|
||||
frame> layout-frame ] }
|
||||
{ [ t ]
|
||||
[ "[drag-size-frame-loop] ignoring event" print flush
|
||||
drag-size-frame-loop ] } }
|
||||
cond ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: drag-size-frame ( event <wm-frame> -- )
|
||||
[ >frame >event
|
||||
event> XButtonEvent-root-position >position
|
||||
draw-size-outline
|
||||
drag-size-frame-loop ]
|
||||
with-scope ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
|
@ -121,32 +152,24 @@ GENERIC: execute-size-request
|
|||
|
||||
TUPLE: wm-root ;
|
||||
|
||||
: create-wm-root ( window -- )
|
||||
>r dpy get r> <window> ! <window>
|
||||
<wm-root> ! <window> <wm-root>
|
||||
[ set-delegate ] keep ! <wm-root>
|
||||
[ add-to-window-table ] keep ! <wm-root>
|
||||
: wm-root-mask ( -- mask )
|
||||
[ SubstructureRedirectMask
|
||||
SubstructureNotifyMask
|
||||
ButtonPressMask
|
||||
ButtonReleaseMask
|
||||
KeyPressMask
|
||||
KeyReleaseMask ] bitmask ;
|
||||
|
||||
[ SubstructureRedirectMask
|
||||
SubstructureNotifyMask
|
||||
ButtonPressMask
|
||||
ButtonReleaseMask
|
||||
KeyPressMask
|
||||
KeyReleaseMask ] 0 [ execute bitor ] reduce ! <wm-frame> mask
|
||||
|
||||
over select-input% ; ! <wm-frame>
|
||||
: create-wm-root ( window-id -- <wm-root> )
|
||||
dpy get swap <window> <wm-root> tuck set-delegate dup add-to-window-table
|
||||
wm-root-mask over select-input% ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
! M: wm-root handle-map-request-event
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: id>obj ( id -- obj )
|
||||
dup ! id id
|
||||
window-table get hash ! id obj-or-f
|
||||
dup
|
||||
[ swap drop ]
|
||||
[ drop >r dpy get r> <window> ]
|
||||
if ;
|
||||
dup window-table get hash dup [ nip ] [ drop dpy get swap <window> ] if ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
|
@ -253,6 +276,12 @@ M: wm-root handle-configure-request-event ( event wm-root -- )
|
|||
! M: wm-root handle-button-press-event
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: XButtonEvent-position ( event -- { x y } )
|
||||
dup XButtonEvent-x swap XButtonEvent-y 2array ;
|
||||
|
||||
: XButtonEvent-root-position ( event -- { x y } )
|
||||
dup XButtonEvent-x_root swap XButtonEvent-y_root 2array ;
|
||||
|
||||
M: wm-root handle-button-press-event ( event wm-root -- )
|
||||
drop ! event
|
||||
|
||||
|
@ -281,36 +310,39 @@ M: wm-root handle-button-press-event ( event wm-root -- )
|
|||
! M: wm-root handle-key-press-event
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
SYMBOL: f1-keycode 67 f1-keycode set-global
|
||||
SYMBOL: f2-keycode 68 f2-keycode set-global
|
||||
SYMBOL: f3-keycode 69 f3-keycode set-global
|
||||
SYMBOL: f4-keycode 70 f4-keycode set-global
|
||||
: True 1 ;
|
||||
: False 0 ;
|
||||
|
||||
: f1-keycode ( -- code ) 67 ;
|
||||
: f2-keycode ( -- code ) 68 ;
|
||||
: f3-keycode ( -- code ) 69 ;
|
||||
: f4-keycode ( -- code ) 70 ;
|
||||
|
||||
: grab-keys ( -- )
|
||||
f1-keycode get Mod1Mask False GrabModeAsync GrabModeAsync grab-key
|
||||
f2-keycode get Mod1Mask False GrabModeAsync GrabModeAsync grab-key
|
||||
f3-keycode get Mod1Mask False GrabModeAsync GrabModeAsync grab-key
|
||||
f4-keycode get Mod1Mask False GrabModeAsync GrabModeAsync grab-key ;
|
||||
f1-keycode Mod1Mask False GrabModeAsync GrabModeAsync grab-key
|
||||
f2-keycode Mod1Mask False GrabModeAsync GrabModeAsync grab-key
|
||||
f3-keycode Mod1Mask False GrabModeAsync GrabModeAsync grab-key
|
||||
f4-keycode Mod1Mask False GrabModeAsync GrabModeAsync grab-key ;
|
||||
|
||||
M: wm-root handle-key-press-event ( event wm-root -- )
|
||||
drop
|
||||
{ { [ dup XKeyEvent-keycode f1-keycode get = ] [ workspace-1 get switch-to ] }
|
||||
{ [ dup XKeyEvent-keycode f2-keycode get = ] [ workspace-2 get switch-to ] }
|
||||
{ [ dup XKeyEvent-keycode f3-keycode get = ] [ workspace-3 get switch-to ] }
|
||||
{ [ dup XKeyEvent-keycode f4-keycode get = ] [ workspace-4 get switch-to ] }
|
||||
{ { [ dup XKeyEvent-keycode f1-keycode = ] [ workspace-1 get switch-to ] }
|
||||
{ [ dup XKeyEvent-keycode f2-keycode = ] [ workspace-2 get switch-to ] }
|
||||
{ [ dup XKeyEvent-keycode f3-keycode = ] [ workspace-3 get switch-to ] }
|
||||
{ [ dup XKeyEvent-keycode f4-keycode = ] [ workspace-4 get switch-to ] }
|
||||
{ [ t ] [ "wm-root ignoring key press" print drop ] } } cond ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
TUPLE: wm-child ;
|
||||
|
||||
: create-wm-child ( id -- <wm-child> )
|
||||
>r dpy get r> <window> <wm-child> ! <window> <wm-child>
|
||||
[ set-delegate ] keep
|
||||
[ add-to-window-table ] keep ;
|
||||
: create-wm-child ( window-id -- <wm-child> )
|
||||
dpy get swap <window> <wm-child> tuck set-delegate dup add-to-window-table ;
|
||||
|
||||
M: wm-child handle-property-event ( child event -- )
|
||||
"A <wm-child> received a property event" print flush drop drop ;
|
||||
M: wm-child handle-property-event ( event <wm-child> -- )
|
||||
"A <wm-child> received a property event" print flush
|
||||
nip
|
||||
window-parent% window-table get hash dup [ update-title ] [ drop ] if ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
|
@ -318,68 +350,62 @@ TUPLE: wm-frame child ;
|
|||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: create-wm-frame ( child -- <wm-frame> )
|
||||
>r create-window-object r> ! <window> child
|
||||
<wm-frame> ! <window> <wm-frame>
|
||||
[ set-delegate ] keep ! <wm-frame>
|
||||
[ add-to-window-table ] keep ! <wm-frame>
|
||||
|
||||
[ SubstructureRedirectMask
|
||||
SubstructureNotifyMask
|
||||
ExposureMask
|
||||
ButtonPressMask
|
||||
ButtonReleaseMask
|
||||
EnterWindowMask ] 0 [ execute bitor ] reduce ! <wm-frame> mask
|
||||
: wm-frame-mask ( -- mask )
|
||||
[ SubstructureRedirectMask
|
||||
SubstructureNotifyMask
|
||||
ExposureMask
|
||||
ButtonPressMask
|
||||
ButtonReleaseMask
|
||||
PointerMotionMask
|
||||
EnterWindowMask ] bitmask ;
|
||||
|
||||
over select-input% ; ! <wm-frame>
|
||||
: create-wm-frame ( <wm-child> -- <wm-frame> )
|
||||
<wm-frame> create-window-object over set-delegate dup add-to-window-table
|
||||
wm-frame-mask over select-input% ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: update-title ( <wm-frame> -- )
|
||||
dup clear-window%
|
||||
{ 5 1 } swap dup wm-frame-child fetch-name% swap draw-string-top-left% ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
VARS: child frame button ;
|
||||
|
||||
: manage-window ( window -- )
|
||||
flush-dpy
|
||||
grab-server
|
||||
flush-dpy
|
||||
|
||||
create-wm-child ! child
|
||||
create-wm-frame ! frame
|
||||
|
||||
dup "cornflowerblue" lookup-color swap set-window-background%
|
||||
|
||||
dup wm-frame-child add-to-save-set% ! frame
|
||||
|
||||
dup wm-frame-child window-position% ! frame position
|
||||
over ! frame position frame
|
||||
move-window%
|
||||
|
||||
dup wm-frame-child 0 swap set-window-border-width%
|
||||
dup dup wm-frame-child ! frame frame child
|
||||
reparent-window%
|
||||
|
||||
dup wm-frame-child window-size% ! frame child-size
|
||||
{ 20 20 } v+ ! frame child-size+
|
||||
over ! frame child-size+ frame
|
||||
resize-window%
|
||||
|
||||
dup wm-frame-child { 10 10 } swap move-window%
|
||||
|
||||
dup map-window%
|
||||
dup map-subwindows%
|
||||
|
||||
dup wm-frame-child PropertyChangeMask swap select-input%
|
||||
|
||||
flush-dpy
|
||||
0 sync-dpy
|
||||
ungrab-server
|
||||
flush-dpy ;
|
||||
flush-dpy grab-server flush-dpy
|
||||
create-wm-child dup create-wm-frame
|
||||
[ child frame ]
|
||||
[ "cornflowerblue" lookup-color frame> set-window-background%
|
||||
child> add-to-save-set%
|
||||
child> window-position% frame> move-window%
|
||||
0 child> set-window-border-width%
|
||||
frame> child> reparent-window%
|
||||
child> window-size% { 10 20 } v+ frame> resize-window%
|
||||
{ 5 15 } child> move-window%
|
||||
"" frame> [ delete-frame ] curry create-button
|
||||
[ button ]
|
||||
[ frame> button> reparent-window%
|
||||
{ 9 9 } button> resize-window%
|
||||
frame> window-width% 9 - 5 - 3 2array button> move-window%
|
||||
NorthEastGravity button> set-window-gravity%
|
||||
black-pixel get button> set-window-background% ]
|
||||
let
|
||||
PropertyChangeMask child> select-input%
|
||||
frame> map-subwindows%
|
||||
frame> map-window%
|
||||
frame> update-title
|
||||
flush-dpy 0 sync-dpy ungrab-server flush-dpy ]
|
||||
let ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: destroy-window-event-match? ( event <wm-frame> -- ? )
|
||||
window-id swap XDestroyWindowEvent-window = ;
|
||||
window-id swap XDestroyWindowEvent-window = ;
|
||||
|
||||
M: wm-frame handle-destroy-window-event ( event <wm-frame> -- )
|
||||
2dup destroy-window-event-match?
|
||||
[ destroy-window% drop ] [ drop drop ] if ;
|
||||
2dup destroy-window-event-match? [ destroy-window% drop ] [ 2drop ] if ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
|
@ -393,7 +419,7 @@ M: wm-frame handle-map-request-event ( event <wm-frame> -- )
|
|||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: map-event-match? ( event <wm-frame> -- ? )
|
||||
window-id swap XMapEvent-window = ;
|
||||
window-id swap XMapEvent-window = ;
|
||||
|
||||
M: wm-frame handle-map-event ( event <wm-frame> -- )
|
||||
2dup map-event-match?
|
||||
|
@ -442,7 +468,7 @@ M: wm-frame size-request-size ( event frame -- size )
|
|||
dup wm-frame-child -rot size-request-size swap resize-window% ;
|
||||
|
||||
: execute-size-request/frame ( event frame )
|
||||
dup -rot size-request-size { 20 20 } v+ swap resize-window% ;
|
||||
dup -rot size-request-size { 10 20 } v+ swap resize-window% ;
|
||||
|
||||
M: wm-frame execute-size-request ( event frame )
|
||||
2dup execute-size-request/child execute-size-request/frame ;
|
||||
|
@ -464,14 +490,10 @@ M: wm-frame handle-unmap-event ( event frame )
|
|||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: drag-move-frame ( frame -- ) drag-move-window% ;
|
||||
|
||||
: drag-resize-frame ( frame -- ) dup drag-resize-window% layout-frame ;
|
||||
|
||||
M: wm-frame handle-button-press-event ( event frame )
|
||||
over XButtonEvent-button ! event frame button
|
||||
{ { [ dup Button1 = ] [ drop nip drag-move-frame ] }
|
||||
{ [ dup Button2 = ] [ drop nip drag-resize-frame ] }
|
||||
{ { [ dup Button1 = ] [ drop drag-move-frame ] }
|
||||
{ [ dup Button2 = ] [ drop drag-size-frame ] }
|
||||
{ [ dup Button3 = ] [ drop nip unmap-window% ] }
|
||||
{ [ t ] [ drop drop drop ] } }
|
||||
cond ;
|
||||
|
@ -486,18 +508,30 @@ M: wm-frame handle-enter-window-event ( event frame )
|
|||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
M: wm-frame handle-property-event ( event frame )
|
||||
"Inside handle-property-event" print flush drop drop ;
|
||||
M: wm-frame handle-property-event ( event frame -- )
|
||||
"Inside handle-property-event" print flush 2drop ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: layout-frame ( frame -- )
|
||||
dup wm-frame-child { 10 10 } swap move-window%
|
||||
dup wm-frame-child ! frame child
|
||||
over window-size% ! frame child size
|
||||
{ 20 20 } v- ! frame child child-size
|
||||
swap resize-window% ! frame
|
||||
drop ;
|
||||
M: wm-frame handle-expose-event ( event frame -- )
|
||||
nip dup clear-window% update-title ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
: frame-position-child ( frame -- ) wm-frame-child { 5 15 } swap move-window% ;
|
||||
|
||||
: frame-fit-child ( frame -- )
|
||||
dup window-size% { 10 20 } v- swap wm-frame-child resize-window% ;
|
||||
|
||||
: layout-frame ( frame -- ) dup frame-position-child frame-fit-child ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
SYMBOL: WM_PROTOCOLS
|
||||
SYMBOL: WM_DELETE_WINDOW
|
||||
|
||||
: delete-frame ( frame -- ) wm-frame-child window-id
|
||||
[ WM_PROTOCOLS get WM_DELETE_WINDOW get send-client-message ] with-win ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
! Workspaces
|
||||
|
@ -562,7 +596,8 @@ SYMBOL: window-list
|
|||
|
||||
: setup-window-list ( -- )
|
||||
create-menu window-list set-global
|
||||
"black" lookup-color window-list get set-window-background% ;
|
||||
"black" lookup-color window-list get set-window-background%
|
||||
300 window-list get set-menu-item-width ;
|
||||
|
||||
: not-transient? ( frame -- ? ) wm-frame-child get-transient-for-hint% not ;
|
||||
|
||||
|
@ -574,7 +609,7 @@ SYMBOL: window-list
|
|||
[ ] [ 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
|
||||
curry ! window-list name action
|
||||
pick ! window-list name action window-list
|
||||
add-popup-menu-item ;
|
||||
|
||||
|
@ -607,8 +642,16 @@ SYMBOL: window-list
|
|||
root get [ black-pixel get set-window-background clear-window ] with-win
|
||||
root get create-wm-root
|
||||
root get [ grab-keys ] with-win
|
||||
"WM_PROTOCOLS" False intern-atom WM_PROTOCOLS set
|
||||
"WM_DELETE_WINDOW" False intern-atom WM_DELETE_WINDOW set
|
||||
"cornflowerblue" lookup-color menu-enter-color set
|
||||
"white" lookup-color menu-leave-color set
|
||||
setup-root-menu
|
||||
setup-window-list
|
||||
setup-workspace-menu
|
||||
manage-existing-windows
|
||||
[ concurrent-event-loop ] spawn ;
|
||||
|
||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
IN: shells USE: listener : factory f start-factory listener ;
|
|
@ -0,0 +1,3 @@
|
|||
REQUIRES: process concurrency x11 vars ;
|
||||
|
||||
PROVIDE: factory { "factory.factor" } ;
|
|
@ -0,0 +1,19 @@
|
|||
USING: kernel test sequences sequences-internals circular ;
|
||||
|
||||
[ 0 ] [ { 0 1 2 3 4 } <circular> 0 swap circular@ drop ] unit-test
|
||||
[ 2 ] [ { 0 1 2 3 4 } <circular> 2 swap circular@ drop ] unit-test
|
||||
|
||||
[ CHAR: t ] [ "test" <circular> 0 swap nth ] unit-test
|
||||
[ "test" ] [ "test" <circular> "" like ] unit-test
|
||||
|
||||
[ "test" <circular> 5 swap nth ] unit-test-fails
|
||||
[ CHAR: e ] [ "test" <circular> 5 swap nth-unsafe ] unit-test
|
||||
|
||||
[ [ 1 2 3 ] ] [ { 1 2 3 } <circular> f like ] unit-test
|
||||
[ [ 2 3 1 ] ] [ { 1 2 3 } <circular> 1 over change-circular-start f like ] unit-test
|
||||
[ [ 3 1 2 ] ] [ { 1 2 3 } <circular> 1 over change-circular-start 1 over change-circular-start f like ] unit-test
|
||||
|
||||
[ "fob" ] [ "foo" <circular> CHAR: b 2 pick set-nth "" like ] unit-test
|
||||
[ "foo" <circular> CHAR: b 3 rot set-nth ] unit-test-fails
|
||||
[ "boo" ] [ "foo" <circular> CHAR: b 3 pick set-nth-unsafe "" like ] unit-test
|
||||
[ "ornact" ] [ "factor" <circular> 4 over change-circular-start CHAR: n 2 pick set-nth "" like ] unit-test
|
|
@ -0,0 +1,25 @@
|
|||
USING: kernel sequences math generic sequences-internals ;
|
||||
IN: circular
|
||||
|
||||
! a circular sequence wraps another sequence, but begins at an arbitrary
|
||||
! element in the underlying sequence.
|
||||
TUPLE: circular start ;
|
||||
|
||||
C: circular ( seq circular -- circular )
|
||||
0 over set-circular-start [ set-delegate ] keep ;
|
||||
|
||||
: circular@ ( n circular -- n seq )
|
||||
[ tuck circular-start + swap length mod ] keep delegate ;
|
||||
|
||||
M: circular nth ( n seq -- elt ) bounds-check circular@ nth ;
|
||||
|
||||
M: circular nth-unsafe ( n seq -- elt ) circular@ nth-unsafe ;
|
||||
|
||||
M: circular set-nth ( elt n seq -- ) bounds-check circular@ set-nth ;
|
||||
|
||||
M: circular set-nth-unsafe ( elt n seq -- ) circular@ set-nth-unsafe ;
|
||||
|
||||
: change-circular-start ( n circular -- )
|
||||
#! change start to (start + n) mod length
|
||||
[ circular@ drop ] keep set-circular-start ;
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
USING: kernel sequences test gap-buffer strings math ;
|
||||
IN: gb-tests
|
||||
|
||||
! test copy-elements
|
||||
[ { 0 3 4 3 4 5 } ] [ { 0 1 2 3 4 5 } dup >r -2 3 5 r> copy-elements ] unit-test
|
||||
[ { 0 1 2 1 2 5 } ] [ { 0 1 2 3 4 5 } dup >r 2 2 0 r> copy-elements ] unit-test
|
||||
[ "01234567856" ] [ "01234567890" dup >r 4 6 4 r> copy-elements ] unit-test
|
||||
|
||||
! test sequence protocol (like, length, nth, set-nth)
|
||||
[ "gap buffers are cool" ] [ "gap buffers are cool" <gb> "" like ] unit-test
|
||||
|
||||
! test move-gap-back-inside
|
||||
[ t f ] [ 5 "0123456" <gb> move-gap-forward? >r move-gap-back-inside? 2nip r> ] unit-test
|
||||
[ "0123456" ] [ "0123456" <gb> 5 over move-gap >string ] unit-test
|
||||
! test move-gap-forward-inside
|
||||
[ t ] [ "I once ate a spaniel" <gb> 15 over move-gap 17 swap move-gap-forward-inside? 2nip ] unit-test
|
||||
[ "I once ate a spaniel" ] [ "I once ate a spaniel" <gb> 15 over move-gap 17 over move-gap >string ] unit-test
|
||||
! test move-gap-back-around
|
||||
[ f f ] [ 2 "terriers are ok too" <gb> move-gap-forward? >r move-gap-back-inside? 2nip r> ] unit-test
|
||||
[ "terriers are ok too" ] [ "terriers are ok too" <gb> 2 over move-gap >string ] unit-test
|
||||
! test move-gap-forward-around
|
||||
[ f t ] [ "god is nam's best friend" <gb> 2 over move-gap 22 over position>index swap move-gap-forward? >r move-gap-forward-inside? 2nip r> ] unit-test
|
||||
[ "god is nam's best friend" ] [ "god is nam's best friend" <gb> 2 over move-gap 22 over move-gap >string ] unit-test
|
||||
|
||||
! test changing buffer contents
|
||||
[ "factory" ] [ "factor" <gb> CHAR: y 6 pick insert* >string ] unit-test
|
||||
! test inserting multiple elements in different places. buffer should grow
|
||||
[ "refractory" ] [ "factor" <gb> CHAR: y 6 pick insert* "re" 0 pick insert* CHAR: r 3 pick insert* >string ] unit-test
|
||||
! test deleting elements. buffer should shrink
|
||||
[ "for" ] [ "factor" <gb> 3 [ 1 over delete* ] times >string ] unit-test
|
||||
! more testing of nth and set-nth
|
||||
[ "raptor" ] [ "factor" <gb> CHAR: p 2 pick set-nth 5 over nth 0 pick set-nth >string ] unit-test
|
||||
|
||||
! test stack/queue operations
|
||||
[ "slaughter" ] [ "laughter" <gb> CHAR: s over push-start >string ] unit-test
|
||||
[ "pantonio" ] [ "pant" <gb> "onio" over push-end >string ] unit-test
|
||||
[ CHAR: f "actor" ] [ "factor" <gb> dup pop-start swap >string ] unit-test
|
||||
[ CHAR: s "pant" ] [ "pants" <gb> dup pop-end swap >string ] unit-test
|
||||
[ "end this is the " ] [ "this is the end " <gb> 4 over rotate >string ] unit-test
|
||||
[ "your jedi training is finished " ] [ "finished your jedi training is " <gb> -9 over rotate >string ] unit-test
|
||||
|
|
@ -0,0 +1,241 @@
|
|||
! gap buffer -- Alex Chapman (chapman.alex@gmail.com)
|
||||
! largely influenced by Strandh and Villeneuve's Flexichain
|
||||
! for a good introduction see:
|
||||
! http://p-cos.net/lisp-ecoop/submissions/StrandhVilleneuveMoore.pdf
|
||||
USING: kernel arrays sequences sequences-internals circular math generic ;
|
||||
IN: gap-buffer
|
||||
|
||||
! gap-start -- the first element of the gap
|
||||
! gap-end -- the first element after the gap
|
||||
! expand-factor -- should be > 1
|
||||
! min-size -- < 5 is not sensible
|
||||
|
||||
TUPLE: gb
|
||||
gap-start
|
||||
gap-end
|
||||
expand-factor
|
||||
min-size ;
|
||||
|
||||
: required-space ( n gb -- n )
|
||||
tuck gb-expand-factor * ceiling >fixnum swap gb-min-size max ;
|
||||
|
||||
C: gb ( seq gb -- gb )
|
||||
5 over set-gb-min-size
|
||||
1.5 over set-gb-expand-factor
|
||||
[ >r length r> set-gb-gap-start ] 2keep
|
||||
[ swap length over required-space swap set-gb-gap-end ] 2keep
|
||||
[
|
||||
over length over required-space rot { } like resize-array <circular> swap set-delegate
|
||||
] keep ;
|
||||
|
||||
M: gb like ( seq gb -- seq ) drop <gb> ;
|
||||
|
||||
: gap-length ( gb -- n ) [ gb-gap-end ] keep gb-gap-start - ;
|
||||
|
||||
: buffer-length ( gb -- n ) delegate length ;
|
||||
|
||||
M: gb length ( gb -- n ) [ buffer-length ] keep gap-length - ;
|
||||
|
||||
: position>index ( n gb -- n )
|
||||
2dup gb-gap-start >= [
|
||||
gap-length +
|
||||
] [ drop ] if ;
|
||||
|
||||
: gb@ ( n gb -- n seq ) [ position>index ] keep delegate ;
|
||||
|
||||
M: gb nth ( n gb -- elt ) bounds-check gb@ nth-unsafe ;
|
||||
|
||||
M: gb nth-unsafe ( n gb -- elt ) gb@ nth-unsafe ;
|
||||
|
||||
M: gb set-nth ( elt n seq -- ) bounds-check gb@ set-nth-unsafe ;
|
||||
|
||||
M: gb set-nth-unsafe ( elt n seq -- ) gb@ set-nth-unsafe ;
|
||||
|
||||
! ------------- moving the gap -------------------------------
|
||||
|
||||
: (copy-element) ( to start seq -- ) tuck nth -rot set-nth ;
|
||||
|
||||
: copy-element ( dst start seq -- ) >r [ + ] keep r> (copy-element) ;
|
||||
|
||||
: copy-elements-back ( dst start seq n -- )
|
||||
dup 0 > [
|
||||
>r [ copy-element ] 3keep >r 1+ r> r> 1- copy-elements-back
|
||||
] [ 3drop drop ] if ;
|
||||
|
||||
: copy-elements-forward ( dst start seq n -- )
|
||||
dup 0 > [
|
||||
>r [ copy-element ] 3keep >r 1- r> r> 1- copy-elements-forward
|
||||
] [ 3drop drop ] if ;
|
||||
|
||||
: copy-elements ( dst start end seq -- )
|
||||
pick pick > [
|
||||
>r dupd - r> swap copy-elements-forward
|
||||
] [
|
||||
>r over - r> swap copy-elements-back
|
||||
] if ;
|
||||
|
||||
! the gap can be moved either forward or back. Moving the gap 'inside' means
|
||||
! moving elements across the gap. Moving the gap 'around' means changing the
|
||||
! start of the circular buffer to avoid moving as many elements.
|
||||
|
||||
! We decide which method (inside or around) to pick based on the number of
|
||||
! elements that will need to be moved. We always try to move as few elements as
|
||||
! possible.
|
||||
|
||||
: move-gap? ( i gb -- i gb ? ) 2dup gb-gap-end = not ;
|
||||
|
||||
: move-gap-forward? ( i gb -- i gb ? ) 2dup gb-gap-start >= ;
|
||||
|
||||
: move-gap-back-inside? ( i gb -- i gb ? )
|
||||
#! is it cheaper to move the gap inside than around?
|
||||
2dup [ gb-gap-start swap 2 * - ] keep [ buffer-length ] keep gb-gap-end - <= ;
|
||||
|
||||
: move-gap-forward-inside? ( i gb -- i gb ? )
|
||||
#! is it cheaper to move the gap inside than around?
|
||||
2dup [ gb-gap-end >r 2 * r> - ] keep [ gb-gap-start ] keep buffer-length + <= ;
|
||||
|
||||
: move-gap-forward-inside ( i gb -- )
|
||||
[ dup gap-length neg swap gb-gap-end rot ] keep delegate copy-elements ;
|
||||
|
||||
: move-gap-back-inside ( i gb -- )
|
||||
[ dup gap-length swap gb-gap-start 1- rot 1- ] keep delegate copy-elements ;
|
||||
|
||||
: move-gap-forward-around ( i gb -- )
|
||||
0 over move-gap-back-inside [
|
||||
dup buffer-length [
|
||||
swap gap-length - neg swap
|
||||
] keep
|
||||
] keep [
|
||||
delegate copy-elements
|
||||
] keep dup gap-length swap delegate change-circular-start ;
|
||||
|
||||
: move-gap-back-around ( i gb -- )
|
||||
dup buffer-length over move-gap-forward-inside [
|
||||
length swap -1
|
||||
] keep [
|
||||
delegate copy-elements
|
||||
] keep dup length swap delegate change-circular-start ;
|
||||
|
||||
: move-gap-forward ( i gb -- )
|
||||
move-gap-forward-inside? [
|
||||
move-gap-forward-inside
|
||||
] [
|
||||
move-gap-forward-around
|
||||
] if ;
|
||||
|
||||
: move-gap-back ( i gb -- )
|
||||
move-gap-back-inside? [
|
||||
move-gap-back-inside
|
||||
] [
|
||||
move-gap-back-around
|
||||
] if ;
|
||||
|
||||
: (move-gap) ( i gb -- )
|
||||
move-gap? [
|
||||
move-gap-forward? [
|
||||
move-gap-forward
|
||||
] [
|
||||
move-gap-back
|
||||
] if
|
||||
] [ 2drop ] if ;
|
||||
|
||||
: fix-gap ( n gb -- )
|
||||
2dup [ gap-length + ] keep set-gb-gap-end set-gb-gap-start ;
|
||||
|
||||
: move-gap ( n gb -- ) 2dup [ position>index ] keep (move-gap) fix-gap ;
|
||||
|
||||
! ------------ resizing -------------------------------------
|
||||
|
||||
: enough-room? ( n gb -- ? )
|
||||
#! is there enough room to add 'n' elements to gb?
|
||||
tuck length + swap buffer-length <= ;
|
||||
|
||||
: set-new-gap-end ( array gb -- )
|
||||
[ buffer-length swap length swap - ] keep
|
||||
[ gb-gap-end + ] keep set-gb-gap-end ;
|
||||
|
||||
: after-gap ( gb -- gb )
|
||||
dup gb-gap-end swap delegate tail ;
|
||||
|
||||
: before-gap ( gb -- gb )
|
||||
dup gb-gap-start swap head ;
|
||||
|
||||
: copy-after-gap ( array gb -- )
|
||||
#! copy everything after the gap in 'gb' into the end of 'array',
|
||||
#! and change 'gb's gap-end to reflect the gap-end in 'array'
|
||||
dup after-gap >r 2dup set-new-gap-end gb-gap-end swap r> copy-into ;
|
||||
|
||||
: copy-before-gap ( array gb -- )
|
||||
#! copy everything before the gap in 'gb' into the start of 'array'
|
||||
before-gap 0 -rot copy-into ; ! gap start doesn't change
|
||||
|
||||
: resize-buffer ( gb new-size -- )
|
||||
f <array> swap 2dup copy-before-gap 2dup copy-after-gap
|
||||
>r <circular> r> set-delegate ;
|
||||
|
||||
: decrease-buffer-size ( gb -- )
|
||||
#! the gap is too big, so resize to something sensible
|
||||
dup length over required-space resize-buffer ;
|
||||
|
||||
: increase-buffer-size ( n gb -- )
|
||||
#! increase the buffer to fit at least 'n' more elements
|
||||
tuck length + over required-space resize-buffer ;
|
||||
|
||||
: gb-too-big? ( gb -- ? )
|
||||
dup buffer-length over gb-min-size > [
|
||||
dup length over buffer-length rot gb-expand-factor sq / <
|
||||
] [ drop f ] if ;
|
||||
|
||||
: maybe-decrease ( gb -- )
|
||||
dup gb-too-big? [
|
||||
decrease-buffer-size
|
||||
] [ drop ] if ;
|
||||
|
||||
: ensure-room ( n gb -- )
|
||||
#! ensure that ther will be enough room for 'n' more elements
|
||||
2dup enough-room? [ 2drop ] [
|
||||
increase-buffer-size
|
||||
] if ;
|
||||
|
||||
! ------- editing operations ---------------
|
||||
|
||||
G: insert* 2 standard-combination ;
|
||||
|
||||
: prepare-insert ( seq position gb -- seq gb )
|
||||
tuck move-gap over length over ensure-room ;
|
||||
|
||||
: insert-elements ( seq gb -- )
|
||||
dup gb-gap-start swap delegate rot copy-into ;
|
||||
|
||||
: increment-gap-start ( gb n -- )
|
||||
over gb-gap-start + swap set-gb-gap-start ;
|
||||
|
||||
M: sequence insert* ( seq position gb -- )
|
||||
prepare-insert [ insert-elements ] 2keep swap length increment-gap-start ;
|
||||
|
||||
M: object insert* ( elem position gb -- ) >r >r 1array r> r> insert* ;
|
||||
|
||||
: delete* ( position gb -- )
|
||||
tuck move-gap dup gb-gap-end 1+ over set-gb-gap-end maybe-decrease ;
|
||||
|
||||
! -------- stack/queue operations -----------
|
||||
|
||||
: push-start ( obj gb -- ) 0 swap insert* ;
|
||||
|
||||
: push-end ( obj gb -- ) [ length ] keep insert* ;
|
||||
|
||||
: pop-elem ( position gb -- elem ) [ nth ] 2keep delete* ;
|
||||
|
||||
: pop-start ( gb -- elem ) 0 swap pop-elem ;
|
||||
|
||||
: pop-end ( gb -- elem ) [ length 1- ] keep pop-elem ;
|
||||
|
||||
: rotate ( n gb -- )
|
||||
dup length 1 > [
|
||||
swap dup 0 > [
|
||||
[ dup [ pop-end ] keep push-start ]
|
||||
] [
|
||||
neg [ dup [ pop-start ] keep push-end ]
|
||||
] if times drop
|
||||
] [ 2drop ] if ;
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
PROVIDE: gap-buffer
|
||||
{ "circular.factor" "gap-buffer.factor" }
|
||||
{ "circular-tests.factor" "gap-buffer-tests.factor" } ;
|
|
@ -0,0 +1,26 @@
|
|||
USING: io kernel math namespaces prettyprint sequences strings ;
|
||||
IN: hexdump-internals
|
||||
|
||||
: .header ( len -- )
|
||||
"Length: " write dup unparse write ", " write >hex write "h" write terpri ;
|
||||
|
||||
: .offset ( lineno -- ) 16 * >hex 8 CHAR: 0 pad-left write "h: " write ;
|
||||
: .h-pad ( digit -- ) >hex 2 CHAR: 0 pad-left write ;
|
||||
: .line ( str n -- )
|
||||
.offset [ [ .h-pad " " write ] each ] keep
|
||||
16 over length - [ " " write ] times
|
||||
[ dup printable? [ drop CHAR: . ] unless ch>string write ] each
|
||||
terpri ;
|
||||
|
||||
IN: hexdump
|
||||
: hexdump ( str -- str )
|
||||
#! Write hexdump to a string
|
||||
[
|
||||
dup length .header
|
||||
16 swap group dup length [ .line ] 2each
|
||||
] string-out ;
|
||||
|
||||
: .hexdump ( str -- )
|
||||
#! Print hexdump
|
||||
hexdump write ;
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
PROVIDE: hexdump {
|
||||
"hexdump.factor"
|
||||
} {
|
||||
"test/hexdump.factor"
|
||||
} ;
|
|
@ -0,0 +1,8 @@
|
|||
IN: temporary
|
||||
USING: hexdump kernel sequences test ;
|
||||
|
||||
[ t ] [ "" hexdump "Length: 0, 0h\n" = ] unit-test
|
||||
[ t ] [ "abcdefghijklmnopqrstuvwxyz" hexdump "Length: 26, 1ah\n00000000h: 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 abcdefghijklmnop\n00000010h: 71 72 73 74 75 76 77 78 79 7a qrstuvwxyz\n" = ] unit-test
|
||||
|
||||
[ t ] [ 256 [ ] map hexdump "Length: 256, 100h\n00000000h: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f ................\n00000010h: 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f ................\n00000020h: 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f !\"#$%&'()*+,-./\n00000030h: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 0123456789:;<=>?\n00000040h: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f @ABCDEFGHIJKLMNO\n00000050h: 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f PQRSTUVWXYZ[\\]^_\n00000060h: 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f `abcdefghijklmno\n00000070h: 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f pqrstuvwxyz{|}~.\n00000080h: 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f ................\n00000090h: 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f ................\n000000a0h: a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af ................\n000000b0h: b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf ................\n000000c0h: c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf ................\n000000d0h: d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df ................\n000000e0h: e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef ................\n000000f0h: f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff ................\n" = ] unit-test
|
||||
|
|
@ -1,64 +1,41 @@
|
|||
! 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.
|
||||
!
|
||||
! A Smalltalk-like browser that runs in the httpd server using
|
||||
! cont-responder facilities.
|
||||
!
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
IN: browser-responder
|
||||
USING: cont-responder hashtables help html io kernel lists
|
||||
memory namespaces prettyprint sequences words xml ;
|
||||
USING: hashtables help html httpd io kernel memory namespaces
|
||||
prettyprint sequences words xml ;
|
||||
|
||||
: option ( current text -- )
|
||||
#! Output the HTML option tag for the given text. If
|
||||
#! it is equal to the current string, make the option selected.
|
||||
2dup = [
|
||||
"<option selected>" write
|
||||
] [
|
||||
"<option>" write
|
||||
] if
|
||||
chars>entities write
|
||||
"</option>\n" write drop ;
|
||||
<option tuck = [ "yes" =selected ] when option>
|
||||
chars>entities write
|
||||
</option> ;
|
||||
|
||||
: vocab-list ( vocab -- )
|
||||
#! Write out the HTML for the list of vocabularies. Make the currently
|
||||
#! selected vocab be 'vocab'.
|
||||
<select "vocab" =name "width: 200px; " =style "20" =size "document.forms.main.submit()" =onchange select>
|
||||
vocabs [ over swap option ] each drop
|
||||
: options ( current seq -- ) [ option ] each-with ;
|
||||
|
||||
: list ( current seq name -- )
|
||||
<select =name "width: 200px;" =style "20" =size "document.forms.main.submit()" =onchange select>
|
||||
options
|
||||
</select> ;
|
||||
|
||||
: word-list ( vocab word -- )
|
||||
#! Write out the HTML for the list of words in a vocabulary. Make the 'word' item
|
||||
#! the currently selected option.
|
||||
<select "word" =name "width: 200px; " =style "20" =size "document.forms.main.submit()" =onchange select>
|
||||
swap words natural-sort
|
||||
[ word-name over swap option ] each drop
|
||||
</select> ;
|
||||
: current-vocab ( -- string )
|
||||
"vocab" query-param [ "kernel" ] unless* ;
|
||||
|
||||
: word-source ( vocab word -- )
|
||||
: current-word ( -- word )
|
||||
"word" query-param "vocab" query-param lookup ;
|
||||
|
||||
: vocab-list ( -- )
|
||||
current-vocab vocabs "vocab" list ;
|
||||
|
||||
: word-list ( -- )
|
||||
current-word [ word-name ] [ f ] if*
|
||||
current-vocab vocab hash-keys natural-sort "word" list ;
|
||||
|
||||
: word-source ( -- )
|
||||
#! Write the source for the given word from the vocab as HTML.
|
||||
swap lookup [ [ (help) ] with-html-stream ] when* ;
|
||||
current-word [ [ see-help ] with-html-stream ] when* ;
|
||||
|
||||
: browser-body ( vocab word -- )
|
||||
: browser-body ( -- )
|
||||
#! Write out the HTML for the body of the main browser page.
|
||||
<table "100%" =width table>
|
||||
<tr>
|
||||
|
@ -67,25 +44,24 @@ memory namespaces prettyprint sequences words xml ;
|
|||
<th> "Documentation" write </th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td "top" =valign "width: 200px;" =style td> over vocab-list </td>
|
||||
<td "top" =valign "width: 200px;" =style td> 2dup word-list </td>
|
||||
<td "top" =valign "width: 200px;" =style td>
|
||||
vocab-list
|
||||
</td>
|
||||
<td "top" =valign "width: 200px;" =style td>
|
||||
word-list
|
||||
</td>
|
||||
<td "top" =valign td> word-source </td>
|
||||
</tr>
|
||||
</table> ;
|
||||
|
||||
: browser-title ( vocab word -- )
|
||||
#! Output the HTML title for the browser.
|
||||
[ "Factor Browser - " % swap % " - " % % ] "" make ;
|
||||
|
||||
: browse ( vocab word -- )
|
||||
#! Display a Smalltalk like browser for exploring words.
|
||||
[
|
||||
2dup browser-title [
|
||||
<form "main" =name "" =action "get" =method form> browser-body </form>
|
||||
] html-document
|
||||
] show-final ;
|
||||
: browser-title ( -- str )
|
||||
current-word
|
||||
[ synopsis ] [ "IN: " current-vocab append ] if* ;
|
||||
|
||||
: browser-responder ( -- )
|
||||
#! Start the Smalltalk-like browser.
|
||||
"vocab" "query" get hash [ "browser-responder" ] unless*
|
||||
"word" "query" get hash [ "browse" ] unless* browse ;
|
||||
#! Display a Smalltalk like browser for exploring words.
|
||||
serving-html browser-title [
|
||||
<form "main" =name "" =action "get" =method form>
|
||||
browser-body
|
||||
</form>
|
||||
] html-document ;
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
! Copyright (C) 2004 Chris Double.
|
||||
! Copyright (C) 2006 Slava Pestov.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
IN: callback-responder
|
||||
USING: hashtables html http httpd io kernel math namespaces
|
||||
sequences ;
|
||||
|
||||
#! Name of the variable holding the continuation used to exit
|
||||
#! back to the httpd responder.
|
||||
SYMBOL: exit-continuation
|
||||
|
||||
#! Tuple to hold global request data. This gets passed to
|
||||
#! the continuation when resumed so it can restore things
|
||||
#! like 'stdio' so it writes to the correct socket.
|
||||
TUPLE: request stream exitcc method url raw-query query header response ;
|
||||
|
||||
C: request ( -- request )
|
||||
[ stdio get swap set-request-stream ] keep
|
||||
[ "method" get swap set-request-method ] keep
|
||||
[ "request" get swap set-request-url ] keep
|
||||
[ "raw-query" get swap set-request-raw-query ] keep
|
||||
[ "query" get swap set-request-query ] keep
|
||||
[ "header" get swap set-request-header ] keep
|
||||
[ "response" get swap set-request-response ] keep
|
||||
[ exit-continuation get swap set-request-exitcc ] keep ;
|
||||
|
||||
: restore-request ( -- )
|
||||
request get
|
||||
dup request-stream stdio set
|
||||
dup request-method "method" set
|
||||
dup request-raw-query "raw-query" set
|
||||
dup request-query "query" set
|
||||
dup request-header "header" set
|
||||
dup request-response "response" set
|
||||
request-exitcc exit-continuation set ;
|
||||
|
||||
: update-request ( request new-request -- )
|
||||
[ request-stream over set-request-stream ] keep
|
||||
[ request-method over set-request-method ] keep
|
||||
[ request-url over set-request-url ] keep
|
||||
[ request-raw-query over set-request-raw-query ] keep
|
||||
[ request-query over set-request-query ] keep
|
||||
[ request-header over set-request-header ] keep
|
||||
[ request-response over set-request-response ] keep
|
||||
request-exitcc swap set-request-exitcc ;
|
||||
|
||||
: with-exit-continuation ( quot -- )
|
||||
#! Call the quotation with the variable exit-continuation bound
|
||||
#! such that when the exit continuation is called, computation
|
||||
#! will resume from the end of this 'with-exit-continuation' call.
|
||||
[
|
||||
exit-continuation set call exit-continuation get continue
|
||||
] callcc0 drop ;
|
||||
|
||||
: expiry-timeout ( -- ms ) 900 1000 * ;
|
||||
|
||||
: get-random-id ( -- id )
|
||||
#! Generate a random id to use for continuation URL's
|
||||
[ "ID" % 32 [ 9 random-int CHAR: 0 + , ] times ] "" make ;
|
||||
|
||||
: callback-table ( -- <hashtable> )
|
||||
#! Return the global table of continuations
|
||||
\ callback-table get-global ;
|
||||
|
||||
: reset-callback-table ( -- )
|
||||
#! Create the initial global table
|
||||
H{ } clone \ callback-table set-global ;
|
||||
|
||||
reset-callback-table
|
||||
|
||||
#! Tuple for holding data related to a callback.
|
||||
TUPLE: item quot expire? request id time-added ;
|
||||
|
||||
C: item ( quot data data-quot expire? id -- item )
|
||||
millis over set-item-time-added
|
||||
[ set-item-id ] keep
|
||||
[ set-item-request ] keep
|
||||
[ set-item-expire? ] keep
|
||||
[ set-item-quot ] keep ;
|
||||
|
||||
: expired? ( item -- ? )
|
||||
#! Return true if the callback item is expirable
|
||||
#! and has expired (ie. was added to the table more than
|
||||
#! timeout milliseconds ago).
|
||||
[ item-time-added expiry-timeout + millis < ] keep
|
||||
item-expire? and ;
|
||||
|
||||
: expire-callbacks ( -- )
|
||||
#! Expire all continuations in the continuation table
|
||||
#! if they are 'timeout-seconds' old (ie. were added
|
||||
#! more than 'timeout-seconds' ago.
|
||||
callback-table clone [
|
||||
expired? [ callback-table remove-hash ] [ drop ] if
|
||||
] hash-each ;
|
||||
|
||||
: id>url ( id -- string )
|
||||
#! Convert the continuation id to an URL suitable for
|
||||
#! embedding in an HREF or other HTML.
|
||||
"/responder/callback/?id=" swap url-encode append ;
|
||||
|
||||
: register-callback ( quot expire? -- url )
|
||||
#! 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.
|
||||
request get get-random-id [ <item> ] keep
|
||||
[ callback-table set-hash ] keep
|
||||
id>url ;
|
||||
|
||||
: register-html-callback ( quot expire? -- url )
|
||||
>r [ serving-html ] swap append r> register-callback ;
|
||||
|
||||
: callback-responder ( -- )
|
||||
expire-callbacks
|
||||
"id" query-param callback-table hash [
|
||||
[
|
||||
dup item-request [
|
||||
<request> update-request
|
||||
] when*
|
||||
item-quot call
|
||||
exit-continuation get continue
|
||||
] with-exit-continuation drop
|
||||
] [
|
||||
"404 Callback not available" httpd-error
|
||||
] if* ;
|
|
@ -1,9 +1,8 @@
|
|||
! Copyright (C) 2004 Chris Double.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
|
||||
USING: http httpd math namespaces io
|
||||
lists strings kernel html hashtables
|
||||
parser generic sequences ;
|
||||
USING: http httpd math namespaces io strings kernel html hashtables
|
||||
parser generic sequences callback-responder ;
|
||||
IN: cont-responder
|
||||
|
||||
#! Used inside the session state of responders to indicate whether the
|
||||
|
@ -11,176 +10,11 @@ IN: cont-responder
|
|||
#! true after each request.
|
||||
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 ;
|
||||
|
||||
: get-random-id ( -- id )
|
||||
#! Generate a random id to use for continuation URL's
|
||||
[ "ID" % 32 [ 9 random-int CHAR: 0 + , ] times ] "" make ;
|
||||
|
||||
SYMBOL: table
|
||||
|
||||
: continuation-table ( -- <hashtable> )
|
||||
#! Return the global table of continuations
|
||||
table get-global ;
|
||||
|
||||
: 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 -- <item> )
|
||||
#! 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 <item> ;
|
||||
|
||||
: seconds>millis ( seconds -- millis )
|
||||
#! Convert a number of seconds to milliseconds
|
||||
1000 * ;
|
||||
|
||||
: expired? ( timeout-seconds <item> -- 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 ;
|
||||
|
||||
: 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 [
|
||||
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 ;
|
||||
|
||||
: 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 ;
|
||||
|
||||
: 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 ;
|
||||
|
||||
: 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 ;
|
||||
|
||||
: get-continuation-item ( id -- <item> )
|
||||
#! 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 ;
|
||||
|
||||
DEFER: show-final
|
||||
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.
|
||||
<html>
|
||||
<body>
|
||||
<p> "This page has expired." write </p>
|
||||
</body>
|
||||
</html> flush ;
|
||||
|
||||
: expired-page-handler ( alist -- )
|
||||
[ (expired-page-handler) ] show-final ;
|
||||
|
||||
: >callable ( quot|interp|f -- interp )
|
||||
dup continuation? [
|
||||
[ continue-with ] cons
|
||||
dup continuation? [
|
||||
[ continue ] curry
|
||||
] 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 ;
|
||||
|
||||
: 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 ;
|
||||
|
||||
#! 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 ;
|
||||
|
||||
: call-exit-continuation ( value -- )
|
||||
#! 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 ;
|
||||
|
||||
#! 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
|
||||
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
|
||||
|
@ -188,7 +22,7 @@ SYMBOL: callback-cc
|
|||
[
|
||||
"HTTP/1.1 302 Document Moved\nLocation: " % %
|
||||
"\nContent-Length: 0\nContent-Type: text/plain\n\n" %
|
||||
] "" make write "" call-exit-continuation ;
|
||||
] "" make write exit-continuation get continue ;
|
||||
|
||||
: forward-to-id ( id -- )
|
||||
#! When executed inside a 'show' call, this will force a
|
||||
|
@ -196,50 +30,68 @@ SYMBOL: callback-cc
|
|||
#! 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 ;
|
||||
SYMBOL: current-show
|
||||
|
||||
: (show) ( quot -- namespace )
|
||||
: store-current-show ( -- )
|
||||
#! Store the current continuation in the variable 'current-show'
|
||||
#! so it can be returned to later by href 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 -- )
|
||||
current-show set ( 0 -- )
|
||||
continue
|
||||
] callcc1 ( 0 [ ] == )
|
||||
nip
|
||||
restore-request
|
||||
call
|
||||
store-current-show
|
||||
] callcc0 restore-request ;
|
||||
|
||||
: 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 [
|
||||
[
|
||||
>callable t register-callback forward-to-url
|
||||
] callcc1 drop restore-request
|
||||
] [
|
||||
t post-refresh-get? set
|
||||
] if ;
|
||||
|
||||
: (show) ( quot -- hashtable )
|
||||
#! 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
|
||||
store-current-show redirect-to-here
|
||||
[
|
||||
expirable register-continuation id>url swap
|
||||
with-scope "" call-exit-continuation
|
||||
] callcc1
|
||||
nip dup resume-stdio stdio set resume-value ;
|
||||
>callable t register-callback swap with-scope
|
||||
exit-continuation get continue
|
||||
] callcc0 drop restore-request "response" get ;
|
||||
|
||||
: 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
|
||||
#! computation will resume from this 'show' call with a hashtable on
|
||||
#! the stack containing any query or post parameters.
|
||||
#! 'quot' has stack effect ( url -- )
|
||||
#! NOTE: On return from 'show' the stack is exactly the same as
|
||||
#! initial entry with 'quot' popped off an <namespace> put on. Even
|
||||
#! initial entry with 'quot' popped off and the hashtable pushed on. Even
|
||||
#! if the quotation consumes items on the stack.
|
||||
\ serving-html swons (show) ;
|
||||
[ serving-html ] swap append (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 ;
|
||||
store-current-show redirect-to-here
|
||||
with-scope exit-continuation get continue ;
|
||||
|
||||
: show-final ( quot -- namespace )
|
||||
#! Similar to 'show', except the quotation does not receive the URL
|
||||
|
@ -248,45 +100,24 @@ SYMBOL: callback-cc
|
|||
#! 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) ;
|
||||
#! 'quot' has stack effect ( -- ).
|
||||
[ serving-html ] swap append (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* ;
|
||||
SYMBOL: root-callback
|
||||
|
||||
: 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 <resume>
|
||||
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 , \ <resume> , callback-cc get ,
|
||||
\ continue-with ,
|
||||
] [ ] make ;
|
||||
#! httpd responder that handles the root continuation request.
|
||||
#! The requests for actual continuation are processed by the
|
||||
#! 'callback-responder'.
|
||||
[
|
||||
[ f post-refresh-get? set <request> request set root-callback get call ] with-scope
|
||||
exit-continuation get continue
|
||||
] with-exit-continuation drop ;
|
||||
|
||||
: quot-url ( quot -- url )
|
||||
callback-quot expirable register-continuation id>url ;
|
||||
current-show get [ continue-with ] curry curry t register-callback ;
|
||||
|
||||
: quot-href ( text quot -- )
|
||||
#! Write to standard output an HTML HREF where the href,
|
||||
|
@ -296,27 +127,17 @@ SYMBOL: root-continuation
|
|||
#! stack.
|
||||
<a quot-url =href a> write </a> ;
|
||||
|
||||
: init-session-namespace ( <resume> -- )
|
||||
#! 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
|
||||
root-callback set
|
||||
] make-responder ;
|
||||
|
||||
: simple-page ( title quot -- )
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
USING: cont-responder io kernel namespaces sequences xml ;
|
||||
USING: httpd io kernel namespaces sequences xml ;
|
||||
|
||||
SYMBOL: darcs-directory
|
||||
|
||||
|
@ -53,4 +53,4 @@ SYMBOL: rss-feed-description
|
|||
|
||||
: darcs-rss-feed darcs-changelog changelog>rss-feed print ;
|
||||
|
||||
"darcs" [ darcs-rss-feed ] install-cont-responder
|
||||
"darcs" [ darcs-rss-feed ] add-simple-responder
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
! Copyright (C) 2004, 2005 Slava Pestov.
|
||||
! See http://factor.sf.net/license.txt for BSD license.
|
||||
! Copyright (C) 2004, 2006 Slava Pestov.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
IN: httpd
|
||||
USING: io browser-responder cont-responder file-responder
|
||||
help-responder inspect-responder kernel namespaces prettyprint ;
|
||||
USING: browser-responder callback-responder file-responder
|
||||
help-responder inspect-responder io kernel namespaces
|
||||
prettyprint ;
|
||||
|
||||
#! Remove all existing responders, and create a blank
|
||||
#! responder table.
|
||||
|
@ -10,30 +11,32 @@ global [
|
|||
H{ } clone responders set
|
||||
|
||||
! 404 error message pages are served by this guy
|
||||
"404" [ no-such-responder ] install-cont-responder
|
||||
"404" [ no-such-responder ] add-simple-responder
|
||||
|
||||
! Online help browsing
|
||||
"help" [ help-responder ] install-cont-responder
|
||||
"help" [ help-responder ] add-simple-responder
|
||||
|
||||
! Used by other responders
|
||||
"callback" [ callback-responder ] add-simple-responder
|
||||
|
||||
! Javascript source used by ajax libraries
|
||||
"javascript" [
|
||||
"resources" [
|
||||
[
|
||||
"contrib/httpd/javascript/" resource-path
|
||||
"doc-root" set
|
||||
"" resource-path "doc-root" set
|
||||
file-responder
|
||||
] with-scope
|
||||
] install-cont-responder
|
||||
] add-simple-responder
|
||||
|
||||
! Global variables
|
||||
"inspector" [ inspect-responder ] install-cont-responder
|
||||
"inspector" [ inspect-responder ] add-simple-responder
|
||||
|
||||
! Servers Factor word definitions from the image.
|
||||
"browser" [ browser-responder ] install-cont-responder
|
||||
"browser" [ browser-responder ] add-simple-responder
|
||||
|
||||
! Serves files from a directory stored in the "doc-root"
|
||||
! variable. You can set the variable in the global namespace,
|
||||
! or inside the responder.
|
||||
"file" [ file-responder ] install-cont-responder
|
||||
"file" [ file-responder ] add-simple-responder
|
||||
|
||||
! The root directory is served by...
|
||||
"file" set-default-responder
|
||||
|
|
|
@ -24,11 +24,11 @@
|
|||
! Simple test applications
|
||||
IN: cont-examples
|
||||
USE: cont-responder
|
||||
USE: hashtables
|
||||
USE: html
|
||||
USE: kernel
|
||||
USE: io
|
||||
USE: html
|
||||
USE: lists
|
||||
USE: strings
|
||||
USE: math
|
||||
USE: namespaces
|
||||
|
@ -40,24 +40,24 @@ USE: sequences
|
|||
#! Display a page with some text to test the cont-responder.
|
||||
#! The page has a link to the 'next' continuation.
|
||||
[
|
||||
<h1> over write </h1>
|
||||
swap [
|
||||
<a =href a> "Next" write </a>
|
||||
] html-document
|
||||
] show drop drop ;
|
||||
] show 2drop ;
|
||||
|
||||
: display-get-name-page ( -- name )
|
||||
#! Display a page prompting for input of a name and return that name.
|
||||
[
|
||||
"Enter your name" [
|
||||
<h1> swap write </h1>
|
||||
<form "post" =method =action form>
|
||||
"Name: " write
|
||||
<input "text" =type "name" =name "20" =size input/>
|
||||
<input "submit" =type "Ok" =value input/>
|
||||
</form>
|
||||
] html-document
|
||||
] show [
|
||||
"name" get
|
||||
] bind ;
|
||||
] show "name" swap hash ;
|
||||
|
||||
: test-cont-responder ( - )
|
||||
#! Test the cont-responder responder by displaying a few pages in a row.
|
||||
|
@ -67,22 +67,21 @@ USE: sequences
|
|||
|
||||
: test-cont-responder2 ( - )
|
||||
#! Test the cont-responder responder by displaying a few pages in a loop.
|
||||
[ "one" "two" "three" "four" ] [ display-page [ .s ] string-out display-page ] each
|
||||
[ "one" "two" "three" "four" ] [ display-page ] each
|
||||
"Done!" display-page ;
|
||||
|
||||
: test-cont-responder3 ( - )
|
||||
#! Test the quot-href word by displaying a menu of the current
|
||||
#! test words. Note that we drop the 'url' argument to the show
|
||||
#! quotation as we don't link to a 'next' page.
|
||||
#! test words. Note that we use show-final as we don't link to a 'next' page.
|
||||
[
|
||||
drop
|
||||
"Menu" [
|
||||
<h1> "Menu" write </h1>
|
||||
<ol>
|
||||
<li> "Test responder1" [ test-cont-responder ] quot-href </li>
|
||||
<li> "Test responder2" [ [ .s ] string-out display-page test-cont-responder2 [ .s ] string-out display-page ] quot-href </li>
|
||||
<li> "Test responder2" [ test-cont-responder2 ] quot-href </li>
|
||||
</ol>
|
||||
] html-document
|
||||
] show drop ;
|
||||
] show-final ;
|
||||
|
||||
: counter-example ( count - )
|
||||
#! Display a counter which can be incremented or decremented
|
||||
|
@ -119,6 +118,6 @@ USE: sequences
|
|||
! Install the examples
|
||||
"counter1" [ drop 0 counter-example ] install-cont-responder
|
||||
"counter2" [ drop counter-example2 ] install-cont-responder
|
||||
"test1" [ drop test-cont-responder ] install-cont-responder
|
||||
"test1" [ test-cont-responder ] install-cont-responder
|
||||
"test2" [ drop test-cont-responder2 ] install-cont-responder
|
||||
"test3" [ drop test-cont-responder3 ] install-cont-responder
|
||||
|
|
|
@ -1,113 +0,0 @@
|
|||
! cont-testing
|
||||
!
|
||||
! 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.
|
||||
!
|
||||
! Words for testing continuation based responders at the console
|
||||
! prompt.
|
||||
!
|
||||
! To start a 'test' session use '<cont-test-state>' to push the
|
||||
! continuation responder state on the stack.
|
||||
!
|
||||
! Then use 'test-cont-function' to call a continuation responder word.
|
||||
! All output will go to the console. From this output you will see
|
||||
! links that you can 'visit' by doing a simulated click. Use the
|
||||
! 'test-cont-click' function by passing the state, the 'id' of the click
|
||||
! continuation, and 'f' or a hashtable containing the post data. The output
|
||||
! from this will be displayed.
|
||||
!
|
||||
! eg.
|
||||
! <cont-test-state> [ test-cont-responder ] test-cont-function
|
||||
! => HTTP/1.1 302 Document Moved
|
||||
! Location: ?id=8506502852110820
|
||||
! Content-Length: 0
|
||||
! Content-Type: text/plain
|
||||
!
|
||||
! "8506502852110820" f test-cont-click
|
||||
! => HTTP/1.0 200 Document follows
|
||||
! Content-Type: text/html
|
||||
!
|
||||
! <html><head><title>Page one</title></head><body>
|
||||
! <h1>Page one</h1><a href='?id=5431597582800278'>Next</a>
|
||||
! </body></html>
|
||||
!
|
||||
! "5431597582800278" f test-cont-click
|
||||
! => HTTP/1.1 302 Document Moved
|
||||
! Location: ?id=7944183606904129
|
||||
! Content-Length: 0
|
||||
! Content-Type: text/plain
|
||||
!
|
||||
! "7944183606904129" f test-cont-click
|
||||
! => HTTP/1.0 200 Document follows
|
||||
! Content-Type: text/html
|
||||
!
|
||||
! <html><head><title>Enter your name</title></head>
|
||||
! <body><h1>Enter your name</h1>
|
||||
! <form method='post' action='?id=8503790719833723'>
|
||||
! Name: <input type='text' name='name'size='20'>
|
||||
! <input type='submit' value='Ok'>
|
||||
! </form></body></html>
|
||||
!
|
||||
! "8503790719833723" [ [[ "name" "Chris" ]] ] alist>hash test-cont-click
|
||||
! => HTTP/1.1 302 Document Moved
|
||||
! Location: ?id=8879727708050260
|
||||
! Content-Length: 0
|
||||
! Content-Type: text/plain
|
||||
!
|
||||
! "8879727708050260" f test-cont-click
|
||||
! => HTTP/1.0 200 Document follows
|
||||
! Content-Type: text/html
|
||||
!
|
||||
! <html><head><title>Hello Chris</title></head>
|
||||
! <body><h1>Hello Chris</h1>
|
||||
! <a href='?id=0937854264503953'>Next</a>
|
||||
! </body></html>
|
||||
!
|
||||
! etc.
|
||||
IN: cont-responder
|
||||
USE: namespaces
|
||||
USE: kernel
|
||||
USE: io
|
||||
|
||||
: <cont-test-state> ( -- <state> )
|
||||
#! Create a namespace holding data required
|
||||
#! for testing continuation based responder functions
|
||||
#! at the interpreter console.
|
||||
[
|
||||
reset-continuation-table
|
||||
init-session-namespace
|
||||
] make-hash ;
|
||||
|
||||
: test-cont-function ( <state> quot -- <state> )
|
||||
#! Call a continuation responder function with required
|
||||
#! plumbing set up so output is displayed to the console.
|
||||
swap dup >r [
|
||||
[ call ] with-exit-continuation
|
||||
] bind write drop r> ;
|
||||
|
||||
: test-cont-click ( <state> id data -- <state> )
|
||||
#! Test function to 'click' a continuation with the given
|
||||
#! 'id' and post data. Display the results on the console.
|
||||
rot dup >r [
|
||||
[ swap resume-continuation ] with-exit-continuation
|
||||
] bind write 2drop r> ;
|
|
@ -1,217 +0,0 @@
|
|||
! 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.
|
||||
!
|
||||
! An httpd responder that allows executing simple definitions.
|
||||
!
|
||||
IN: eval-responder
|
||||
USE: html
|
||||
USE: cont-responder
|
||||
USE: kernel
|
||||
USE: namespaces
|
||||
USE: io
|
||||
USE: parser
|
||||
USE: lists
|
||||
USE: errors
|
||||
USE: strings
|
||||
USE: prettyprint
|
||||
USE: words
|
||||
USE: vectors
|
||||
USE: sequences
|
||||
USE: hashtables
|
||||
|
||||
: <evaluator> ( stack msg history -- )
|
||||
#! Create an 'evaluator' object that holds
|
||||
#! the current stack, output and history for
|
||||
#! do-eval.
|
||||
[
|
||||
"history" set
|
||||
"output" set
|
||||
"stack" set
|
||||
] make-hash ;
|
||||
|
||||
: display-eval-form ( url -- )
|
||||
#! Display the components for allowing entry of
|
||||
#! factor words to be evaluated.
|
||||
<form "main" =name "post" =method =action form>
|
||||
[
|
||||
[
|
||||
<textarea "eval" =name "10" =rows "40" =cols textarea>
|
||||
"" write
|
||||
</textarea>
|
||||
]
|
||||
[
|
||||
<input "submit" =type "Evaluate" =value "e" =accesskey input/>
|
||||
]
|
||||
] vertical-layout
|
||||
</form>
|
||||
"<script language='javascript'>document.forms.main.eval.focus()</script>" write ;
|
||||
|
||||
: escape-quotes ( string -- string )
|
||||
#! Replace occurrences of single quotes with
|
||||
#! backslash quote.
|
||||
[
|
||||
[ dup H{ { CHAR: ' "\\'" } { CHAR: " "\\\"" } } hash [ % ] [ % ] ?if ] each
|
||||
] "" make ;
|
||||
|
||||
: make-eval-javascript ( string -- string )
|
||||
#! Give a string return some javascript that when
|
||||
#! executed will set the eval textarea to that string.
|
||||
[ "document.forms.main.eval.value=\"" % escape-quotes % "\"" % ] "" make ;
|
||||
: write-eval-link ( string -- )
|
||||
#! Given text to evaluate, create an A HREF link which when
|
||||
#! clicked sets the eval textarea to that value.
|
||||
<a "#" =href dup make-eval-javascript =onclick a> write </a> ;
|
||||
|
||||
: display-stack ( list -- )
|
||||
#! Write out html to display the stack.
|
||||
<table "1" =border table>
|
||||
<tr> <th> "Callstack" write </th> </tr>
|
||||
[ <tr> <td> [ unparse write ] string-out write-eval-link </td> </tr> ] each
|
||||
</table> ;
|
||||
|
||||
: display-clear-history-link ( -- )
|
||||
#! Write out html to display a link that will clear
|
||||
#! the history list.
|
||||
" (" write
|
||||
"Clear" [ [ ] "history" set ] quot-href
|
||||
")" write ;
|
||||
|
||||
: display-history ( list -- )
|
||||
#! Write out html to display the history.
|
||||
<table "1" =border table>
|
||||
<tr> <th> "History" write display-clear-history-link </th> </tr>
|
||||
[ <tr> <td> write-eval-link </td> </tr> ] each
|
||||
</table> ;
|
||||
|
||||
: usages. ( word -- )
|
||||
#! Write to output the words that use the given word, one
|
||||
#! per line.
|
||||
usages [ . ] each ;
|
||||
|
||||
: html-for-word-source ( word-string -- )
|
||||
#! Return an html fragment dispaying the source
|
||||
#! of the given word.
|
||||
dup dup
|
||||
[
|
||||
"browser" "responder" set
|
||||
<table "1" =border table>
|
||||
<tr> <th "2" =colspan th> "Source" write </th> </tr>
|
||||
<tr> <td "2" =colspan td> [ [ parse ] catch [ "No such word" write ] [ car see ] if ] with-html-stream </td> </tr>
|
||||
<tr> <th> "Apropos" write </th> <th> "Usages" write </th> </tr>
|
||||
<tr> <td "top" =valign td> [ apropos ] with-html-stream </td>
|
||||
<td "top" =valign td> [ [ parse ] catch [ "No such word" write ] [ car usages. ] if ] with-html-stream </td>
|
||||
</tr>
|
||||
</table>
|
||||
] make-hash ;
|
||||
|
||||
: display-last-output ( string -- )
|
||||
#! Write out html to display the last output.
|
||||
<table "1" =border table>
|
||||
<tr> <th> "Last Output" write </th> </tr>
|
||||
<tr> <td> <pre> write </pre> </td> </tr>
|
||||
</table> ;
|
||||
|
||||
|
||||
: get-expr-to-eval ( -- string )
|
||||
#! Show a page to the user requesting the form to be
|
||||
#! evaluated. Return the form as a string. Assumes
|
||||
#! an evaluator is on the namestack.
|
||||
[
|
||||
<html>
|
||||
<head>
|
||||
<title> "Factor Evaluator" write </title>
|
||||
</head>
|
||||
<body>
|
||||
"Use Alt+E to evaluate, or press 'Evaluate'" paragraph
|
||||
[
|
||||
[ display-eval-form ]
|
||||
[ "stack" get display-stack ]
|
||||
[ "history" get display-history ]
|
||||
] horizontal-layout
|
||||
"output" get display-last-output
|
||||
</body>
|
||||
</html>
|
||||
] show [
|
||||
"eval" get
|
||||
] bind ;
|
||||
|
||||
: >pop> dup pop* ;
|
||||
|
||||
: infra ( list quot -- list )
|
||||
#! Call the quotation using 'list' as the datastack
|
||||
#! return the result datastack as a list.
|
||||
datastack >r
|
||||
swap >vector tuck push
|
||||
set-datastack call datastack >list
|
||||
r> >pop> >pop> tuck push set-datastack ;
|
||||
|
||||
: do-eval ( list string -- list )
|
||||
#! Evaluate the expression in 'string' using 'list' as
|
||||
#! the datastack. Return the resulting stack as a list.
|
||||
parse infra ;
|
||||
|
||||
: do-eval-to-string ( list string -- list string )
|
||||
#! Evaluate expression using 'list' as the current callstack.
|
||||
#! All output should go to a string which is returned on the
|
||||
#! callstack along with the resulting datastack as a list.
|
||||
[
|
||||
"browser" "responder" set
|
||||
1024 <sbuf> dup >r <html-stream> [
|
||||
do-eval
|
||||
] with-stream r> >string
|
||||
] with-scope ;
|
||||
|
||||
: forever ( quot -- )
|
||||
#! The code is evaluated in an infinite loop. Typically, a
|
||||
#! continuation is used to escape the infinite loop.
|
||||
#!
|
||||
#! This combinator will not compile.
|
||||
dup slip forever ;
|
||||
|
||||
: cons@ ( value name -- )
|
||||
#! Get the value of the variable named by 'name'
|
||||
#! from the current namespace and cons 'value' to its
|
||||
#! current value.
|
||||
dup get rot swons swap set ;
|
||||
|
||||
: run-eval-requester ( evaluator -- )
|
||||
#! Enter a loop request an expression to
|
||||
#! evaluate, and displaying the results.
|
||||
[
|
||||
[
|
||||
get-expr-to-eval dup "history" cons@
|
||||
"stack" get swap do-eval-to-string
|
||||
"output" set "stack" set
|
||||
] forever
|
||||
] bind ;
|
||||
|
||||
: eval-responder ( evaluator -- )
|
||||
#! Run an eval-responder using the given evaluation details.
|
||||
[
|
||||
[
|
||||
run-eval-requester
|
||||
] catch
|
||||
dup [ show-message-page ] [ drop ] if
|
||||
] forever ;
|
||||
|
||||
"eval" [ [ ] "None" [ ] <evaluator> eval-responder ] install-cont-responder
|
|
@ -6,6 +6,4 @@ USING: words kernel parser sequences io compiler ;
|
|||
{
|
||||
"cont-examples"
|
||||
"cont-numbers-game"
|
||||
"eval-responder"
|
||||
"cont-testing"
|
||||
} [ "/contrib/httpd/examples/" swap ".factor" append3 run-resource ] each
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
! Copyright (C) 2004,2005 Slava Pestov.
|
||||
! See http://factor.sf.net/license.txt for BSD license.
|
||||
! Copyright (C) 2004, 2006 Slava Pestov.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
IN: file-responder
|
||||
USING: cont-responder html httpd io kernel lists math namespaces
|
||||
parser sequences strings ;
|
||||
USING: embedded errors html httpd io kernel math namespaces parser
|
||||
sequences strings ;
|
||||
|
||||
: serving-path ( filename -- filename )
|
||||
[ "" ] unless* "doc-root" get swap append ;
|
||||
|
@ -20,12 +20,19 @@ parser sequences strings ;
|
|||
<file-reader> stdio get stream-copy
|
||||
] if ;
|
||||
|
||||
SYMBOL: page
|
||||
|
||||
: run-page ( filename -- )
|
||||
dup
|
||||
[ [ dup page set run-embedded-file ] with-scope ] try
|
||||
drop ;
|
||||
|
||||
: include-page ( filename -- )
|
||||
"doc-root" get swap path+ run-page ;
|
||||
|
||||
: serve-file ( filename -- )
|
||||
dup mime-type dup "application/x-factor-server-page" = [
|
||||
drop run-file
|
||||
] [
|
||||
serve-static
|
||||
] if ;
|
||||
dup mime-type dup "application/x-factor-server-page" =
|
||||
[ drop serving-html run-page ] [ serve-static ] if ;
|
||||
|
||||
: list-directory ( directory -- )
|
||||
serving-html
|
||||
|
@ -35,13 +42,15 @@ parser sequences strings ;
|
|||
"request" get [ dup log-message directory. ] simple-html-document
|
||||
] if ;
|
||||
|
||||
: find-index ( filename -- path )
|
||||
{ "index.html" "index.fhtml" }
|
||||
[ dupd path+ exists? ] find nip
|
||||
dup [ path+ ] [ nip ] if ;
|
||||
|
||||
: serve-directory ( filename -- )
|
||||
dup "/" tail? [
|
||||
dup "index.html" append dup exists? [
|
||||
nip serve-file
|
||||
] [
|
||||
drop list-directory
|
||||
] if
|
||||
dup find-index
|
||||
[ serve-file ] [ list-directory ] ?if
|
||||
] [
|
||||
drop directory-no/
|
||||
] if ;
|
||||
|
@ -50,14 +59,12 @@ parser sequences strings ;
|
|||
dup directory? [ serve-directory ] [ serve-file ] if ;
|
||||
|
||||
: file-responder ( -- )
|
||||
[
|
||||
"doc-root" get [
|
||||
"argument" get serving-path dup exists? [
|
||||
serve-object
|
||||
] [
|
||||
drop "404 not found" httpd-error
|
||||
] if
|
||||
"doc-root" get [
|
||||
"argument" get serving-path dup exists? [
|
||||
serve-object
|
||||
] [
|
||||
"404 doc-root not set" httpd-error
|
||||
drop "404 not found" httpd-error
|
||||
] if
|
||||
] (show-final) ;
|
||||
] [
|
||||
"404 doc-root not set" httpd-error
|
||||
] if ;
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
! Copyright (C) 2006 Slava Pestov.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
IN: help-responder
|
||||
USING: cont-responder hashtables help html kernel namespaces
|
||||
sequences ;
|
||||
USING: hashtables help html httpd io kernel namespaces sequences ;
|
||||
|
||||
: help-responder ( filename -- )
|
||||
[
|
||||
"topic" "query" get hash
|
||||
dup empty? [ drop "handbook" ] when
|
||||
dup article-title
|
||||
[ [ (help) ] with-html-stream ] html-document
|
||||
] show-final ;
|
||||
: help-topic
|
||||
"topic" query-param dup empty? [ drop "handbook" ] when ;
|
||||
|
||||
: help-responder ( -- )
|
||||
serving-html
|
||||
help-topic dup article-title [
|
||||
[ help ] with-html-stream
|
||||
] html-document ;
|
||||
|
|
|
@ -1,32 +1,11 @@
|
|||
! cont-html v0.6
|
||||
!
|
||||
! 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.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
|
||||
IN: html
|
||||
USE: prettyprint
|
||||
USE: strings
|
||||
USE: lists
|
||||
USE: kernel
|
||||
USE: io
|
||||
USE: namespaces
|
||||
|
@ -86,7 +65,7 @@ SYMBOL: html
|
|||
: def-for-html-word-<foo> ( name -- )
|
||||
#! Return the name and code for the <foo> patterned
|
||||
#! word.
|
||||
dup <foo> swap [ <foo> write-html ] cons html-word
|
||||
dup <foo> swap [ <foo> write-html ] curry html-word
|
||||
define-open ;
|
||||
|
||||
: <foo "<" swap append ;
|
||||
|
@ -94,7 +73,7 @@ SYMBOL: html
|
|||
: def-for-html-word-<foo ( name -- )
|
||||
#! Return the name and code for the <foo patterned
|
||||
#! word.
|
||||
<foo dup [ write-html ] cons html-word drop ;
|
||||
<foo dup [ write-html ] curry html-word drop ;
|
||||
|
||||
: foo> ">" append ;
|
||||
|
||||
|
@ -108,14 +87,14 @@ SYMBOL: html
|
|||
: def-for-html-word-</foo> ( name -- )
|
||||
#! Return the name and code for the </foo> patterned
|
||||
#! word.
|
||||
</foo> dup [ write-html ] cons html-word define-close ;
|
||||
</foo> dup [ write-html ] curry html-word define-close ;
|
||||
|
||||
: <foo/> [ "<" % % "/>" % ] "" make ;
|
||||
|
||||
: def-for-html-word-<foo/> ( name -- )
|
||||
#! Return the name and code for the <foo/> patterned
|
||||
#! word.
|
||||
dup <foo/> swap [ <foo/> write-html ] cons html-word drop ;
|
||||
dup <foo/> swap [ <foo/> write-html ] curry html-word drop ;
|
||||
|
||||
: foo/> "/>" append ;
|
||||
|
||||
|
@ -172,5 +151,5 @@ SYMBOL: html
|
|||
"size" "href" "class" "border" "rows" "cols"
|
||||
"id" "onclick" "style" "valign" "accesskey"
|
||||
"src" "language" "colspan" "onchange" "rel"
|
||||
"width"
|
||||
"width" "selected"
|
||||
] [ define-attribute-word ] each
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
! Copyright (C) 2004, 2006 Slava Pestov.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: cont-responder generic hashtables help http inspector io
|
||||
kernel lists prototype-js math namespaces sequences strings
|
||||
styles words xml ;
|
||||
USING: callback-responder generic hashtables help http inspector
|
||||
io kernel math namespaces prototype-js sequences strings styles
|
||||
words xml ;
|
||||
IN: html
|
||||
|
||||
: hex-color, ( triplet -- )
|
||||
|
@ -18,9 +18,9 @@ IN: html
|
|||
: style-css, ( flag -- )
|
||||
dup
|
||||
{ italic bold-italic } member?
|
||||
[ "font-style: italic; " % ] when
|
||||
"font-style: " % "italic" "normal" ? % "; " %
|
||||
{ bold bold-italic } member?
|
||||
[ "font-weight: bold; " % ] when ;
|
||||
"font-weight: " % "bold" "normal" ? % "; " % ;
|
||||
|
||||
: size-css, ( size -- )
|
||||
"font-size: " % # "pt; " % ;
|
||||
|
@ -81,23 +81,6 @@ IN: html
|
|||
<div =style div> call </div>
|
||||
] if ;
|
||||
|
||||
: resolve-file-link ( path -- link )
|
||||
#! The file responder needs relative links not absolute
|
||||
#! links.
|
||||
"doc-root" get [
|
||||
?head [ "/" ?head drop ] when
|
||||
] when* "/" ?tail drop ;
|
||||
|
||||
: file-link-href ( path -- href )
|
||||
[ "/" % resolve-file-link url-encode % ] "" make ;
|
||||
|
||||
: file-link-tag ( style quot -- )
|
||||
over file swap hash [
|
||||
<a file-link-href =href a> call </a>
|
||||
] [
|
||||
call
|
||||
] if* ;
|
||||
|
||||
: do-escaping ( string style -- string )
|
||||
html swap hash [ chars>entities ] unless ;
|
||||
|
||||
|
@ -117,6 +100,17 @@ M: link browser-link-href
|
|||
"/responder/help/" swap "topic" associate build-url
|
||||
] if ;
|
||||
|
||||
: resolve-file-link ( path -- link )
|
||||
#! The file responder needs relative links not absolute
|
||||
#! links.
|
||||
"doc-root" get [
|
||||
?head [ "/" ?head drop ] when
|
||||
] when* "/" ?tail drop ;
|
||||
|
||||
M: pathname browser-link-href
|
||||
pathname-string
|
||||
"/" swap resolve-file-link url-encode append ;
|
||||
|
||||
: object-link-tag ( style quot -- )
|
||||
presented pick hash browser-link-href
|
||||
[ <a =href a> call </a> ] [ call ] if* ;
|
||||
|
@ -139,31 +133,30 @@ M: html-stream stream-write1 ( char stream -- )
|
|||
M: html-stream stream-write ( str stream -- )
|
||||
>r chars>entities r> delegate-write ;
|
||||
|
||||
: with-html-style ( quot style stream -- )
|
||||
[ [ swap span-tag ] object-link-tag ] with-stream* ; inline
|
||||
|
||||
M: html-stream with-stream-style ( quot style stream -- )
|
||||
[ drop call ] -rot with-html-style ;
|
||||
|
||||
M: html-stream stream-format ( str style stream -- )
|
||||
[
|
||||
[
|
||||
[
|
||||
[
|
||||
do-escaping stdio get delegate-write
|
||||
] span-tag
|
||||
] file-link-tag
|
||||
] object-link-tag
|
||||
] with-stream* ;
|
||||
[ do-escaping stdio get delegate-write ] -rot
|
||||
with-html-style ;
|
||||
|
||||
: with-html-stream ( quot -- )
|
||||
stdio get <html-stream> swap with-stream* ;
|
||||
|
||||
: make-outliner-quot
|
||||
[
|
||||
<div "padding-left:10px;" =style div>
|
||||
<div "padding-left: 20px; " =style div>
|
||||
with-html-stream
|
||||
</div>
|
||||
] curry [ , \ show-final , ] [ ] make ;
|
||||
] curry ;
|
||||
|
||||
: html-outliner ( caption contents -- )
|
||||
"+ " get-random-id dup >r
|
||||
rot make-outliner-quot updating-anchor call
|
||||
<span r> =id span> </span> ;
|
||||
<span r> =id "display: none; " =style span> </span> ;
|
||||
|
||||
: outliner-tag ( style quot -- )
|
||||
outline pick hash [ html-outliner ] [ call ] if* ;
|
||||
|
@ -179,6 +172,31 @@ M: html-stream with-nested-stream ( quot style stream -- )
|
|||
] outliner-tag
|
||||
] with-stream* ;
|
||||
|
||||
: border-spacing-css,
|
||||
"padding: " % first2 max 2 /i # "px; " % ;
|
||||
|
||||
: table-style ( style -- str )
|
||||
[
|
||||
H{
|
||||
{ table-border [ border-css, ] }
|
||||
{ table-gap [ border-spacing-css, ] }
|
||||
} hash-apply
|
||||
] "" make ;
|
||||
|
||||
: table-attrs ( style -- )
|
||||
table-style " border-collapse: collapse;" append =style ;
|
||||
|
||||
M: html-stream with-stream-table ( grid quot style stream -- )
|
||||
[
|
||||
<table dup table-attrs table> rot [
|
||||
<tr> [
|
||||
<td "top" =valign over table-style =style td>
|
||||
pick H{ } swap with-nesting
|
||||
</td>
|
||||
] each </tr>
|
||||
] each 2drop </table>
|
||||
] with-stream* ;
|
||||
|
||||
M: html-stream stream-terpri [ <br/> ] with-stream* ;
|
||||
|
||||
: default-css ( -- )
|
||||
|
@ -186,7 +204,7 @@ M: html-stream stream-terpri [ <br/> ] with-stream* ;
|
|||
"A:link { text-decoration: none; color: black; }" print
|
||||
"A:visited { text-decoration: none; color: black; }" print
|
||||
"A:active { text-decoration: none; color: black; }" print
|
||||
"A:hover, A:hover { text-decoration: none; color: black; }" print
|
||||
"A:hover, A:hover { text-decoration: underline; color: black; }" print
|
||||
</style> ;
|
||||
|
||||
: xhtml-preamble
|
||||
|
@ -195,7 +213,7 @@ M: html-stream stream-terpri [ <br/> ] with-stream* ;
|
|||
|
||||
: html-document ( title quot -- )
|
||||
xhtml-preamble
|
||||
swap chars>entities dup
|
||||
swap chars>entities
|
||||
<html>
|
||||
<head>
|
||||
<title> write </title>
|
||||
|
@ -203,7 +221,6 @@ M: html-stream stream-terpri [ <br/> ] with-stream* ;
|
|||
include-prototype-js
|
||||
</head>
|
||||
<body>
|
||||
<h1> write </h1>
|
||||
call
|
||||
</body>
|
||||
</html> ;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
! Copyright (C) 2003, 2005 Slava Pestov
|
||||
IN: http
|
||||
USING: errors hashtables io kernel lists math namespaces parser
|
||||
USING: errors hashtables io kernel math namespaces parser
|
||||
sequences strings ;
|
||||
|
||||
: header-line ( line -- )
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
! Copyright (C) 2003, 2005 Slava Pestov.
|
||||
! See http://factor.sf.net/license.txt for BSD license.
|
||||
IN: httpd
|
||||
USING: errors hashtables kernel lists namespaces io strings
|
||||
USING: errors hashtables kernel namespaces io strings
|
||||
threads http sequences ;
|
||||
|
||||
: (url>path) ( uri -- path )
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
! Copyright (C) 2006 Slava Pestov.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
IN: inspect-responder
|
||||
USING: cont-responder generic hashtables help html inspector
|
||||
kernel lists namespaces sequences ;
|
||||
USING: callback-responder generic hashtables help html httpd
|
||||
inspector kernel namespaces sequences ;
|
||||
|
||||
! Mini object inspector
|
||||
: http-inspect ( obj -- )
|
||||
"Inspecting " over summary append
|
||||
[ describe ] simple-html-document ;
|
||||
dup summary [ describe ] simple-html-document ;
|
||||
|
||||
M: general-t browser-link-href
|
||||
[ [ http-inspect ] show-final ] curry quot-url ;
|
||||
[ http-inspect ] curry t register-html-callback ;
|
||||
|
||||
: inspect-responder ( url -- )
|
||||
[ global http-inspect ] show-final ;
|
||||
serving-html global http-inspect ;
|
||||
|
|
|
@ -1,28 +1,30 @@
|
|||
IN: scratchpad
|
||||
USING: words kernel parser sequences io compiler ;
|
||||
USING: io ;
|
||||
|
||||
{
|
||||
"mime"
|
||||
"xml"
|
||||
"http-common"
|
||||
"html-tags"
|
||||
"responder"
|
||||
"httpd"
|
||||
"cont-responder"
|
||||
"prototype-js"
|
||||
"html"
|
||||
"file-responder"
|
||||
"help-responder"
|
||||
"inspect-responder"
|
||||
"browser-responder"
|
||||
"default-responders"
|
||||
"http-client"
|
||||
REQUIRES: embedded ;
|
||||
|
||||
"test/html"
|
||||
"test/http-client"
|
||||
"test/httpd"
|
||||
"test/url-encoding"
|
||||
} [ "/contrib/httpd/" swap ".factor" append3 run-resource ] each
|
||||
PROVIDE: httpd {
|
||||
"mime.factor"
|
||||
"xml.factor"
|
||||
"http-common.factor"
|
||||
"html-tags.factor"
|
||||
"responder.factor"
|
||||
"httpd.factor"
|
||||
"callback-responder.factor"
|
||||
"cont-responder.factor"
|
||||
"prototype-js.factor"
|
||||
"html.factor"
|
||||
"file-responder.factor"
|
||||
"help-responder.factor"
|
||||
"inspect-responder.factor"
|
||||
"browser-responder.factor"
|
||||
"default-responders.factor"
|
||||
"http-client.factor"
|
||||
} {
|
||||
"test/html.factor"
|
||||
"test/http-client.factor"
|
||||
"test/httpd.factor"
|
||||
"test/url-encoding.factor"
|
||||
} ;
|
||||
|
||||
"To start the HTTP server, issue the following command in the listener:" print
|
||||
" USE: httpd" print
|
||||
|
|
|
@ -28,7 +28,7 @@ H{
|
|||
{ "gz" "application/octet-stream" }
|
||||
|
||||
{ "pdf" "application/pdf" }
|
||||
|
||||
|
||||
{ "factor" "text/plain" }
|
||||
{ "factsp" "application/x-factor-server-page" }
|
||||
{ "fhtml" "application/x-factor-server-page" }
|
||||
} "mime-types" global set-hash
|
||||
|
|
|
@ -5,23 +5,35 @@
|
|||
! For information and license details for protoype
|
||||
! see http://prototype.conio.net
|
||||
IN: prototype-js
|
||||
USING: io httpd cont-responder html kernel lists namespaces strings ;
|
||||
USING: callback-responder html httpd io kernel namespaces
|
||||
strings ;
|
||||
|
||||
: include-prototype-js ( -- )
|
||||
#! Write out the HTML script tag to include the prototype
|
||||
#! javascript library.
|
||||
<script "text/javascript" =type "/responder/javascript/prototype.js" =src script>
|
||||
<script "text/javascript" =type "/responder/resources/contrib/httpd/javascript/prototype.js"
|
||||
=src script>
|
||||
</script> ;
|
||||
|
||||
: updating-javascript ( id quot -- string )
|
||||
#! Return the javascript code to perform the updating
|
||||
#! ajax call.
|
||||
quot-url swap
|
||||
t register-html-callback swap
|
||||
[ "new Ajax.Updater(\"" % % "\",\"" % % "\", { method: \"get\" });" % ] "" make ;
|
||||
|
||||
: toggle-javascript ( string id -- string )
|
||||
[
|
||||
"if(Element.visible(\"" % dup % "\"))" %
|
||||
"Element.hide(\"" % dup % "\");" %
|
||||
"else {" %
|
||||
swap %
|
||||
" Element.show(\"" % % "\"); }" %
|
||||
] "" make ;
|
||||
|
||||
: updating-anchor ( text id quot -- )
|
||||
#! Write the HTML for an anchor that when clicked will
|
||||
#! call the given quotation on the server. The output generated
|
||||
#! from that quotation will replace the DOM element on the page with
|
||||
#! the given id. The 'text' is the anchor text.
|
||||
<a updating-javascript =onclick a> write </a> ;
|
||||
over >r updating-javascript r> toggle-javascript
|
||||
<a =onclick a> write </a> ;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
! Copyright (C) 2004, 2005 Slava Pestov.
|
||||
! See http://factor.sf.net/license.txt for BSD license.
|
||||
IN: httpd
|
||||
USING: arrays hashtables http kernel lists math namespaces
|
||||
parser sequences io strings ;
|
||||
USING: arrays hashtables html http io kernel math namespaces
|
||||
parser sequences strings ;
|
||||
|
||||
! Variables
|
||||
SYMBOL: vhosts
|
||||
|
@ -15,7 +15,7 @@ SYMBOL: responders
|
|||
"HTTP/1.0 " write print print-header ;
|
||||
|
||||
: error-body ( error -- body )
|
||||
"<html><body><h1>" swap "</h1></body></html>" append3 print ;
|
||||
<html> <body> <h1> write </h1> </body> </html> ;
|
||||
|
||||
: error-head ( error -- )
|
||||
dup log-error
|
||||
|
@ -91,10 +91,18 @@ SYMBOL: responders
|
|||
! - header -- a hashtable of headers from the user's client
|
||||
! - response -- a hashtable of the POST request response
|
||||
|
||||
: query-param ( key -- value ) "query" get hash ;
|
||||
|
||||
: add-responder ( responder -- )
|
||||
#! Add a responder object to the list.
|
||||
"responder" over hash responders get set-hash ;
|
||||
|
||||
: add-simple-responder ( name quot -- )
|
||||
[
|
||||
[ drop ] swap append dup "get" set "post" set
|
||||
"responder" set
|
||||
] make-hash add-responder ;
|
||||
|
||||
: make-responder ( quot -- responder )
|
||||
[
|
||||
( url -- )
|
||||
|
|
|
@ -15,7 +15,7 @@ USING: html http io kernel namespaces styles test xml ;
|
|||
[
|
||||
[
|
||||
"/home/slava/doc/" "doc-root" set
|
||||
"/home/slava/doc/foo/bar" file-link-href
|
||||
"/home/slava/doc/foo/bar" <pathname> browser-link-href
|
||||
] with-scope
|
||||
] unit-test
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ USE: namespaces
|
|||
USE: io
|
||||
USE: test
|
||||
USE: strings
|
||||
USE: lists
|
||||
|
||||
[ "HTTP/1.0 200 OK\nContent-Length: 12\nContent-Type: text/html\n\n" ]
|
||||
[
|
||||
|
|
|
@ -1,75 +1,13 @@
|
|||
USING: arrays errors generic hashtables io kernel lists math
|
||||
USING: arrays errors generic hashtables io kernel math
|
||||
namespaces parser prettyprint sequences strings vectors words ;
|
||||
IN: xml
|
||||
|
||||
! * Simple SAX-ish parser
|
||||
|
||||
! -- Basic utility words
|
||||
|
||||
SYMBOL: code #! Source code
|
||||
SYMBOL: spot #! Current index of string
|
||||
SYMBOL: version
|
||||
SYMBOL: line
|
||||
SYMBOL: column
|
||||
|
||||
: set-code ( string -- ) ! for debugging
|
||||
code set [ spot line column ] [ 0 swap set ] each ;
|
||||
|
||||
: more? ( -- ? )
|
||||
#! Return t if spot is not at the end of code
|
||||
code get length spot get = not ;
|
||||
|
||||
: char ( -- char/f )
|
||||
more? [ spot get code get nth ] [ f ] if ;
|
||||
|
||||
: incr-spot ( -- )
|
||||
#! Increment spot.
|
||||
spot [ 1 + ] change
|
||||
char "\n\r" member? [
|
||||
0 column set
|
||||
line
|
||||
] [
|
||||
column
|
||||
] if [ 1 + ] change ;
|
||||
|
||||
: skip-until ( quot -- | quot: char -- ? )
|
||||
more? [
|
||||
char swap [ call ] keep swap [ drop ] [
|
||||
incr-spot skip-until
|
||||
] if
|
||||
] [ drop ] if ; inline
|
||||
|
||||
: take-until ( quot -- string | quot: char -- ? )
|
||||
#! Take the substring of a string starting at spot
|
||||
#! from code until the quotation given is true and
|
||||
#! advance spot to after the substring.
|
||||
spot get >r skip-until r>
|
||||
spot get code get subseq ; inline
|
||||
|
||||
: pass-blank ( -- )
|
||||
#! Advance code past any whitespace, including newlines
|
||||
[ blank? not ] skip-until ;
|
||||
|
||||
: string-matches? ( string -- ? )
|
||||
spot get dup pick length + code get subseq = ;
|
||||
|
||||
DEFER: <xml-string-error>
|
||||
: (take-until-string) ( string -- n )
|
||||
more? [
|
||||
dup string-matches? [
|
||||
drop spot get
|
||||
] [
|
||||
incr-spot (take-until-string)
|
||||
] if
|
||||
] [ "Missing closing token" <xml-string-error> throw ] if ;
|
||||
|
||||
: take-until-string ( string -- string )
|
||||
[ >r spot get r> (take-until-string) code get subseq ] keep
|
||||
length spot [ + ] change ;
|
||||
|
||||
: in-range-seq? ( number { [[ min max ]] ... } -- ? )
|
||||
[ uncons between? not ] all-with? not ;
|
||||
|
||||
! -- Error reporting
|
||||
|
||||
TUPLE: xml-error line column ;
|
||||
|
@ -111,6 +49,58 @@ M: xml-string-error error.
|
|||
dup xml-error.
|
||||
xml-string-error-string print ;
|
||||
|
||||
! -- Basic utility words
|
||||
|
||||
: set-code ( string -- ) ! for debugging
|
||||
code set [ spot line column ] [ 0 swap set ] each ;
|
||||
|
||||
: more? ( -- ? )
|
||||
#! Return t if spot is not at the end of code
|
||||
code get length spot get = not ;
|
||||
|
||||
: char ( -- char/f )
|
||||
more? [ spot get code get nth ] [ f ] if ;
|
||||
|
||||
: incr-spot ( -- )
|
||||
#! Increment spot.
|
||||
spot inc
|
||||
char "\n\r" member? [ 0 column set line ] [ column ] if
|
||||
inc ;
|
||||
|
||||
: skip-until ( quot -- | quot: char -- ? )
|
||||
more? [
|
||||
char swap [ call ] keep swap [ drop ] [
|
||||
incr-spot skip-until
|
||||
] if
|
||||
] [ drop ] if ; inline
|
||||
|
||||
: take-until ( quot -- string | quot: char -- ? )
|
||||
#! Take the substring of a string starting at spot
|
||||
#! from code until the quotation given is true and
|
||||
#! advance spot to after the substring.
|
||||
spot get >r skip-until r>
|
||||
spot get code get subseq ; inline
|
||||
|
||||
: pass-blank ( -- )
|
||||
#! Advance code past any whitespace, including newlines
|
||||
[ blank? not ] skip-until ;
|
||||
|
||||
: string-matches? ( string -- ? )
|
||||
spot get dup pick length + code get subseq = ;
|
||||
|
||||
: (take-until-string) ( string -- n )
|
||||
more? [
|
||||
dup string-matches? [
|
||||
drop spot get
|
||||
] [
|
||||
incr-spot (take-until-string)
|
||||
] if
|
||||
] [ "Missing closing token" <xml-string-error> throw ] if ;
|
||||
|
||||
: take-until-string ( string -- string )
|
||||
[ >r spot get r> (take-until-string) code get subseq ] keep
|
||||
length spot [ + ] change ;
|
||||
|
||||
! -- Parsing strings
|
||||
|
||||
: expect ( ch -- )
|
||||
|
@ -119,18 +109,20 @@ M: xml-string-error error.
|
|||
] if incr-spot ;
|
||||
|
||||
: expect-string ( string -- )
|
||||
>r spot get r> t over [ char incr-spot = and ] each [ 2drop ] [
|
||||
>r spot get r> t over [ char incr-spot = and ] each [
|
||||
2drop
|
||||
] [
|
||||
swap spot get code get subseq <expected> throw
|
||||
] if ;
|
||||
|
||||
: entities
|
||||
#! We have both directions here as a shortcut.
|
||||
H{
|
||||
{ "lt" CHAR: < }
|
||||
{ "gt" CHAR: > }
|
||||
{ "amp" CHAR: & }
|
||||
{ "apos" CHAR: ' }
|
||||
{ "quot" CHAR: " }
|
||||
{ "lt" CHAR: < }
|
||||
{ "gt" CHAR: > }
|
||||
{ "amp" CHAR: & }
|
||||
{ "apos" CHAR: ' }
|
||||
{ "quot" CHAR: " }
|
||||
{ CHAR: < "<" }
|
||||
{ CHAR: > ">" }
|
||||
{ CHAR: & "&" }
|
||||
|
@ -139,43 +131,59 @@ M: xml-string-error error.
|
|||
} ;
|
||||
|
||||
: parse-entity ( -- ch )
|
||||
incr-spot [ CHAR: ; = ] take-until incr-spot
|
||||
dup first CHAR: # = [
|
||||
1 swap tail "x" ?head 16 10 ? base>
|
||||
incr-spot [ CHAR: ; = ] take-until "#" ?head [
|
||||
"x" ?head 16 10 ? base>
|
||||
] [
|
||||
dup entities hash [ nip ] [ <no-entity> throw ] if*
|
||||
dup entities hash [ ] [ <no-entity> throw ] ?if
|
||||
] if ;
|
||||
|
||||
: (parse-text) ( vector -- vector )
|
||||
[ CHAR: & = ] take-until over push
|
||||
char CHAR: & = [
|
||||
parse-entity ch>string over push (parse-text)
|
||||
] when ;
|
||||
: parsed-ch ( buf ch -- buf ) over push incr-spot ;
|
||||
|
||||
: parse-text ( string -- string )
|
||||
[
|
||||
code set 0 spot set
|
||||
100 <vector> (parse-text) concat
|
||||
] with-scope ;
|
||||
: (parse-text) ( buf -- buf )
|
||||
{
|
||||
{ [ more? not ] [ ] }
|
||||
{ [ char CHAR: < = ] [ ] }
|
||||
{ [ char CHAR: & = ] [ parse-entity parsed-ch (parse-text) ] }
|
||||
{ [ t ] [ char parsed-ch (parse-text) ] }
|
||||
} cond ;
|
||||
|
||||
: get-text ( -- string )
|
||||
[ CHAR: < = ] take-until parse-text ;
|
||||
: parse-text ( -- string )
|
||||
SBUF" " clone (parse-text) >string ;
|
||||
|
||||
! -- Parsing tags
|
||||
|
||||
: in-range-seq? ( number { { min max } ... } -- ? )
|
||||
[ first2 between? ] contains-with? ;
|
||||
|
||||
: name-start-char? ( ch -- ? )
|
||||
dup ":_" member? swap {
|
||||
[[ CHAR: A CHAR: Z ]] [[ CHAR: a CHAR: z ]] [[ HEX: C0 HEX: D6 ]]
|
||||
[[ HEX: D8 HEX: F6 ]] [[ HEX: F8 HEX: 2FF ]] [[ HEX: 370 HEX: 37D ]]
|
||||
[[ HEX: 37F HEX: 1FFF ]] [[ HEX: 200C HEX: 200D ]] [[ HEX: 2070 HEX: 218F ]]
|
||||
[[ HEX: 2C00 HEX: 2FEF ]] [[ HEX: 3001 HEX: D7FF ]] [[ HEX: F900 HEX: FDCF ]]
|
||||
[[ HEX: FDF0 HEX: FFFD ]] [[ HEX: 10000 HEX: EFFFF ]]
|
||||
} in-range-seq? or ;
|
||||
{
|
||||
{ CHAR: : CHAR: : }
|
||||
{ CHAR: _ CHAR: _ }
|
||||
{ CHAR: A CHAR: Z }
|
||||
{ CHAR: a CHAR: z }
|
||||
{ HEX: C0 HEX: D6 }
|
||||
{ HEX: D8 HEX: F6 }
|
||||
{ HEX: F8 HEX: 2FF }
|
||||
{ HEX: 370 HEX: 37D }
|
||||
{ HEX: 37F HEX: 1FFF }
|
||||
{ HEX: 200C HEX: 200D }
|
||||
{ HEX: 2070 HEX: 218F }
|
||||
{ HEX: 2C00 HEX: 2FEF }
|
||||
{ HEX: 3001 HEX: D7FF }
|
||||
{ HEX: F900 HEX: FDCF }
|
||||
{ HEX: FDF0 HEX: FFFD }
|
||||
{ HEX: 10000 HEX: EFFFF }
|
||||
} in-range-seq? ;
|
||||
|
||||
: name-char? ( ch -- ? )
|
||||
dup name-start-char? over "-." member? or over HEX: B7 = or swap
|
||||
{ [[ CHAR: 0 CHAR: 9 ]] [[ HEX: 300 HEX: 36F ]] [[ HEX: 203F HEX: 2040 ]] }
|
||||
in-range-seq? or ;
|
||||
dup name-start-char? swap {
|
||||
{ CHAR: - CHAR: - }
|
||||
{ CHAR: . CHAR: . }
|
||||
{ CHAR: 0 CHAR: 9 }
|
||||
{ HEX: b7 HEX: b7 }
|
||||
{ HEX: 300 HEX: 36F }
|
||||
{ HEX: 203F HEX: 2040 }
|
||||
} in-range-seq? or ;
|
||||
|
||||
: parse-name ( -- name )
|
||||
char dup name-start-char? [
|
||||
|
@ -184,56 +192,70 @@ M: xml-string-error error.
|
|||
"Malformed name" <xml-string-error> throw
|
||||
] if ;
|
||||
|
||||
: parse-quot ( ch -- str )
|
||||
incr-spot [ dupd = ] take-until parse-text nip incr-spot ;
|
||||
|
||||
: parse-prop-value ( -- str )
|
||||
char dup "'\"" member? [
|
||||
parse-quot
|
||||
] [
|
||||
"Attribute lacks quote" <xml-string-error> throw
|
||||
] if ;
|
||||
|
||||
: parse-prop ( -- { name value } )
|
||||
parse-name pass-blank CHAR: = expect pass-blank
|
||||
parse-prop-value 2array pass-blank ;
|
||||
|
||||
TUPLE: opener name props ;
|
||||
TUPLE: closer name ;
|
||||
TUPLE: contained name props ;
|
||||
TUPLE: comment text ;
|
||||
TUPLE: directive text ;
|
||||
|
||||
: start-tag ( -- string ? )
|
||||
#! Outputs the name and whether this is a closing tag
|
||||
char CHAR: / = dup [ incr-spot ] when
|
||||
parse-name swap ;
|
||||
|
||||
: (middle-tag) ( list -- list )
|
||||
pass-blank char name-char? [ parse-prop swons (middle-tag) ] when ;
|
||||
: (parse-quot) ( ch buf -- buf )
|
||||
{
|
||||
{ [ more? not ] [ nip ] }
|
||||
{ [ char pick = ] [ incr-spot nip ] }
|
||||
{ [ char CHAR: & = ] [ parse-entity parsed-ch (parse-quot) ] }
|
||||
{ [ t ] [ char parsed-ch (parse-quot) ] }
|
||||
} cond ;
|
||||
|
||||
: middle-tag ( -- hash )
|
||||
f (middle-tag) alist>hash ;
|
||||
: parse-quot ( ch -- str )
|
||||
SBUF" " clone (parse-quot) >string ;
|
||||
|
||||
: end-tag ( string hash -- tag )
|
||||
pass-blank char CHAR: / = [
|
||||
<contained> incr-spot
|
||||
: parse-prop-value ( -- str )
|
||||
char dup "'\"" member? [
|
||||
incr-spot parse-quot
|
||||
] [
|
||||
<opener>
|
||||
"Attribute lacks quote" <xml-string-error> throw
|
||||
] if ;
|
||||
|
||||
: parse-prop ( -- name value )
|
||||
parse-name pass-blank CHAR: = expect pass-blank
|
||||
parse-prop-value 2array ;
|
||||
|
||||
: (middle-tag) ( seq -- seq )
|
||||
pass-blank char name-char?
|
||||
[ parse-prop over push (middle-tag) ] when ;
|
||||
|
||||
: middle-tag ( -- hash )
|
||||
V{ } clone (middle-tag) alist>hash pass-blank ;
|
||||
|
||||
: end-tag ( string hash -- tag )
|
||||
pass-blank char CHAR: / =
|
||||
[ <contained> incr-spot ] [ <opener> ] if ;
|
||||
|
||||
: skip-comment ( -- comment )
|
||||
"--" expect-string "--" take-until-string <comment> CHAR: > expect ;
|
||||
"--" expect-string
|
||||
"--" take-until-string
|
||||
<comment>
|
||||
CHAR: > expect ;
|
||||
|
||||
: cdata ( -- string )
|
||||
"[CDATA[" expect-string "]]>" take-until-string ;
|
||||
|
||||
: cdata/comment ( -- object )
|
||||
incr-spot char CHAR: - = [ skip-comment ] [ cdata ] if ;
|
||||
: directive ( -- object )
|
||||
{
|
||||
{ [ "--" string-matches? ] [ skip-comment ] }
|
||||
{ [ "[CDATA[" string-matches? ] [ cdata ] }
|
||||
{ [ t ] [ ">" take-until-string <directive> ] }
|
||||
} cond ;
|
||||
|
||||
: make-tag ( -- tag/f )
|
||||
CHAR: < expect
|
||||
char CHAR: ! = [
|
||||
cdata/comment
|
||||
incr-spot directive
|
||||
] [
|
||||
start-tag [
|
||||
<closer>
|
||||
|
@ -251,30 +273,11 @@ TUPLE: comment text ;
|
|||
"version" swap hash [ version set ] when*
|
||||
] when ;
|
||||
|
||||
: dip-ns ( quot -- )
|
||||
n> slip >n ; inline
|
||||
|
||||
: (xml-each) ( quot -- )
|
||||
get-text swap [ dip-ns ] keep
|
||||
more? [
|
||||
make-tag [ swap [ dip-ns ] keep ] when* (xml-each)
|
||||
] [ drop ] if ; inline
|
||||
|
||||
: xml-each ( string quot -- | quot: node -- )
|
||||
#! Quotation is called with each node: an opener, closer, contained,
|
||||
#! comment, or string
|
||||
#! Somewhat like SAX but vastly simplified.
|
||||
[
|
||||
swap code set
|
||||
[ spot line column ] [ 0 swap set ] each
|
||||
"1.0" version set
|
||||
get-version (xml-each)
|
||||
] with-scope ; inline
|
||||
|
||||
! * Data tree
|
||||
|
||||
TUPLE: tag name props children ;
|
||||
|
||||
! A stack of { tag children } pairs
|
||||
SYMBOL: xml-stack
|
||||
|
||||
TUPLE: mismatched open close ;
|
||||
|
@ -285,47 +288,62 @@ M: mismatched error.
|
|||
|
||||
TUPLE: unclosed tags ;
|
||||
C: unclosed ( -- unclosed )
|
||||
1 xml-stack get tail-slice [ car opener-name ] map
|
||||
1 xml-stack get tail-slice [ first opener-name ] map
|
||||
swap [ set-unclosed-tags ] keep ;
|
||||
M: unclosed error.
|
||||
"Unclosed tags" print
|
||||
"Tags: " print
|
||||
unclosed-tags [ " <" write write ">" print ] each ;
|
||||
|
||||
: push-datum ( object -- )
|
||||
xml-stack get peek cdr push ;
|
||||
: add-child ( object -- )
|
||||
xml-stack get peek second push ;
|
||||
|
||||
: push-xml-stack ( object -- )
|
||||
V{ } clone 2array xml-stack get push ;
|
||||
|
||||
GENERIC: process ( object -- )
|
||||
|
||||
M: string process push-datum ;
|
||||
M: comment process push-datum ;
|
||||
M: f process drop ;
|
||||
|
||||
M: string process add-child ;
|
||||
M: comment process add-child ;
|
||||
M: directive process add-child ;
|
||||
|
||||
M: contained process
|
||||
[ contained-name ] keep contained-props 0 <vector> <tag> push-datum ;
|
||||
[ contained-name ] keep contained-props
|
||||
V{ } clone <tag> add-child ;
|
||||
|
||||
M: opener process
|
||||
V{ } clone cons
|
||||
xml-stack get push ;
|
||||
push-xml-stack ;
|
||||
|
||||
M: closer process
|
||||
closer-name xml-stack get pop uncons
|
||||
>r [
|
||||
closer-name xml-stack get pop first2 >r [
|
||||
opener-name [
|
||||
2dup = [ 2drop ] [ swap <mismatched> throw ] if
|
||||
] keep
|
||||
] keep opener-props r> <tag> push-datum ;
|
||||
] keep opener-props r> <tag> add-child ;
|
||||
|
||||
: initialize-xml-stack ( -- )
|
||||
f V{ } clone cons unit >vector xml-stack set ;
|
||||
: init-xml-stack ( -- )
|
||||
V{ } clone xml-stack set f push-xml-stack ;
|
||||
|
||||
: xml ( string -- tag )
|
||||
: init-xml ( string -- )
|
||||
code set
|
||||
[ spot line column ] [ 0 swap set ] each
|
||||
"1.0" version set
|
||||
init-xml-stack ;
|
||||
|
||||
: (string>xml) ( -- )
|
||||
parse-text process
|
||||
more? [ make-tag process (string>xml) ] when ; inline
|
||||
|
||||
: string>xml ( string -- tag )
|
||||
#! Produces a tree of XML nodes
|
||||
[
|
||||
initialize-xml-stack
|
||||
[ process ] xml-each
|
||||
init-xml
|
||||
get-version (string>xml)
|
||||
xml-stack get
|
||||
dup length 1 = [ <unclosed> throw ] unless
|
||||
first cdr second
|
||||
first second
|
||||
] with-scope ;
|
||||
|
||||
! * Printer
|
||||
|
@ -356,16 +374,14 @@ M: tag (xml>string)
|
|||
CHAR: < ,
|
||||
dup tag-name %
|
||||
dup tag-props print-props
|
||||
dup tag-children [ "" = not ] subset empty? [
|
||||
drop "/>" %
|
||||
] [
|
||||
print-open/close
|
||||
] if ;
|
||||
dup tag-children [ empty? not ] contains?
|
||||
[ print-open/close ] [ drop "/>" % ] if ;
|
||||
|
||||
M: comment (xml>string)
|
||||
"<!--" %
|
||||
comment-text %
|
||||
"-->" % ;
|
||||
"<!--" % comment-text % "-->" % ;
|
||||
|
||||
M: object (xml>string)
|
||||
[ (xml>string) ] each ;
|
||||
|
||||
: xml-preamble
|
||||
"<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>" ;
|
||||
|
@ -374,13 +390,13 @@ M: comment (xml>string)
|
|||
[ xml-preamble % (xml>string) ] "" make ;
|
||||
|
||||
: xml-reprint ( string -- string )
|
||||
xml xml>string ;
|
||||
string>xml xml>string ;
|
||||
|
||||
! * Easy XML generation for more literal things
|
||||
! should this be rewritten?
|
||||
|
||||
: text ( string -- )
|
||||
chars>entities push-datum ;
|
||||
chars>entities add-child ;
|
||||
|
||||
: tag ( string attr-quot contents-quot -- )
|
||||
>r swap >r make-hash r> swap r>
|
||||
|
@ -391,15 +407,15 @@ M: comment (xml>string)
|
|||
: text-tag ( content name attr-quot -- ) [ text ] tag ; inline
|
||||
|
||||
: comment ( string -- )
|
||||
<comment> push-datum ;
|
||||
<comment> add-child ;
|
||||
|
||||
: make-xml ( quot -- vector )
|
||||
#! Produces a tree of XML from a quotation to generate it
|
||||
[
|
||||
initialize-xml-stack
|
||||
init-xml-stack
|
||||
call
|
||||
xml-stack get
|
||||
first cdr first
|
||||
first second first
|
||||
] with-scope ; inline
|
||||
|
||||
! * System for words specialized on tag names
|
||||
|
@ -416,14 +432,3 @@ M: process-missing error.
|
|||
>r dup tag-name r> hash* [ 2nip call ] [
|
||||
drop <process-missing> throw
|
||||
] if ;
|
||||
|
||||
: PROCESS:
|
||||
CREATE
|
||||
dup H{ } clone "xtable" set-word-prop
|
||||
dup literalize [ run-process ] cons define-compound ; parsing
|
||||
|
||||
: TAG:
|
||||
scan scan-word [
|
||||
swap "xtable" word-prop
|
||||
rot "/" split [ >r 2dup r> swap set-hash ] each 2drop
|
||||
] f ; parsing
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
! :folding=indent:collapseFolds=1:
|
||||
|
||||
! $Id$
|
||||
! Rewritten by Matthew Willis, July 2006
|
||||
!
|
||||
! Copyright (C) 2003, 2004 Mackenzie Straight.
|
||||
! 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:
|
||||
|
@ -25,25 +23,26 @@
|
|||
! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
IN: io
|
||||
USE: compiler
|
||||
USE: namespaces
|
||||
USE: kernel
|
||||
USE: win32-io-internals
|
||||
USE: win32-stream
|
||||
USE: win32-api
|
||||
USING: lazy-lists math kernel sequences test ;
|
||||
IN: lazy-examples
|
||||
|
||||
: <file-reader> <win32-file-reader> ;
|
||||
: <file-writer> <win32-file-writer> ;
|
||||
: <server> <win32-server> ;
|
||||
: naturals 0 lfrom ;
|
||||
: positves 1 lfrom ;
|
||||
: evens 0 [ 2 + ] lfrom-by ;
|
||||
: odds 1 lfrom [ 2 mod 1 = ] lsubset ;
|
||||
: powers-of-2 1 [ 2 * ] lfrom-by ;
|
||||
: ones 1 [ ] lfrom-by ;
|
||||
: squares naturals [ dup * ] lmap ;
|
||||
: first-five-squares 5 squares ltake list>array ;
|
||||
|
||||
IN: io-internals
|
||||
: divisible-by? ( a b -- bool )
|
||||
#! Return true if a is divisible by b
|
||||
mod 0 = ;
|
||||
|
||||
: io-multiplex ( timeout -- )
|
||||
#! FIXME: needs to work given a timeout
|
||||
dup -1 = [ drop INFINITE ] when cancel-timedout wait-for-io
|
||||
swap [ continue-with ] [ drop ] if* ;
|
||||
: filter-multiples ( n list - list )
|
||||
#! Given a lazy list of numbers, filter multiples of n
|
||||
swap [ divisible-by? not ] curry lsubset ;
|
||||
|
||||
: init-io ( -- )
|
||||
win32-init-stdio ;
|
||||
: primes 2 lfrom [ filter-multiples ] lapply ;
|
||||
|
||||
: first-ten-primes 10 primes ltake list>array ;
|
|
@ -0,0 +1,207 @@
|
|||
! Updated by Matthew Willis, July 2006
|
||||
!
|
||||
! 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.
|
||||
|
||||
USING: kernel sequences math vectors arrays namespaces ;
|
||||
IN: lazy-lists
|
||||
|
||||
TUPLE: promise quot forced? value ;
|
||||
|
||||
C: promise ( quot -- promise ) [ set-promise-quot ] keep ;
|
||||
|
||||
: force ( promise -- value )
|
||||
#! Force the given promise leaving the value of calling the
|
||||
#! promises quotation on the stack. Re-forcing the promise
|
||||
#! will return the same value and not recall the quotation.
|
||||
dup promise-forced? [
|
||||
dup promise-quot call over set-promise-value
|
||||
t over set-promise-forced?
|
||||
] unless
|
||||
promise-value ;
|
||||
|
||||
TUPLE: cons car cdr ;
|
||||
|
||||
: nil ( -- list )
|
||||
#! The nil lazy list.
|
||||
T{ promise f [ { } ] t { } } ;
|
||||
|
||||
: nil? ( list -- bool )
|
||||
#! Is the given lazy cons the nil value
|
||||
force { } = ;
|
||||
|
||||
: car ( list -- car )
|
||||
#! Return the value of the head of the lazy list.
|
||||
force cons-car ;
|
||||
|
||||
: cdr ( list -- cdr )
|
||||
#! Return the rest of the lazy list.
|
||||
#! This is itself a lazy list.
|
||||
force cons-cdr ;
|
||||
|
||||
: cons ( car cdr -- list )
|
||||
#! Given a car and cdr, both lazy values, return a lazy cons.
|
||||
[ swap , , \ <cons> , ] [ ] make <promise> ;
|
||||
|
||||
: lunit ( obj -- list )
|
||||
#! Given a value produce a lazy list containing that value.
|
||||
nil cons ;
|
||||
|
||||
: lnth ( n list -- value )
|
||||
#! Return the nth item in a lazy list
|
||||
swap [ cdr ] times car ;
|
||||
|
||||
: uncons ( cons -- car cdr )
|
||||
#! Return the car and cdr of the lazy list
|
||||
force dup cons-car swap cons-cdr ;
|
||||
|
||||
: force-promise ( list-quot -- list )
|
||||
#! Promises to force list-quot, which should be
|
||||
#! a quot that produces a list.
|
||||
#! This allows caching of the resultant list value.
|
||||
[ call \ force , ] [ ] make <promise> ; inline
|
||||
|
||||
DEFER: lmap
|
||||
: (lmap) ( list quot -- list )
|
||||
over nil? [ drop ]
|
||||
[
|
||||
swap 2dup
|
||||
cdr swap lmap >r
|
||||
car swap call r>
|
||||
cons
|
||||
] if ;
|
||||
|
||||
: lmap ( list quot -- list )
|
||||
#! Return a lazy list containing the collected result of calling
|
||||
#! quot on the original lazy list.
|
||||
[ swap , , \ (lmap) , ] force-promise ;
|
||||
|
||||
DEFER: ltake
|
||||
: (ltake) ( n list -- list )
|
||||
over 0 = [ 2drop nil ]
|
||||
[ dup nil? [ nip ]
|
||||
[
|
||||
swap ( list n -- list )
|
||||
1 - >r uncons r> swap ltake
|
||||
cons
|
||||
] if
|
||||
] if ;
|
||||
|
||||
: ltake ( n list -- list )
|
||||
#! Return a lazy list containing the first n items from
|
||||
#! the original lazy list.
|
||||
[ swap , , \ (ltake) , ] force-promise ;
|
||||
|
||||
DEFER: lsubset
|
||||
: (lsubset) ( list pred -- list )
|
||||
>r dup nil? [ r> drop ]
|
||||
[
|
||||
uncons swap dup r> dup >r call
|
||||
[ swap r> lsubset cons ]
|
||||
[ drop r> (lsubset) ] if
|
||||
] if ;
|
||||
|
||||
: lsubset ( list pred -- list )
|
||||
#! Return a lazy list containing the elements in llist
|
||||
#! satisfying pred
|
||||
[ swap , , \ (lsubset) , ] force-promise ;
|
||||
|
||||
: (list>backwards-vector) ( list -- vector )
|
||||
dup nil? [ drop V{ } clone ]
|
||||
[ uncons (list>backwards-vector) swap over push ] if ;
|
||||
|
||||
: list>vector ( list -- vector )
|
||||
#! Convert a lazy list to a vector. This will cause
|
||||
#! an infinite loop if the lazy list is an infinite list.
|
||||
(list>backwards-vector) reverse ;
|
||||
|
||||
: list>array ( list -- array )
|
||||
list>vector >array ;
|
||||
|
||||
DEFER: backwards-vector>list
|
||||
: (backwards-vector>list) ( vector -- list )
|
||||
dup empty? [ drop nil ]
|
||||
[ dup pop swap backwards-vector>list cons ] if ;
|
||||
|
||||
: backwards-vector>list ( vector -- list )
|
||||
[ , \ (backwards-vector>list) , ] force-promise ;
|
||||
|
||||
: array>list ( array -- list )
|
||||
#! Convert a list to a lazy list.
|
||||
reverse >vector backwards-vector>list ;
|
||||
|
||||
DEFER: lappend*
|
||||
: (lappend*) ( lists -- list )
|
||||
dup nil? [
|
||||
uncons >r dup nil? [ drop r> (lappend*) ]
|
||||
[ uncons r> cons lappend* cons ] if
|
||||
] unless ;
|
||||
|
||||
: lappend* ( llists -- list )
|
||||
#! Given a lazy list of lazy lists, concatenate them
|
||||
#! together in a lazy fashion. The actual appending is
|
||||
#! done lazily on iteration rather than immediately
|
||||
#! so it works very fast no matter how large the lists.
|
||||
[ , \ (lappend*) , ] force-promise ;
|
||||
|
||||
: lappend ( list1 list2 -- llist )
|
||||
#! Concatenate two lazy lists such that they appear to be one big
|
||||
#! lazy list.
|
||||
lunit cons lappend* ;
|
||||
|
||||
: leach ( list quot -- )
|
||||
#! Call the quotation on each item in the lazy list.
|
||||
#! Warning: If the list is infinite then this will
|
||||
#! never return.
|
||||
swap dup nil? [ 2drop ] [
|
||||
uncons swap pick call swap leach
|
||||
] if ;
|
||||
|
||||
DEFER: lapply
|
||||
: (lapply) ( list quot -- list )
|
||||
over nil? [ drop ] [
|
||||
swap dup car >r uncons pick call swap lapply
|
||||
r> swap cons
|
||||
] if ;
|
||||
|
||||
: lapply ( list quot -- list )
|
||||
#! Returns a lazy list which is
|
||||
#! (cons (car list)
|
||||
#! (lapply (quot (car list) (cdr list)) quot))
|
||||
#! This allows for complicated list functions
|
||||
[ swap , , \ (lapply) , ] force-promise ;
|
||||
|
||||
DEFER: lfrom-by
|
||||
: (lfrom-by) ( n quot -- list )
|
||||
2dup call swap lfrom-by cons ;
|
||||
|
||||
: lfrom-by ( n quot -- list )
|
||||
#! Return a lazy list of values starting from n, with
|
||||
#! each successive value being the result of applying quot to
|
||||
#! n.
|
||||
[ swap , , \ (lfrom-by) , ] force-promise ;
|
||||
|
||||
: lfrom ( n -- list )
|
||||
#! Return a lazy list of increasing numbers starting
|
||||
#! from the initial value 'n'.
|
||||
[ 1 + ] lfrom-by ;
|
|
@ -0,0 +1,7 @@
|
|||
PROVIDE: lazy-lists {
|
||||
"lists.factor"
|
||||
"examples.factor"
|
||||
} {
|
||||
"test/lists.factor"
|
||||
"test/examples.factor"
|
||||
} ;
|
|
@ -0,0 +1,6 @@
|
|||
USING: lazy-examples lazy-lists test ;
|
||||
IN: temporary
|
||||
|
||||
[ { 1 3 5 7 } ] [ 4 odds ltake list>array ] unit-test
|
||||
[ { 0 1 4 9 16 } ] [ first-five-squares ] unit-test
|
||||
[ { 2 3 5 7 11 13 17 19 23 29 } ] [ first-ten-primes ] unit-test
|
|
@ -1,8 +1,4 @@
|
|||
! :folding=indent:collapseFolds=1:
|
||||
|
||||
! $Id$
|
||||
!
|
||||
! Copyright (C) 2004 Mackenzie Straight.
|
||||
! Copyright (C) 2006 Matthew Willis.
|
||||
!
|
||||
! Redistribution and use in source and binary forms, with or without
|
||||
! modification, are permitted provided that the following conditions are met:
|
||||
|
@ -25,46 +21,40 @@
|
|||
! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
IN: win32-api
|
||||
USE: errors
|
||||
USE: kernel
|
||||
USE: io-internals
|
||||
USE: lists
|
||||
USE: math
|
||||
USE: parser
|
||||
USE: alien
|
||||
USE: words
|
||||
USE: sequences
|
||||
|
||||
: CONSTANT: CREATE
|
||||
[ [ [ swons ] each ] cons define-compound POSTPONE: parsing ]
|
||||
[ ] ; parsing
|
||||
|
||||
CONSTANT: ERROR_SUCCESS 0 ;
|
||||
CONSTANT: ERROR_HANDLE_EOF 38 ;
|
||||
CONSTANT: ERROR_IO_PENDING 997 ;
|
||||
CONSTANT: WAIT_TIMEOUT 258 ;
|
||||
|
||||
: FORMAT_MESSAGE_ALLOCATE_BUFFER HEX: 00000100 ;
|
||||
: FORMAT_MESSAGE_IGNORE_INSERTS HEX: 00000200 ;
|
||||
: FORMAT_MESSAGE_FROM_STRING HEX: 00000400 ;
|
||||
: FORMAT_MESSAGE_FROM_HMODULE HEX: 00000800 ;
|
||||
: FORMAT_MESSAGE_FROM_SYSTEM HEX: 00001000 ;
|
||||
: FORMAT_MESSAGE_ARGUMENT_ARRAY HEX: 00002000 ;
|
||||
: FORMAT_MESSAGE_MAX_WIDTH_MASK HEX: 000000FF ;
|
||||
|
||||
: MAKELANGID ( primary sub -- lang )
|
||||
10 shift bitor ;
|
||||
|
||||
: LANG_NEUTRAL 0 ;
|
||||
: SUBLANG_DEFAULT 1 ;
|
||||
|
||||
: GetLastError ( -- int )
|
||||
"int" "kernel32" "GetLastError" [ ] alien-invoke ;
|
||||
|
||||
: win32-error-message ( id -- string )
|
||||
"char*" f "error_message" [ "int" ] alien-invoke ;
|
||||
|
||||
: win32-throw-error ( -- )
|
||||
GetLastError win32-error-message throw ;
|
||||
USING: lazy-lists test kernel math io ;
|
||||
IN: temporary
|
||||
|
||||
[ t ] [ nil nil? ] unit-test
|
||||
[ 5 ] [ 5 lunit car ] unit-test
|
||||
[ f ] [ nil nil cons nil? ] unit-test
|
||||
[ 5 t ] [ 5 lunit uncons nil? ] unit-test
|
||||
[ 6 ] [
|
||||
5 6 lunit cons
|
||||
1 swap lnth
|
||||
] unit-test
|
||||
[ 12 13 t ] [
|
||||
5 6 lunit cons
|
||||
[ 7 + ] lmap uncons uncons nil?
|
||||
] unit-test
|
||||
[ 5 6 t ] [
|
||||
5 6 7 lunit cons cons 2 swap ltake
|
||||
uncons uncons nil?
|
||||
] unit-test
|
||||
[ 6 7 t ] [ 5 6 7 lunit cons cons [ 5 > ] lsubset
|
||||
uncons uncons nil? ] unit-test
|
||||
[ 7 t ] [ 5 6 7 lunit cons cons [ 6 > ] lsubset
|
||||
uncons nil? ] unit-test
|
||||
[ 1 3 5 t ] [ { 1 3 5 } array>list
|
||||
uncons uncons uncons nil? ] unit-test
|
||||
[ { 1 3 5 } ] [ { 1 3 5 } array>list list>array ] unit-test
|
||||
[ { 1 2 3 4 5 6 7 8 9 } ] [
|
||||
{ 1 2 3 } array>list
|
||||
{ 4 5 6 } array>list
|
||||
{ 7 8 9 } array>list
|
||||
lunit cons cons lappend* list>array ] unit-test
|
||||
[ { 1 2 3 4 5 6 } ]
|
||||
[ { 1 2 3 } array>list { 4 5 6 } array>list
|
||||
lappend list>array ] unit-test
|
||||
[ ] [ { 1 2 3 } array>list [ 3 + number>string print ] leach ] unit-test
|
||||
[ { 1 2 3 4 } ]
|
||||
[ 0 lfrom [ 5 < ] lsubset [ 0 > ] lsubset 4 swap ltake list>array ] unit-test
|
|
@ -1,26 +0,0 @@
|
|||
! Load all contrib libs, compile them, and save a new image.
|
||||
IN: scratchpad
|
||||
USING: alien compiler kernel memory parser sequences words ;
|
||||
|
||||
{
|
||||
"coroutines"
|
||||
"dlists"
|
||||
"splay-trees"
|
||||
} [ "/contrib/" swap ".factor" append3 run-resource clear ] each
|
||||
|
||||
{ "cairo"
|
||||
"math"
|
||||
"concurrency"
|
||||
"crypto"
|
||||
"aim"
|
||||
"httpd"
|
||||
"units"
|
||||
"sqlite"
|
||||
"win32"
|
||||
"x11"
|
||||
! "factory" has a C component, ick.
|
||||
"postgresql"
|
||||
"parser-combinators"
|
||||
"cont-responder"
|
||||
"space-invaders"
|
||||
} [ "/contrib/" swap "/load.factor" append3 run-resource clear ] each
|
|
@ -17,19 +17,24 @@ USING: kernel sequences errors namespaces math ;
|
|||
#! calculate n! given n, k, k!
|
||||
(k..n] product * ;
|
||||
|
||||
|
||||
: nCk ( n k -- nCk )
|
||||
#! uses the results from min(k!,(n-k)!) to compute max(k!,(n-k)!)
|
||||
#! use max(k!,(n-k)!) to compute n!
|
||||
2dup < [ "n >= k only" throw ] when
|
||||
[ - ] 2keep rot 2dup < [ swap ] when
|
||||
[ factorial ] keep over
|
||||
>r rot [ factorial-part ] keep rot pick >r factorial-part r> r> * / ;
|
||||
2dup < [
|
||||
2drop 0
|
||||
] [
|
||||
[ - ] 2keep rot 2dup < [ swap ] when
|
||||
[ factorial ] keep over
|
||||
>r rot [ factorial-part ] keep rot pick >r factorial-part r> r> * /
|
||||
] if ;
|
||||
|
||||
: nPk ( n k -- nPk )
|
||||
#! uses the results from (n-k)! to compute n!
|
||||
2dup < [ "n >= k only" throw ] when
|
||||
2dup - nip [ factorial ] keep rot pick >r factorial-part r> / ;
|
||||
2dup < [
|
||||
2drop 0
|
||||
] [
|
||||
2dup - nip [ factorial ] keep rot pick >r factorial-part r> /
|
||||
] if ;
|
||||
|
||||
: binomial ( n k -- nCk )
|
||||
#! same as nCk
|
||||
|
|
|
@ -1,365 +0,0 @@
|
|||
IN: infix
|
||||
USING: arrays errors generic hashtables io kernel kernel-internals lists math math-contrib namespaces parser parser-combinators prettyprint sequences strings vectors words ;
|
||||
|
||||
: 2list ( x y -- [ x y ] ) f cons cons ;
|
||||
|
||||
! Tokenizer
|
||||
|
||||
TUPLE: tok char ;
|
||||
|
||||
TUPLE: brackets seq ender ;
|
||||
|
||||
SYMBOL: apostrophe
|
||||
|
||||
SYMBOL: code #! Source code
|
||||
SYMBOL: spot #! Current index of string
|
||||
|
||||
: take-until ( quot -- parsed-stuff | quot: char -- ? )
|
||||
#! Take the substring of a string starting at spot
|
||||
#! from code until the quotation given is true and
|
||||
#! advance spot to after the substring.
|
||||
>r spot get code get 2dup r>
|
||||
skip [ swap subseq ] keep
|
||||
spot set ;
|
||||
|
||||
: parse-blank ( -- )
|
||||
#! Advance code past any whitespace, including newlines
|
||||
spot get code get [ blank? not ] skip spot set ;
|
||||
|
||||
: not-done? ( -- ? )
|
||||
#! Return t if spot is not at the end of code
|
||||
code get length spot get = not ;
|
||||
|
||||
: incr-spot ( -- )
|
||||
#! Increment spot.
|
||||
spot [ 1 + ] change ;
|
||||
|
||||
: parse-var ( -- variable-name )
|
||||
#! Take a series of letters from code, advancing
|
||||
#! spot and returning the letters.
|
||||
[ letter? not ] take-until ;
|
||||
|
||||
: parse-num ( -- number )
|
||||
#! Take a number from code, advancing spot and
|
||||
#! returning the number.
|
||||
[ "0123456789." member? not ] take-until string>number ;
|
||||
|
||||
: get-token ( -- char )
|
||||
spot get code get nth ;
|
||||
|
||||
DEFER: token
|
||||
|
||||
: next-token ( list -- list )
|
||||
#! Take one token from code and return it
|
||||
parse-blank not-done? [
|
||||
get-token token
|
||||
] when ;
|
||||
|
||||
: token
|
||||
{
|
||||
{ [ dup letter? ] [ drop parse-var swons ] }
|
||||
{ [ dup "0123456789." member? ] [ drop parse-num swons ] }
|
||||
{ [ dup ";!@#$%^&*?/|\\=+_-~" member? ] [ <tok> swons incr-spot ] }
|
||||
{ [ dup "([{" member? ] [ drop f incr-spot ] }
|
||||
{ [ dup ")]}" member? ] [ <brackets> swons incr-spot ] }
|
||||
{ [ dup CHAR: ' = ] [ drop apostrophe swons incr-spot ] }
|
||||
{ [ t ] [ "Bad character " swap ch>string append throw ] }
|
||||
} cond next-token ;
|
||||
|
||||
: tokenize ( string -- tokens )
|
||||
#! Tokenize a string, returning a list of tokens
|
||||
[
|
||||
code set 0 spot set
|
||||
f next-token reverse
|
||||
] with-scope ;
|
||||
|
||||
|
||||
! Parser
|
||||
|
||||
TUPLE: apply func args ;
|
||||
#! Function application
|
||||
C: apply
|
||||
>r [ ] subset r>
|
||||
[ set-apply-args ] keep
|
||||
[ set-apply-func ] keep ;
|
||||
|
||||
UNION: value number string ;
|
||||
|
||||
: semicolon ( -- semicolon )
|
||||
#! The semicolon token
|
||||
T{ tok f CHAR: ; } ;
|
||||
|
||||
: unswons uncons swap ;
|
||||
|
||||
: nest-apply ( [ ast ] -- apply )
|
||||
unswons unit swap [
|
||||
swap <apply> unit
|
||||
] each car ;
|
||||
|
||||
GENERIC: parse-token ( ast tokens token -- ast tokens )
|
||||
#! Take one or more tokens
|
||||
|
||||
DEFER: parse-tokens
|
||||
|
||||
: semicolon-split ( list -- [ ast ] )
|
||||
reverse semicolon unit split [ parse-tokens ] map ;
|
||||
|
||||
M: value parse-token
|
||||
swapd swons swap ;
|
||||
|
||||
M: brackets parse-token
|
||||
swapd dup brackets-seq swap brackets-ender {
|
||||
{ [ dup CHAR: ] = ] [ drop semicolon-split >r unswons r> <apply> swons ] }
|
||||
{ [ dup CHAR: } = ] [ drop semicolon-split >vector swons ] }
|
||||
{ [ CHAR: ) = ] [ reverse parse-tokens swons ] }
|
||||
} cond swap ;
|
||||
|
||||
M: object tok-char drop -1 ; ! Hack!
|
||||
|
||||
GENERIC: tok>string ( token/string -- string )
|
||||
M: tok tok>string
|
||||
tok-char ch>string ;
|
||||
M: string tok>string ;
|
||||
|
||||
: binary-op ( ast tokens token -- ast )
|
||||
>r >r unswons r> parse-tokens 2list r>
|
||||
tok>string swap <apply> swons ;
|
||||
|
||||
: unary-op ( ast tokens token -- ast )
|
||||
tok>string -rot nip
|
||||
parse-tokens unit <apply> unit ;
|
||||
|
||||
: null-op ( ast tokens token -- ast )
|
||||
nip tok-char ch>string swons ;
|
||||
|
||||
M: tok parse-token
|
||||
over [
|
||||
pick [
|
||||
binary-op
|
||||
] [
|
||||
unary-op
|
||||
] if
|
||||
] [
|
||||
null-op
|
||||
] if f ;
|
||||
|
||||
( ast tokens token -- ast tokens )
|
||||
|
||||
M: symbol parse-token ! apostrophe
|
||||
drop unswons >r parse-tokens >r unswons r> 2list r>
|
||||
unit parse-tokens swap <apply> swons f ;
|
||||
|
||||
: (parse-tokens) ( ast tokens -- ast )
|
||||
dup [
|
||||
unswons parse-token (parse-tokens)
|
||||
] [
|
||||
drop
|
||||
] if ;
|
||||
|
||||
: parse-tokens ( tokens -- ast )
|
||||
#! Convert a list of tokens into an AST
|
||||
f swap (parse-tokens) nest-apply ;
|
||||
|
||||
: parse-full ( string -- ast )
|
||||
#! Convert a string into an AST
|
||||
tokenize parse-tokens ;
|
||||
|
||||
|
||||
! Compiler
|
||||
|
||||
GENERIC: compile-ast ( vars ast -- quot )
|
||||
|
||||
M: string compile-ast ! variables
|
||||
swap index dup -1 = [
|
||||
"Variable not found" throw
|
||||
] [
|
||||
[ swap array-nth ] cons
|
||||
] if ;
|
||||
|
||||
: replace-with ( data -- [ drop data ] )
|
||||
\ drop swap 2list ;
|
||||
|
||||
UNION: comp-literal number general-list ;
|
||||
|
||||
M: comp-literal compile-ast ! literal numbers
|
||||
replace-with nip ;
|
||||
|
||||
: accumulator ( vars { asts } quot -- quot )
|
||||
-rot [
|
||||
[
|
||||
\ dup ,
|
||||
compile-ast %
|
||||
dup %
|
||||
] each-with
|
||||
] [ ] make nip ;
|
||||
|
||||
M: vector compile-ast ! literal vectors
|
||||
dup [ number? ] all? [
|
||||
replace-with nip
|
||||
] [
|
||||
[ , ] accumulator [ { } make nip ] cons
|
||||
] if ;
|
||||
|
||||
: infix-relation
|
||||
#! Wraps operators like = and > so that if they're given
|
||||
#! f as either argument, they return f, and they return f if
|
||||
#! the operation yields f, but if it yields t, it returns the
|
||||
#! left argument. This way, these types of operations can be
|
||||
#! composed.
|
||||
>r 2dup and not [
|
||||
r> 3drop f
|
||||
] [
|
||||
dupd r> call [
|
||||
drop f
|
||||
] unless
|
||||
] if ;
|
||||
|
||||
: functions
|
||||
#! Regular functions
|
||||
#! Gives quotation applicable to stack
|
||||
H{
|
||||
[ [[ "+" 2 ]] + ]
|
||||
[ [[ "-" 2 ]] - ]
|
||||
[ [[ ">" 2 ]] [ > ] infix-relation ]
|
||||
[ [[ "<" 2 ]] [ < ] infix-relation ]
|
||||
[ [[ "=" 2 ]] [ = ] infix-relation ]
|
||||
[ [[ "-" 1 ]] neg ]
|
||||
[ [[ "~" 1 ]] not ]
|
||||
[ [[ "&" 2 ]] and ]
|
||||
[ [[ "|" 2 ]] or ]
|
||||
[ [[ "&" 1 ]] t [ and ] reduce ]
|
||||
[ [[ "|" 1 ]] f [ or ] reduce ]
|
||||
[ [[ "*" 2 ]] * ]
|
||||
[ [[ "ln" 1 ]] log ]
|
||||
[ [[ "plusmin" 2 ]] [ + ] 2keep - ]
|
||||
[ [[ "@" 2 ]] swap nth ]
|
||||
[ [[ "sqrt" 1 ]] sqrt ]
|
||||
[ [[ "/" 2 ]] / ]
|
||||
[ [[ "^" 2 ]] ^ ]
|
||||
[ [[ "#" 1 ]] length ]
|
||||
[ [[ "eq" 2 ]] eq? ]
|
||||
[ [[ "*" 1 ]] first ]
|
||||
[ [[ "+" 1 ]] flip ]
|
||||
[ [[ "\\" 1 ]] <reversed> ]
|
||||
[ [[ "sin" 1 ]] sin ]
|
||||
[ [[ "cos" 1 ]] cos ]
|
||||
[ [[ "tan" 1 ]] tan ]
|
||||
[ [[ "max" 2 ]] max ]
|
||||
[ [[ "min" 2 ]] min ]
|
||||
[ [[ "," 2 ]] append ]
|
||||
[ [[ "," 1 ]] concat ]
|
||||
[ [[ "sn" 3 ]] -rot set-nth ]
|
||||
[ [[ "prod" 1 ]] product ]
|
||||
[ [[ "vec" 1 ]] >vector ]
|
||||
} ;
|
||||
|
||||
: drc ( list -- list )
|
||||
#! all of list except last element (backwards cdr)
|
||||
dup cdr [
|
||||
uncons drc cons
|
||||
] [
|
||||
drop f
|
||||
] if ;
|
||||
|
||||
: map-with-left ( seq object quot -- seq )
|
||||
[ swapd call ] cons swapd map-with ; inline
|
||||
|
||||
: high-functions
|
||||
#! Higher-order functions
|
||||
#! Gives quotation applicable to quotation and rest of stack
|
||||
H{
|
||||
[ [[ "!" 2 ]] 2map ]
|
||||
[ [[ "!" 1 ]] map ]
|
||||
[ [[ ">" 2 ]] map-with ]
|
||||
[ [[ "<" 2 ]] map-with-left ]
|
||||
[ [[ "^" 1 ]] all? ]
|
||||
[ [[ "~" 1 ]] call not ]
|
||||
[ [[ "~" 2 ]] call not ]
|
||||
[ [[ "/" 2 ]] swapd reduce ]
|
||||
[ [[ "\\" 2 ]] swapd accumulate ]
|
||||
} ;
|
||||
|
||||
: get-hash ( key table -- value )
|
||||
#! like hash but throws exception if f
|
||||
dupd hash [ nip ] [
|
||||
[ "Key not found " write . ] string-out throw
|
||||
] if* ;
|
||||
|
||||
: >apply< ( apply -- func args )
|
||||
dup apply-func swap apply-args ;
|
||||
|
||||
: make-apply ( arity apply/string -- quot )
|
||||
dup string? [
|
||||
swons functions get-hash
|
||||
] [
|
||||
>apply< car >r over r> make-apply
|
||||
-rot swons high-functions get-hash cons
|
||||
] if ;
|
||||
|
||||
: get-function ( apply -- quot )
|
||||
>apply< length swap make-apply ;
|
||||
|
||||
M: apply compile-ast ! function application
|
||||
[ apply-args [ swap ] accumulator [ drop ] append ] keep
|
||||
get-function append ;
|
||||
|
||||
: push-list ( list item -- list )
|
||||
unit append ;
|
||||
|
||||
: parse-comp ( args string -- quot )
|
||||
#! Compile a string into a quotation w/o prologue
|
||||
parse-full compile-ast ;
|
||||
|
||||
: prologue ( args -- quot )
|
||||
#! Build the prolog for a function
|
||||
[
|
||||
length dup , \ <array> ,
|
||||
[ 1 - ] keep [
|
||||
2dup - [ swap set-array-nth ] cons , \ keep ,
|
||||
] repeat drop
|
||||
] [ ] make ;
|
||||
|
||||
: ast>quot ( args ast -- quot )
|
||||
over prologue -rot compile-ast append ;
|
||||
|
||||
: define-math ( seq -- )
|
||||
" " join
|
||||
dup parse-full apply-args uncons car swap
|
||||
>apply< >r create-in r>
|
||||
[ "math-args" set-word-prop ] 2keep
|
||||
>r tuck >r >r swap "code" set-word-prop r> r> r>
|
||||
rot ast>quot define-compound ;
|
||||
|
||||
: MATH:
|
||||
#! MATH: sq[x]=x*x ;
|
||||
"in-definition" on
|
||||
string-mode on
|
||||
[
|
||||
string-mode off define-math
|
||||
] f ; parsing
|
||||
|
||||
: TEST-MATH:
|
||||
#! Executes and prints the result of a math
|
||||
#! expression at parsetime
|
||||
string-mode on [
|
||||
" " join string-mode off parse-full
|
||||
f swap ast>quot call .
|
||||
] f ; parsing
|
||||
|
||||
! PREDICATE: compound infix-word "code" word-prop ;
|
||||
! M: infix-word definer
|
||||
! drop POSTPONE: MATH: ;
|
||||
! M: infix-word class.
|
||||
! "code" word-prop write " ;" print ;
|
||||
!
|
||||
! Redefine compound to not include infix words so see works
|
||||
! IN: words
|
||||
! USING: kernel words parse-k ;
|
||||
!
|
||||
! PREDICATE: word compound
|
||||
! dup word-primitive 1 = swap infix-word? not and ;
|
||||
|
||||
|
||||
|
||||
MATH: quadratic[a;b;c] =
|
||||
plusmin[(-b)/2*a;(sqrt(b^2)-4*a*c)/2*a] ;
|
|
@ -1,13 +1,10 @@
|
|||
IN: scratchpad
|
||||
USING: kernel parser sequences words compiler ;
|
||||
|
||||
{
|
||||
"utils"
|
||||
"combinatorics"
|
||||
"analysis"
|
||||
"polynomials"
|
||||
"quaternions"
|
||||
"matrices"
|
||||
"statistics"
|
||||
"numerical-integration"
|
||||
} [ "/contrib/math/" swap ".factor" append3 run-resource ] each
|
||||
PROVIDE: math {
|
||||
"utils.factor"
|
||||
"combinatorics.factor"
|
||||
"analysis.factor"
|
||||
"polynomials.factor"
|
||||
"quaternions.factor"
|
||||
"matrices.factor"
|
||||
"statistics.factor"
|
||||
"numerical-integration.factor"
|
||||
} ;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
IN: math-contrib
|
||||
|
||||
USING: kernel sequences errors namespaces math lists vectors errors prettyprint ;
|
||||
USING: io inspector ;
|
||||
USING: kernel sequences errors namespaces math vectors errors prettyprint io inspector ;
|
||||
|
||||
: setup-range ( from to -- frange )
|
||||
step-size get swap <frange> ;
|
||||
|
|
|
@ -13,6 +13,13 @@ USING: errors kernel sequences math sequences-internals namespaces arrays ;
|
|||
gcd 1 = [ "Non-trivial divisor found" throw ] unless ;
|
||||
foldable
|
||||
|
||||
: each-bit ( n quot -- | quot: 0/1 -- )
|
||||
over zero? pick -1 number= or [
|
||||
2drop
|
||||
] [
|
||||
2dup >r >r >r 1 bitand r> call r> -1 shift r> each-bit
|
||||
] if ; inline
|
||||
|
||||
: (^mod) ( n z w -- z^w )
|
||||
1 swap [
|
||||
1 number= [ dupd * pick mod ] when >r sq over mod r>
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
! 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: lazy-examples
|
||||
USE: lazy
|
||||
USE: math
|
||||
USE: lists
|
||||
USE: parser-combinators
|
||||
USE: kernel
|
||||
USE: sequences
|
||||
USE: namespaces
|
||||
|
||||
: lfrom ( n -- llist )
|
||||
#! Return a lazy list of increasing numbers starting
|
||||
#! from the initial value 'n'.
|
||||
dup unit delay swap
|
||||
[ 1 + lfrom ] cons delay lcons ;
|
||||
|
||||
: lfrom-by ( n quot -- llist )
|
||||
#! Return a lazy list of values starting from n, with
|
||||
#! each successive value being the result of applying quot to
|
||||
#! n.
|
||||
swap dup unit delay -rot
|
||||
[ , dup , \ call , , \ lfrom-by , ] [ ] make delay lcons ;
|
||||
|
||||
: lnaturals 0 lfrom ;
|
||||
: lpositves 1 lfrom ;
|
||||
: levens 0 [ 2 + ] lfrom-by ;
|
||||
: lodds 1 lfrom [ 2 mod 1 = ] lsubset ;
|
||||
: lpowers-of-2 1 [ 2 * ] lfrom-by ;
|
||||
: lones 1 [ ] lfrom-by ;
|
||||
: lsquares lnaturals [ dup * ] lmap ;
|
||||
: first-five-squares 5 lsquares ltake ;
|
||||
|
||||
: divisible-by? ( a b -- bool )
|
||||
#! Return true if a is divisible by b
|
||||
mod 0 = ;
|
||||
|
||||
: sieve ( llist - llist )
|
||||
#! Given a lazy list of numbers, use the sieve of eratosthenes
|
||||
#! algorithm to return a lazy list of primes.
|
||||
luncons over [ divisible-by? not ]
|
||||
cons lsubset [ sieve ] cons delay >r unit delay r> lcons ;
|
||||
|
||||
: lprimes 2 lfrom sieve ;
|
||||
|
||||
: first-ten-primes 10 lprimes ltake llist>list ;
|
|
@ -1,265 +0,0 @@
|
|||
! 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: lazy
|
||||
USE: kernel
|
||||
USE: sequences
|
||||
USE: namespaces
|
||||
USE: lists
|
||||
USE: math
|
||||
|
||||
TUPLE: promise quot forced? value ;
|
||||
|
||||
: delay ( quot -- <promise> )
|
||||
#! Given a quotation, create a promise which may later be forced.
|
||||
#! When forced the quotation will execute returning the value. Future
|
||||
#! forces of the promise will return that value and not re-execute
|
||||
#! the quotation.
|
||||
f f <promise> ;
|
||||
|
||||
: (force) ( <promise> -- value )
|
||||
#! Force the given promise leaving the value of calling the
|
||||
#! promises quotation on the stack. Re-forcing the promise
|
||||
#! will return the same value and not recall the quotation.
|
||||
dup promise-forced? [
|
||||
dup promise-quot call over set-promise-value
|
||||
t over set-promise-forced?
|
||||
] unless
|
||||
promise-value ;
|
||||
|
||||
: force ( <promise> -- value )
|
||||
(force) dup promise? [
|
||||
force
|
||||
] when ;
|
||||
|
||||
TUPLE: lcons car cdr ;
|
||||
|
||||
SYMBOL: lazy-nil
|
||||
DEFER: lnil
|
||||
[ [ ] ] delay lazy-nil set
|
||||
|
||||
: lnil ( -- lcons )
|
||||
#! Return the nil lazy list.
|
||||
lazy-nil get ;
|
||||
|
||||
: lnil? ( lcons -- bool )
|
||||
#! Is the given lazy cons the nil value
|
||||
force not ;
|
||||
|
||||
: lcar ( lcons -- car )
|
||||
#! Return the value of the head of the lazy list.
|
||||
dup lnil? [
|
||||
force lcons-car (force)
|
||||
] unless ;
|
||||
|
||||
: lcdr ( lcons -- cdr )
|
||||
#! Return the value of the rest of the lazy list.
|
||||
#! This is itself a lazy list.
|
||||
dup lnil? [
|
||||
force lcons-cdr (force)
|
||||
] unless ;
|
||||
|
||||
: lcons ( lcar lcdr -- promise )
|
||||
#! Given a car and cdr, both lazy values, return a lazy cons.
|
||||
swap [ , , \ <lcons> , ] [ ] make delay ;
|
||||
|
||||
: lunit ( lvalue -- llist )
|
||||
#! Given a lazy value (a quotation that when called produces
|
||||
#! the value) produce a lazy list containing that value.
|
||||
[ lnil ] delay lcons ;
|
||||
|
||||
: lnth ( n llist -- value )
|
||||
#! Return the nth item in a lazy list
|
||||
swap [ lcdr ] times lcar ;
|
||||
|
||||
: luncons ( lcons -- car cdr )
|
||||
#! Return the car and cdr of the lazy list
|
||||
dup lcar swap lcdr ;
|
||||
|
||||
: lmap ( llist quot -- llist )
|
||||
#! Return a lazy list containing the collected result of calling
|
||||
#! quot on the original lazy list.
|
||||
over lnil? [
|
||||
drop
|
||||
] [
|
||||
swap 2dup
|
||||
[ , \ lcdr , , \ lmap , ] [ ] make delay >r
|
||||
[ , \ lcar , , \ call , ] [ ] make delay r>
|
||||
lcons
|
||||
] if ;
|
||||
|
||||
: ltake ( n llist -- llist )
|
||||
#! Return a lazy list containing the first n items from
|
||||
#! the original lazy list.
|
||||
over 0 = [
|
||||
2drop lnil
|
||||
] [
|
||||
dup lnil? [
|
||||
nip
|
||||
] [
|
||||
swap dupd ( llist llist n -- )
|
||||
[ [ 1 - ] cons , \ call , , \ lcdr , \ ltake , ] [ ] make delay >r
|
||||
[ , \ lcar , ] [ ] make delay r>
|
||||
lcons
|
||||
] if
|
||||
] if ;
|
||||
|
||||
DEFER: lsubset
|
||||
TUPLE: lsubset-state llist pred ;
|
||||
|
||||
: (lsubset-cdr) ( state -- llist )
|
||||
#! Given a predicate and a lazy list, do the cdr
|
||||
#! portion of lsubset.
|
||||
dup lsubset-state-llist lcdr swap lsubset-state-pred lsubset ;
|
||||
|
||||
: (lsubset-car) ( state -- value )
|
||||
#! Given a predicate and a lazy list, do the car
|
||||
#! portion of lsubset.
|
||||
dup lsubset-state-llist lcar over
|
||||
lsubset-state-pred dupd call [ ( state lcar -- )
|
||||
nip
|
||||
] [ ( state lcar -- )
|
||||
drop dup lsubset-state-llist lcdr over set-lsubset-state-llist
|
||||
(lsubset-car)
|
||||
] if ;
|
||||
|
||||
: (lsubset-set-first-car) ( state -- bool )
|
||||
#! Set the state to the first valid car. If none found
|
||||
#! return false.
|
||||
dup lsubset-state-llist lcar over
|
||||
lsubset-state-pred dupd call [ ( state lcar -- )
|
||||
2drop t
|
||||
] [ ( state lcar -- )
|
||||
drop dup lsubset-state-llist lcdr dup lnil? [
|
||||
2drop f
|
||||
] [
|
||||
over set-lsubset-state-llist
|
||||
(lsubset-set-first-car)
|
||||
] if
|
||||
] if ;
|
||||
|
||||
: lsubset ( llist pred -- llist )
|
||||
#! Return a lazy list containing only the items from the original
|
||||
#! lazy list for which the predicate returns a value other than f.
|
||||
over lnil? [
|
||||
drop
|
||||
] [
|
||||
<lsubset-state> dup
|
||||
(lsubset-set-first-car) [
|
||||
dup
|
||||
[ (lsubset-cdr) ] cons delay >r
|
||||
[ (lsubset-car) ] cons delay r> lcons
|
||||
] [
|
||||
drop lnil
|
||||
] if
|
||||
] if ;
|
||||
|
||||
DEFER: lappend*
|
||||
DEFER: (lappend*)
|
||||
TUPLE: lappend*-state current rest ;
|
||||
|
||||
USE: io
|
||||
|
||||
: (lappend*-cdr) ( state -- llist )
|
||||
#! Given the state object, do the cdr portion of the
|
||||
#! lazy append.
|
||||
dup lappend*-state-current dup lnil? [ ( state current -- )
|
||||
nip
|
||||
] [ ( state current -- )
|
||||
lcdr ( state cdr -- )
|
||||
dup lnil? [ ( state cdr -- )
|
||||
drop dup lappend*-state-rest dup lnil? [ ( state rest )
|
||||
nip
|
||||
] [
|
||||
nip
|
||||
luncons ( state rest-car rest-cdr -- )
|
||||
<lappend*-state> (lappend*)
|
||||
] if
|
||||
] [ ( state cdr -- )
|
||||
swap lappend*-state-rest <lappend*-state> (lappend*)
|
||||
] if
|
||||
] if ;
|
||||
|
||||
: (lappend*-car) ( state -- value )
|
||||
#! Given the state object, do the car portion of the
|
||||
#! lazy append.
|
||||
dup lappend*-state-current dup lnil? [ ( state current -- )
|
||||
nip
|
||||
] [ ( state current -- )
|
||||
lcar nip
|
||||
] if ;
|
||||
|
||||
: (lappend*) ( state -- llist )
|
||||
#! Do the main work of the lazy list appending using a
|
||||
#! state object.
|
||||
dup
|
||||
[ (lappend*-cdr) ] cons delay >r
|
||||
[ (lappend*-car) ] cons delay r> lcons ;
|
||||
|
||||
: lappend* ( llists -- llist )
|
||||
#! Given a lazy list of lazy lists, return a lazy list that
|
||||
#! works through all of the sub-lists in sequence.
|
||||
[ lnil? not ] lsubset
|
||||
dup lnil? [
|
||||
luncons <lappend*-state> (lappend*)
|
||||
] unless ;
|
||||
|
||||
DEFER: list>llist
|
||||
|
||||
: lappend ( llist1 llist2 -- llist )
|
||||
#! Concatenate two lazy lists such that they appear to be one big
|
||||
#! lazy list.
|
||||
[ ] cons cons list>llist lappend* ;
|
||||
|
||||
: leach ( llist quot -- )
|
||||
#! Call the quotation on each item in the lazy list.
|
||||
#! Warning: If the list is infinite then this will
|
||||
#! never return.
|
||||
over lnil? [
|
||||
2drop
|
||||
] [
|
||||
>r luncons r> tuck >r >r call r> r> leach
|
||||
] if ;
|
||||
|
||||
|
||||
: (llist>list) ( result llist -- list )
|
||||
#! Helper function for llist>list.
|
||||
dup lnil? [
|
||||
drop
|
||||
] [
|
||||
dup lcar ( result llist car )
|
||||
swap lcdr >r swons r> (llist>list)
|
||||
] if ;
|
||||
|
||||
: llist>list ( llist -- list )
|
||||
#! Convert a lazy list to a normal list. This will cause
|
||||
#! an infinite loop if the lazy list is an infinite list.
|
||||
f swap (llist>list) reverse ;
|
||||
|
||||
: list>llist ( list -- llist )
|
||||
#! Convert a list to a lazy list.
|
||||
dup [
|
||||
uncons [ list>llist ] cons delay >r unit delay r> lcons
|
||||
] [
|
||||
drop lnil
|
||||
] if ;
|
||||
|
|
@ -1,11 +1,5 @@
|
|||
IN: scratchpad
|
||||
USING: alien compiler kernel parser sequences words ;
|
||||
USING: alien ;
|
||||
|
||||
"postgresql" "libpq" add-simple-library
|
||||
|
||||
{
|
||||
"libpq"
|
||||
"postgresql"
|
||||
"postgresql-test"
|
||||
! "private" ! Put your password in this file
|
||||
} [ "/contrib/postgresql/" swap ".factor" append3 run-resource ] each
|
||||
PROVIDE: postgresql
|
||||
{ "libpq.factor" "postgresql.factor" }
|
||||
{ "postgresql-test" } ;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
! tested on debian linux with postgresql 7.4.7
|
||||
|
||||
IN: postgresql
|
||||
USING: kernel alien errors io prettyprint sequences lists namespaces arrays math ;
|
||||
USING: kernel alien errors io prettyprint sequences namespaces arrays math ;
|
||||
SYMBOL: postgres-conn
|
||||
SYMBOL: query-res
|
||||
|
||||
|
@ -59,5 +59,3 @@ SYMBOL: query-res
|
|||
|
||||
: print-table ( seq -- )
|
||||
[ [ "\t" append write ] each "\n" write ] each ;
|
||||
|
||||
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
IN: process
|
||||
USING: compiler io io-internals kernel parser ;
|
||||
|
||||
FUNCTION: int system ( char* command ) ; compiled
|
||||
FUNCTION: int system ( char* command ) ;
|
||||
|
||||
FUNCTION: void* popen ( char* command, char* type ) ; compiled
|
||||
FUNCTION: void* popen ( char* command, char* type ) ;
|
||||
|
||||
: <process-stream> ( command mode -- stream )
|
||||
popen dup <c-stream> ;
|
||||
|
||||
: !" parse-string system drop ; parsing
|
||||
|
||||
PROVIDE: process ;
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
USING: kernel parser sequences words compiler ;
|
||||
IN: scratchpad
|
||||
|
||||
{
|
||||
"utils"
|
||||
"random"
|
||||
"random-tester"
|
||||
} [ "/contrib/random-tester/" swap ".factor" append3 run-resource ] each
|
||||
PROVIDE: random-tester {
|
||||
"utils.factor"
|
||||
"random.factor"
|
||||
"random-tester.factor"
|
||||
} ;
|
||||
|
|
|
@ -1,30 +1,40 @@
|
|||
USING: kernel math sequences namespaces errors hashtables words arrays parser
|
||||
compiler syntax lists io ;
|
||||
USING: inspector prettyprint ;
|
||||
USING: optimizer compiler-frontend compiler-backend inference ;
|
||||
USING: kernel math math-internals memory sequences namespaces errors
|
||||
hashtables words arrays parser compiler syntax io
|
||||
inspector prettyprint optimizer inference ;
|
||||
IN: random-tester
|
||||
|
||||
! Math words are listed in arrays according to the number of arguments,
|
||||
! if they can throw exceptions or not, and what they output.
|
||||
! integer>x -> takes an integer, outputs anything
|
||||
! integer>integer -> always outputs an integer
|
||||
! n-foo>bar -- list of words of type 'foo' that take n parameters
|
||||
! and output a 'bar'
|
||||
|
||||
|
||||
! Math vocabulary words
|
||||
: math-1 ( -- seq )
|
||||
: 1-x>y ( -- seq )
|
||||
#! Words that take one argument
|
||||
{
|
||||
1+ 1- >bignum >digit >fixnum abs absq arg
|
||||
bitnot bits>double bits>float ceiling cis conjugate cos cosec cosech
|
||||
cosh cot coth denominator double>bits exp float>bits floor imaginary
|
||||
log neg next-power-of-2 numerator quadrant real sec
|
||||
log neg numerator quadrant real sec ! next-power-of-2
|
||||
sech sgn sin sinh sq sqrt tan tanh truncate
|
||||
} ;
|
||||
: math-throw-1
|
||||
|
||||
: 1-x>y-throws
|
||||
#! Words that take one argument and possibly throw an error
|
||||
{
|
||||
recip log2
|
||||
asec asech acot acoth acosec acosech acos acosh asin asinh atan atanh
|
||||
} ;
|
||||
|
||||
: integer>x
|
||||
: 2-x>y ( -- seq )
|
||||
#! Words that take two arguments
|
||||
{ * + - /f max min polar> bitand bitor bitxor align } ;
|
||||
|
||||
: 2-x>y-throws ( -- seq )
|
||||
#! Words that take two arguments and possibly throw an error
|
||||
{ / /i mod rem } ;
|
||||
|
||||
: 1-integer>x
|
||||
#! Words that take an integer and output a type (not necessarily integer)
|
||||
{
|
||||
1+ 1- >bignum >digit >fixnum abs absq arg
|
||||
bitnot bits>double bits>float ceiling cis conjugate cos cosec cosech
|
||||
|
@ -33,7 +43,7 @@ IN: random-tester
|
|||
sech sgn sin sinh sq sqrt tan tanh truncate
|
||||
} ;
|
||||
|
||||
: ratio>x
|
||||
: 1-ratio>x
|
||||
{
|
||||
1+ 1- >bignum >digit >fixnum abs absq arg ceiling
|
||||
cis conjugate cos cosec cosech
|
||||
|
@ -42,36 +52,36 @@ IN: random-tester
|
|||
sech sgn sin sinh sq sqrt tan tanh truncate
|
||||
} ;
|
||||
|
||||
: float>x ( float -- x )
|
||||
: 1-float>x ( float -- x )
|
||||
{
|
||||
1+ 1- >bignum >digit >fixnum abs absq arg
|
||||
ceiling cis conjugate cos cosec cosech
|
||||
cosh cot coth double>bits exp float>bits floor imaginary
|
||||
log neg next-power-of-2 quadrant real sec
|
||||
log neg quadrant real sec ! next-power-of-2
|
||||
sech sgn sin sinh sq sqrt tan tanh truncate
|
||||
} ;
|
||||
|
||||
: complex>x
|
||||
: 1-complex>x
|
||||
{
|
||||
1+ 1- abs absq arg
|
||||
conjugate cos cosec cosech
|
||||
cosh cot coth exp imaginary
|
||||
log neg quadrant real
|
||||
1+ 1- abs absq arg conjugate cos cosec cosech
|
||||
cosh cot coth exp imaginary log neg quadrant real
|
||||
sec sech sin sinh sq sqrt tan tanh
|
||||
} ;
|
||||
|
||||
: integer>x-throw
|
||||
: 1-integer>x-throws
|
||||
{
|
||||
recip log2
|
||||
asec asech acot acoth acosec acosech acos acosh asin asinh atan atanh
|
||||
} ;
|
||||
: ratio>x-throw
|
||||
|
||||
: 1-ratio>x-throws
|
||||
{
|
||||
recip
|
||||
asec asech acot acoth acosec acosech acos acosh asin asinh atan atanh
|
||||
} ;
|
||||
|
||||
: integer>integer
|
||||
: 1-integer>integer
|
||||
#! Subset of 1-integer>x
|
||||
{
|
||||
1+ 1- >bignum >digit >fixnum abs absq
|
||||
bitnot ceiling conjugate
|
||||
|
@ -80,17 +90,16 @@ IN: random-tester
|
|||
real sgn sq truncate
|
||||
} ;
|
||||
|
||||
: ratio>ratio { 1+ 1- >digit abs absq conjugate neg real sq } ;
|
||||
: 1-ratio>ratio
|
||||
{ 1+ 1- >digit abs absq conjugate neg real sq } ;
|
||||
|
||||
: float>float
|
||||
: 1-float>float
|
||||
{
|
||||
1+ 1- >digit abs absq arg ceiling
|
||||
conjugate cos cosec cosech
|
||||
cosh cot coth exp floor neg real sec
|
||||
sech sin sinh sq tan tanh truncate
|
||||
conjugate exp floor neg real sq truncate
|
||||
} ;
|
||||
|
||||
: complex>complex
|
||||
: 1-complex>complex
|
||||
{
|
||||
1+ 1- abs absq arg
|
||||
conjugate cosec cosech
|
||||
|
@ -99,461 +108,224 @@ IN: random-tester
|
|||
sech sin sinh sq sqrt tanh
|
||||
} ;
|
||||
|
||||
|
||||
: math-2 ( -- seq )
|
||||
: 2-integer>x ( n n -- x )
|
||||
{ * + - /f max min polar> bitand bitor bitxor align } ;
|
||||
: math-throw-2 ( -- seq ) { / /i mod rem } ;
|
||||
: 2-ratio>x ( r r -- x )
|
||||
{ * + - /f max min polar> } ;
|
||||
: 2-float>x ( f f -- x )
|
||||
{ float+ float- float* float/f + - * /f max min polar> } ;
|
||||
: 2-complex>x ( c c -- x ) { * + - /f } ;
|
||||
|
||||
: 2integer>x ( n n -- x ) ( -- word )
|
||||
{ * + - /f max min polar> bitand bitor bitxor align } ;
|
||||
: 2ratio>x ( r r -- x ) ( -- word ) { * + - /f max min polar> } ;
|
||||
: 2float>x ( f f -- x ) ( -- word ) { * + - /f max min polar> } ;
|
||||
: 2complex>x ( c c -- x ) ( -- word ) { * + - /f } ;
|
||||
|
||||
: 2integer>integer ( n n -- n ) ( -- word )
|
||||
: 2-integer>integer ( n n -- n )
|
||||
{ * + - max min bitand bitor bitxor align } ;
|
||||
: 2ratio>ratio ( r r -- r ) ( -- word ) { * + - max min } ;
|
||||
: 2float>float ( f f -- f ) ( -- word ) { * + - /f max min } ;
|
||||
: 2complex>complex ( c c -- c ) ( -- word ) { * + - /f } ;
|
||||
: 2-ratio>ratio ( r r -- r )
|
||||
{ * + - max min } ;
|
||||
: 2-float>float ( f f -- f )
|
||||
{ float* float+ float- float/f max min /f + - } ;
|
||||
: 2-complex>complex ( c c -- c )
|
||||
{ * + - /f } ;
|
||||
|
||||
: (random-integer-quotation) ( -- quot )
|
||||
random-integer ,
|
||||
max-length random-int
|
||||
[
|
||||
[
|
||||
[ integer>integer nth-rand , ]
|
||||
[ random-integer , 2integer>integer nth-rand , ]
|
||||
] do-one
|
||||
] times ;
|
||||
: random-integer-quotation ( -- quot )
|
||||
[
|
||||
(random-integer-quotation)
|
||||
] [ ] make ;
|
||||
|
||||
: random-integer-quotation-1 ( -- quot )
|
||||
[
|
||||
(random-integer-quotation) 2integer>integer nth-rand ,
|
||||
] [ ] make ;
|
||||
|
||||
: (random-ratio-quotation) ( -- quot )
|
||||
random-ratio ,
|
||||
max-length random-int
|
||||
[
|
||||
[
|
||||
[ ratio>ratio nth-rand , ]
|
||||
[ random-ratio , 2ratio>ratio nth-rand , ]
|
||||
] do-one
|
||||
] times ;
|
||||
|
||||
: random-ratio-quotation ( -- quot )
|
||||
[
|
||||
(random-ratio-quotation)
|
||||
] [ ] make ;
|
||||
|
||||
: random-ratio-quotation-1 ( -- quot )
|
||||
[
|
||||
(random-ratio-quotation) 2ratio>ratio nth-rand ,
|
||||
] [ ] make ;
|
||||
|
||||
: random-float-quotation ( -- quot )
|
||||
[
|
||||
random-float ,
|
||||
max-length random-int
|
||||
[
|
||||
[
|
||||
[ float>float nth-rand , ]
|
||||
[ random-float , 2float>float nth-rand , ]
|
||||
] do-one
|
||||
] times
|
||||
] [ ] make ;
|
||||
|
||||
: random-complex-quotation ( -- quot )
|
||||
[
|
||||
random-complex ,
|
||||
max-length random-int
|
||||
[
|
||||
[
|
||||
[ complex>complex nth-rand , ]
|
||||
[ random-complex , 2complex>complex nth-rand , ]
|
||||
] do-one
|
||||
] times
|
||||
] [ ] make ;
|
||||
|
||||
|
||||
SYMBOL: last-quot
|
||||
SYMBOL: first-arg
|
||||
: runtime-check
|
||||
SYMBOL: second-arg
|
||||
: 0-runtime-check ( quot -- )
|
||||
#! Checks the runtime only, not the compiler
|
||||
#! Evaluates the quotation twice and makes sure the results agree
|
||||
[ last-quot set ] keep
|
||||
[ call ] keep
|
||||
call
|
||||
! 2dup swap unparse write " " write unparse print
|
||||
! 2dup swap unparse write " " write unparse print flush
|
||||
= [ last-quot get . "problem in runtime" throw ] unless ;
|
||||
|
||||
: runtime-check-1
|
||||
: 1-runtime-check ( quot -- )
|
||||
#! Checks the runtime only, not the compiler
|
||||
#! Evaluates the quotation twice and makes sure the results agree
|
||||
#! For quotations that are given one argument
|
||||
[ last-quot set first-arg set ] 2keep
|
||||
[ call ] 2keep
|
||||
call
|
||||
2dup swap unparse write " " write unparse print
|
||||
2dup swap unparse write " " write unparse print flush
|
||||
= [ "problem in runtime" throw ] unless ;
|
||||
|
||||
: interp-runtime-check ( quot -- )
|
||||
! dup .
|
||||
[ last-quot set ] keep
|
||||
[ call ] keep call ! compile-1
|
||||
! 2dup swap unparse write " " write unparse print
|
||||
= [ "problem in math" throw ] unless ;
|
||||
|
||||
: interp-compile-check-1 ( x quot -- )
|
||||
.s flush
|
||||
[ last-quot set ] keep
|
||||
: 1-interpreted-vs-compiled-check ( x quot -- )
|
||||
#! Checks the runtime output vs the compiler output
|
||||
#! quot: ( x -- y )
|
||||
2dup swap unparse write " " write . flush
|
||||
[ last-quot set first-arg set ] 2keep
|
||||
[ call ] 2keep compile-1
|
||||
2dup swap unparse write " " write unparse print
|
||||
= [ "problem in math" throw ] unless ;
|
||||
2dup swap unparse write " " write unparse print flush
|
||||
= [ "problem in math1" throw ] unless ;
|
||||
|
||||
: interp-compile-check-2 ( x quot -- )
|
||||
: 2-interpreted-vs-compiled-check ( x y quot -- )
|
||||
#! Checks the runtime output vs the compiler output
|
||||
#! quot: ( x y -- z )
|
||||
.s flush
|
||||
[ last-quot set ] keep
|
||||
[ last-quot set first-arg set second-arg set ] 3keep
|
||||
[ call ] 3keep compile-1
|
||||
2dup swap unparse write " " write unparse print
|
||||
= [ "problem in math" throw ] unless ;
|
||||
2dup swap unparse write " " write unparse print flush
|
||||
= [ "problem in math2" throw ] unless ;
|
||||
|
||||
: interp-compile-check* ( quot -- )
|
||||
dup .
|
||||
>r 100 200 300 400 r> [ call 4array ] keep
|
||||
>r 100 200 300 400 r> compile-1 4array
|
||||
= [ "problem found! (compile-check*)" throw ] unless ;
|
||||
|
||||
: interp-compile-check-catch ( quot -- )
|
||||
: 0-interpreted-vs-compiled-check-catch ( quot -- )
|
||||
#! Check the runtime output vs the compiler output for words that throw
|
||||
#!
|
||||
dup .
|
||||
[ last-quot set ] keep
|
||||
[ catch [ "caught: " write dup print-error ] when* ] keep
|
||||
[ compile-1 ] catch [ nip "caught: " write dup print-error ] when*
|
||||
= [ "problem in math" throw ] unless ;
|
||||
= [ "problem in math3" throw ] unless ;
|
||||
|
||||
: update-math-xt ( -- )
|
||||
math-1 [ update-xt ] each
|
||||
math-throw-1 [ update-xt ] each
|
||||
math-2 [ update-xt ] each
|
||||
math-throw-2 [ update-xt ] each ;
|
||||
: 1-interpreted-vs-compiled-check-catch ( quot -- )
|
||||
#! Check the runtime output vs the compiler output for words that throw
|
||||
2dup swap unparse write " " write .
|
||||
! "." write
|
||||
[ last-quot set first-arg set ] 2keep
|
||||
[ catch [ nip "caught: " write dup print-error ] when* ] 2keep
|
||||
[ compile-1 ] catch [ 2nip "caught: " write dup print-error ] when*
|
||||
= [ "problem in math4" throw ] unless ;
|
||||
|
||||
: update-xt-check ( quot -- )
|
||||
update-math-xt
|
||||
dup .
|
||||
[ last-quot set ] keep
|
||||
[ call ] keep
|
||||
[ peek update-xt ] keep call
|
||||
2dup swap unparse write " " write unparse print
|
||||
= [ "update-xt problem" throw ] unless ;
|
||||
: 2-interpreted-vs-compiled-check-catch ( quot -- )
|
||||
#! Check the runtime output vs the compiler output for words that throw
|
||||
! 3dup rot unparse write " " write swap unparse write " " write .
|
||||
"." write
|
||||
[ last-quot set first-arg set second-arg set ] 3keep
|
||||
[ catch [ 2nip "caught: " write dup print-error ] when* ] 3keep
|
||||
[ compile-1 ] catch [ 2nip nip "caught: " write dup print-error ] when*
|
||||
= [ "problem in math5" throw ] unless ;
|
||||
|
||||
|
||||
! RANDOM QUOTATIONS TO TEST
|
||||
: random-1-integer>x-quot ( -- quot ) 1-integer>x nth-rand unit ;
|
||||
: random-1-ratio>x-quot ( -- quot ) 1-ratio>x nth-rand unit ;
|
||||
: random-1-float>x-quot ( -- quot ) 1-float>x nth-rand unit ;
|
||||
: random-1-complex>x-quot ( -- quot ) 1-complex>x nth-rand unit ;
|
||||
|
||||
: test-1-integer>x ( -- )
|
||||
random-integer random-1-integer>x-quot 1-interpreted-vs-compiled-check ;
|
||||
: test-1-ratio>x ( -- )
|
||||
random-ratio random-1-ratio>x-quot 1-interpreted-vs-compiled-check ;
|
||||
: test-1-float>x ( -- )
|
||||
random-float random-1-float>x-quot 1-interpreted-vs-compiled-check ;
|
||||
: test-1-complex>x ( -- )
|
||||
random-complex random-1-complex>x-quot 1-interpreted-vs-compiled-check ;
|
||||
|
||||
|
||||
: random-1-float>float-quot ( -- ) 1-float>float nth-rand unit ;
|
||||
: random-2-float>float-quot ( -- ) 2-float>float nth-rand unit ;
|
||||
: nrandom-2-float>float-quot ( -- )
|
||||
[
|
||||
5
|
||||
[
|
||||
{
|
||||
[ 2-float>float nth-rand , random-float , ]
|
||||
[ 1-float>float nth-rand , ]
|
||||
} do-one
|
||||
] times
|
||||
2-float>float nth-rand ,
|
||||
] [ ] make ;
|
||||
|
||||
: test-1-float>float ( -- )
|
||||
random-float random-1-float>float-quot 1-interpreted-vs-compiled-check ;
|
||||
: test-2-float>float ( -- )
|
||||
random-float random-float random-2-float>float-quot
|
||||
2-interpreted-vs-compiled-check ;
|
||||
|
||||
: test-n-2-float>float ( -- )
|
||||
random-float random-float nrandom-2-float>float-quot
|
||||
2-interpreted-vs-compiled-check ;
|
||||
|
||||
: test-1-integer>x-runtime ( -- )
|
||||
random-integer random-1-integer>x-quot 1-runtime-check ;
|
||||
|
||||
: random-1-integer>x-throws-quot ( -- ) 1-integer>x-throws nth-rand unit ;
|
||||
: random-1-ratio>x-throws-quot ( -- ) 1-ratio>x-throws nth-rand unit ;
|
||||
: test-1-integer>x-throws ( -- )
|
||||
random-integer random-1-integer>x-throws-quot
|
||||
1-interpreted-vs-compiled-check-catch ;
|
||||
: test-1-ratio>x-throws ( -- )
|
||||
random-ratio random-1-ratio>x-throws-quot
|
||||
1-interpreted-vs-compiled-check-catch ;
|
||||
|
||||
|
||||
|
||||
|
||||
! 1-arg tests
|
||||
|
||||
: random-integer>x-quot random-integer integer>x nth-rand unit cons ;
|
||||
: random-ratio>x-quot ( -- ) random-ratio ratio>x nth-rand unit cons ;
|
||||
: random-float>x-quot ( -- ) random-float float>x nth-rand unit cons ;
|
||||
: random-complex>x-quot ( -- ) random-complex complex>x nth-rand unit cons ;
|
||||
|
||||
: test-integer>x ( -- ) random-integer>x-quot interp-runtime-check ;
|
||||
: test-ratio>x ( -- ) random-ratio>x-quot interp-runtime-check ;
|
||||
: test-float>x ( -- ) random-float>x-quot interp-runtime-check ;
|
||||
: test-complex>x ( -- ) random-complex>x-quot interp-runtime-check ;
|
||||
|
||||
: test-integer>x-runtime ( -- ) random-integer>x-quot runtime-check ;
|
||||
: test-integer>x-1-runtime ( -- ) random-integer>x-quot runtime-check ;
|
||||
|
||||
: test-integer>x-1 ( -- )
|
||||
random-integer integer>x nth-rand unit interp-compile-check-1 ;
|
||||
: test-ratio>x-1 ( -- )
|
||||
random-ratio ratio>x nth-rand unit interp-compile-check-1 ;
|
||||
: test-float>x-1 ( -- )
|
||||
random-float float>x nth-rand unit interp-compile-check-1 ;
|
||||
: test-complex>x-1 ( -- )
|
||||
random-complex complex>x nth-rand unit interp-compile-check-1 ;
|
||||
|
||||
: test-integer>x-throws ( -- )
|
||||
random-integer integer>x-throw nth-rand unit cons interp-compile-check-catch ;
|
||||
: test-ratio>x-throws ( -- )
|
||||
random-ratio ratio>x-throw nth-rand unit cons interp-compile-check-catch ;
|
||||
|
||||
: test-update-xt ( -- )
|
||||
random-integer random-integer 2integer>x nth-rand unit cons cons update-xt-check ;
|
||||
|
||||
! 2-arg tests
|
||||
: test-2integer>x ( -- )
|
||||
random-integer random-integer 2integer>x nth-rand unit cons cons interp-runtime-check ;
|
||||
|
||||
: test-2ratio>x ( -- )
|
||||
random-ratio random-ratio 2ratio>x nth-rand unit cons cons interp-runtime-check ;
|
||||
|
||||
: test-2float>x ( -- )
|
||||
random-float random-float 2float>x nth-rand unit cons cons interp-runtime-check ;
|
||||
|
||||
: test-2complex>x ( -- )
|
||||
random-complex random-complex 2complex>x nth-rand unit cons cons interp-runtime-check ;
|
||||
|
||||
|
||||
: test-2random>x ( -- )
|
||||
random-number random-number math-2 nth-rand unit cons cons interp-runtime-check ;
|
||||
|
||||
|
||||
|
||||
: test-2integer>x-2 ( -- )
|
||||
random-integer random-integer 2integer>x nth-rand unit interp-compile-check-2 ;
|
||||
|
||||
: test-2ratio>x-2 ( -- )
|
||||
random-ratio random-ratio 2ratio>x nth-rand unit interp-compile-check-2 ;
|
||||
|
||||
: test-2float>x-2 ( -- )
|
||||
random-float random-float 2float>x nth-rand unit interp-compile-check-2 ;
|
||||
|
||||
: test-2complex>x-2 ( -- )
|
||||
random-complex random-complex 2complex>x nth-rand unit interp-compile-check-2 ;
|
||||
|
||||
|
||||
! : test-2integer>x-1 ( -- )
|
||||
! random-integer random-integer-quotation-1 interp-compile-check-1 ;
|
||||
|
||||
|
||||
: test-2integer>x-throws ( -- )
|
||||
: test-2-integer>x-throws ( -- )
|
||||
[
|
||||
random-integer , random-integer ,
|
||||
math-throw-2 nth-rand ,
|
||||
] [ ] make interp-compile-check-catch ;
|
||||
2-x>y-throws nth-rand ,
|
||||
] [ ] make 2-interpreted-vs-compiled-check-catch ;
|
||||
|
||||
: test-^-shift ( -- )
|
||||
! : test-^-shift ( -- )
|
||||
! [
|
||||
! 100 random-int 50 - ,
|
||||
! 100 random-int 50 - ,
|
||||
! { ^ shift } nth-rand ,
|
||||
! ] [ ] make 2-interpreted-vs-compiled-check-catch ;
|
||||
|
||||
! : test-^-ratio ( -- )
|
||||
! [
|
||||
! random-ratio , random-ratio , \ ^ ,
|
||||
! ] [ ] make interp-compile-check-catch ;
|
||||
|
||||
: test-0-float?-when
|
||||
[
|
||||
100 random-int 50 - ,
|
||||
100 random-int 50 - ,
|
||||
{ ^ shift } nth-rand ,
|
||||
] [ ] make interp-compile-check-catch ;
|
||||
random-number , \ dup , \ float? , 1-float>x nth-rand unit , \ when ,
|
||||
] [ ] make 0-runtime-check ;
|
||||
|
||||
: test-^-ratio ( -- )
|
||||
[
|
||||
random-ratio , random-ratio , \ ^ ,
|
||||
] [ ] make interp-compile-check-catch ;
|
||||
: test-1-integer?-when
|
||||
random-integer [
|
||||
\ dup , \ integer? , 1-integer>x nth-rand unit , \ when ,
|
||||
] [ ] make 1-interpreted-vs-compiled-check ;
|
||||
|
||||
: test-math {
|
||||
! test-integer>x
|
||||
! test-ratio>x
|
||||
! test-float>x
|
||||
! test-complex>x
|
||||
|
||||
! test-integer>x-1
|
||||
! test-ratio>x-1
|
||||
! test-float>x-1
|
||||
! test-complex>x-1
|
||||
|
||||
! test-integer>x-throws
|
||||
! test-ratio>x-throws
|
||||
|
||||
! ! test-update-xt
|
||||
! test-2integer>x
|
||||
! test-2ratio>x
|
||||
! test-2float>x
|
||||
! test-2complex>x
|
||||
test-2integer>x-2
|
||||
test-2ratio>x-2
|
||||
test-2float>x-2
|
||||
test-2complex>x-2
|
||||
! ! test-2integer>x-1
|
||||
! test-2integer>x-throws
|
||||
! test-^-shift
|
||||
! test-^-ratio
|
||||
} nth-rand unit call ;
|
||||
|
||||
|
||||
! Boolean logic tests
|
||||
: logic-0 ( -- seq )
|
||||
{ bootstrapping? f t } ;
|
||||
|
||||
: logic-1 ( -- seq )
|
||||
{
|
||||
not tuple? float? integer? complex? ratio? continuation? wrapper?
|
||||
number? rational? bignum? fixnum? float? primitive? symbol?
|
||||
compound? real?
|
||||
} ;
|
||||
! odd? even? power-of-2?
|
||||
: logic-2 ( -- seq ) { < > <= >= number= = eq? and or } ;
|
||||
: logic-3 ( -- seq ) { between? } ;
|
||||
: complex-logic-2 ( -- seq ) { number= = eq? and or } ;
|
||||
|
||||
: logic-0-test ( -- ) logic-0 nth-rand unit interp-runtime-check ;
|
||||
|
||||
: integer-logic-1-test ( -- )
|
||||
[
|
||||
random-integer , logic-1 nth-rand ,
|
||||
] [ ] make interp-runtime-check ;
|
||||
|
||||
: ratio-logic-1-test ( -- )
|
||||
[
|
||||
random-ratio , logic-1 nth-rand ,
|
||||
] [ ] make interp-runtime-check ;
|
||||
|
||||
: float-logic-1-test ( -- )
|
||||
[
|
||||
random-float , logic-1 nth-rand ,
|
||||
] [ ] make interp-runtime-check ;
|
||||
|
||||
: complex-logic-1-test ( -- )
|
||||
[
|
||||
random-complex , logic-1 nth-rand ,
|
||||
] [ ] make interp-runtime-check ;
|
||||
|
||||
|
||||
: integer-logic-2-test ( -- )
|
||||
[
|
||||
random-integer , random-integer , logic-2 nth-rand ,
|
||||
] [ ] make interp-runtime-check ;
|
||||
|
||||
: ratio-logic-2-test ( -- )
|
||||
[
|
||||
random-ratio , random-ratio , logic-2 nth-rand ,
|
||||
] [ ] make interp-runtime-check ;
|
||||
|
||||
: float-logic-2-test ( -- )
|
||||
[
|
||||
random-float , random-float , logic-2 nth-rand ,
|
||||
] [ ] make interp-runtime-check ;
|
||||
|
||||
: complex-logic-2-test ( -- )
|
||||
[
|
||||
random-complex , random-complex , complex-logic-2 nth-rand ,
|
||||
] [ ] make interp-runtime-check ;
|
||||
|
||||
|
||||
: string-to-math-test ( -- )
|
||||
[
|
||||
{
|
||||
[ random-integer , \ number>string , ]
|
||||
[ random-integer , \ number>string , \ string>number , ]
|
||||
} do-one
|
||||
] [ ] make interp-runtime-check ;
|
||||
|
||||
|
||||
: test-float?-when
|
||||
[
|
||||
random-number , \ dup , \ float? , float>x nth-rand unit , \ when ,
|
||||
] [ ] make interp-runtime-check ;
|
||||
|
||||
: test-integer?-when-1
|
||||
random-float [
|
||||
\ dup , \ float? , float>x nth-rand unit , \ when ,
|
||||
] [ ] make interp-compile-check-1 ;
|
||||
|
||||
: test-ratio?-when-1
|
||||
: test-1-ratio?-when
|
||||
random-ratio [
|
||||
\ dup , \ ratio? , ratio>x nth-rand unit , \ when ,
|
||||
] [ ] make interp-compile-check-1 ;
|
||||
\ dup , \ ratio? , 1-ratio>x nth-rand unit , \ when ,
|
||||
] [ ] make 1-interpreted-vs-compiled-check ;
|
||||
|
||||
: test-float?-when-1
|
||||
: test-1-float?-when
|
||||
random-float [
|
||||
\ dup , \ float? , float>x nth-rand unit , \ when ,
|
||||
] [ ] make interp-compile-check-1 ;
|
||||
\ dup , \ float? , 1-float>x nth-rand unit , \ when ,
|
||||
] [ ] make 1-interpreted-vs-compiled-check ;
|
||||
|
||||
: test-complex?-when-1
|
||||
: test-1-complex?-when
|
||||
random-complex [
|
||||
\ dup , \ complex? , complex>x nth-rand unit , \ when ,
|
||||
] [ ] make interp-compile-check-1 ;
|
||||
\ dup , \ complex? , 1-complex>x nth-rand unit , \ when ,
|
||||
] [ ] make 1-interpreted-vs-compiled-check ;
|
||||
|
||||
: stack-identity-0
|
||||
H{
|
||||
{ 1 drop }
|
||||
{ 1000000000000000000000000001 drop }
|
||||
{ -11111111111111111111111111 drop }
|
||||
{ -1 drop }
|
||||
{ 1.203 drop }
|
||||
{ -1.203 drop }
|
||||
{ "asdf" drop }
|
||||
} ; inline
|
||||
: stack-identity-1
|
||||
H{
|
||||
{ dup drop }
|
||||
{ >r r> }
|
||||
} ; inline
|
||||
: stack-identity-2
|
||||
H{
|
||||
{ swap swap }
|
||||
{ over drop }
|
||||
{ dupd nip }
|
||||
{ 2dup 2drop }
|
||||
} ; inline
|
||||
: stack-identity-3
|
||||
H{
|
||||
{ rot -rot }
|
||||
{ pick drop }
|
||||
{ 3dup 3drop }
|
||||
} ; inline
|
||||
: stack-identity-4
|
||||
H{
|
||||
{ 2swap 2swap }
|
||||
} ; inline
|
||||
|
||||
: get-stack-identity-table ( n -- hash )
|
||||
: many-word-test ( -- )
|
||||
#! defines words a1000 down to a0, which does a trivial addition
|
||||
"random-tester-scratchpad" vocabularies get remove-hash
|
||||
"random-tester-scratchpad" [ ensure-vocab ] keep use+
|
||||
"a0" "random-tester-scratchpad" create [ 1 1 + ] define-compound
|
||||
100 [
|
||||
[ 1+ "a" swap unparse append "random-tester-scratchpad" create ] keep
|
||||
"a" swap unparse append [ parse ] catch [ 0 :res ] when define-compound
|
||||
] each ;
|
||||
|
||||
: compile-loop ( -- )
|
||||
10 [ many-word-test "a100" parse first compile ] times ;
|
||||
|
||||
: random-test
|
||||
{
|
||||
{ [ dup 0 = ] [ drop stack-identity-0 ] }
|
||||
{ [ dup 1 = ] [ drop stack-identity-1 ] }
|
||||
{ [ dup 2 = ] [ drop stack-identity-2 ] }
|
||||
{ [ dup 3 = ] [ drop stack-identity-3 ] }
|
||||
{ [ dup 4 = ] [ drop stack-identity-4 ] }
|
||||
{ [ t ] [ drop f ] }
|
||||
} cond ;
|
||||
|
||||
: get-stack-identity-table<= ( n -- hash )
|
||||
1+ random-int get-stack-identity-table ;
|
||||
|
||||
|
||||
: random-stack-identity ( n -- quot )
|
||||
#! n is number of items on stack
|
||||
[
|
||||
max-length random-int
|
||||
[ dup get-stack-identity-table<= random-hash-entry swap , , ] times
|
||||
drop
|
||||
] [ ] make ;
|
||||
|
||||
|
||||
: test-random-stack-identity ( -- )
|
||||
4 random-stack-identity interp-compile-check* ;
|
||||
|
||||
|
||||
! change the % to make longer quotations
|
||||
: if-quot ( -- )
|
||||
[
|
||||
random-ratio , random-ratio , logic-2 nth-rand ,
|
||||
2 [ 30% [ if-quot ] [ random-ratio-quotation-1 ] if unit % ] times
|
||||
\ if ,
|
||||
] [ ] make ;
|
||||
|
||||
: when-quot
|
||||
[
|
||||
random-ratio , random-ratio , logic-2 nth-rand ,
|
||||
90% [ when-quot ] [ random-ratio-quotation-1 ] if unit %
|
||||
coin-flip \ when \ unless ? ,
|
||||
] [ ] make ;
|
||||
|
||||
: nested-ifs ( -- quot )
|
||||
[
|
||||
random-ratio ,
|
||||
if-quot %
|
||||
! when-quot %
|
||||
] [ ] make ;
|
||||
|
||||
: test-if ( -- ) nested-ifs interp-runtime-check ;
|
||||
|
||||
: random-test ( -- )
|
||||
{
|
||||
test-if
|
||||
test-random-stack-identity
|
||||
test-math
|
||||
}
|
||||
nth-rand execute ;
|
||||
|
||||
|
||||
: watch-simplifier ( -- )
|
||||
[
|
||||
dup word-def dataflow optimize
|
||||
linearize [ split-blocks simplify . ] hash-each
|
||||
] with-compiler ;
|
||||
|
||||
test-1-integer>x
|
||||
test-1-ratio>x
|
||||
test-1-float>x
|
||||
test-1-complex>x
|
||||
test-1-integer>x-throws
|
||||
test-1-ratio>x-throws
|
||||
test-1-float>float
|
||||
test-2-float>float
|
||||
test-n-2-float>float
|
||||
test-1-integer>x-runtime
|
||||
! test-0-float?-when
|
||||
test-1-integer?-when
|
||||
test-1-ratio?-when
|
||||
test-1-float?-when
|
||||
test-1-complex?-when
|
||||
full-gc
|
||||
} nth-rand execute ;
|
||||
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
USING: kernel math sequences namespaces errors hashtables words arrays parser
|
||||
compiler syntax lists io ;
|
||||
USING: inspector prettyprint ;
|
||||
USING: optimizer compiler-frontend compiler-backend inference ;
|
||||
USING: kernel math sequences namespaces errors hashtables words
|
||||
arrays parser compiler syntax io inspector prettyprint optimizer
|
||||
inference ;
|
||||
IN: random-tester
|
||||
|
||||
! Tweak me
|
||||
: max-length 7 ; inline
|
||||
: max-length 15 ; inline
|
||||
: max-value 1000000000 ; inline
|
||||
|
||||
: 10% ( -- bool ) 10 random-int 8 > ;
|
||||
|
@ -31,11 +30,11 @@ IN: random-tester
|
|||
|
||||
SYMBOL: special-integers
|
||||
[ { -1 0 1 } % most-negative-fixnum , most-positive-fixnum , first-bignum , ]
|
||||
{ } make \ special-integers set
|
||||
{ } make \ special-integers set-global
|
||||
: special-integers ( -- seq ) \ special-integers get ;
|
||||
SYMBOL: special-floats
|
||||
[ { 0.0 -0.0 } % e , pi , 1./0. , -1./0. , 0./0. , epsilon , epsilon neg , ]
|
||||
{ } make \ special-floats set
|
||||
{ } make \ special-floats set-global
|
||||
: special-floats ( -- seq ) \ special-floats get ;
|
||||
SYMBOL: special-complexes
|
||||
[
|
||||
|
@ -44,7 +43,7 @@ SYMBOL: special-complexes
|
|||
0 pi rect> , 0 pi neg rect> , pi neg 0 rect> , pi pi rect> ,
|
||||
pi pi neg rect> , pi neg pi rect> , pi neg pi neg rect> ,
|
||||
e neg e neg rect> , e e rect> ,
|
||||
] { } make \ special-complexes set
|
||||
] { } make \ special-complexes set-global
|
||||
: special-complexes ( -- seq ) \ special-complexes get ;
|
||||
|
||||
: random-fixnum ( -- fixnum )
|
||||
|
@ -53,12 +52,12 @@ SYMBOL: special-complexes
|
|||
: random-bignum ( -- bignum )
|
||||
400 random-bits first-bignum + coin-flip [ neg ] when ;
|
||||
|
||||
: random-integer
|
||||
: random-integer ( -- n )
|
||||
coin-flip [
|
||||
random-fixnum
|
||||
] [
|
||||
coin-flip [ random-bignum ] [ special-integers nth-rand ] if
|
||||
] if ;
|
||||
random-fixnum
|
||||
] [
|
||||
coin-flip [ random-bignum ] [ special-integers nth-rand ] if
|
||||
] if ;
|
||||
|
||||
: random-positive-integer ( -- int )
|
||||
random-integer dup 0 < [
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue